To ease accessing image descriptors in tests.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
| ... | ... |
@@ -473,7 +473,8 @@ func loadSpecialImage(c *testing.T, imageFunc specialimage.SpecialImageFunc) str |
| 473 | 473 |
imgDir := filepath.Join(tmpDir, "image") |
| 474 | 474 |
assert.NilError(c, os.Mkdir(imgDir, 0o755)) |
| 475 | 475 |
|
| 476 |
- assert.NilError(c, imageFunc(imgDir)) |
|
| 476 |
+ _, err := imageFunc(imgDir) |
|
| 477 |
+ assert.NilError(c, err) |
|
| 477 | 478 |
|
| 478 | 479 |
rc, err := archive.TarWithOptions(imgDir, &archive.TarOptions{})
|
| 479 | 480 |
assert.NilError(c, err) |
| ... | ... |
@@ -4,6 +4,8 @@ import ( |
| 4 | 4 |
"os" |
| 5 | 5 |
"path/filepath" |
| 6 | 6 |
"strings" |
| 7 |
+ |
|
| 8 |
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 7 | 9 |
) |
| 8 | 10 |
|
| 9 | 11 |
const danglingImageManifestDigest = "sha256:16d365089e5c10e1673ee82ab5bba38ade9b763296ad918bd24b42a1156c5456" // #nosec G101 -- ignoring: Potential hardcoded credentials (gosec) |
| ... | ... |
@@ -12,30 +14,30 @@ const danglingImageConfigDigest = "sha256:0df1207206e5288f4a989a2f13d1f5b3c4e704 |
| 12 | 12 |
// Dangling creates an image with no layers and no tag. |
| 13 | 13 |
// It also has an extra org.mobyproject.test.specialimage=1 label set. |
| 14 | 14 |
// Layout: OCI. |
| 15 |
-func Dangling(dir string) error {
|
|
| 15 |
+func Dangling(dir string) (*ocispec.Index, error) {
|
|
| 16 | 16 |
if err := os.WriteFile(filepath.Join(dir, "index.json"), []byte(`{"schemaVersion":2,"manifests":[{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:16d365089e5c10e1673ee82ab5bba38ade9b763296ad918bd24b42a1156c5456","size":264,"annotations":{"org.opencontainers.image.created":"2023-05-19T08:00:44Z"},"platform":{"architecture":"amd64","os":"linux"}}]}`), 0o644); err != nil {
|
| 17 |
- return err |
|
| 17 |
+ return nil, err |
|
| 18 | 18 |
} |
| 19 | 19 |
|
| 20 | 20 |
if err := os.WriteFile(filepath.Join(dir, "manifest.json"), []byte(`[{"Config":"blobs/sha256/0df1207206e5288f4a989a2f13d1f5b3c4e70467702c1d5d21dfc9f002b7bd43","RepoTags":null,"Layers":null}]`), 0o644); err != nil {
|
| 21 |
- return err |
|
| 21 |
+ return nil, err |
|
| 22 | 22 |
} |
| 23 | 23 |
|
| 24 | 24 |
if err := os.Mkdir(filepath.Join(dir, "blobs"), 0o755); err != nil {
|
| 25 |
- return err |
|
| 25 |
+ return nil, err |
|
| 26 | 26 |
} |
| 27 | 27 |
|
| 28 | 28 |
blobsDir := filepath.Join(dir, "blobs", "sha256") |
| 29 | 29 |
if err := os.Mkdir(blobsDir, 0o755); err != nil {
|
| 30 |
- return err |
|
| 30 |
+ return nil, err |
|
| 31 | 31 |
} |
| 32 | 32 |
|
| 33 | 33 |
if err := os.WriteFile(filepath.Join(blobsDir, strings.TrimPrefix(danglingImageManifestDigest, "sha256:")), []byte(`{"schemaVersion":2,"mediaType":"application/vnd.docker.distribution.manifest.v2+json","config":{"mediaType":"application/vnd.docker.container.image.v1+json","digest":"sha256:0df1207206e5288f4a989a2f13d1f5b3c4e70467702c1d5d21dfc9f002b7bd43","size":390},"layers":[]}`), 0o644); err != nil {
|
| 34 |
- return err |
|
| 34 |
+ return nil, err |
|
| 35 | 35 |
} |
| 36 | 36 |
if err := os.WriteFile(filepath.Join(blobsDir, strings.TrimPrefix(danglingImageConfigDigest, "sha256:")), []byte(`{"architecture":"amd64","config":{"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"WorkingDir":"/","Labels":{"org.mobyproject.test.specialimage":"1"},"OnBuild":null},"created":null,"history":[{"created_by":"LABEL org.mobyproject.test.specialimage=1","comment":"buildkit.dockerfile.v0","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":null}}`), 0o644); err != nil {
|
| 37 |
- return err |
|
| 37 |
+ return nil, err |
|
| 38 | 38 |
} |
| 39 | 39 |
|
| 40 |
- return nil |
|
| 40 |
+ return nil, nil |
|
| 41 | 41 |
} |
| ... | ... |
@@ -4,53 +4,55 @@ import ( |
| 4 | 4 |
"io" |
| 5 | 5 |
"os" |
| 6 | 6 |
"path/filepath" |
| 7 |
+ |
|
| 8 |
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 7 | 9 |
) |
| 8 | 10 |
|
| 9 | 11 |
// EmptyFS builds an image with an empty rootfs. |
| 10 | 12 |
// Layout: Legacy Docker Archive |
| 11 | 13 |
// See https://github.com/docker/docker/pull/5262 |
| 12 | 14 |
// and also https://github.com/docker/docker/issues/4242 |
| 13 |
-func EmptyFS(dir string) error {
|
|
| 15 |
+func EmptyFS(dir string) (*ocispec.Index, error) {
|
|
| 14 | 16 |
if err := os.WriteFile(filepath.Join(dir, "manifest.json"), []byte(`[{"Config":"11f64303f0f7ffdc71f001788132bca5346831939a956e3e975c93267d89a16d.json","RepoTags":["emptyfs:latest"],"Layers":["511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158/layer.tar"]}]`), 0o644); err != nil {
|
| 15 |
- return err |
|
| 17 |
+ return nil, err |
|
| 16 | 18 |
} |
| 17 | 19 |
|
| 18 | 20 |
if err := os.Mkdir(filepath.Join(dir, "blobs"), 0o755); err != nil {
|
| 19 |
- return err |
|
| 21 |
+ return nil, err |
|
| 20 | 22 |
} |
| 21 | 23 |
|
| 22 | 24 |
blobsDir := filepath.Join(dir, "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") |
| 23 | 25 |
if err := os.Mkdir(blobsDir, 0o755); err != nil {
|
| 24 |
- return err |
|
| 26 |
+ return nil, err |
|
| 25 | 27 |
} |
| 26 | 28 |
|
| 27 | 29 |
if err := os.WriteFile(filepath.Join(dir, "VERSION"), []byte(`1.0`), 0o644); err != nil {
|
| 28 |
- return err |
|
| 30 |
+ return nil, err |
|
| 29 | 31 |
} |
| 30 | 32 |
if err := os.WriteFile(filepath.Join(dir, "repositories"), []byte(`{"emptyfs":{"latest":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"}}`), 0o644); err != nil {
|
| 31 |
- return err |
|
| 33 |
+ return nil, err |
|
| 32 | 34 |
} |
| 33 | 35 |
if err := os.WriteFile(filepath.Join(dir, "11f64303f0f7ffdc71f001788132bca5346831939a956e3e975c93267d89a16d.json"), []byte(`{"architecture":"x86_64","comment":"Imported from -","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"created":"2013-06-13T14:03:50.821769-07:00","docker_version":"0.4.0","history":[{"created":"2013-06-13T14:03:50.821769-07:00","comment":"Imported from -"}],"rootfs":{"type":"layers","diff_ids":["sha256:84ff92691f909a05b224e1c56abb4864f01b4f8e3c854e4bb4c7baf1d3f6d652"]}}`), 0o644); err != nil {
|
| 34 |
- return err |
|
| 36 |
+ return nil, err |
|
| 35 | 37 |
} |
| 36 | 38 |
|
| 37 | 39 |
if err := os.WriteFile(filepath.Join(blobsDir, "json"), []byte(`{"id":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158","comment":"Imported from -","created":"2013-06-13T14:03:50.821769-07:00","container_config":{"Hostname":"","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":null},"docker_version":"0.4.0","architecture":"x86_64","Size":0}`+"\n"), 0o644); err != nil {
|
| 38 |
- return err |
|
| 40 |
+ return nil, err |
|
| 39 | 41 |
} |
| 40 | 42 |
|
| 41 | 43 |
layerFile, err := os.OpenFile(filepath.Join(blobsDir, "layer.tar"), os.O_CREATE|os.O_WRONLY, 0o644) |
| 42 | 44 |
if err != nil {
|
| 43 |
- return err |
|
| 45 |
+ return nil, err |
|
| 44 | 46 |
} |
| 45 | 47 |
defer layerFile.Close() |
| 46 | 48 |
|
| 47 | 49 |
// 10240 NUL bytes is a valid empty tar archive. |
| 48 | 50 |
_, err = io.Copy(layerFile, io.LimitReader(zeroReader{}, 10240))
|
| 49 | 51 |
if err != nil {
|
| 50 |
- return err |
|
| 52 |
+ return nil, err |
|
| 51 | 53 |
} |
| 52 | 54 |
|
| 53 |
- return nil |
|
| 55 |
+ return nil, nil |
|
| 54 | 56 |
} |
| 55 | 57 |
|
| 56 | 58 |
type zeroReader struct{}
|
| ... | ... |
@@ -12,15 +12,16 @@ import ( |
| 12 | 12 |
"github.com/docker/docker/client" |
| 13 | 13 |
"github.com/docker/docker/pkg/archive" |
| 14 | 14 |
"github.com/docker/docker/pkg/jsonmessage" |
| 15 |
+ ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
|
| 15 | 16 |
"gotest.tools/v3/assert" |
| 16 | 17 |
) |
| 17 | 18 |
|
| 18 |
-type SpecialImageFunc func(string) error |
|
| 19 |
+type SpecialImageFunc func(string) (*ocispec.Index, error) |
|
| 19 | 20 |
|
| 20 | 21 |
func Load(ctx context.Context, t *testing.T, apiClient client.APIClient, imageFunc SpecialImageFunc) string {
|
| 21 | 22 |
tempDir := t.TempDir() |
| 22 | 23 |
|
| 23 |
- err := imageFunc(tempDir) |
|
| 24 |
+ _, err := imageFunc(tempDir) |
|
| 24 | 25 |
assert.NilError(t, err) |
| 25 | 26 |
|
| 26 | 27 |
rc, err := archive.TarWithOptions(tempDir, &archive.TarOptions{})
|
| ... | ... |
@@ -16,20 +16,20 @@ import ( |
| 16 | 16 |
ocispec "github.com/opencontainers/image-spec/specs-go/v1" |
| 17 | 17 |
) |
| 18 | 18 |
|
| 19 |
-func MultiLayer(dir string) error {
|
|
| 19 |
+func MultiLayer(dir string) (*ocispec.Index, error) {
|
|
| 20 | 20 |
const imageRef = "multilayer:latest" |
| 21 | 21 |
|
| 22 | 22 |
layer1Desc, err := writeLayerWithOneFile(dir, "foo", []byte("1"))
|
| 23 | 23 |
if err != nil {
|
| 24 |
- return err |
|
| 24 |
+ return nil, err |
|
| 25 | 25 |
} |
| 26 | 26 |
layer2Desc, err := writeLayerWithOneFile(dir, "bar", []byte("2"))
|
| 27 | 27 |
if err != nil {
|
| 28 |
- return err |
|
| 28 |
+ return nil, err |
|
| 29 | 29 |
} |
| 30 | 30 |
layer3Desc, err := writeLayerWithOneFile(dir, "hello", []byte("world"))
|
| 31 | 31 |
if err != nil {
|
| 32 |
- return err |
|
| 32 |
+ return nil, err |
|
| 33 | 33 |
} |
| 34 | 34 |
|
| 35 | 35 |
configDesc, err := writeJsonBlob(dir, ocispec.MediaTypeImageConfig, ocispec.Image{
|
| ... | ... |
@@ -43,7 +43,7 @@ func MultiLayer(dir string) error {
|
| 43 | 43 |
}, |
| 44 | 44 |
}) |
| 45 | 45 |
if err != nil {
|
| 46 |
- return err |
|
| 46 |
+ return nil, err |
|
| 47 | 47 |
} |
| 48 | 48 |
|
| 49 | 49 |
manifest := ocispec.Manifest{
|
| ... | ... |
@@ -53,7 +53,7 @@ func MultiLayer(dir string) error {
|
| 53 | 53 |
} |
| 54 | 54 |
|
| 55 | 55 |
legacyManifests := []manifestItem{
|
| 56 |
- manifestItem{
|
|
| 56 |
+ {
|
|
| 57 | 57 |
Config: blobPath(configDesc), |
| 58 | 58 |
RepoTags: []string{imageRef},
|
| 59 | 59 |
Layers: []string{blobPath(layer1Desc), blobPath(layer2Desc), blobPath(layer3Desc)},
|
| ... | ... |
@@ -62,7 +62,7 @@ func MultiLayer(dir string) error {
|
| 62 | 62 |
|
| 63 | 63 |
ref, err := reference.ParseNormalizedNamed(imageRef) |
| 64 | 64 |
if err != nil {
|
| 65 |
- return err |
|
| 65 |
+ return nil, err |
|
| 66 | 66 |
} |
| 67 | 67 |
return singlePlatformImage(dir, ref, manifest, legacyManifests) |
| 68 | 68 |
} |
| ... | ... |
@@ -74,10 +74,10 @@ type manifestItem struct {
|
| 74 | 74 |
Layers []string |
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 |
-func singlePlatformImage(dir string, ref reference.Named, manifest ocispec.Manifest, legacyManifests []manifestItem) error {
|
|
| 77 |
+func singlePlatformImage(dir string, ref reference.Named, manifest ocispec.Manifest, legacyManifests []manifestItem) (*ocispec.Index, error) {
|
|
| 78 | 78 |
manifestDesc, err := writeJsonBlob(dir, ocispec.MediaTypeImageManifest, manifest) |
| 79 | 79 |
if err != nil {
|
| 80 |
- return err |
|
| 80 |
+ return nil, err |
|
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 | 83 |
if ref != nil {
|
| ... | ... |
@@ -90,25 +90,24 @@ func singlePlatformImage(dir string, ref reference.Named, manifest ocispec.Manif |
| 90 | 90 |
} |
| 91 | 91 |
} |
| 92 | 92 |
|
| 93 |
- if err := writeJson(ocispec.Index{
|
|
| 93 |
+ idx := ocispec.Index{
|
|
| 94 | 94 |
Versioned: specs.Versioned{SchemaVersion: 2},
|
| 95 | 95 |
MediaType: ocispec.MediaTypeImageIndex, |
| 96 | 96 |
Manifests: []ocispec.Descriptor{manifestDesc},
|
| 97 |
- }, filepath.Join(dir, "index.json")); err != nil {
|
|
| 98 |
- return err |
|
| 99 | 97 |
} |
| 100 |
- if err != nil {
|
|
| 101 |
- return err |
|
| 98 |
+ if err := writeJson(idx, filepath.Join(dir, "index.json")); err != nil {
|
|
| 99 |
+ return nil, err |
|
| 102 | 100 |
} |
| 103 |
- |
|
| 104 | 101 |
if err := writeJson(legacyManifests, filepath.Join(dir, "manifest.json")); err != nil {
|
| 105 |
- return err |
|
| 102 |
+ return nil, err |
|
| 106 | 103 |
} |
| 104 |
+ |
|
| 105 |
+ err = os.WriteFile(filepath.Join(dir, "oci-layout"), []byte(`{"imageLayoutVersion": "1.0.0"}`), 0o644)
|
|
| 107 | 106 |
if err != nil {
|
| 108 |
- return err |
|
| 107 |
+ return nil, err |
|
| 109 | 108 |
} |
| 110 | 109 |
|
| 111 |
- return os.WriteFile(filepath.Join(dir, "oci-layout"), []byte(`{"imageLayoutVersion": "1.0.0"}`), 0o644)
|
|
| 110 |
+ return &idx, nil |
|
| 112 | 111 |
} |
| 113 | 112 |
|
| 114 | 113 |
func fileArchive(dir string, name string, content []byte) (io.ReadCloser, error) {
|