!153 isula-build: sync upstream to fix panic when using image ID to save separated image
From: @DCCooper Reviewed-by: @jingxiaolu Signed-off-by: @jingxiaolu
This commit is contained in:
commit
13391dd049
@ -1 +1 @@
|
||||
0.9.5-18
|
||||
0.9.5-19
|
||||
|
||||
@ -1 +1 @@
|
||||
f7609ebf9b086beeb7ef204cb89a70c4a34fde84
|
||||
d69cf1b4393964819a1515a5399c1a2ac10c8d03
|
||||
|
||||
@ -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 <lixiang172@huawei.com> - 0.9.5-18
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user