isula-build/patch/0046-check-if-add-default-tag-to-image-name-when-using-pu.patch
DCCooper 950f2f8ba2 isula-build:Sync upstream patches
Signed-off-by: DCCooper <1866858@gmail.com>
2021-03-03 19:29:30 +08:00

337 lines
9.5 KiB
Diff

From 6ce9d998d0b8e15d7a673626a54477a0bfc9f768 Mon Sep 17 00:00:00 2001
From: meilier <xingweizheng@huawei.com>
Date: Wed, 3 Feb 2021 01:04:17 +0800
Subject: [PATCH 08/10] check if add default tag to image name when using push
and save command
---
daemon/pull_test.go | 6 +-
daemon/push.go | 6 ++
daemon/push_test.go | 13 ++-
daemon/save.go | 8 ++
daemon/save_test.go | 193 ++++++++++++++++++++++++++++++++++++++++++++
image/image.go | 23 ++++++
6 files changed, 246 insertions(+), 3 deletions(-)
create mode 100644 daemon/save_test.go
diff --git a/daemon/pull_test.go b/daemon/pull_test.go
index 67459d19..27a4d6e8 100644
--- a/daemon/pull_test.go
+++ b/daemon/pull_test.go
@@ -58,7 +58,6 @@ func (c *controlPullServer) Send(response *pb.PullResponse) error {
func init() {
reexec.Init()
-
}
func prepare(t *testing.T) daemonTestOptions {
@@ -100,7 +99,10 @@ func TestPull(t *testing.T) {
defer tmpClean(d)
options := &storage.ImageOptions{}
- d.Daemon.localStore.CreateImage(stringid.GenerateRandomID(), []string{"image:test"}, "", "", options)
+ _, err := d.Daemon.localStore.CreateImage(stringid.GenerateRandomID(), []string{"image:test"}, "", "", options)
+ if err != nil {
+ t.Fatalf("create image with error: %v", err)
+ }
testcases := []struct {
name string
diff --git a/daemon/push.go b/daemon/push.go
index e6053dd8..4e3a6ed9 100644
--- a/daemon/push.go
+++ b/daemon/push.go
@@ -63,6 +63,12 @@ func (b *Backend) Push(req *pb.PushRequest, stream pb.Control_PushServer) error
return err
}
+ imageName, err := image.CheckAndAddDefaultTag(opt.imageName, opt.localStore)
+ if err != nil {
+ return err
+ }
+ opt.imageName = imageName
+
manifestType, gErr := exporter.GetManifestType(opt.format)
if gErr != nil {
return gErr
diff --git a/daemon/push_test.go b/daemon/push_test.go
index 573e97fe..f4a9e2b1 100644
--- a/daemon/push_test.go
+++ b/daemon/push_test.go
@@ -79,10 +79,21 @@ func TestPush(t *testing.T) {
Format: "oci",
},
},
+ {
+ name: "manifestNotExist fine without tag latest",
+ pushRequest: &pb.PushRequest{
+ PushID: stringid.GenerateNonCryptoID()[:constant.DefaultIDLen],
+ ImageName: "127.0.0.1/no-repository/no-name",
+ Format: "oci",
+ },
+ },
}
options := &storage.ImageOptions{}
- d.Daemon.localStore.CreateImage(stringid.GenerateRandomID(), []string{"127.0.0.1/no-repository/no-name:latest"}, "", "", options)
+ _, err := d.Daemon.localStore.CreateImage(stringid.GenerateRandomID(), []string{"127.0.0.1/no-repository/no-name:latest"}, "", "", options)
+ if err != nil {
+ t.Fatalf("create image with error: %v", err)
+ }
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
diff --git a/daemon/save.go b/daemon/save.go
index c6411e04..fd6174b4 100644
--- a/daemon/save.go
+++ b/daemon/save.go
@@ -79,6 +79,14 @@ func (b *Backend) Save(req *pb.SaveRequest, stream pb.Control_SaveServer) error
return errors.New("wrong image format provided")
}
+ for i, imageName := range opts.oriImgList {
+ nameWithTag, cErr := image.CheckAndAddDefaultTag(imageName, opts.localStore)
+ if cErr != nil {
+ return cErr
+ }
+ opts.oriImgList[i] = nameWithTag
+ }
+
defer func() {
if err != nil {
if rErr := os.Remove(opts.outputPath); rErr != nil && !os.IsNotExist(rErr) {
diff --git a/daemon/save_test.go b/daemon/save_test.go
new file mode 100644
index 00000000..a59086a8
--- /dev/null
+++ b/daemon/save_test.go
@@ -0,0 +1,193 @@
+// Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
+// isula-build licensed under the Mulan PSL v2.
+// You can use this software according to the terms and conditions of the Mulan PSL v2.
+// You may obtain a copy of Mulan PSL v2 at:
+// http://license.coscl.org.cn/MulanPSL2
+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+// PURPOSE.
+// See the Mulan PSL v2 for more details.
+// Author: Weizheng Xing
+// Create: 2020-02-03
+// Description: This file tests Save interface
+
+package daemon
+
+import (
+ "context"
+ "testing"
+
+ "github.com/containers/storage"
+ "github.com/containers/storage/pkg/reexec"
+ "github.com/containers/storage/pkg/stringid"
+ "github.com/pkg/errors"
+ "golang.org/x/sync/errgroup"
+ "google.golang.org/grpc"
+ "gotest.tools/v3/assert"
+ "gotest.tools/v3/fs"
+
+ constant "isula.org/isula-build"
+ pb "isula.org/isula-build/api/services"
+ _ "isula.org/isula-build/exporter/register"
+ "isula.org/isula-build/pkg/logger"
+)
+
+type controlSaveServer struct {
+ grpc.ServerStream
+}
+
+func (c *controlSaveServer) Context() context.Context {
+ return context.Background()
+}
+
+func (c *controlSaveServer) Send(response *pb.SaveResponse) error {
+ if response.Log == "error" {
+ return errors.New("error happened")
+ }
+ return nil
+}
+
+func init() {
+ reexec.Init()
+}
+
+func TestSave(t *testing.T) {
+ d := prepare(t)
+ defer tmpClean(d)
+
+ //TODO: create image manually and save
+ options := &storage.ImageOptions{}
+ img, err := d.Daemon.localStore.CreateImage(stringid.GenerateRandomID(), []string{"image:latest"}, "", "", options)
+ if err != nil {
+ t.Fatalf("create image with error: %v", err)
+ }
+
+ _, err = d.Daemon.localStore.CreateImage(stringid.GenerateRandomID(), []string{"image2:test"}, "", "", options)
+ if err != nil {
+ t.Fatalf("create image with error: %v", err)
+ }
+
+ tempTarfileDir := fs.NewDir(t, t.Name())
+ defer tempTarfileDir.Remove()
+
+ testcases := []struct {
+ name string
+ req *pb.SaveRequest
+ wantErr bool
+ errString string
+ }{
+ {
+ name: "normal case save with repository[:tag]",
+ req: &pb.SaveRequest{
+ SaveID: stringid.GenerateNonCryptoID()[:constant.DefaultIDLen],
+ Images: []string{"image:latest"},
+ Path: tempTarfileDir.Join("repotag.tar"),
+ Format: "docker",
+ },
+ wantErr: true,
+ errString: "file does not exist",
+ },
+ {
+ name: "normal case save with repository add default latest",
+ req: &pb.SaveRequest{
+ SaveID: stringid.GenerateNonCryptoID()[:constant.DefaultIDLen],
+ Images: []string{"image"},
+ Path: tempTarfileDir.Join("repolatest.tar"),
+ Format: "oci",
+ },
+ wantErr: true,
+ errString: "file does not exist",
+ },
+ {
+ name: "normal case with imageid",
+ req: &pb.SaveRequest{
+ SaveID: stringid.GenerateNonCryptoID()[:constant.DefaultIDLen],
+ Images: []string{img.ID},
+ Path: tempTarfileDir.Join("imageid.tar"),
+ Format: "docker",
+ },
+ wantErr: true,
+ errString: "file does not exist",
+ },
+ {
+ name: "normal case save multiple images with repository and ID",
+ req: &pb.SaveRequest{
+ SaveID: stringid.GenerateNonCryptoID()[:constant.DefaultIDLen],
+ Images: []string{"image2:test", img.ID},
+ Path: tempTarfileDir.Join("double.tar"),
+ Format: "docker",
+ },
+ wantErr: true,
+ errString: "file does not exist",
+ },
+ {
+ name: "abnormal case save image that not exist in local store",
+ req: &pb.SaveRequest{
+ SaveID: stringid.GenerateNonCryptoID()[:constant.DefaultIDLen],
+ Images: []string{"noexist", img.ID},
+ Path: tempTarfileDir.Join("notexist.tar"),
+ Format: "docker",
+ },
+ wantErr: true,
+ errString: "failed to parse image",
+ },
+ {
+ name: "abnormal case wrong image format",
+ req: &pb.SaveRequest{
+ SaveID: stringid.GenerateNonCryptoID()[:constant.DefaultIDLen],
+ Images: []string{"image", img.ID},
+ Path: tempTarfileDir.Join("image.tar"),
+ Format: "dock",
+ },
+ wantErr: true,
+ errString: "wrong image format provided",
+ },
+ }
+
+ for _, tc := range testcases {
+ t.Run(tc.name, func(t *testing.T) {
+ stream := &controlSaveServer{}
+
+ err := d.Daemon.backend.Save(tc.req, stream)
+ if tc.wantErr == true {
+ assert.ErrorContains(t, err, tc.errString)
+ }
+ if tc.wantErr == false {
+ assert.NilError(t, err)
+ }
+ })
+ }
+
+}
+
+func TestSaveHandler(t *testing.T) {
+ ctx := context.TODO()
+ eg, _ := errgroup.WithContext(ctx)
+
+ eg.Go(saveHandlerPrint("Push Response"))
+ eg.Go(saveHandlerPrint(""))
+ eg.Go(saveHandlerPrint("error"))
+
+ eg.Wait()
+}
+
+func saveHandlerPrint(message string) func() error {
+ return func() error {
+ stream := &controlSaveServer{}
+ cliLogger := logger.NewCliLogger(constant.CliLogBufferLen)
+
+ ctx := context.TODO()
+ eg, _ := errgroup.WithContext(ctx)
+
+ eg.Go(messageHandler(stream, cliLogger))
+ eg.Go(func() error {
+ cliLogger.Print(message)
+ cliLogger.CloseContent()
+ return nil
+ })
+
+ eg.Wait()
+
+ return nil
+ }
+}
diff --git a/image/image.go b/image/image.go
index 36785bdf..1e480391 100644
--- a/image/image.go
+++ b/image/image.go
@@ -689,3 +689,26 @@ func tryResolveNameInRegistries(name string, sc *types.SystemContext) ([]string,
}
return candidates, exporter.DockerTransport
}
+
+// CheckAndAddDefaultTag checks if src is format of repository[:tag], add default tag if src without tag
+func CheckAndAddDefaultTag(imageName string, store *store.Store) (string, error) {
+ _, img, err := FindImage(store, imageName)
+ if err != nil {
+ return "", errors.Wrapf(err, "find src image: %q failed", imageName)
+ }
+
+ defaultTag := "latest"
+ for _, name := range img.Names {
+ // for imageName is the format of repository[:tag]
+ if imageName == name {
+ return imageName, nil
+ }
+ // for name is the format of repository
+ if fmt.Sprintf("%s:%s", imageName, defaultTag) == name {
+ return name, nil
+ }
+ }
+
+ // for imageName is the format of imageID
+ return imageName, nil
+}
--
2.27.0