diff --git a/.github/workflows/ci-userspace-convertor.yml b/.github/workflows/ci-userspace-convertor.yml index 7e4795e1..9877abb0 100644 --- a/.github/workflows/ci-userspace-convertor.yml +++ b/.github/workflows/ci-userspace-convertor.yml @@ -69,3 +69,20 @@ jobs: /opt/overlaybd/snapshotter/convertor -r localhost:5000/redis -i 7.2.3 --overlaybd 7.2.3_overlaybd --turboOCI 7.2.3_turbo bash run_container.sh localhost:5000/redis:7.2.3_overlaybd bash run_container.sh localhost:5000/redis:7.2.3_turbo + + - name: install Go + uses: actions/setup-go@v5 + with: + go-version: '1.22.0' + + - name: set env + shell: bash + run: | + echo "GOPATH=${{ github.workspace }}" >> $GITHUB_ENV + echo "${{ github.workspace }}/bin" >> $GITHUB_PATH + + - name: CI - E2E Go Test + working-directory: ci/e2e + shell: bash + run: | + go test -v ./... diff --git a/ci/e2e/convert/referrer_test.go b/ci/e2e/convert/referrer_test.go new file mode 100644 index 00000000..69c73ae9 --- /dev/null +++ b/ci/e2e/convert/referrer_test.go @@ -0,0 +1,182 @@ +/* + Copyright The Accelerated Container Image Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package convert_test + +import ( + "context" + "encoding/json" + "fmt" + "io" + "os/exec" + "path/filepath" + "runtime" + "testing" + + dockerspec "github.com/containerd/containerd/v2/core/images" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/stretchr/testify/require" + "oras.land/oras-go/v2" + "oras.land/oras-go/v2/content/oci" + "oras.land/oras-go/v2/registry" + "oras.land/oras-go/v2/registry/remote" +) + +const ( + ArtifactTypeOverlaybd = "application/vnd.containerd.overlaybd.native.v1+json" + ArtifactTypeTurboOCI = "application/vnd.containerd.overlaybd.turbo.v1+json" + + TestRepository = "localhost:5000/hello-world" +) + +func TestConvertReferrer(t *testing.T) { + ctx := context.Background() + require := require.New(t) + + if err := copyImageToRegistry(ctx); err != nil { + t.Fatal(err) + } + + repo, err := remote.NewRepository(TestRepository) + require.Nil(err, err) + repo.SetReferrersCapability(true) + + fetchJSON := func(src ocispec.Descriptor, v any) { + rc, err := repo.Fetch(ctx, src) + require.Nil(err, err) + defer rc.Close() + bytes, err := io.ReadAll(rc) + require.Nil(err, err) + err = json.Unmarshal(bytes, v) + require.Nil(err, err) + + t.Logf("fetch %s, content:\n%s", src.Digest.String(), string(bytes)) + } + + var checkReferrer func(src, dst ocispec.Descriptor, artifactType string) + checkReferrer = func(src, dst ocispec.Descriptor, artifactType string) { + t.Logf("checking src %v to dst %v, artifact type %s", src, dst, artifactType) + require.Equal(isIndex(src.MediaType), isIndex(dst.MediaType)) + + switch dst.MediaType { + case ocispec.MediaTypeImageManifest, dockerspec.MediaTypeDockerSchema2Manifest: + var manifest ocispec.Manifest + fetchJSON(dst, &manifest) + require.Equal(artifactType, manifest.ArtifactType) + require.Equal(src.Digest, manifest.Subject.Digest) + require.Equal(src.Size, manifest.Subject.Size) + require.Equal(src.MediaType, manifest.Subject.MediaType) + + case ocispec.MediaTypeImageIndex, dockerspec.MediaTypeDockerSchema2ManifestList: + var index ocispec.Index + fetchJSON(dst, &index) + require.Equal(artifactType, index.ArtifactType) + require.Equal(src.Digest, index.Subject.Digest) + require.Equal(src.Size, index.Subject.Size) + require.Equal(src.MediaType, index.Subject.MediaType) + + var srcIndex ocispec.Index + fetchJSON(src, &srcIndex) + require.Equal(len(srcIndex.Manifests), len(index.Manifests)) + for idx := range index.Manifests { + checkReferrer(srcIndex.Manifests[idx], index.Manifests[idx], artifactType) + } + } + } + + testcases := []struct { + name string + reference string + }{ + { + name: "simple", + reference: TestRepository + ":amd64", + }, + { + name: "index", + reference: TestRepository + ":multi-arch", + }, + { + name: "nested index", + reference: TestRepository + ":nested-index", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + err := convert(ctx, tc.reference) + require.Nil(err, err) + + src, err := repo.Resolve(ctx, tc.reference) + require.Nil(err, err) + + obd, err := repo.Resolve(ctx, tc.reference+"_overlaybd") + require.Nil(err, err) + + turbo, err := repo.Resolve(ctx, tc.reference+"_turbo") + require.Nil(err, err) + + checkReferrer(src, obd, ArtifactTypeOverlaybd) + checkReferrer(src, turbo, ArtifactTypeTurboOCI) + }) + } +} + +const convertBin = "/opt/overlaybd/snapshotter/convertor" + +func convert(ctx context.Context, refspec string) error { + ref, err := registry.ParseReference(refspec) + if err != nil { + return err + } + cmd := exec.CommandContext(ctx, convertBin, + "-r", fmt.Sprintf("%s/%s", ref.Registry, ref.Repository), + "-i", ref.Reference, + "--overlaybd", ref.Reference+"_overlaybd", + "--turboOCI", ref.Reference+"_turbo", + "--referrer", + ) + if out, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("failed to convert: %w, output: %s", err, out) + } + return nil +} + +func copyImageToRegistry(ctx context.Context) error { + _, filename, _, _ := runtime.Caller(0) + local, err := oci.New(filepath.Join(filepath.Dir(filename), "..", "resources", "store", "hello-world")) + if err != nil { + return err + } + repo, err := remote.NewRepository(TestRepository) + if err != nil { + return err + } + + images := []string{"amd64", "arm64", "multi-arch", "nested-index"} + for _, img := range images { + src := img + dst := TestRepository + ":" + img + if _, err := oras.Copy(ctx, local, src, repo, dst, oras.CopyOptions{}); err != nil { + return err + } + } + return nil +} + +func isIndex(mediaType string) bool { + return mediaType == ocispec.MediaTypeImageIndex || mediaType == dockerspec.MediaTypeDockerSchema2ManifestList +} diff --git a/ci/e2e/go.mod b/ci/e2e/go.mod new file mode 100644 index 00000000..dd51a51b --- /dev/null +++ b/ci/e2e/go.mod @@ -0,0 +1,27 @@ +module github.com/containerd/accelerated-container-image/ci/e2e + +go 1.22.2 + +require ( + github.com/containerd/containerd/v2 v2.0.0-rc.3 + github.com/opencontainers/image-spec v1.1.0 + github.com/stretchr/testify v1.9.0 + oras.land/oras-go/v2 v2.5.0 +) + +require ( + github.com/containerd/errdefs v0.1.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/klauspost/compress v1.17.8 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect + google.golang.org/grpc v1.63.2 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/ci/e2e/go.sum b/ci/e2e/go.sum new file mode 100644 index 00000000..4935075c --- /dev/null +++ b/ci/e2e/go.sum @@ -0,0 +1,51 @@ +github.com/containerd/containerd/v2 v2.0.0-rc.3 h1:rRISeKYnunLx8Byw8FQ/a62mTMtcr6ESGptS4+MwLaQ= +github.com/containerd/containerd/v2 v2.0.0-rc.3/go.mod h1:UBHR1DgWRQcEOINFkR94m0VC0MgKd3qg9LVPnudv9vs= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c= +oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZHg= diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/004d23c66201b22fce069b7505756f17088de7889c83891e9bc69d749fa3690e b/ci/e2e/resources/store/hello-world/blobs/sha256/004d23c66201b22fce069b7505756f17088de7889c83891e9bc69d749fa3690e new file mode 100644 index 00000000..6c74c418 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/004d23c66201b22fce069b7505756f17088de7889c83891e9bc69d749fa3690e @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1468, + "digest": "sha256:a8117b42328be6ba54c594f9f14e216db10203deb22cc28aaa2c134f9ae2e0fd" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 2716, + "digest": "sha256:630da353b594c9ca52c67727920737dba3e5aaa4fbe20cdd0fc70c0591b7a639" + } + ] +} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/06bca41ba617acf0b3644df05d0d9c2d2f82ccaab629c0e39792b24682970040 b/ci/e2e/resources/store/hello-world/blobs/sha256/06bca41ba617acf0b3644df05d0d9c2d2f82ccaab629c0e39792b24682970040 new file mode 100644 index 00000000..3765e46f --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/06bca41ba617acf0b3644df05d0d9c2d2f82ccaab629c0e39792b24682970040 @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1473, + "digest": "sha256:e4728a982b0acd74e810aeb5e8a5c1bd87f0de7ed93a678d58b3a79e6f7da2e9" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 4065, + "digest": "sha256:4bf3d0e19af8069cca924c84fccd58558900bd382ffbde49778906172aa135fb" + } + ] +} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/084c3bdd1271adc754e2c5f6ba7046f1a2c099597dbd9643592fa8eb99981402 b/ci/e2e/resources/store/hello-world/blobs/sha256/084c3bdd1271adc754e2c5f6ba7046f1a2c099597dbd9643592fa8eb99981402 new file mode 100644 index 00000000..72e864d6 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/084c3bdd1271adc754e2c5f6ba7046f1a2c099597dbd9643592fa8eb99981402 @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1483, + "digest": "sha256:de23d9589845285bb62b33da594c4a19802fda5b09bb6aef4d00e5e8c747a8df" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 3658, + "digest": "sha256:337a0e31c52265fdbab8ffb4f8922b73f2ea3689cf9970150afee8a5a026db30" + } + ] +} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/337a0e31c52265fdbab8ffb4f8922b73f2ea3689cf9970150afee8a5a026db30 b/ci/e2e/resources/store/hello-world/blobs/sha256/337a0e31c52265fdbab8ffb4f8922b73f2ea3689cf9970150afee8a5a026db30 new file mode 100644 index 00000000..d85451c8 Binary files /dev/null and b/ci/e2e/resources/store/hello-world/blobs/sha256/337a0e31c52265fdbab8ffb4f8922b73f2ea3689cf9970150afee8a5a026db30 differ diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/38d49488e3b0689e88335277a18bdc2d03c9b58cb45b79902bf648885e23b9f4 b/ci/e2e/resources/store/hello-world/blobs/sha256/38d49488e3b0689e88335277a18bdc2d03c9b58cb45b79902bf648885e23b9f4 new file mode 100644 index 00000000..52e8faf7 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/38d49488e3b0689e88335277a18bdc2d03c9b58cb45b79902bf648885e23b9f4 @@ -0,0 +1 @@ +{"architecture":"arm","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:b428cee5a856e0a27a68a92fdc79e07ce0e679444984d60dc60d09da91d3b256","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"a1cc96094ddc296dcc3e123f4153239d280bb09ade31fdbd6e430d19e9b48d76","container_config":{"Hostname":"a1cc96094ddc","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:b428cee5a856e0a27a68a92fdc79e07ce0e679444984d60dc60d09da91d3b256","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2023-05-04T11:46:35.356328888Z","docker_version":"20.10.23","history":[{"created":"2023-05-04T11:46:35.27781596Z","created_by":"/bin/sh -c #(nop) COPY file:bf40f70af9a56eec54a66883a31493ea31545ec09ad150c432566b5e24b0528c in / "},{"created":"2023-05-04T11:46:35.356328888Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:c8d6fe9d9f8fb6ab6e0d701141d358a8bc40b1d5c46cbdc6fd445371c895b1f6"]},"variant":"v7"} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/4bf3d0e19af8069cca924c84fccd58558900bd382ffbde49778906172aa135fb b/ci/e2e/resources/store/hello-world/blobs/sha256/4bf3d0e19af8069cca924c84fccd58558900bd382ffbde49778906172aa135fb new file mode 100644 index 00000000..71a04f78 Binary files /dev/null and b/ci/e2e/resources/store/hello-world/blobs/sha256/4bf3d0e19af8069cca924c84fccd58558900bd382ffbde49778906172aa135fb differ diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/4f1af0faa5862569c7c76d72b1c8e09ba01f2adeea0a44f8f3758d185e95e918 b/ci/e2e/resources/store/hello-world/blobs/sha256/4f1af0faa5862569c7c76d72b1c8e09ba01f2adeea0a44f8f3758d185e95e918 new file mode 100644 index 00000000..b5d09121 Binary files /dev/null and b/ci/e2e/resources/store/hello-world/blobs/sha256/4f1af0faa5862569c7c76d72b1c8e09ba01f2adeea0a44f8f3758d185e95e918 differ diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/5735de2b810bba182986adaf3f0d2e6567697caecbebb5d3f2934d8d37f32d2d b/ci/e2e/resources/store/hello-world/blobs/sha256/5735de2b810bba182986adaf3f0d2e6567697caecbebb5d3f2934d8d37f32d2d new file mode 100644 index 00000000..9bd92551 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/5735de2b810bba182986adaf3f0d2e6567697caecbebb5d3f2934d8d37f32d2d @@ -0,0 +1 @@ +{"architecture":"ppc64le","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:d10f62162101fe360d2292f3163e7d4d07c9bd3a4bbba4a48a4bdccfa622cd5d","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"bf5c33b539ecc0a88ba3448ed5d95fdc587a6fb295347fc31a296286a419aea6","container_config":{"Hostname":"bf5c33b539ec","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:d10f62162101fe360d2292f3163e7d4d07c9bd3a4bbba4a48a4bdccfa622cd5d","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2023-05-04T23:35:14.791724762Z","docker_version":"20.10.23","history":[{"created":"2023-05-04T23:35:14.47386416Z","created_by":"/bin/sh -c #(nop) COPY file:d983edb4c32b67abbd6c309cebc3bf9ace8e1c065505fe8ae03686b5a75a5552 in / "},{"created":"2023-05-04T23:35:14.791724762Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:ac1bc0996cc2106a1e725a10fac1236fb365304b85257f0b82ab950db3bd8880"]}} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/574efe68740d3bee2ef780036aee2e2da5cf7097ac06513f9f01f41e03365399 b/ci/e2e/resources/store/hello-world/blobs/sha256/574efe68740d3bee2ef780036aee2e2da5cf7097ac06513f9f01f41e03365399 new file mode 100644 index 00000000..ae7d84dd --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/574efe68740d3bee2ef780036aee2e2da5cf7097ac06513f9f01f41e03365399 @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1470, + "digest": "sha256:d549b3d1a2550a5e42a3f3250ce9fa4aa882b25f8528fd2eea1b789ce136631b" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 3265, + "digest": "sha256:d898e3d98788d70a8f874f818177c11569c5bb3c818ef45b877e7bba29a3bf7f" + } + ] +} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/630da353b594c9ca52c67727920737dba3e5aaa4fbe20cdd0fc70c0591b7a639 b/ci/e2e/resources/store/hello-world/blobs/sha256/630da353b594c9ca52c67727920737dba3e5aaa4fbe20cdd0fc70c0591b7a639 new file mode 100644 index 00000000..0538fb33 Binary files /dev/null and b/ci/e2e/resources/store/hello-world/blobs/sha256/630da353b594c9ca52c67727920737dba3e5aaa4fbe20cdd0fc70c0591b7a639 differ diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/70f5ac315c5af948332962ff4678084ebcc215809506e4b8cd9e509660417205 b/ci/e2e/resources/store/hello-world/blobs/sha256/70f5ac315c5af948332962ff4678084ebcc215809506e4b8cd9e509660417205 new file mode 100644 index 00000000..6ee05062 Binary files /dev/null and b/ci/e2e/resources/store/hello-world/blobs/sha256/70f5ac315c5af948332962ff4678084ebcc215809506e4b8cd9e509660417205 differ diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/719385e32844401d57ecfd3eacab360bf551a1491c05b85806ed8f1b08d792f6 b/ci/e2e/resources/store/hello-world/blobs/sha256/719385e32844401d57ecfd3eacab360bf551a1491c05b85806ed8f1b08d792f6 new file mode 100644 index 00000000..e1b49b11 Binary files /dev/null and b/ci/e2e/resources/store/hello-world/blobs/sha256/719385e32844401d57ecfd3eacab360bf551a1491c05b85806ed8f1b08d792f6 differ diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/726023f73a8fc5103fa6776d48090539042cb822531c6b751b1f6dd18cb5705d b/ci/e2e/resources/store/hello-world/blobs/sha256/726023f73a8fc5103fa6776d48090539042cb822531c6b751b1f6dd18cb5705d new file mode 100644 index 00000000..684c8f2e --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/726023f73a8fc5103fa6776d48090539042cb822531c6b751b1f6dd18cb5705d @@ -0,0 +1 @@ +{"manifests":[{"digest":"sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"amd64","os":"linux"},"size":525},{"digest":"sha256:084c3bdd1271adc754e2c5f6ba7046f1a2c099597dbd9643592fa8eb99981402","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"arm","os":"linux","variant":"v5"},"size":525},{"digest":"sha256:a0a386314d69d1514d7aa63d12532b284bf37bba15ed7b4fc1a3f86605f86c63","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"arm","os":"linux","variant":"v7"},"size":525},{"digest":"sha256:efebf0f7aee69450f99deafe11121afa720abed733943e50581a9dc7540689c8","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"arm64","os":"linux","variant":"v8"},"size":525},{"digest":"sha256:004d23c66201b22fce069b7505756f17088de7889c83891e9bc69d749fa3690e","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"386","os":"linux"},"size":525},{"digest":"sha256:06bca41ba617acf0b3644df05d0d9c2d2f82ccaab629c0e39792b24682970040","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"mips64le","os":"linux"},"size":525},{"digest":"sha256:fbe0ff1e7697da39d987a975c737a7d2fa40b6e7f7f40c00b1dcc387b9ac0e85","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"ppc64le","os":"linux"},"size":525},{"digest":"sha256:72ba79e34f1baa40cd4d9ecd684b8389d0a1e18cf6e6d5c44c19716d25f65e20","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"riscv64","os":"linux"},"size":525},{"digest":"sha256:574efe68740d3bee2ef780036aee2e2da5cf7097ac06513f9f01f41e03365399","mediaType":"application\/vnd.docker.distribution.manifest.v2+json","platform":{"architecture":"s390x","os":"linux"},"size":525}],"mediaType":"application\/vnd.docker.distribution.manifest.list.v2+json","schemaVersion":2} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/72ba79e34f1baa40cd4d9ecd684b8389d0a1e18cf6e6d5c44c19716d25f65e20 b/ci/e2e/resources/store/hello-world/blobs/sha256/72ba79e34f1baa40cd4d9ecd684b8389d0a1e18cf6e6d5c44c19716d25f65e20 new file mode 100644 index 00000000..0cc18849 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/72ba79e34f1baa40cd4d9ecd684b8389d0a1e18cf6e6d5c44c19716d25f65e20 @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1472, + "digest": "sha256:eb6f80695a28848498afd1eb4f9e12caeeae15f3ea5f39e1427c828f8fb38e5f" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 2976, + "digest": "sha256:b102dd09f2b38103852530d8d5288ceb6779bcf33b4a453c10ac4d79fb083651" + } + ] +} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3 b/ci/e2e/resources/store/hello-world/blobs/sha256/7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3 new file mode 100644 index 00000000..3191185f --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3 @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1470, + "digest": "sha256:9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 2457, + "digest": "sha256:719385e32844401d57ecfd3eacab360bf551a1491c05b85806ed8f1b08d792f6" + } + ] +} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d b/ci/e2e/resources/store/hello-world/blobs/sha256/9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d new file mode 100644 index 00000000..4460e125 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/9c7a54a9a43cca047013b82af109fe963fde787f63f9e016fdc3384500c2823d @@ -0,0 +1 @@ +{"architecture":"amd64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:62a15619037f3c4fb4e6ba9bd224cba3540e393a55dc52f6bebe212ca7b5e1a7","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"347ca68872ee924c4f9394b195dcadaf591d387a45d624225251efc6cb7a348e","container_config":{"Hostname":"347ca68872ee","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:62a15619037f3c4fb4e6ba9bd224cba3540e393a55dc52f6bebe212ca7b5e1a7","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2023-05-04T17:37:03.872958712Z","docker_version":"20.10.23","history":[{"created":"2023-05-04T17:37:03.801840823Z","created_by":"/bin/sh -c #(nop) COPY file:201f8f1849e89d53be9f6aa76937f5e209d745abfd15a8552fcf2ba45ab267f9 in / "},{"created":"2023-05-04T17:37:03.872958712Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:01bb4fce3eb1b56b05adf99504dafd31907a5aadac736e36b27595c8b92f07f1"]}} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/9f32e20678dd3c4e7474ed063fcdaa62d32fef2046458f57efae408eccb1f935 b/ci/e2e/resources/store/hello-world/blobs/sha256/9f32e20678dd3c4e7474ed063fcdaa62d32fef2046458f57efae408eccb1f935 new file mode 100644 index 00000000..72a1143c --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/9f32e20678dd3c4e7474ed063fcdaa62d32fef2046458f57efae408eccb1f935 @@ -0,0 +1,20 @@ +{ + "manifests": [ + { + "digest": "sha256:004d23c66201b22fce069b7505756f17088de7889c83891e9bc69d749fa3690e", + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "platform": { + "architecture": "386", + "os": "linux" + }, + "size": 525 + }, + { + "digest": "sha256:a88a816b83f40e5d7b73eda36a450e1b07c5982840f13b0d2a1048adb98571c2", + "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", + "size": 709 + } + ], + "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", + "schemaVersion": 2 +} diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/a0a386314d69d1514d7aa63d12532b284bf37bba15ed7b4fc1a3f86605f86c63 b/ci/e2e/resources/store/hello-world/blobs/sha256/a0a386314d69d1514d7aa63d12532b284bf37bba15ed7b4fc1a3f86605f86c63 new file mode 100644 index 00000000..779d69f2 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/a0a386314d69d1514d7aa63d12532b284bf37bba15ed7b4fc1a3f86605f86c63 @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1482, + "digest": "sha256:38d49488e3b0689e88335277a18bdc2d03c9b58cb45b79902bf648885e23b9f4" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 2979, + "digest": "sha256:c4018b8bf4381a79e05c15591e1a1adf4452a9d383c4dcb63b1b7d4617d73af8" + } + ] +} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/a8117b42328be6ba54c594f9f14e216db10203deb22cc28aaa2c134f9ae2e0fd b/ci/e2e/resources/store/hello-world/blobs/sha256/a8117b42328be6ba54c594f9f14e216db10203deb22cc28aaa2c134f9ae2e0fd new file mode 100644 index 00000000..b9c02a21 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/a8117b42328be6ba54c594f9f14e216db10203deb22cc28aaa2c134f9ae2e0fd @@ -0,0 +1 @@ +{"architecture":"386","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:f21e55e51b02da347e5fc02f6e732997f4e0d8c8b7cb5b1359b51412c0538003","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"7e7ed95b255ae6284e5c7104fb101b1bc24e8e906232984227b7c3f785337b7c","container_config":{"Hostname":"7e7ed95b255a","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:f21e55e51b02da347e5fc02f6e732997f4e0d8c8b7cb5b1359b51412c0538003","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2023-05-04T05:56:18.664081874Z","docker_version":"20.10.23","history":[{"created":"2023-05-04T05:56:18.563912865Z","created_by":"/bin/sh -c #(nop) COPY file:228838c88f804dd6c5bd18ef2380612177731c208f251810fa950e1bc8527467 in / "},{"created":"2023-05-04T05:56:18.664081874Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:71fa18497d9fad69ff5100f14054d4d6eb3660c3ee306906ca592bac083c8c0e"]}} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/a88a816b83f40e5d7b73eda36a450e1b07c5982840f13b0d2a1048adb98571c2 b/ci/e2e/resources/store/hello-world/blobs/sha256/a88a816b83f40e5d7b73eda36a450e1b07c5982840f13b0d2a1048adb98571c2 new file mode 100644 index 00000000..c157b8e0 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/a88a816b83f40e5d7b73eda36a450e1b07c5982840f13b0d2a1048adb98571c2 @@ -0,0 +1,25 @@ +{ + "manifests": [ + { + "digest": "sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3", + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "platform": { + "architecture": "amd64", + "os": "linux" + }, + "size": 525 + }, + { + "digest": "sha256:efebf0f7aee69450f99deafe11121afa720abed733943e50581a9dc7540689c8", + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "platform": { + "architecture": "arm64", + "os": "linux", + "variant": "v8" + }, + "size": 525 + } + ], + "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", + "schemaVersion": 2 +} diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/b038788ddb222cb7d6025b411759e4f5abe9910486c8f98534ead97befd77dd7 b/ci/e2e/resources/store/hello-world/blobs/sha256/b038788ddb222cb7d6025b411759e4f5abe9910486c8f98534ead97befd77dd7 new file mode 100644 index 00000000..1e9e394c --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/b038788ddb222cb7d6025b411759e4f5abe9910486c8f98534ead97befd77dd7 @@ -0,0 +1 @@ +{"architecture":"arm64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:80d5abfa0241246d5bf678c139e16ee47a1e70eb57b29fd414dd4f0b36d34ed8","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"9388ffe1ee206146f45b0716291ad77e94686218696a0f140a90a957a38e21ef","container_config":{"Hostname":"9388ffe1ee20","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:80d5abfa0241246d5bf678c139e16ee47a1e70eb57b29fd414dd4f0b36d34ed8","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2023-05-04T08:43:21.769453191Z","docker_version":"20.10.23","history":[{"created":"2023-05-04T08:43:21.705077487Z","created_by":"/bin/sh -c #(nop) COPY file:f56689f2cf47e7530b9a14ed69e80d2ce38371866c8776256c24d80d148ff825 in / "},{"created":"2023-05-04T08:43:21.769453191Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:a7866053acacfefb68912a8916b67d6847c12b51949c6b8a5580c6609c08ae45"]},"variant":"v8"} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/b102dd09f2b38103852530d8d5288ceb6779bcf33b4a453c10ac4d79fb083651 b/ci/e2e/resources/store/hello-world/blobs/sha256/b102dd09f2b38103852530d8d5288ceb6779bcf33b4a453c10ac4d79fb083651 new file mode 100644 index 00000000..6da3d065 Binary files /dev/null and b/ci/e2e/resources/store/hello-world/blobs/sha256/b102dd09f2b38103852530d8d5288ceb6779bcf33b4a453c10ac4d79fb083651 differ diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/c4018b8bf4381a79e05c15591e1a1adf4452a9d383c4dcb63b1b7d4617d73af8 b/ci/e2e/resources/store/hello-world/blobs/sha256/c4018b8bf4381a79e05c15591e1a1adf4452a9d383c4dcb63b1b7d4617d73af8 new file mode 100644 index 00000000..8d20e0cf Binary files /dev/null and b/ci/e2e/resources/store/hello-world/blobs/sha256/c4018b8bf4381a79e05c15591e1a1adf4452a9d383c4dcb63b1b7d4617d73af8 differ diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/d549b3d1a2550a5e42a3f3250ce9fa4aa882b25f8528fd2eea1b789ce136631b b/ci/e2e/resources/store/hello-world/blobs/sha256/d549b3d1a2550a5e42a3f3250ce9fa4aa882b25f8528fd2eea1b789ce136631b new file mode 100644 index 00000000..14c43d32 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/d549b3d1a2550a5e42a3f3250ce9fa4aa882b25f8528fd2eea1b789ce136631b @@ -0,0 +1 @@ +{"architecture":"s390x","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:0a4ed120e12f159b468ae1fbdf6d7e2c053fd5547f6ad1e12019283e425a4f0c","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"16de42fe001ec70d74120e5db0a765dc7cf960bc3ecdfdd23fe034dac2b12962","container_config":{"Hostname":"16de42fe001e","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:0a4ed120e12f159b468ae1fbdf6d7e2c053fd5547f6ad1e12019283e425a4f0c","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2023-05-05T06:04:49.524781092Z","docker_version":"20.10.23","history":[{"created":"2023-05-05T06:04:49.407407092Z","created_by":"/bin/sh -c #(nop) COPY file:2412b45fdbb28b2191d4b0d59a4c66e460863549bae786d0aaf49c123b876e0b in / "},{"created":"2023-05-05T06:04:49.524781092Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:3aced21b93452b84cf84067c6ef10ea4a4841f8ca36a18300504f9b408f0082f"]}} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/d898e3d98788d70a8f874f818177c11569c5bb3c818ef45b877e7bba29a3bf7f b/ci/e2e/resources/store/hello-world/blobs/sha256/d898e3d98788d70a8f874f818177c11569c5bb3c818ef45b877e7bba29a3bf7f new file mode 100644 index 00000000..1f7906e9 Binary files /dev/null and b/ci/e2e/resources/store/hello-world/blobs/sha256/d898e3d98788d70a8f874f818177c11569c5bb3c818ef45b877e7bba29a3bf7f differ diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/de23d9589845285bb62b33da594c4a19802fda5b09bb6aef4d00e5e8c747a8df b/ci/e2e/resources/store/hello-world/blobs/sha256/de23d9589845285bb62b33da594c4a19802fda5b09bb6aef4d00e5e8c747a8df new file mode 100644 index 00000000..1cd079a3 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/de23d9589845285bb62b33da594c4a19802fda5b09bb6aef4d00e5e8c747a8df @@ -0,0 +1 @@ +{"architecture":"arm","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:3a7d6bbfa313f2c4ebb372d8db938b3fabc10d1843e47d88ab3eeebed171ae59","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"ef67c81477122128426ed18ce8bfea148aae5c7e560b8aabe9e9608a71e43468","container_config":{"Hostname":"ef67c8147712","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:3a7d6bbfa313f2c4ebb372d8db938b3fabc10d1843e47d88ab3eeebed171ae59","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2023-05-03T22:48:45.064468815Z","docker_version":"20.10.23","history":[{"created":"2023-05-03T22:48:44.585409244Z","created_by":"/bin/sh -c #(nop) COPY file:7df2eb05fc4f800f8ec9f08c58b4b76c2309d1d066bbb12db0f513480bd0a58f in / "},{"created":"2023-05-03T22:48:45.064468815Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:e0558fdde929b43545f3d356da59c2b877dac23a836501975b8d187d2f8aeaf0"]},"variant":"v5"} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/e4728a982b0acd74e810aeb5e8a5c1bd87f0de7ed93a678d58b3a79e6f7da2e9 b/ci/e2e/resources/store/hello-world/blobs/sha256/e4728a982b0acd74e810aeb5e8a5c1bd87f0de7ed93a678d58b3a79e6f7da2e9 new file mode 100644 index 00000000..b4ae4eea --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/e4728a982b0acd74e810aeb5e8a5c1bd87f0de7ed93a678d58b3a79e6f7da2e9 @@ -0,0 +1 @@ +{"architecture":"mips64le","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:055f6f260e8a9010f1749aec3bf7b31607ac2bad9a71efc0d46cc65c3f8f85e2","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"c508647c03f03d4f3316b2c7b5aa9414807547ddc28c9222c8bf5ec923fee7ba","container_config":{"Hostname":"c508647c03f0","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:055f6f260e8a9010f1749aec3bf7b31607ac2bad9a71efc0d46cc65c3f8f85e2","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2023-05-04T16:39:55.753058102Z","docker_version":"20.10.23","history":[{"created":"2023-05-04T16:39:54.174773277Z","created_by":"/bin/sh -c #(nop) COPY file:c4f860518106986675ada896e1418193ce3a20128315306f91e75f3a73a2993e in / "},{"created":"2023-05-04T16:39:55.753058102Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:ac81192890ade5849cdfceda04ba3bb672c3ff78d22a56a3d62c69304346d2dd"]}} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/eb6f80695a28848498afd1eb4f9e12caeeae15f3ea5f39e1427c828f8fb38e5f b/ci/e2e/resources/store/hello-world/blobs/sha256/eb6f80695a28848498afd1eb4f9e12caeeae15f3ea5f39e1427c828f8fb38e5f new file mode 100644 index 00000000..c0ac0207 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/eb6f80695a28848498afd1eb4f9e12caeeae15f3ea5f39e1427c828f8fb38e5f @@ -0,0 +1 @@ +{"architecture":"riscv64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:e49a60172bde032c6acee9573c6c6862161cdd81679ac04be3222df964e476cb","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"d1030c0984bdd994cca44f1832ec5f9630879484e0d20bb400583ab130587e0b","container_config":{"Hostname":"d1030c0984bd","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:e49a60172bde032c6acee9573c6c6862161cdd81679ac04be3222df964e476cb","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2023-05-03T23:08:38.909796734Z","docker_version":"20.10.17","history":[{"created":"2023-05-03T23:08:38.382314898Z","created_by":"/bin/sh -c #(nop) COPY file:85aecc4e10d311916d976ca1efd6561da1bb16c0d6ae089b7e9b78f5d0967acc in / "},{"created":"2023-05-03T23:08:38.909796734Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:4a72d706a8b7a23ce9d3137fd2a92ee180382acaf4a4fc3a099de96c059c3575"]}} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/efebf0f7aee69450f99deafe11121afa720abed733943e50581a9dc7540689c8 b/ci/e2e/resources/store/hello-world/blobs/sha256/efebf0f7aee69450f99deafe11121afa720abed733943e50581a9dc7540689c8 new file mode 100644 index 00000000..5aafebf6 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/efebf0f7aee69450f99deafe11121afa720abed733943e50581a9dc7540689c8 @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1485, + "digest": "sha256:b038788ddb222cb7d6025b411759e4f5abe9910486c8f98534ead97befd77dd7" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 3190, + "digest": "sha256:70f5ac315c5af948332962ff4678084ebcc215809506e4b8cd9e509660417205" + } + ] +} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/blobs/sha256/fbe0ff1e7697da39d987a975c737a7d2fa40b6e7f7f40c00b1dcc387b9ac0e85 b/ci/e2e/resources/store/hello-world/blobs/sha256/fbe0ff1e7697da39d987a975c737a7d2fa40b6e7f7f40c00b1dcc387b9ac0e85 new file mode 100644 index 00000000..8c38c734 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/blobs/sha256/fbe0ff1e7697da39d987a975c737a7d2fa40b6e7f7f40c00b1dcc387b9ac0e85 @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1471, + "digest": "sha256:5735de2b810bba182986adaf3f0d2e6567697caecbebb5d3f2934d8d37f32d2d" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 3922, + "digest": "sha256:4f1af0faa5862569c7c76d72b1c8e09ba01f2adeea0a44f8f3758d185e95e918" + } + ] +} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/index.json b/ci/e2e/resources/store/hello-world/index.json new file mode 100644 index 00000000..b039ddec --- /dev/null +++ b/ci/e2e/resources/store/hello-world/index.json @@ -0,0 +1 @@ +{"schemaVersion":2,"manifests":[{"mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","digest":"sha256:9f32e20678dd3c4e7474ed063fcdaa62d32fef2046458f57efae408eccb1f935","size":603,"annotations":{"org.opencontainers.image.ref.name":"nested-index"}},{"mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","digest":"sha256:726023f73a8fc5103fa6776d48090539042cb822531c6b751b1f6dd18cb5705d","size":2069,"annotations":{"org.opencontainers.image.ref.name":"multi-arch"}},{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3","size":525,"annotations":{"org.opencontainers.image.ref.name":"amd64"}},{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:efebf0f7aee69450f99deafe11121afa720abed733943e50581a9dc7540689c8","size":525,"annotations":{"org.opencontainers.image.ref.name":"arm64"}},{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:06bca41ba617acf0b3644df05d0d9c2d2f82ccaab629c0e39792b24682970040","size":525,"platform":{"architecture":"mips64le","os":"linux"}},{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:fbe0ff1e7697da39d987a975c737a7d2fa40b6e7f7f40c00b1dcc387b9ac0e85","size":525,"platform":{"architecture":"ppc64le","os":"linux"}},{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:084c3bdd1271adc754e2c5f6ba7046f1a2c099597dbd9643592fa8eb99981402","size":525,"platform":{"architecture":"arm","os":"linux","variant":"v5"}},{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:a0a386314d69d1514d7aa63d12532b284bf37bba15ed7b4fc1a3f86605f86c63","size":525,"platform":{"architecture":"arm","os":"linux","variant":"v7"}},{"mediaType":"application/vnd.docker.distribution.manifest.list.v2+json","digest":"sha256:a88a816b83f40e5d7b73eda36a450e1b07c5982840f13b0d2a1048adb98571c2","size":709},{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:574efe68740d3bee2ef780036aee2e2da5cf7097ac06513f9f01f41e03365399","size":525,"platform":{"architecture":"s390x","os":"linux"}},{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:004d23c66201b22fce069b7505756f17088de7889c83891e9bc69d749fa3690e","size":525,"platform":{"architecture":"386","os":"linux"}},{"mediaType":"application/vnd.docker.distribution.manifest.v2+json","digest":"sha256:72ba79e34f1baa40cd4d9ecd684b8389d0a1e18cf6e6d5c44c19716d25f65e20","size":525,"platform":{"architecture":"riscv64","os":"linux"}}]} \ No newline at end of file diff --git a/ci/e2e/resources/store/hello-world/oci-layout b/ci/e2e/resources/store/hello-world/oci-layout new file mode 100644 index 00000000..1343d370 --- /dev/null +++ b/ci/e2e/resources/store/hello-world/oci-layout @@ -0,0 +1 @@ +{"imageLayoutVersion":"1.0.0"} \ No newline at end of file diff --git a/cmd/convertor/builder/builder.go b/cmd/convertor/builder/builder.go index 4e8688c4..6d952205 100644 --- a/cmd/convertor/builder/builder.go +++ b/cmd/convertor/builder/builder.go @@ -70,6 +70,9 @@ type BuilderOptions struct { // disable sparse file when converting overlaybd DisableSparse bool + + // Push manifests with subject + Referrer bool } type graphBuilder struct { @@ -164,13 +167,31 @@ func (b *graphBuilder) process(ctx context.Context, src v1.Descriptor, tag bool) } // upload index + if b.Referrer { + index.ArtifactType = b.Engine.ArtifactType() + index.Subject = &v1.Descriptor{ + MediaType: src.MediaType, + Digest: src.Digest, + Size: src.Size, + } + } + if b.OCI { + index.MediaType = v1.MediaTypeImageIndex + } indexBytes, err = json.Marshal(index) if err != nil { return v1.Descriptor{}, fmt.Errorf("failed to marshal index: %w", err) } - expected := src - expected.Digest = digest.FromBytes(indexBytes) - expected.Size = int64(len(indexBytes)) + if b.DumpManifest { + if err := os.WriteFile(filepath.Join(b.WorkDir, "index.json"), indexBytes, 0644); err != nil { + return v1.Descriptor{}, fmt.Errorf("failed to dump index: %w", err) + } + } + expected := v1.Descriptor{ + MediaType: index.MediaType, + Digest: digest.FromBytes(indexBytes), + Size: int64(len(indexBytes)), + } var pusher remotes.Pusher if tag { pusher = b.tagPusher @@ -180,6 +201,7 @@ func (b *graphBuilder) process(ctx context.Context, src v1.Descriptor, tag bool) if err := uploadBytes(ctx, pusher, expected, indexBytes); err != nil { return v1.Descriptor{}, fmt.Errorf("failed to upload index: %w", err) } + log.G(ctx).Infof("index uploaded, %s", expected.Digest) return expected, nil default: return v1.Descriptor{}, fmt.Errorf("unsupported media type %q", src.MediaType) @@ -232,6 +254,7 @@ func (b *graphBuilder) buildOne(ctx context.Context, src v1.Descriptor, tag bool manifest: *manifest, config: *config, inputDesc: src, + referrer: b.Referrer, } engineBase.workDir = workdir engineBase.oci = b.OCI @@ -267,8 +290,11 @@ func (b *graphBuilder) buildOne(ctx context.Context, src v1.Descriptor, tag bool if err != nil { return v1.Descriptor{}, fmt.Errorf("failed to build %s: %w", workdir, err) } + + // preserve the other fields from src descriptor src.Digest = desc.Digest src.Size = desc.Size + src.MediaType = desc.MediaType return src, nil } diff --git a/cmd/convertor/builder/builder_engine.go b/cmd/convertor/builder/builder_engine.go index 860681ba..2ff1548c 100644 --- a/cmd/convertor/builder/builder_engine.go +++ b/cmd/convertor/builder/builder_engine.go @@ -27,10 +27,10 @@ import ( "github.com/containerd/containerd/v2/core/remotes" "github.com/containerd/containerd/v2/pkg/archive/compression" "github.com/containerd/continuity" + "github.com/containerd/log" "github.com/opencontainers/go-digest" specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" - "github.com/sirupsen/logrus" ) type BuilderEngineType int @@ -40,6 +40,22 @@ const ( TurboOCI ) +const ( + ArtifactTypeOverlaybd = "application/vnd.containerd.overlaybd.native.v1+json" + ArtifactTypeTurboOCI = "application/vnd.containerd.overlaybd.turbo.v1+json" +) + +func (engine BuilderEngineType) ArtifactType() string { + switch engine { + case Overlaybd: + return ArtifactTypeOverlaybd + case TurboOCI: + return ArtifactTypeTurboOCI + default: + return "" + } +} + type builderEngine interface { DownloadLayer(ctx context.Context, idx int) error @@ -96,6 +112,7 @@ type builderEngineBase struct { reserve bool noUpload bool dumpManifest bool + referrer bool } func (e *builderEngineBase) isGzipLayer(ctx context.Context, idx int) (bool, error) { @@ -164,14 +181,14 @@ func (e *builderEngineBase) uploadManifestAndConfig(ctx context.Context) (specs. if err = uploadBytes(ctx, e.pusher, e.manifest.Config, cbuf); err != nil { return specs.Descriptor{}, errors.Wrapf(err, "failed to upload config") } - logrus.Infof("config uploaded") + log.G(ctx).Infof("config uploaded") } if e.dumpManifest { confPath := path.Join(e.workDir, "config.json") if err := continuity.AtomicWriteFile(confPath, cbuf, 0644); err != nil { return specs.Descriptor{}, err } - logrus.Infof("config dumped") + log.G(ctx).Infof("config dumped") } e.manifest.MediaType = e.mediaTypeManifest() @@ -189,14 +206,14 @@ func (e *builderEngineBase) uploadManifestAndConfig(ctx context.Context) (specs. return specs.Descriptor{}, errors.Wrapf(err, "failed to upload manifest") } e.outputDesc = manifestDesc - logrus.Infof("manifest uploaded") + log.G(ctx).Infof("manifest uploaded, %s", manifestDesc.Digest) } if e.dumpManifest { descPath := path.Join(e.workDir, "manifest.json") if err := continuity.AtomicWriteFile(descPath, cbuf, 0644); err != nil { return specs.Descriptor{}, err } - logrus.Infof("manifest dumped") + log.G(ctx).Infof("manifest dumped") } return manifestDesc, nil } diff --git a/cmd/convertor/builder/overlaybd_builder.go b/cmd/convertor/builder/overlaybd_builder.go index 271b002f..f98674e0 100644 --- a/cmd/convertor/builder/overlaybd_builder.go +++ b/cmd/convertor/builder/overlaybd_builder.go @@ -198,7 +198,14 @@ func (e *overlaybdBuilderEngine) UploadImage(ctx context.Context) (specs.Descrip e.manifest.Layers = append([]specs.Descriptor{baseDesc}, e.manifest.Layers...) e.config.RootFS.DiffIDs = append([]digest.Digest{baseDesc.Digest}, e.config.RootFS.DiffIDs...) } - + if e.referrer { + e.manifest.ArtifactType = ArtifactTypeOverlaybd + e.manifest.Subject = &specs.Descriptor{ + MediaType: e.inputDesc.MediaType, + Digest: e.inputDesc.Digest, + Size: e.inputDesc.Size, + } + } return e.uploadManifestAndConfig(ctx) } diff --git a/cmd/convertor/builder/turboOCI_builder.go b/cmd/convertor/builder/turboOCI_builder.go index 0b0ea0c1..f7742048 100644 --- a/cmd/convertor/builder/turboOCI_builder.go +++ b/cmd/convertor/builder/turboOCI_builder.go @@ -202,6 +202,14 @@ func (e *turboOCIBuilderEngine) UploadImage(ctx context.Context) (specs.Descript e.manifest.Layers = append([]specs.Descriptor{baseDesc}, e.manifest.Layers...) e.config.RootFS.DiffIDs = append([]digest.Digest{baseDesc.Digest}, e.config.RootFS.DiffIDs...) } + if e.referrer { + e.manifest.ArtifactType = ArtifactTypeTurboOCI + e.manifest.Subject = &specs.Descriptor{ + MediaType: e.inputDesc.MediaType, + Digest: e.inputDesc.Digest, + Size: e.inputDesc.Size, + } + } return e.uploadManifestAndConfig(ctx) } @@ -234,7 +242,9 @@ func (e *turboOCIBuilderEngine) StoreConvertedManifestDetails(ctx context.Contex } func (e *turboOCIBuilderEngine) Cleanup() { - os.RemoveAll(e.workDir) + if !e.reserve { + os.RemoveAll(e.workDir) + } } func (e *turboOCIBuilderEngine) getLayerDir(idx int) string { diff --git a/cmd/convertor/main.go b/cmd/convertor/main.go index 3ec132c2..a1edd44a 100644 --- a/cmd/convertor/main.go +++ b/cmd/convertor/main.go @@ -50,6 +50,7 @@ var ( dbType string concurrencyLimit int disableSparse bool + referrer bool // certification certDirs []string @@ -87,6 +88,10 @@ Version: ` + commitID, tb = turboOCI } + if referrer { + oci = true + } + ctx := context.Background() opt := builder.BuilderOptions{ Ref: repo + ":" + tagInput, @@ -108,6 +113,7 @@ Version: ` + commitID, DumpManifest: dumpManifest, ConcurrencyLimit: concurrencyLimit, DisableSparse: disableSparse, + Referrer: referrer, } if overlaybd != "" { logrus.Info("building [Overlaybd - Native] image...") @@ -171,6 +177,7 @@ func init() { rootCmd.Flags().StringVar(&dbType, "db-type", "", "type of db to use for conversion deduplication. Available: mysql. Default none") rootCmd.Flags().IntVar(&concurrencyLimit, "concurrency-limit", 4, "the number of manifests that can be built at the same time, used for multi-arch images, 0 means no limit") rootCmd.Flags().BoolVar(&disableSparse, "disable-sparse", false, "disable sparse file for overlaybd") + rootCmd.Flags().BoolVar(&referrer, "referrer", false, "push converted manifests with subject, note '--oci' will be enabled automatically if '--referrer' is set, cause the referrer must be in OCI format.") // certification rootCmd.Flags().StringArrayVar(&certDirs, "cert-dir", nil, "In these directories, root CA should be named as *.crt and client cert should be named as *.cert, *.key") diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md index eea05f5d..747e18e4 100644 --- a/docs/QUICKSTART.md +++ b/docs/QUICKSTART.md @@ -249,7 +249,7 @@ sudo nerdctl rmi registry.hub.docker.com/overlaybd/redis:6.2.1_obd_new ```bash # userspace-image-convertor will automatically pull and push images from and to the registry -sudo /opt/overlaybd/snapshotter/convertor -r registry.hub.docker.com/library -i redis:6.2.1 -o 6.2.1_obd_new +sudo /opt/overlaybd/snapshotter/convertor -r registry.hub.docker.com/library/redis -i 6.2.1 -o 6.2.1_obd_new ``` ## Image build diff --git a/docs/USERSPACE_CONVERTOR.md b/docs/USERSPACE_CONVERTOR.md index d0b35dd7..3d2777aa 100644 --- a/docs/USERSPACE_CONVERTOR.md +++ b/docs/USERSPACE_CONVERTOR.md @@ -42,6 +42,7 @@ Flags: -o, --output-tag string tag for image converting to -d, --dir string directory used for temporary data (default "tmp_conv") --oci export image with oci spec + --fstype string filesystem type of converted image. (default "ext4") --mkfs make ext4 fs in bottom layer (default true) --vsize int virtual block device size (GB) (default 64) --fastoci string build 'Overlaybd-Turbo OCIv1' format (old name of turboOCIv1. deprecated) @@ -50,6 +51,8 @@ Flags: --db-str string db str for overlaybd conversion --db-type string type of db to use for conversion deduplication. Available: mysql. Default none --concurrency-limit int the number of manifests that can be built at the same time, used for multi-arch images, 0 means no limit (default 4) + --disable-sparse disable sparse file for overlaybd + --referrer push converted manifests with subject, note '--oci' will be enabled automatically if '--referrer' is set, cause the referrer must be in OCI format. --cert-dir stringArray In these directories, root CA should be named as *.crt and client cert should be named as *.cert, *.key --root-ca stringArray root CA certificates --client-cert stringArray client cert certificates, should form in ${cert-file}:${key-file} @@ -66,6 +69,73 @@ $ bin/convertor -r docker.io/overlaybd/redis -u user:pass -i 6.2.6 -o 6.2.6_obd ``` +### Referrers API support (Experimental) + +Referrers API provides the ability to reference artifacts to existing artifacts, it returns all artifacts that have a `subject` field of the given manifest digest. If your registry has supported this feature, you can enable `--referrer` so that the converted image will be referenced to the original image. See [Listing Referrers](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#listing-referrers) and for more details. + +The artifact type for overlaybd and turboOCIv1 is `application/vnd.containerd.overlaybd.native.v1+json` and `application/vnd.containerd.overlaybd.turbo.v1+json` respectively. + +The format of the converted images is as follows, note that if the original image is an index (multi-arch image), all converted indexes and manifests will have a `subject` field. + +#### index.json + +``` +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.image.index.v1+json", + "artifactType": "application/vnd.containerd.overlaybd.native.v1+json", + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:b0a40a33547de0961b6e0064a298e55484a2636830ba8bf5d05e34fae88b1443", + "size": 882, + "platform": { + "architecture": "386", + "os": "linux" + } + }, + ... + ], + "subject": { + "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", + "digest": "sha256:5df8d0e068b9c8c95c330607dfd96db51ac0b670b3a974ab23449866c0aa70a1", + "size": 1076 + } +} +``` + +#### manifest.json + +``` +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "artifactType": "application/vnd.containerd.overlaybd.native.v1+json", + "config": { + "mediaType": "application/vnd.oci.image.config.v1+json", + "digest": "sha256:e006fc50e6cec5e81844abb28abd0a01f4ff599432818a3bb9dfb96ce3e5daae", + "size": 571 + }, + "layers": [ + { + "mediaType": "application/vnd.oci.image.layer.v1.tar", + "digest": "sha256:63e766ab33f12958a0d94676a0bf5f7b800e04e4fac2124d785a8a54a8108e45", + "size": 3933696, + "annotations": { + "containerd.io/snapshot/overlaybd/blob-digest": "sha256:63e766ab33f12958a0d94676a0bf5f7b800e04e4fac2124d785a8a54a8108e45", + "containerd.io/snapshot/overlaybd/blob-size": "3933696", + "containerd.io/snapshot/overlaybd/version": "0.1.0" + } + } + ], + "subject": { + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "digest": "sha256:096958b089cdfa4b345dba0ae0a1e43bea59e4de6e084c26429b6c85096322cf", + "size": 528 + } +} +``` + ### Layer/Manifest Deduplication To avoid converting the same layer for every image conversion, a database is required to store the correspondence between OCIv1 image layer and overlaybd layer.