isula-build/patch/0044-fix-load-oci-image-panic.patch
DCCooper 950f2f8ba2 isula-build:Sync upstream patches
Signed-off-by: DCCooper <1866858@gmail.com>
2021-03-03 19:29:30 +08:00

341 lines
10 KiB
Diff

From 947fc1ef0c103f687e195c467ddabd3cf0aa746f Mon Sep 17 00:00:00 2001
From: meilier <xingweizheng@huawei.com>
Date: Sat, 20 Feb 2021 00:42:55 +0800
Subject: [PATCH 06/10] fix load oci image panic
---
cmd/cli/save.go | 3 +
cmd/cli/save_test.go | 18 +++++
daemon/load.go | 11 +--
daemon/load_test.go | 188 +++++++++++++++++++++++++++++++++++--------
4 files changed, 181 insertions(+), 39 deletions(-)
diff --git a/cmd/cli/save.go b/cmd/cli/save.go
index 64dc8acc..fe676731 100644
--- a/cmd/cli/save.go
+++ b/cmd/cli/save.go
@@ -72,6 +72,9 @@ func saveCommand(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("save accepts at least one image")
}
+ if saveOpts.format == exporter.OCITransport && len(args) >= 2 {
+ return errors.New("oci image format now only supports saving single image")
+ }
if err := exporter.CheckImageFormat(saveOpts.format); err != nil {
return err
}
diff --git a/cmd/cli/save_test.go b/cmd/cli/save_test.go
index 4183aa8b..3fe6bf81 100644
--- a/cmd/cli/save_test.go
+++ b/cmd/cli/save_test.go
@@ -38,6 +38,8 @@ func TestSaveCommand(t *testing.T) {
wantErr bool
}
+ // For normal cases, default err is "invalid socket path: unix:///var/run/isula_build.sock".
+ // As daemon is not running as we run unit test.
var testcases = []testcase{
{
name: "TC1 - normal case with format docker",
@@ -103,6 +105,22 @@ func TestSaveCommand(t *testing.T) {
errString: "colon in path",
format: "docker",
},
+ {
+ name: "TC9 - normal case save multiple images with format docker",
+ path: tmpDir.Join("test9"),
+ args: []string{"testImage1", "testImage2"},
+ wantErr: true,
+ errString: "isula_build.sock",
+ format: "docker",
+ },
+ {
+ name: "TC10 - abnormal case save multiple images with format oci",
+ path: tmpDir.Join("test10"),
+ args: []string{"testImage1", "testImage2"},
+ wantErr: true,
+ errString: "oci image format now only supports saving single image",
+ format: "oci",
+ },
}
for _, tc := range testcases {
diff --git a/daemon/load.go b/daemon/load.go
index d756f9ed..b557d386 100644
--- a/daemon/load.go
+++ b/daemon/load.go
@@ -147,7 +147,6 @@ func tryToParseImageFormatFromTarball(dataRoot string, opts *loadOptions) ([][]s
func getDockerRepoTagFromImageTar(systemContext *types.SystemContext, path string) ([][]string, error) {
// tmp dir will be removed after NewSourceFromFileWithContext
-
tarfileSource, err := tarfile.NewSourceFromFileWithContext(systemContext, path)
if err != nil {
return nil, errors.Wrapf(err, "failed to get the source of loading tar file")
@@ -168,8 +167,7 @@ func getDockerRepoTagFromImageTar(systemContext *types.SystemContext, path strin
func getOCIRepoTagFromImageTar(systemContext *types.SystemContext, path string) ([][]string, error) {
var (
- allRepoTags [][]string
- err error
+ err error
)
srcRef, err := alltransports.ParseImageName(exporter.FormatTransport(exporter.OCIArchiveTransport, path))
@@ -179,14 +177,13 @@ func getOCIRepoTagFromImageTar(systemContext *types.SystemContext, path string)
tarManifest, err := ociarchive.LoadManifestDescriptorWithContext(systemContext, srcRef)
if err != nil {
- return nil, errors.Wrapf(err, "failed to loadmanifest descriptor of oci image format")
+ return nil, errors.Wrapf(err, "failed to load manifest descriptor of oci image format")
}
- // If index.json has no reference name, compute the image digest instead
// For now, we only support load single image in archive file
if _, ok := tarManifest.Annotations[imgspecv1.AnnotationRefName]; ok {
- allRepoTags = [][]string{{tarManifest.Annotations[imgspecv1.AnnotationRefName]}}
+ return [][]string{{tarManifest.Annotations[imgspecv1.AnnotationRefName]}}, nil
}
- return allRepoTags, nil
+ return [][]string{{}}, nil
}
diff --git a/daemon/load_test.go b/daemon/load_test.go
index 0513a889..cbcb5d8f 100644
--- a/daemon/load_test.go
+++ b/daemon/load_test.go
@@ -30,6 +30,12 @@ import (
"isula.org/isula-build/store"
)
+const (
+ loadedTarFile = "load.tar"
+ manifestJSONFile = "manifest.json"
+ indexJSONFile = "index.json"
+)
+
var (
localStore store.Store
daemon *Daemon
@@ -51,10 +57,10 @@ func (x *controlLoadServer) Context() context.Context {
return context.Background()
}
-func prepareLoadTar(dir *fs.Dir) error {
- manifest := dir.Join("manifest.json")
+func prepareLoadTar(dir *fs.Dir, jsonFile string) error {
+ manifest := dir.Join(jsonFile)
- fi, err := os.Create(dir.Join("load.tar"))
+ fi, err := os.Create(dir.Join(loadedTarFile))
if err != nil {
return nil
}
@@ -88,9 +94,9 @@ func prepareLoadTar(dir *fs.Dir) error {
}
-func prepareForLoad(t *testing.T, manifest string) *fs.Dir {
- tmpDir := fs.NewDir(t, t.Name(), fs.WithFile("manifest.json", manifest))
- if err := prepareLoadTar(tmpDir); err != nil {
+func prepareForLoad(t *testing.T, jsonFile, manifest string) *fs.Dir {
+ tmpDir := fs.NewDir(t, t.Name(), fs.WithFile(jsonFile, manifest))
+ if err := prepareLoadTar(tmpDir, jsonFile); err != nil {
tmpDir.Remove()
return nil
}
@@ -119,34 +125,152 @@ func clean(dir *fs.Dir) {
dir.Remove()
}
-func TestLoad(t *testing.T) {
- manifestJSON :=
- `[
- {
- "Config":"76a4dd2d5d6a18323ac8d90f959c3c8562bf592e2a559bab9b462ab600e9e5fc.json",
- "RepoTags":[
- "hello:latest"
- ],
- "Layers":[
- "6eb4c21cc3fcb729a9df230ae522c1d3708ca66e5cf531713dbfa679837aa287.tar",
- "37841116ad3b1eeea972c75ab8bad05f48f721a7431924bc547fc91c9076c1c8.tar"
- ]
+func TestLoadSingleImage(t *testing.T) {
+ testcases := []struct {
+ name string
+ manifest string
+ format string
+ tarPath string
+ withTag bool
+ wantErr bool
+ errString string
+ }{
+ {
+ name: "TC1 normal case load docker tar",
+ manifest: `[
+ {
+ "Config":"76a4dd2d5d6a18323ac8d90f959c3c8562bf592e2a559bab9b462ab600e9e5fc.json",
+ "RepoTags":[
+ "hello:latest"
+ ],
+ "Layers":[
+ "6eb4c21cc3fcb729a9df230ae522c1d3708ca66e5cf531713dbfa679837aa287.tar",
+ "37841116ad3b1eeea972c75ab8bad05f48f721a7431924bc547fc91c9076c1c8.tar"
+ ]
+ }
+ ]`,
+ format: "docker",
+ withTag: true,
+ },
+ {
+ name: "TC2 normal case load oci tar",
+ manifest: `{
+ "schemaVersion": 2,
+ "manifests": [
+ {
+ "mediaType": "application/vnd.oci.image.manifest.v1+json",
+ "digest": "sha256:a65db259a719d915df30c82ce554ab3880ea567e2150d6288580408c2629b802",
+ "size": 347,
+ "annotations": {
+ "org.opencontainers.image.ref.name": "hello:latest"
+ }
+ }
+ ]
+ }`,
+ format: "oci",
+ withTag: true,
+ },
+ {
+ name: "TC3 normal case load docker tar with no RepoTags",
+ manifest: `[
+ {
+ "Config":"76a4dd2d5d6a18323ac8d90f959c3c8562bf592e2a559bab9b462ab600e9e5fc.json",
+ "RepoTags":[],
+ "Layers":[
+ "6eb4c21cc3fcb729a9df230ae522c1d3708ca66e5cf531713dbfa679837aa287.tar",
+ "37841116ad3b1eeea972c75ab8bad05f48f721a7431924bc547fc91c9076c1c8.tar"
+ ]
+ }
+ ]`,
+ format: "docker",
+ withTag: false,
+ },
+ {
+ name: "TC4 normal case load oci tar with no annotations",
+ manifest: `{
+ "schemaVersion": 2,
+ "manifests": [
+ {
+ "mediaType": "application/vnd.oci.image.manifest.v1+json",
+ "digest": "sha256:a65db259a719d915df30c82ce554ab3880ea567e2150d6288580408c2629b802",
+ "size": 347
+ }
+ ]
+ }`,
+ format: "oci",
+ withTag: false,
+ },
+ {
+ name: "TC5 abnormal case load docker tar with wrong manifestJSON",
+ manifest: `[
+ {
+ :"76a4dd2d5d6a18323ac8d90f959c3c8562bf592e2a559bab9b462ab600e9e5fc.json",
+ "RepoTags":[
+ "hello:latest"
+ ],
+ "Layers":[
+ "6eb4c21cc3fcb729a9df230ae522c1d3708ca66e5cf531713dbfa679837aa287.tar",
+ "37841116ad3b1eeea972c75ab8bad05f48f721a7431924bc547fc91c9076c1c8.tar"
+ ]
+ }
+ ]`,
+ format: "docker",
+ withTag: true,
+ wantErr: true,
+ errString: "error loading index",
+ },
+ {
+ name: "TC6 abnormal case with wrong tar path",
+ manifest: `[
+ {
+ "Config":"76a4dd2d5d6a18323ac8d90f959c3c8562bf592e2a559bab9b462ab600e9e5fc.json",
+ "RepoTags":[
+ "hello:latest"
+ ],
+ "Layers":[
+ "6eb4c21cc3fcb729a9df230ae522c1d3708ca66e5cf531713dbfa679837aa287.tar",
+ "37841116ad3b1eeea972c75ab8bad05f48f721a7431924bc547fc91c9076c1c8.tar"
+ ]
+ }
+ ]`,
+
+ tarPath: "/path/that/not/exist/load.tar",
+ format: "docker",
+ withTag: true,
+ wantErr: true,
+ errString: "no such file or directory",
+ },
+ }
+
+ for _, tc := range testcases {
+ t.Run(tc.name, func(t *testing.T) {
+ var jsonFile string
+ if tc.format == "docker" {
+ jsonFile = manifestJSONFile
}
- ]`
- dir := prepareForLoad(t, manifestJSON)
- assert.Equal(t, dir != nil, true)
- defer clean(dir)
+ if tc.format == "oci" {
+ jsonFile = indexJSONFile
+ }
+ dir := prepareForLoad(t, jsonFile, tc.manifest)
+ assert.Equal(t, dir != nil, true)
+ defer clean(dir)
- path := dir.Join("load.tar")
- repoTags, err := tryToParseImageFormatFromTarball(daemon.opts.DataRoot, &loadOptions{path: path})
- assert.NilError(t, err)
- assert.Equal(t, repoTags[0][0], "hello:latest")
+ path := dir.Join(loadedTarFile)
+ if tc.tarPath == "" {
+ tc.tarPath = path
+ }
+ req := &pb.LoadRequest{Path: tc.tarPath}
+ stream := &controlLoadServer{}
- req := &pb.LoadRequest{Path: path}
- stream := &controlLoadServer{}
+ err := daemon.backend.Load(req, stream)
+ if tc.wantErr {
+ assert.ErrorContains(t, err, tc.errString)
+ return
+ }
+ assert.ErrorContains(t, err, "failed to get the image")
+ })
+ }
- err = daemon.backend.Load(req, stream)
- assert.ErrorContains(t, err, "failed to get the image")
}
func TestLoadMultipleImages(t *testing.T) {
@@ -181,11 +305,11 @@ func TestLoadMultipleImages(t *testing.T) {
]
}
]`
- dir := prepareForLoad(t, manifestJSON)
+ dir := prepareForLoad(t, manifestJSONFile, manifestJSON)
assert.Equal(t, dir != nil, true)
defer clean(dir)
- path := dir.Join("load.tar")
+ path := dir.Join(loadedTarFile)
repoTags, err := tryToParseImageFormatFromTarball(daemon.opts.DataRoot, &loadOptions{path: path})
assert.NilError(t, err)
assert.Equal(t, repoTags[0][0], "registry.example.com/sayhello:first")
--
2.27.0