From f3f4360f9a2237dc72f7200e3048368f9f180e71 Mon Sep 17 00:00:00 2001 From: DCCooper <1866858@gmail.com> Date: Thu, 4 Nov 2021 16:53:15 +0800 Subject: [PATCH] isula-build: sync upstream to fix panic when using image ID to save separated image Signed-off-by: DCCooper <1866858@gmail.com> --- VERSION-openeuler | 2 +- git-commit | 2 +- isula-build.spec | 8 +- ...panic-when-using-image-ID-to-save-se.patch | 305 ++++++++++++++++++ series.conf | 1 + 5 files changed, 315 insertions(+), 3 deletions(-) create mode 100644 patch/0089-isula-build-fix-panic-when-using-image-ID-to-save-se.patch diff --git a/VERSION-openeuler b/VERSION-openeuler index 3b6ec87..1021efb 100644 --- a/VERSION-openeuler +++ b/VERSION-openeuler @@ -1 +1 @@ -0.9.5-18 +0.9.5-19 diff --git a/git-commit b/git-commit index 317f3e6..f9f564e 100644 --- a/git-commit +++ b/git-commit @@ -1 +1 @@ -f7609ebf9b086beeb7ef204cb89a70c4a34fde84 +d69cf1b4393964819a1515a5399c1a2ac10c8d03 diff --git a/isula-build.spec b/isula-build.spec index 8e6c3a3..2664d08 100644 --- a/isula-build.spec +++ b/isula-build.spec @@ -2,7 +2,7 @@ Name: isula-build Version: 0.9.5 -Release: 18 +Release: 19 Summary: A tool to build container images License: Mulan PSL V2 URL: https://gitee.com/openeuler/isula-build @@ -85,6 +85,12 @@ fi /usr/share/bash-completion/completions/isula-build %changelog +* Thu Nov 04 2021 DCCooper <1866858@gmail.com> - 0.9.5-19 +- Type:bugfix +- CVE:NA +- SUG:restat +- DESC:fix panic when using image ID to save separated image + * Wed Nov 03 2021 lixiang - 0.9.5-18 - Type:bugfix - CVE:NA diff --git a/patch/0089-isula-build-fix-panic-when-using-image-ID-to-save-se.patch b/patch/0089-isula-build-fix-panic-when-using-image-ID-to-save-se.patch new file mode 100644 index 0000000..02188a7 --- /dev/null +++ b/patch/0089-isula-build-fix-panic-when-using-image-ID-to-save-se.patch @@ -0,0 +1,305 @@ +From 2b845fdb3e3c9d23b0fec856bcd5ce8ced868683 Mon Sep 17 00:00:00 2001 +From: DCCooper <1866858@gmail.com> +Date: Thu, 4 Nov 2021 14:38:20 +0800 +Subject: [PATCH] isula-build:fix panic when using image ID to save separated + image + +Signed-off-by: DCCooper <1866858@gmail.com> +--- + daemon/save.go | 120 +++++++++++++-------- + .../src/cover_test_save_separated_image_failed.sh | 28 +++++ + .../src/cover_test_save_separated_image_success.sh | 24 ++++- + 3 files changed, 127 insertions(+), 45 deletions(-) + +diff --git a/daemon/save.go b/daemon/save.go +index 9ad4e03..9c5e563 100644 +--- a/daemon/save.go ++++ b/daemon/save.go +@@ -83,6 +83,7 @@ type separatorSave struct { + base string + lib string + dest string ++ renameFile string + enabled bool + } + +@@ -141,15 +142,7 @@ type tarballInfo struct { + BaseLayers []string `json:"baseLayer"` + } + +-func (b *Backend) getSaveOptions(req *pb.SaveRequest) (saveOptions, error) { +- var sep = separatorSave{ +- base: req.GetSep().GetBase(), +- lib: req.GetSep().GetLib(), +- dest: req.GetSep().GetDest(), +- log: logrus.WithFields(logrus.Fields{"SaveID": req.GetSaveID()}), +- enabled: req.GetSep().GetEnabled(), +- } +- ++func (b *Backend) getSaveOptions(req *pb.SaveRequest) saveOptions { + var opt = saveOptions{ + sysCtx: image.GetSystemContext(), + localStore: b.daemon.localStore, +@@ -161,11 +154,19 @@ func (b *Backend) getSaveOptions(req *pb.SaveRequest) (saveOptions, error) { + outputPath: req.GetPath(), + logger: logger.NewCliLogger(constant.CliLogBufferLen), + logEntry: logrus.WithFields(logrus.Fields{"SaveID": req.GetSaveID(), "Format": req.GetFormat()}), +- sep: sep, + } + // normal save +- if !sep.enabled { +- return opt, nil ++ if !req.GetSep().GetEnabled() { ++ return opt ++ } ++ ++ opt.sep = separatorSave{ ++ base: req.GetSep().GetBase(), ++ lib: req.GetSep().GetLib(), ++ dest: req.GetSep().GetDest(), ++ log: logrus.WithFields(logrus.Fields{"SaveID": req.GetSaveID()}), ++ enabled: req.GetSep().GetEnabled(), ++ renameFile: req.GetSep().GetRename(), + } + + // save separated image +@@ -175,44 +176,22 @@ func (b *Backend) getSaveOptions(req *pb.SaveRequest) (saveOptions, error) { + baseDir := filepath.Join(tmpRoot, baseUntarTempDirName) + libDir := filepath.Join(tmpRoot, libUntarTempDirName) + +- opt.sep.tmpDir = imageTmpDir{ +- app: appDir, +- base: baseDir, +- lib: libDir, +- untar: untar, +- root: tmpRoot, +- } ++ opt.sep.tmpDir = imageTmpDir{app: appDir, base: baseDir, lib: libDir, untar: untar, root: tmpRoot} + opt.outputPath = filepath.Join(untar, unionTarName) +- renameFile := req.GetSep().GetRename() +- if len(renameFile) != 0 { +- var reName []renames +- if err := util.LoadJSONFile(renameFile, &reName); err != nil { +- return saveOptions{}, err +- } +- opt.sep.renameData = reName +- } + +- return opt, nil ++ return opt + } + + // Save receives a save request and save the image(s) into tarball +-func (b *Backend) Save(req *pb.SaveRequest, stream pb.Control_SaveServer) error { ++func (b *Backend) Save(req *pb.SaveRequest, stream pb.Control_SaveServer) (err error) { + logrus.WithFields(logrus.Fields{ + "SaveID": req.GetSaveID(), + "Format": req.GetFormat(), + }).Info("SaveRequest received") + +- var err error +- opts, err := b.getSaveOptions(req) +- if err != nil { +- return errors.Wrap(err, "process save options failed") +- } +- +- if err = checkFormat(&opts); err != nil { +- return err +- } +- if err = filterImageName(&opts); err != nil { +- return err ++ opts := b.getSaveOptions(req) ++ if err = opts.check(); err != nil { ++ return errors.Wrap(err, "check save options failed") + } + + defer func() { +@@ -299,7 +278,47 @@ func messageHandler(stream pb.Control_SaveServer, cliLogger *logger.Logger) func + } + } + +-func checkFormat(opts *saveOptions) error { ++func (opts *saveOptions) check() error { ++ if err := opts.checkImageNameIsID(); err != nil { ++ return err ++ } ++ if err := opts.checkFormat(); err != nil { ++ return err ++ } ++ if err := opts.filterImageName(); err != nil { ++ return err ++ } ++ if err := opts.checkRenameFile(); err != nil { ++ return err ++ } ++ ++ return nil ++} ++ ++func (opts *saveOptions) checkImageNameIsID() error { ++ imageNames := opts.oriImgList ++ if opts.sep.enabled { ++ if len(opts.sep.base) != 0 { ++ imageNames = append(imageNames, opts.sep.base) ++ } ++ if len(opts.sep.lib) != 0 { ++ imageNames = append(imageNames, opts.sep.lib) ++ } ++ } ++ for _, name := range imageNames { ++ _, img, err := image.FindImage(opts.localStore, name) ++ if err != nil { ++ return errors.Wrapf(err, "check image name failed when finding image name %q", name) ++ } ++ if strings.HasPrefix(img.ID, name) && opts.sep.enabled { ++ return errors.Errorf("using image ID %q as image name to save separated image is not allowed", name) ++ } ++ } ++ ++ return nil ++} ++ ++func (opts *saveOptions) checkFormat() error { + switch opts.format { + case constant.DockerTransport: + opts.format = constant.DockerArchiveTransport +@@ -312,7 +331,7 @@ func checkFormat(opts *saveOptions) error { + return nil + } + +-func filterImageName(opts *saveOptions) error { ++func (opts *saveOptions) filterImageName() error { + if opts.format == constant.OCIArchiveTransport { + opts.finalImageOrdered = opts.oriImgList + return nil +@@ -350,6 +369,18 @@ func filterImageName(opts *saveOptions) error { + return nil + } + ++func (opts *saveOptions) checkRenameFile() error { ++ if len(opts.sep.renameFile) != 0 { ++ var reName []renames ++ if err := util.LoadJSONFile(opts.sep.renameFile, &reName); err != nil { ++ return errors.Wrap(err, "check rename file failed") ++ } ++ opts.sep.renameData = reName ++ } ++ ++ return nil ++} ++ + func getLayerHashFromStorage(store *store.Store, name string) ([]string, error) { + if len(name) == 0 { + return nil, nil +@@ -770,6 +801,11 @@ func getLayersID(layer []string) []string { + + func (s *separatorSave) constructSingleImgInfo(mani imageManifest, store *store.Store) (imageInfo, error) { + var libLayers, appLayers []string ++ // image name should not be empty here ++ if len(mani.RepoTags) == 0 { ++ return imageInfo{}, errors.New("image name and tag is empty") ++ } ++ // if there is more than one repoTag, will use first one as image name + imageRepoFields := strings.Split(mani.RepoTags[0], ":") + imageLayers := getLayersID(mani.Layers) + +diff --git a/tests/src/cover_test_save_separated_image_failed.sh b/tests/src/cover_test_save_separated_image_failed.sh +index c64dcf5..66db580 100644 +--- a/tests/src/cover_test_save_separated_image_failed.sh ++++ b/tests/src/cover_test_save_separated_image_failed.sh +@@ -89,6 +89,33 @@ function test_run6() { + rm -rf "${workspace}"/Images + } + ++# using image id to save ++function test_run7() { ++ base_image_id=$(isula-build ctr-img images ${base_image_name} | tail -n 2 | head -n 1 | awk '{print $3}') ++ lib_image_id=$(isula-build ctr-img images ${lib_image_name} | tail -n 2 | head -n 1 | awk '{print $3}') ++ app_image_id=$(isula-build ctr-img images ${app1_image_name} | tail -n 2 | head -n 1 | awk '{print $3}') ++ app1_image_id=$(isula-build ctr-img images ${app2_image_name} | tail -n 2 | head -n 1 | awk '{print $3}') ++ # all name is image id ++ isula-build ctr-img save -b "${base_image_id}" -l "${lib_image_id}" -d "${workspace}"/Images "${app1_image_id}" "${app2_image_id}" ++ check_result_not_equal $? 0 ++ rm -rf "${workspace}"/Images ++ ++ # app name is image id ++ isula-build ctr-img save -b "${base_image_name}" -l "${lib_image_name}" -d "${workspace}"/Images "${app1_image_id}" "${app2_image_name}" ++ check_result_not_equal $? 0 ++ rm -rf "${workspace}"/Images ++ ++ # lib name is image id ++ isula-build ctr-img save -b "${base_image_name}" -l "${lib_image_id}" -d "${workspace}"/Images "${app1_image_name}" "${app2_image_name}" ++ check_result_not_equal $? 0 ++ rm -rf "${workspace}"/Images ++ ++ # base name is image id ++ isula-build ctr-img save -b "${base_image_id}" -l "${lib_image_name}" -d "${workspace}"/Images "${app1_image_name}" "${app2_image_name}" ++ check_result_not_equal $? 0 ++ rm -rf "${workspace}"/Images ++} ++ + function cleanup() { + rm -rf "${workspace}" + isula-build ctr-img rm "${bad_lib_image_name}" "${bad_app1_image_name}" "${bad_app2_image_name}" "${lib_image_name}" "${app1_image_name}" "${app2_image_name}" +@@ -102,6 +129,7 @@ test_run3 + test_run4 + test_run5 + test_run6 ++test_run7 + cleanup + # shellcheck disable=SC2154 + exit "${exit_flag}" +diff --git a/tests/src/cover_test_save_separated_image_success.sh b/tests/src/cover_test_save_separated_image_success.sh +index 2095bd3..68d2cae 100644 +--- a/tests/src/cover_test_save_separated_image_success.sh ++++ b/tests/src/cover_test_save_separated_image_success.sh +@@ -26,6 +26,11 @@ function pre_run() { + lib_image_name="lib:latest" + app1_image_name="app1:latest" + app2_image_name="app2:latest" ++ base_image_short_name="b:latest" ++ lib_image_short_name="l:latest" ++ app1_image_short_name="a:latest" ++ app2_image_short_name="c:latest" ++ + lib_layer_number=5 + app1_layer_number=4 + app2_layer_number=3 +@@ -37,18 +42,31 @@ function pre_run() { + build_image "${app2_image_name}" "${workspace}" + } + +-function test_run() { ++function test_run1() { + isula-build ctr-img save -b "${base_image_name}" -l "${lib_image_name}" -d "${workspace}"/Images "${app1_image_name}" "${app2_image_name}" + check_result_equal $? 0 ++ rm -rf "${workspace}" ++} ++ ++# use short image name ++function test_run2() { ++ isula-build ctr-img tag "${base_image_name}" "${base_image_short_name}" ++ isula-build ctr-img tag "${lib_image_name}" "${lib_image_short_name}" ++ isula-build ctr-img tag "${app1_image_name}" "${app1_image_short_name}" ++ isula-build ctr-img tag "${app2_image_name}" "${app2_image_short_name}" ++ isula-build ctr-img save -b "${base_image_short_name}" -l "${lib_image_short_name}" -d "${workspace}"/Images "${app1_image_short_name}" "${app2_image_short_name}" ++ check_result_equal $? 0 ++ rm -rf "${workspace}" + } + + function cleanup() { + rm -rf "${workspace}" +- isula-build ctr-img rm "${lib_image_name}" "${app1_image_name}" "${app2_image_name}" ++ isula-build ctr-img rm "${lib_image_name}" "${app1_image_name}" "${app2_image_name}" "${base_image_short_name}" "${lib_image_short_name}" "${app1_image_short_name}" "${app2_image_short_name}" + } + + pre_run +-test_run ++test_run1 ++test_run2 + cleanup + # shellcheck disable=SC2154 + exit "${exit_flag}" +-- +1.8.3.1 + diff --git a/series.conf b/series.conf index a66abfa..6373b64 100644 --- a/series.conf +++ b/series.conf @@ -51,3 +51,4 @@ patch/0085-util-add-unit-test-for-increment-util-functions.patch patch/0086-bugfix-fix-random-sequence-for-saving-separated-imag.patch patch/0087-bugfix-optimize-function-IsExist.patch patch/0088-bugfix-loaded-images-cover-existing-images-name-and-.patch +patch/0089-isula-build-fix-panic-when-using-image-ID-to-save-se.patch