Also remove the DOCKER_ALLOW_SCHEMA1_PUSH_DONOTUSE from Jenkins
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -78,41 +78,8 @@ RUN --mount=type=cache,sharing=locked,id=moby-criu-aptlib,target=/var/lib/apt \ |
| 78 | 78 |
&& /build/criu --version |
| 79 | 79 |
|
| 80 | 80 |
# registry |
| 81 |
-FROM base AS registry-src |
|
| 82 |
-WORKDIR /usr/src/registry |
|
| 83 |
-RUN git init . && git remote add origin "https://github.com/distribution/distribution.git" |
|
| 84 |
- |
|
| 85 |
-FROM base AS registry |
|
| 86 |
-WORKDIR /go/src/github.com/docker/distribution |
|
| 87 |
- |
|
| 88 |
-# REGISTRY_VERSION_SCHEMA1 specifies the version of the registry to build and |
|
| 89 |
-# install from the https://github.com/docker/distribution repository. This is |
|
| 90 |
-# an older (pre v2.3.0) version of the registry that only supports schema1 |
|
| 91 |
-# manifests. This version of the registry is not working on arm64, so installation |
|
| 92 |
-# is skipped on that architecture. |
|
| 93 |
-ARG REGISTRY_VERSION_SCHEMA1=v2.1.0 |
|
| 94 |
-ARG TARGETPLATFORM |
|
| 95 |
-RUN --mount=from=registry-src,src=/usr/src/registry,rw \ |
|
| 96 |
- --mount=type=cache,target=/root/.cache/go-build,id=registry-build-$TARGETPLATFORM \ |
|
| 97 |
- --mount=type=cache,target=/go/pkg/mod \ |
|
| 98 |
- --mount=type=tmpfs,target=/go/src <<EOT |
|
| 99 |
- set -ex |
|
| 100 |
- export GOPATH="/go/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" |
|
| 101 |
- # Make the /build directory no matter what so that it doesn't fail on arm64 or |
|
| 102 |
- # any other platform where we don't build this registry |
|
| 103 |
- mkdir /build |
|
| 104 |
- case $TARGETPLATFORM in |
|
| 105 |
- linux/amd64|linux/arm/v7|linux/ppc64le|linux/s390x) |
|
| 106 |
- git fetch -q --depth 1 origin "${REGISTRY_VERSION_SCHEMA1}" +refs/tags/*:refs/tags/*
|
|
| 107 |
- git checkout -q FETCH_HEAD |
|
| 108 |
- CGO_ENABLED=0 xx-go build -o /build/registry-v2-schema1 -v ./cmd/registry |
|
| 109 |
- xx-verify /build/registry-v2-schema1 |
|
| 110 |
- ;; |
|
| 111 |
- esac |
|
| 112 |
-EOT |
|
| 113 |
- |
|
| 114 |
-FROM distribution/distribution:$REGISTRY_VERSION AS registry-v2 |
|
| 115 |
-RUN mkdir /build && mv /bin/registry /build/registry-v2 |
|
| 81 |
+FROM distribution/distribution:$REGISTRY_VERSION AS registry |
|
| 82 |
+RUN mkdir /build && mv /bin/registry /build/registry |
|
| 116 | 83 |
|
| 117 | 84 |
# go-swagger |
| 118 | 85 |
FROM base AS swagger-src |
| ... | ... |
@@ -467,7 +434,6 @@ COPY --link --from=delve /build/ /usr/local/bin/ |
| 467 | 467 |
COPY --link --from=gowinres /build/ /usr/local/bin/ |
| 468 | 468 |
COPY --link --from=tini /build/ /usr/local/bin/ |
| 469 | 469 |
COPY --link --from=registry /build/ /usr/local/bin/ |
| 470 |
-COPY --link --from=registry-v2 /build/ /usr/local/bin/ |
|
| 471 | 470 |
|
| 472 | 471 |
# Skip the CRIU stage for now, as the opensuse package repository is sometimes |
| 473 | 472 |
# unstable, and we're currently not using it in CI. |
| ... | ... |
@@ -4,7 +4,6 @@ import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
"encoding/json" |
| 6 | 6 |
"net/http" |
| 7 |
- "os" |
|
| 8 | 7 |
|
| 9 | 8 |
"github.com/distribution/reference" |
| 10 | 9 |
"github.com/docker/distribution" |
| ... | ... |
@@ -154,15 +153,10 @@ func (dr *distributionRouter) fetchManifest(ctx context.Context, distrepo distri |
| 154 | 154 |
distributionInspect.Platforms = append(distributionInspect.Platforms, platform) |
| 155 | 155 |
} |
| 156 | 156 |
} |
| 157 |
+ |
|
| 158 |
+ // TODO(thaJeztah); we only use this to produce a nice error, but as a result, we can't remove libtrust as dependency - see if we can reduce the dependencies, but still able to detect it's a deprecated manifest |
|
| 157 | 159 |
case *schema1.SignedManifest: |
| 158 |
- if os.Getenv("DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE") == "" {
|
|
| 159 |
- return registry.DistributionInspect{}, distributionpkg.DeprecatedSchema1ImageError(namedRef)
|
|
| 160 |
- } |
|
| 161 |
- platform := ocispec.Platform{
|
|
| 162 |
- Architecture: mnfstObj.Architecture, |
|
| 163 |
- OS: "linux", |
|
| 164 |
- } |
|
| 165 |
- distributionInspect.Platforms = append(distributionInspect.Platforms, platform) |
|
| 160 |
+ return registry.DistributionInspect{}, distributionpkg.DeprecatedSchema1ImageError(namedRef)
|
|
| 166 | 161 |
} |
| 167 | 162 |
return distributionInspect, nil |
| 168 | 163 |
} |
| ... | ... |
@@ -4,7 +4,6 @@ import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"io" |
| 7 |
- "os" |
|
| 8 | 7 |
"strings" |
| 9 | 8 |
"time" |
| 10 | 9 |
|
| ... | ... |
@@ -151,16 +150,10 @@ func (i *ImageService) pullTag(ctx context.Context, ref reference.Named, platfor |
| 151 | 151 |
} |
| 152 | 152 |
}() |
| 153 | 153 |
|
| 154 |
- var sentPullingFrom, sentSchema1Deprecation bool |
|
| 154 |
+ var sentPullingFrom bool |
|
| 155 | 155 |
ah := c8dimages.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
| 156 |
- if desc.MediaType == c8dimages.MediaTypeDockerSchema1Manifest && !sentSchema1Deprecation {
|
|
| 157 |
- err := distribution.DeprecatedSchema1ImageError(ref) |
|
| 158 |
- if os.Getenv("DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE") == "" {
|
|
| 159 |
- log.G(context.TODO()).Warn(err.Error()) |
|
| 160 |
- return nil, err |
|
| 161 |
- } |
|
| 162 |
- progress.Message(out, "", err.Error()) |
|
| 163 |
- sentSchema1Deprecation = true |
|
| 156 |
+ if desc.MediaType == c8dimages.MediaTypeDockerSchema1Manifest {
|
|
| 157 |
+ return nil, distribution.DeprecatedSchema1ImageError(ref) |
|
| 164 | 158 |
} |
| 165 | 159 |
if c8dimages.IsLayerType(desc.MediaType) {
|
| 166 | 160 |
id := stringid.TruncateID(desc.Digest.String()) |
| ... | ... |
@@ -235,7 +235,7 @@ type invalidArgumentErr struct{ error }
|
| 235 | 235 |
func (invalidArgumentErr) InvalidParameter() {}
|
| 236 | 236 |
|
| 237 | 237 |
func DeprecatedSchema1ImageError(ref reference.Named) error {
|
| 238 |
- msg := "[DEPRECATION NOTICE] Docker Image Format v1 and Docker Image manifest version 2, schema 1 support is disabled by default and will be removed in an upcoming release." |
|
| 238 |
+ msg := "Docker Image Format v1 and Docker Image manifest version 2, schema 1 support has been removed." |
|
| 239 | 239 |
if ref != nil {
|
| 240 | 240 |
msg += " Suggest the author of " + ref.String() + " to upgrade the image to the OCI Format or Docker Image manifest v2, schema 2." |
| 241 | 241 |
} |
| 242 | 242 |
deleted file mode 100644 |
| ... | ... |
@@ -1,38 +0,0 @@ |
| 1 |
-{
|
|
| 2 |
- "schemaVersion": 2, |
|
| 3 |
- "name": "library/hello-world", |
|
| 4 |
- "tag": "latest", |
|
| 5 |
- "architecture": "amd64", |
|
| 6 |
- "fsLayers": [ |
|
| 7 |
- {
|
|
| 8 |
- "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4" |
|
| 9 |
- }, |
|
| 10 |
- {
|
|
| 11 |
- "blobSum": "sha256:03f4658f8b782e12230c1783426bd3bacce651ce582a4ffb6fbbfa2079428ecb" |
|
| 12 |
- } |
|
| 13 |
- ], |
|
| 14 |
- "history": [ |
|
| 15 |
- {
|
|
| 16 |
- "v1Compatibility": "{\"id\":\"af340544ed62de0680f441c71fa1a80cb084678fed42bae393e543faea3a572c\",\"parent\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"created\":\"2015-08-06T23:53:22.608577814Z\",\"container\":\"c2b715156f640c7ac7d98472ea24335aba5432a1323a3bb722697e6d37ef794f\",\"container_config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [\\\"/hello\\\"]\"],\"Image\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":{}},\"docker_version\":\"1.7.1\",\"config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/hello\"],\"Image\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"
|
|
| 17 |
- }, |
|
| 18 |
- {
|
|
| 19 |
- "v1Compatibility": "{\"id\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"created\":\"2015-08-06T23:53:22.241352727Z\",\"container\":\"9aeb0006ffa72a8287564caaea87625896853701459261d3b569e320c0c9d5dc\",\"container_config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) COPY file:4abd3bff60458ca3b079d7b131ce26b2719055a030dfa96ff827da2b7c7038a7 in /\"],\"Image\":\"\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"docker_version\":\"1.7.1\",\"config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":960}\n"
|
|
| 20 |
- } |
|
| 21 |
- ], |
|
| 22 |
- "signatures": [ |
|
| 23 |
- {
|
|
| 24 |
- "header": {
|
|
| 25 |
- "jwk": {
|
|
| 26 |
- "crv": "P-256", |
|
| 27 |
- "kid": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4", |
|
| 28 |
- "kty": "EC", |
|
| 29 |
- "x": "Cu_UyxwLgHzE9rvlYSmvVdqYCXY42E9eNhBb0xNv0SQ", |
|
| 30 |
- "y": "zUsjWJkeKQ5tv7S-hl1Tg71cd-CqnrtiiLxSi6N_yc8" |
|
| 31 |
- }, |
|
| 32 |
- "alg": "ES256" |
|
| 33 |
- }, |
|
| 34 |
- "signature": "Y6xaFz9Sy-OtcnKQS1Ilq3Dh8cu4h3nBTJCpOTF1XF7vKtcxxA_xMP8-SgDo869SJ3VsvgPL9-Xn-OoYG2rb1A", |
|
| 35 |
- "protected": "eyJmb3JtYXRMZW5ndGgiOjMxOTcsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNS0wOS0xMVQwNDoxMzo0OFoifQ" |
|
| 36 |
- } |
|
| 37 |
- ] |
|
| 38 |
-} |
| 39 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,46 +0,0 @@ |
| 1 |
-{
|
|
| 2 |
- "schemaVersion": 1, |
|
| 3 |
- "name": "library/hello-world", |
|
| 4 |
- "tag": "latest", |
|
| 5 |
- "architecture": "amd64", |
|
| 6 |
- "fsLayers": [ |
|
| 7 |
- {
|
|
| 8 |
- "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4" |
|
| 9 |
- }, |
|
| 10 |
- {
|
|
| 11 |
- "blobSum": "sha256:03f4658f8b782e12230c1783426bd3bacce651ce582a4ffb6fbbfa2079428ecb" |
|
| 12 |
- } |
|
| 13 |
- ], |
|
| 14 |
- "history": [ |
|
| 15 |
- {
|
|
| 16 |
- "v1Compatibility": "{\"id\":\"af340544ed62de0680f441c71fa1a80cb084678fed42bae393e543faea3a572c\",\"parent\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"created\":\"2015-08-06T23:53:22.608577814Z\",\"container\":\"c2b715156f640c7ac7d98472ea24335aba5432a1323a3bb722697e6d37ef794f\",\"container_config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [\\\"/hello\\\"]\"],\"Image\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":{}},\"docker_version\":\"1.7.1\",\"config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/hello\"],\"Image\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"
|
|
| 17 |
- }, |
|
| 18 |
- {
|
|
| 19 |
- "v1Compatibility": "{\"id\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"created\":\"2015-08-06T23:53:22.241352727Z\",\"container\":\"9aeb0006ffa72a8287564caaea87625896853701459261d3b569e320c0c9d5dc\",\"container_config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) COPY file:4abd3bff60458ca3b079d7b131ce26b2719055a030dfa96ff827da2b7c7038a7 in /\"],\"Image\":\"\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"docker_version\":\"1.7.1\",\"config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":960}\n"
|
|
| 20 |
- } |
|
| 21 |
- ], |
|
| 22 |
- "fsLayers": [ |
|
| 23 |
- {
|
|
| 24 |
- "blobSum": "sha256:ffff95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4" |
|
| 25 |
- }, |
|
| 26 |
- {
|
|
| 27 |
- "blobSum": "sha256:ffff658f8b782e12230c1783426bd3bacce651ce582a4ffb6fbbfa2079428ecb" |
|
| 28 |
- } |
|
| 29 |
- ], |
|
| 30 |
- "signatures": [ |
|
| 31 |
- {
|
|
| 32 |
- "header": {
|
|
| 33 |
- "jwk": {
|
|
| 34 |
- "crv": "P-256", |
|
| 35 |
- "kid": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4", |
|
| 36 |
- "kty": "EC", |
|
| 37 |
- "x": "Cu_UyxwLgHzE9rvlYSmvVdqYCXY42E9eNhBb0xNv0SQ", |
|
| 38 |
- "y": "zUsjWJkeKQ5tv7S-hl1Tg71cd-CqnrtiiLxSi6N_yc8" |
|
| 39 |
- }, |
|
| 40 |
- "alg": "ES256" |
|
| 41 |
- }, |
|
| 42 |
- "signature": "Y6xaFz9Sy-OtcnKQS1Ilq3Dh8cu4h3nBTJCpOTF1XF7vKtcxxA_xMP8-SgDo869SJ3VsvgPL9-Xn-OoYG2rb1A", |
|
| 43 |
- "protected": "eyJmb3JtYXRMZW5ndGgiOjMxOTcsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNS0wOS0xMVQwNDoxMzo0OFoifQ" |
|
| 44 |
- } |
|
| 45 |
- ] |
|
| 46 |
-} |
| 47 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,38 +0,0 @@ |
| 1 |
-{
|
|
| 2 |
- "schemaVersion": 1, |
|
| 3 |
- "name": "library/hello-world", |
|
| 4 |
- "tag": "latest", |
|
| 5 |
- "architecture": "amd64", |
|
| 6 |
- "fsLayers": [ |
|
| 7 |
- {
|
|
| 8 |
- "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4" |
|
| 9 |
- }, |
|
| 10 |
- {
|
|
| 11 |
- "blobSum": "sha256:03f4658f8b782e12230c1783426bd3bacce651ce582a4ffb6fbbfa2079428ecb" |
|
| 12 |
- } |
|
| 13 |
- ], |
|
| 14 |
- "history": [ |
|
| 15 |
- {
|
|
| 16 |
- "v1Compatibility": "{\"id\":\"af340544ed62de0680f441c71fa1a80cb084678fed42bae393e543faea3a572c\",\"parent\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"created\":\"2015-08-06T23:53:22.608577814Z\",\"container\":\"c2b715156f640c7ac7d98472ea24335aba5432a1323a3bb722697e6d37ef794f\",\"container_config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [\\\"/hello\\\"]\"],\"Image\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":{}},\"docker_version\":\"1.7.1\",\"config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/hello\"],\"Image\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"
|
|
| 17 |
- }, |
|
| 18 |
- {
|
|
| 19 |
- "v1Compatibility": "{\"id\":\"535020c3e8add9d6bb06e5ac15a261e73d9b213d62fb2c14d752b8e189b2b912\",\"created\":\"2015-08-06T23:53:22.241352727Z\",\"container\":\"9aeb0006ffa72a8287564caaea87625896853701459261d3b569e320c0c9d5dc\",\"container_config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) COPY file:4abd3bff60458ca3b079d7b131ce26b2719055a030dfa96ff827da2b7c7038a7 in /\"],\"Image\":\"\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"docker_version\":\"1.7.1\",\"config\":{\"Hostname\":\"9aeb0006ffa7\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"VolumeDriver\":\"\",\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":960}\n"
|
|
| 20 |
- } |
|
| 21 |
- ], |
|
| 22 |
- "signatures": [ |
|
| 23 |
- {
|
|
| 24 |
- "header": {
|
|
| 25 |
- "jwk": {
|
|
| 26 |
- "crv": "P-256", |
|
| 27 |
- "kid": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4", |
|
| 28 |
- "kty": "EC", |
|
| 29 |
- "x": "Cu_UyxwLgHzE9rvlYSmvVdqYCXY42E9eNhBb0xNv0SQ", |
|
| 30 |
- "y": "zUsjWJkeKQ5tv7S-hl1Tg71cd-CqnrtiiLxSi6N_yc8" |
|
| 31 |
- }, |
|
| 32 |
- "alg": "ES256" |
|
| 33 |
- }, |
|
| 34 |
- "signature": "Y6xaFz9Sy-OtcnKQS1Ilq3Dh8cu4h3nBTJCpOTF1XF7vKtcxxA_xMP8-SgDo869SJ3VsvgPL9-Xn-OoYG2rb1A", |
|
| 35 |
- "protected": "eyJmb3JtYXRMZW5ndGgiOjMxOTcsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNS0wOS0xMVQwNDoxMzo0OFoifQ" |
|
| 36 |
- } |
|
| 37 |
- ] |
|
| 38 |
-} |
|
| 39 | 1 |
\ No newline at end of file |
| ... | ... |
@@ -5,7 +5,6 @@ import ( |
| 5 | 5 |
"encoding/json" |
| 6 | 6 |
"fmt" |
| 7 | 7 |
"io" |
| 8 |
- "os" |
|
| 9 | 8 |
"strings" |
| 10 | 9 |
|
| 11 | 10 |
"github.com/containerd/containerd/v2/core/content" |
| ... | ... |
@@ -292,15 +291,7 @@ func detectManifestBlobMediaType(dt []byte) (string, error) {
|
| 292 | 292 |
} |
| 293 | 293 |
return mfst.MediaType, nil |
| 294 | 294 |
case schema1.MediaTypeManifest: |
| 295 |
- if os.Getenv("DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE") == "" {
|
|
| 296 |
- err := DeprecatedSchema1ImageError(nil) |
|
| 297 |
- log.G(context.TODO()).Warn(err.Error()) |
|
| 298 |
- return "", err |
|
| 299 |
- } |
|
| 300 |
- if mfst.Manifests != nil || mfst.Layers != nil {
|
|
| 301 |
- return "", fmt.Errorf(`media-type: %q should not have "manifests" or "layers"`, mfst.MediaType) |
|
| 302 |
- } |
|
| 303 |
- return mfst.MediaType, nil |
|
| 295 |
+ return "", DeprecatedSchema1ImageError(nil) |
|
| 304 | 296 |
default: |
| 305 | 297 |
if mfst.MediaType != "" {
|
| 306 | 298 |
return mfst.MediaType, nil |
| ... | ... |
@@ -308,12 +299,7 @@ func detectManifestBlobMediaType(dt []byte) (string, error) {
|
| 308 | 308 |
} |
| 309 | 309 |
switch {
|
| 310 | 310 |
case mfst.FSLayers != nil && mfst.Manifests == nil && mfst.Layers == nil && mfst.Config == nil: |
| 311 |
- if os.Getenv("DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE") == "" {
|
|
| 312 |
- err := DeprecatedSchema1ImageError(nil) |
|
| 313 |
- log.G(context.TODO()).Warn(err.Error()) |
|
| 314 |
- return "", err |
|
| 315 |
- } |
|
| 316 |
- return schema1.MediaTypeManifest, nil |
|
| 311 |
+ return "", DeprecatedSchema1ImageError(nil) |
|
| 317 | 312 |
case mfst.Config != nil && mfst.Manifests == nil && mfst.FSLayers == nil, |
| 318 | 313 |
mfst.Layers != nil && mfst.Manifests == nil && mfst.FSLayers == nil: |
| 319 | 314 |
return ocispec.MediaTypeImageManifest, nil |
| ... | ... |
@@ -14,7 +14,6 @@ import ( |
| 14 | 14 |
"github.com/docker/distribution" |
| 15 | 15 |
"github.com/docker/distribution/manifest/manifestlist" |
| 16 | 16 |
"github.com/docker/distribution/manifest/ocischema" |
| 17 |
- "github.com/docker/distribution/manifest/schema1" |
|
| 18 | 17 |
"github.com/docker/distribution/manifest/schema2" |
| 19 | 18 |
"github.com/google/go-cmp/cmp/cmpopts" |
| 20 | 19 |
"github.com/opencontainers/go-digest" |
| ... | ... |
@@ -338,14 +337,12 @@ func TestDetectManifestBlobMediaType(t *testing.T) {
|
| 338 | 338 |
cases := map[string]testCase{
|
| 339 | 339 |
"mediaType is set": {[]byte(`{"mediaType": "bananas"}`), "bananas"},
|
| 340 | 340 |
"oci manifest": {[]byte(`{"config": {}}`), ocispec.MediaTypeImageManifest},
|
| 341 |
- "schema1": {[]byte(`{"fsLayers": []}`), schema1.MediaTypeManifest},
|
|
| 342 | 341 |
"oci index fallback": {[]byte(`{}`), ocispec.MediaTypeImageIndex},
|
| 343 | 342 |
// Make sure we prefer mediaType |
| 344 | 343 |
"mediaType and config set": {[]byte(`{"mediaType": "bananas", "config": {}}`), "bananas"},
|
| 345 | 344 |
"mediaType and fsLayers set": {[]byte(`{"mediaType": "bananas", "fsLayers": []}`), "bananas"},
|
| 346 | 345 |
} |
| 347 | 346 |
|
| 348 |
- t.Setenv("DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE", "1")
|
|
| 349 | 347 |
for name, tc := range cases {
|
| 350 | 348 |
t.Run(name, func(t *testing.T) {
|
| 351 | 349 |
mt, err := detectManifestBlobMediaType(tc.json) |
| ... | ... |
@@ -361,14 +358,6 @@ func TestDetectManifestBlobMediaTypeInvalid(t *testing.T) {
|
| 361 | 361 |
expected string |
| 362 | 362 |
} |
| 363 | 363 |
cases := map[string]testCase{
|
| 364 |
- "schema 1 mediaType with manifests": {
|
|
| 365 |
- []byte(`{"mediaType": "` + schema1.MediaTypeManifest + `","manifests":[]}`),
|
|
| 366 |
- `media-type: "application/vnd.docker.distribution.manifest.v1+json" should not have "manifests" or "layers"`, |
|
| 367 |
- }, |
|
| 368 |
- "schema 1 mediaType with layers": {
|
|
| 369 |
- []byte(`{"mediaType": "` + schema1.MediaTypeManifest + `","layers":[]}`),
|
|
| 370 |
- `media-type: "application/vnd.docker.distribution.manifest.v1+json" should not have "manifests" or "layers"`, |
|
| 371 |
- }, |
|
| 372 | 364 |
"schema 2 mediaType with manifests": {
|
| 373 | 365 |
[]byte(`{"mediaType": "` + schema2.MediaTypeManifest + `","manifests":[]}`),
|
| 374 | 366 |
`media-type: "application/vnd.docker.distribution.manifest.v2+json" should not have "manifests" or "fsLayers"`, |
| ... | ... |
@@ -415,7 +404,6 @@ func TestDetectManifestBlobMediaTypeInvalid(t *testing.T) {
|
| 415 | 415 |
}, |
| 416 | 416 |
} |
| 417 | 417 |
|
| 418 |
- t.Setenv("DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE", "1")
|
|
| 419 | 418 |
for name, tc := range cases {
|
| 420 | 419 |
t.Run(name, func(t *testing.T) {
|
| 421 | 420 |
mt, err := detectManifestBlobMediaType(tc.json) |
| ... | ... |
@@ -2,7 +2,6 @@ package distribution // import "github.com/docker/docker/distribution" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 |
- "encoding/json" |
|
| 6 | 5 |
"fmt" |
| 7 | 6 |
"io" |
| 8 | 7 |
"os" |
| ... | ... |
@@ -22,7 +21,6 @@ import ( |
| 22 | 22 |
"github.com/docker/docker/distribution/metadata" |
| 23 | 23 |
"github.com/docker/docker/distribution/xfer" |
| 24 | 24 |
"github.com/docker/docker/image" |
| 25 |
- v1 "github.com/docker/docker/image/v1" |
|
| 26 | 25 |
"github.com/docker/docker/layer" |
| 27 | 26 |
"github.com/docker/docker/pkg/ioutils" |
| 28 | 27 |
"github.com/docker/docker/pkg/progress" |
| ... | ... |
@@ -428,17 +426,7 @@ func (p *puller) pullTag(ctx context.Context, ref reference.Named, platform *oci |
| 428 | 428 |
|
| 429 | 429 |
switch v := manifest.(type) {
|
| 430 | 430 |
case *schema1.SignedManifest: |
| 431 |
- err := DeprecatedSchema1ImageError(ref) |
|
| 432 |
- log.G(ctx).Warn(err.Error()) |
|
| 433 |
- if os.Getenv("DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE") == "" {
|
|
| 434 |
- return false, err |
|
| 435 |
- } |
|
| 436 |
- progress.Message(p.config.ProgressOutput, "", err.Error()) |
|
| 437 |
- |
|
| 438 |
- id, manifestDigest, err = p.pullSchema1(ctx, ref, v, platform) |
|
| 439 |
- if err != nil {
|
|
| 440 |
- return false, err |
|
| 441 |
- } |
|
| 431 |
+ return false, DeprecatedSchema1ImageError(ref) |
|
| 442 | 432 |
case *schema2.DeserializedManifest: |
| 443 | 433 |
id, manifestDigest, err = p.pullSchema2(ctx, ref, v, platform) |
| 444 | 434 |
if err != nil {
|
| ... | ... |
@@ -508,88 +496,6 @@ func (p *puller) validateMediaType(mediaType string) error {
|
| 508 | 508 |
return invalidManifestClassError{mediaType, configClass}
|
| 509 | 509 |
} |
| 510 | 510 |
|
| 511 |
-func (p *puller) pullSchema1(ctx context.Context, ref reference.Reference, unverifiedManifest *schema1.SignedManifest, platform *ocispec.Platform) (id digest.Digest, manifestDigest digest.Digest, _ error) {
|
|
| 512 |
- if platform != nil {
|
|
| 513 |
- // Early bath if the requested OS doesn't match that of the configuration. |
|
| 514 |
- // This avoids doing the download, only to potentially fail later. |
|
| 515 |
- if err := image.CheckOS(platform.OS); err != nil {
|
|
| 516 |
- return "", "", fmt.Errorf("cannot download image with operating system %q when requesting %q", runtime.GOOS, platform.OS)
|
|
| 517 |
- } |
|
| 518 |
- } |
|
| 519 |
- |
|
| 520 |
- var verifiedManifest *schema1.Manifest |
|
| 521 |
- verifiedManifest, err := verifySchema1Manifest(ctx, unverifiedManifest, ref) |
|
| 522 |
- if err != nil {
|
|
| 523 |
- return "", "", err |
|
| 524 |
- } |
|
| 525 |
- |
|
| 526 |
- rootFS := image.NewRootFS() |
|
| 527 |
- |
|
| 528 |
- // remove duplicate layers and check parent chain validity |
|
| 529 |
- err = fixManifestLayers(verifiedManifest) |
|
| 530 |
- if err != nil {
|
|
| 531 |
- return "", "", err |
|
| 532 |
- } |
|
| 533 |
- |
|
| 534 |
- var descriptors []xfer.DownloadDescriptor |
|
| 535 |
- |
|
| 536 |
- // Image history converted to the new format |
|
| 537 |
- var history []image.History |
|
| 538 |
- |
|
| 539 |
- // Note that the order of this loop is in the direction of bottom-most |
|
| 540 |
- // to top-most, so that the downloads slice gets ordered correctly. |
|
| 541 |
- for i := len(verifiedManifest.FSLayers) - 1; i >= 0; i-- {
|
|
| 542 |
- blobSum := verifiedManifest.FSLayers[i].BlobSum |
|
| 543 |
- if err = blobSum.Validate(); err != nil {
|
|
| 544 |
- return "", "", errors.Wrapf(err, "could not validate layer digest %q", blobSum) |
|
| 545 |
- } |
|
| 546 |
- |
|
| 547 |
- var throwAway struct {
|
|
| 548 |
- ThrowAway bool `json:"throwaway,omitempty"` |
|
| 549 |
- } |
|
| 550 |
- if err := json.Unmarshal([]byte(verifiedManifest.History[i].V1Compatibility), &throwAway); err != nil {
|
|
| 551 |
- return "", "", err |
|
| 552 |
- } |
|
| 553 |
- |
|
| 554 |
- h, err := v1.HistoryFromConfig([]byte(verifiedManifest.History[i].V1Compatibility), throwAway.ThrowAway) |
|
| 555 |
- if err != nil {
|
|
| 556 |
- return "", "", err |
|
| 557 |
- } |
|
| 558 |
- history = append(history, h) |
|
| 559 |
- |
|
| 560 |
- if throwAway.ThrowAway {
|
|
| 561 |
- continue |
|
| 562 |
- } |
|
| 563 |
- |
|
| 564 |
- descriptors = append(descriptors, &layerDescriptor{
|
|
| 565 |
- digest: blobSum, |
|
| 566 |
- repoName: p.repoName, |
|
| 567 |
- repo: p.repo, |
|
| 568 |
- metadataService: p.metadataService, |
|
| 569 |
- }) |
|
| 570 |
- } |
|
| 571 |
- |
|
| 572 |
- resultRootFS, release, err := p.config.DownloadManager.Download(ctx, *rootFS, descriptors, p.config.ProgressOutput) |
|
| 573 |
- if err != nil {
|
|
| 574 |
- return "", "", err |
|
| 575 |
- } |
|
| 576 |
- defer release() |
|
| 577 |
- |
|
| 578 |
- config, err := v1.MakeConfigFromV1Config([]byte(verifiedManifest.History[0].V1Compatibility), &resultRootFS, history) |
|
| 579 |
- if err != nil {
|
|
| 580 |
- return "", "", err |
|
| 581 |
- } |
|
| 582 |
- |
|
| 583 |
- imageID, err := p.config.ImageStore.Put(ctx, config) |
|
| 584 |
- if err != nil {
|
|
| 585 |
- return "", "", err |
|
| 586 |
- } |
|
| 587 |
- |
|
| 588 |
- manifestDigest = digest.FromBytes(unverifiedManifest.Canonical) |
|
| 589 |
- |
|
| 590 |
- return imageID, manifestDigest, nil |
|
| 591 |
-} |
|
| 592 |
- |
|
| 593 | 511 |
func checkSupportedMediaType(mediaType string) error {
|
| 594 | 512 |
lowerMt := strings.ToLower(mediaType) |
| 595 | 513 |
for _, mt := range supportedMediaTypes {
|
| ... | ... |
@@ -862,17 +768,7 @@ func (p *puller) pullManifestList(ctx context.Context, ref reference.Named, mfst |
| 862 | 862 |
|
| 863 | 863 |
switch v := manifest.(type) {
|
| 864 | 864 |
case *schema1.SignedManifest: |
| 865 |
- err := DeprecatedSchema1ImageError(ref) |
|
| 866 |
- log.G(ctx).Warn(err.Error()) |
|
| 867 |
- if os.Getenv("DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE") == "" {
|
|
| 868 |
- return "", "", err |
|
| 869 |
- } |
|
| 870 |
- progress.Message(p.config.ProgressOutput, "", err.Error()) |
|
| 871 |
- |
|
| 872 |
- id, _, err = p.pullSchema1(ctx, manifestRef, v, toOCIPlatform(match.Platform)) |
|
| 873 |
- if err != nil {
|
|
| 874 |
- return "", "", err |
|
| 875 |
- } |
|
| 865 |
+ return "", "", DeprecatedSchema1ImageError(ref) |
|
| 876 | 866 |
case *schema2.DeserializedManifest: |
| 877 | 867 |
id, _, err = p.pullSchema2(ctx, manifestRef, v, toOCIPlatform(match.Platform)) |
| 878 | 868 |
if err != nil {
|
| ... | ... |
@@ -999,83 +895,6 @@ func schema2ManifestDigest(ref reference.Named, mfst distribution.Manifest) (dig |
| 999 | 999 |
return digest.FromBytes(canonical), nil |
| 1000 | 1000 |
} |
| 1001 | 1001 |
|
| 1002 |
-func verifySchema1Manifest(ctx context.Context, signedManifest *schema1.SignedManifest, ref reference.Reference) (*schema1.Manifest, error) {
|
|
| 1003 |
- // If pull by digest, then verify the manifest digest. NOTE: It is |
|
| 1004 |
- // important to do this first, before any other content validation. If the |
|
| 1005 |
- // digest cannot be verified, don't even bother with those other things. |
|
| 1006 |
- if digested, isCanonical := ref.(reference.Canonical); isCanonical {
|
|
| 1007 |
- verifier := digested.Digest().Verifier() |
|
| 1008 |
- if _, err := verifier.Write(signedManifest.Canonical); err != nil {
|
|
| 1009 |
- return nil, err |
|
| 1010 |
- } |
|
| 1011 |
- if !verifier.Verified() {
|
|
| 1012 |
- err := fmt.Errorf("image verification failed for digest %s", digested.Digest())
|
|
| 1013 |
- log.G(ctx).Error(err) |
|
| 1014 |
- return nil, err |
|
| 1015 |
- } |
|
| 1016 |
- } |
|
| 1017 |
- |
|
| 1018 |
- m := &signedManifest.Manifest |
|
| 1019 |
- if m.SchemaVersion != 1 {
|
|
| 1020 |
- return nil, fmt.Errorf("unsupported schema version %d for %q", m.SchemaVersion, reference.FamiliarString(ref))
|
|
| 1021 |
- } |
|
| 1022 |
- if len(m.FSLayers) != len(m.History) {
|
|
| 1023 |
- return nil, fmt.Errorf("length of history not equal to number of layers for %q", reference.FamiliarString(ref))
|
|
| 1024 |
- } |
|
| 1025 |
- if len(m.FSLayers) == 0 {
|
|
| 1026 |
- return nil, fmt.Errorf("no FSLayers in manifest for %q", reference.FamiliarString(ref))
|
|
| 1027 |
- } |
|
| 1028 |
- return m, nil |
|
| 1029 |
-} |
|
| 1030 |
- |
|
| 1031 |
-// fixManifestLayers removes repeated layers from the manifest and checks the |
|
| 1032 |
-// correctness of the parent chain. |
|
| 1033 |
-func fixManifestLayers(m *schema1.Manifest) error {
|
|
| 1034 |
- imgs := make([]*image.V1Image, len(m.FSLayers)) |
|
| 1035 |
- for i := range m.FSLayers {
|
|
| 1036 |
- img := &image.V1Image{}
|
|
| 1037 |
- |
|
| 1038 |
- if err := json.Unmarshal([]byte(m.History[i].V1Compatibility), img); err != nil {
|
|
| 1039 |
- return err |
|
| 1040 |
- } |
|
| 1041 |
- |
|
| 1042 |
- imgs[i] = img |
|
| 1043 |
- if err := v1.ValidateID(img.ID); err != nil {
|
|
| 1044 |
- return err |
|
| 1045 |
- } |
|
| 1046 |
- } |
|
| 1047 |
- |
|
| 1048 |
- if imgs[len(imgs)-1].Parent != "" && runtime.GOOS != "windows" {
|
|
| 1049 |
- // Windows base layer can point to a base layer parent that is not in manifest. |
|
| 1050 |
- return errors.New("invalid parent ID in the base layer of the image")
|
|
| 1051 |
- } |
|
| 1052 |
- |
|
| 1053 |
- // check general duplicates to error instead of a deadlock |
|
| 1054 |
- idmap := make(map[string]struct{})
|
|
| 1055 |
- |
|
| 1056 |
- var lastID string |
|
| 1057 |
- for _, img := range imgs {
|
|
| 1058 |
- // skip IDs that appear after each other, we handle those later |
|
| 1059 |
- if _, exists := idmap[img.ID]; img.ID != lastID && exists {
|
|
| 1060 |
- return fmt.Errorf("ID %+v appears multiple times in manifest", img.ID)
|
|
| 1061 |
- } |
|
| 1062 |
- lastID = img.ID |
|
| 1063 |
- idmap[lastID] = struct{}{}
|
|
| 1064 |
- } |
|
| 1065 |
- |
|
| 1066 |
- // backwards loop so that we keep the remaining indexes after removing items |
|
| 1067 |
- for i := len(imgs) - 2; i >= 0; i-- {
|
|
| 1068 |
- if imgs[i].ID == imgs[i+1].ID { // repeated ID. remove and continue
|
|
| 1069 |
- m.FSLayers = append(m.FSLayers[:i], m.FSLayers[i+1:]...) |
|
| 1070 |
- m.History = append(m.History[:i], m.History[i+1:]...) |
|
| 1071 |
- } else if imgs[i].Parent != imgs[i+1].ID {
|
|
| 1072 |
- return fmt.Errorf("invalid parent ID. Expected %v, got %v", imgs[i+1].ID, imgs[i].Parent)
|
|
| 1073 |
- } |
|
| 1074 |
- } |
|
| 1075 |
- |
|
| 1076 |
- return nil |
|
| 1077 |
-} |
|
| 1078 |
- |
|
| 1079 | 1002 |
func createDownloadFile() (*os.File, error) {
|
| 1080 | 1003 |
return os.CreateTemp("", "GetImageBlob")
|
| 1081 | 1004 |
} |
| ... | ... |
@@ -2,20 +2,15 @@ package distribution // import "github.com/docker/docker/distribution" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 |
- "encoding/json" |
|
| 6 | 5 |
"net/http" |
| 7 | 6 |
"net/http/httptest" |
| 8 | 7 |
"net/url" |
| 9 |
- "os" |
|
| 10 |
- "reflect" |
|
| 11 | 8 |
"runtime" |
| 12 | 9 |
"strings" |
| 13 | 10 |
"sync/atomic" |
| 14 | 11 |
"testing" |
| 15 | 12 |
|
| 16 |
- "github.com/containerd/log/logtest" |
|
| 17 | 13 |
"github.com/distribution/reference" |
| 18 |
- "github.com/docker/distribution/manifest/schema1" |
|
| 19 | 14 |
registrytypes "github.com/docker/docker/api/types/registry" |
| 20 | 15 |
"github.com/docker/docker/image" |
| 21 | 16 |
"github.com/docker/docker/registry" |
| ... | ... |
@@ -25,177 +20,6 @@ import ( |
| 25 | 25 |
is "gotest.tools/v3/assert/cmp" |
| 26 | 26 |
) |
| 27 | 27 |
|
| 28 |
-// TestFixManifestLayers checks that fixManifestLayers removes a duplicate |
|
| 29 |
-// layer, and that it makes no changes to the manifest when called a second |
|
| 30 |
-// time, after the duplicate is removed. |
|
| 31 |
-func TestFixManifestLayers(t *testing.T) {
|
|
| 32 |
- duplicateLayerManifest := schema1.Manifest{
|
|
| 33 |
- FSLayers: []schema1.FSLayer{
|
|
| 34 |
- {BlobSum: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4")},
|
|
| 35 |
- {BlobSum: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4")},
|
|
| 36 |
- {BlobSum: digest.Digest("sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa")},
|
|
| 37 |
- }, |
|
| 38 |
- History: []schema1.History{
|
|
| 39 |
- {V1Compatibility: "{\"id\":\"3b38edc92eb7c074812e217b41a6ade66888531009d6286a6f5f36a06f9841b9\",\"parent\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:11.368300679Z\",\"container\":\"d91be3479d5b1e84b0c00d18eea9dc777ca0ad166d51174b24283e2e6f104253\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) ENTRYPOINT [\\\"/go/bin/dnsdock\\\"]\"],\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":null,\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"},
|
|
| 40 |
- {V1Compatibility: "{\"id\":\"3b38edc92eb7c074812e217b41a6ade66888531009d6286a6f5f36a06f9841b9\",\"parent\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:11.368300679Z\",\"container\":\"d91be3479d5b1e84b0c00d18eea9dc777ca0ad166d51174b24283e2e6f104253\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) ENTRYPOINT [\\\"/go/bin/dnsdock\\\"]\"],\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":null,\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"},
|
|
| 41 |
- {V1Compatibility: "{\"id\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:07.568027497Z\",\"container\":\"fe9e5a5264a843c9292d17b736c92dd19bdb49986a8782d7389964ddaff887cc\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"cd /go/src/github.com/tonistiigi/dnsdock \\u0026\\u0026 go get -v github.com/tools/godep \\u0026\\u0026 godep restore \\u0026\\u0026 go install -ldflags \\\"-X main.version `git describe --tags HEAD``if [[ -n $(command git status --porcelain --untracked-files=no 2\\u003e/dev/null) ]]; then echo \\\"-dirty\\\"; fi`\\\" ./...\"],\"Image\":\"e3b0ff09e647595dafee15c54cd632c900df9e82b1d4d313b1e20639a1461779\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/bash\"],\"Image\":\"e3b0ff09e647595dafee15c54cd632c900df9e82b1d4d313b1e20639a1461779\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":118430532}\n"},
|
|
| 42 |
- }, |
|
| 43 |
- } |
|
| 44 |
- |
|
| 45 |
- duplicateLayerManifestExpectedOutput := schema1.Manifest{
|
|
| 46 |
- FSLayers: []schema1.FSLayer{
|
|
| 47 |
- {BlobSum: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4")},
|
|
| 48 |
- {BlobSum: digest.Digest("sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa")},
|
|
| 49 |
- }, |
|
| 50 |
- History: []schema1.History{
|
|
| 51 |
- {V1Compatibility: "{\"id\":\"3b38edc92eb7c074812e217b41a6ade66888531009d6286a6f5f36a06f9841b9\",\"parent\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:11.368300679Z\",\"container\":\"d91be3479d5b1e84b0c00d18eea9dc777ca0ad166d51174b24283e2e6f104253\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) ENTRYPOINT [\\\"/go/bin/dnsdock\\\"]\"],\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":null,\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"},
|
|
| 52 |
- {V1Compatibility: "{\"id\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:07.568027497Z\",\"container\":\"fe9e5a5264a843c9292d17b736c92dd19bdb49986a8782d7389964ddaff887cc\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"cd /go/src/github.com/tonistiigi/dnsdock \\u0026\\u0026 go get -v github.com/tools/godep \\u0026\\u0026 godep restore \\u0026\\u0026 go install -ldflags \\\"-X main.version `git describe --tags HEAD``if [[ -n $(command git status --porcelain --untracked-files=no 2\\u003e/dev/null) ]]; then echo \\\"-dirty\\\"; fi`\\\" ./...\"],\"Image\":\"e3b0ff09e647595dafee15c54cd632c900df9e82b1d4d313b1e20639a1461779\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/bash\"],\"Image\":\"e3b0ff09e647595dafee15c54cd632c900df9e82b1d4d313b1e20639a1461779\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":118430532}\n"},
|
|
| 53 |
- }, |
|
| 54 |
- } |
|
| 55 |
- |
|
| 56 |
- if err := fixManifestLayers(&duplicateLayerManifest); err != nil {
|
|
| 57 |
- t.Fatalf("unexpected error from fixManifestLayers: %v", err)
|
|
| 58 |
- } |
|
| 59 |
- |
|
| 60 |
- if !reflect.DeepEqual(duplicateLayerManifest, duplicateLayerManifestExpectedOutput) {
|
|
| 61 |
- t.Fatal("incorrect output from fixManifestLayers on duplicate layer manifest")
|
|
| 62 |
- } |
|
| 63 |
- |
|
| 64 |
- // Run fixManifestLayers again and confirm that it doesn't change the |
|
| 65 |
- // manifest (which no longer has duplicate layers). |
|
| 66 |
- if err := fixManifestLayers(&duplicateLayerManifest); err != nil {
|
|
| 67 |
- t.Fatalf("unexpected error from fixManifestLayers: %v", err)
|
|
| 68 |
- } |
|
| 69 |
- |
|
| 70 |
- if !reflect.DeepEqual(duplicateLayerManifest, duplicateLayerManifestExpectedOutput) {
|
|
| 71 |
- t.Fatal("incorrect output from fixManifestLayers on duplicate layer manifest (second pass)")
|
|
| 72 |
- } |
|
| 73 |
-} |
|
| 74 |
- |
|
| 75 |
-// TestFixManifestLayersBaseLayerParent makes sure that fixManifestLayers fails |
|
| 76 |
-// if the base layer configuration specifies a parent. |
|
| 77 |
-func TestFixManifestLayersBaseLayerParent(t *testing.T) {
|
|
| 78 |
- // TODO Windows: Fix this unit text |
|
| 79 |
- if runtime.GOOS == "windows" {
|
|
| 80 |
- t.Skip("Needs fixing on Windows")
|
|
| 81 |
- } |
|
| 82 |
- duplicateLayerManifest := schema1.Manifest{
|
|
| 83 |
- FSLayers: []schema1.FSLayer{
|
|
| 84 |
- {BlobSum: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4")},
|
|
| 85 |
- {BlobSum: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4")},
|
|
| 86 |
- {BlobSum: digest.Digest("sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa")},
|
|
| 87 |
- }, |
|
| 88 |
- History: []schema1.History{
|
|
| 89 |
- {V1Compatibility: "{\"id\":\"3b38edc92eb7c074812e217b41a6ade66888531009d6286a6f5f36a06f9841b9\",\"parent\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:11.368300679Z\",\"container\":\"d91be3479d5b1e84b0c00d18eea9dc777ca0ad166d51174b24283e2e6f104253\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) ENTRYPOINT [\\\"/go/bin/dnsdock\\\"]\"],\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":null,\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"},
|
|
| 90 |
- {V1Compatibility: "{\"id\":\"3b38edc92eb7c074812e217b41a6ade66888531009d6286a6f5f36a06f9841b9\",\"parent\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:11.368300679Z\",\"container\":\"d91be3479d5b1e84b0c00d18eea9dc777ca0ad166d51174b24283e2e6f104253\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) ENTRYPOINT [\\\"/go/bin/dnsdock\\\"]\"],\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":null,\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"},
|
|
| 91 |
- {V1Compatibility: "{\"id\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"parent\":\"e3b0ff09e647595dafee15c54cd632c900df9e82b1d4d313b1e20639a1461779\",\"created\":\"2015-08-19T16:49:07.568027497Z\",\"container\":\"fe9e5a5264a843c9292d17b736c92dd19bdb49986a8782d7389964ddaff887cc\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"cd /go/src/github.com/tonistiigi/dnsdock \\u0026\\u0026 go get -v github.com/tools/godep \\u0026\\u0026 godep restore \\u0026\\u0026 go install -ldflags \\\"-X main.version `git describe --tags HEAD``if [[ -n $(command git status --porcelain --untracked-files=no 2\\u003e/dev/null) ]]; then echo \\\"-dirty\\\"; fi`\\\" ./...\"],\"Image\":\"e3b0ff09e647595dafee15c54cd632c900df9e82b1d4d313b1e20639a1461779\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/bash\"],\"Image\":\"e3b0ff09e647595dafee15c54cd632c900df9e82b1d4d313b1e20639a1461779\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":118430532}\n"},
|
|
| 92 |
- }, |
|
| 93 |
- } |
|
| 94 |
- |
|
| 95 |
- if err := fixManifestLayers(&duplicateLayerManifest); err == nil || !strings.Contains(err.Error(), "invalid parent ID in the base layer of the image") {
|
|
| 96 |
- t.Fatalf("expected an invalid parent ID error from fixManifestLayers")
|
|
| 97 |
- } |
|
| 98 |
-} |
|
| 99 |
- |
|
| 100 |
-// TestFixManifestLayersBadParent makes sure that fixManifestLayers fails |
|
| 101 |
-// if an image configuration specifies a parent that doesn't directly follow |
|
| 102 |
-// that (deduplicated) image in the image history. |
|
| 103 |
-func TestFixManifestLayersBadParent(t *testing.T) {
|
|
| 104 |
- duplicateLayerManifest := schema1.Manifest{
|
|
| 105 |
- FSLayers: []schema1.FSLayer{
|
|
| 106 |
- {BlobSum: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4")},
|
|
| 107 |
- {BlobSum: digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4")},
|
|
| 108 |
- {BlobSum: digest.Digest("sha256:86e0e091d0da6bde2456dbb48306f3956bbeb2eae1b5b9a43045843f69fe4aaa")},
|
|
| 109 |
- }, |
|
| 110 |
- History: []schema1.History{
|
|
| 111 |
- {V1Compatibility: "{\"id\":\"3b38edc92eb7c074812e217b41a6ade66888531009d6286a6f5f36a06f9841b9\",\"parent\":\"ac3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:11.368300679Z\",\"container\":\"d91be3479d5b1e84b0c00d18eea9dc777ca0ad166d51174b24283e2e6f104253\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) ENTRYPOINT [\\\"/go/bin/dnsdock\\\"]\"],\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":null,\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"},
|
|
| 112 |
- {V1Compatibility: "{\"id\":\"3b38edc92eb7c074812e217b41a6ade66888531009d6286a6f5f36a06f9841b9\",\"parent\":\"ac3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:11.368300679Z\",\"container\":\"d91be3479d5b1e84b0c00d18eea9dc777ca0ad166d51174b24283e2e6f104253\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) ENTRYPOINT [\\\"/go/bin/dnsdock\\\"]\"],\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":null,\"Image\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":[\"/go/bin/dnsdock\"],\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"},
|
|
| 113 |
- {V1Compatibility: "{\"id\":\"ec3025ca8cc9bcab039e193e20ec647c2da3c53a74020f2ba611601f9b2c6c02\",\"created\":\"2015-08-19T16:49:07.568027497Z\",\"container\":\"fe9e5a5264a843c9292d17b736c92dd19bdb49986a8782d7389964ddaff887cc\",\"container_config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"cd /go/src/github.com/tonistiigi/dnsdock \\u0026\\u0026 go get -v github.com/tools/godep \\u0026\\u0026 godep restore \\u0026\\u0026 go install -ldflags \\\"-X main.version `git describe --tags HEAD``if [[ -n $(command git status --porcelain --untracked-files=no 2\\u003e/dev/null) ]]; then echo \\\"-dirty\\\"; fi`\\\" ./...\"],\"Image\":\"e3b0ff09e647595dafee15c54cd632c900df9e82b1d4d313b1e20639a1461779\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"docker_version\":\"1.6.2\",\"config\":{\"Hostname\":\"03797203757d\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/go/bin:/usr/src/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"GOLANG_VERSION=1.4.1\",\"GOPATH=/go\"],\"Cmd\":[\"/bin/bash\"],\"Image\":\"e3b0ff09e647595dafee15c54cd632c900df9e82b1d4d313b1e20639a1461779\",\"Volumes\":null,\"WorkingDir\":\"/go\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"Labels\":{}},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":118430532}\n"},
|
|
| 114 |
- }, |
|
| 115 |
- } |
|
| 116 |
- |
|
| 117 |
- err := fixManifestLayers(&duplicateLayerManifest) |
|
| 118 |
- assert.Check(t, is.ErrorContains(err, "invalid parent ID")) |
|
| 119 |
-} |
|
| 120 |
- |
|
| 121 |
-// TestValidateManifest verifies the validateManifest function |
|
| 122 |
-func TestValidateManifest(t *testing.T) {
|
|
| 123 |
- // TODO Windows: Fix this unit text |
|
| 124 |
- if runtime.GOOS == "windows" {
|
|
| 125 |
- t.Skip("Needs fixing on Windows")
|
|
| 126 |
- } |
|
| 127 |
- ctx := context.TODO() |
|
| 128 |
- ctx = logtest.WithT(ctx, t) |
|
| 129 |
- |
|
| 130 |
- expectedDigest, err := reference.ParseNormalizedNamed("repo@sha256:02fee8c3220ba806531f606525eceb83f4feb654f62b207191b1c9209188dedd")
|
|
| 131 |
- if err != nil {
|
|
| 132 |
- t.Fatal("could not parse reference")
|
|
| 133 |
- } |
|
| 134 |
- expectedFSLayer0 := digest.Digest("sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4")
|
|
| 135 |
- |
|
| 136 |
- // Good manifest |
|
| 137 |
- |
|
| 138 |
- goodManifestBytes, err := os.ReadFile("fixtures/validate_manifest/good_manifest")
|
|
| 139 |
- if err != nil {
|
|
| 140 |
- t.Fatal("error reading fixture:", err)
|
|
| 141 |
- } |
|
| 142 |
- |
|
| 143 |
- var goodSignedManifest schema1.SignedManifest |
|
| 144 |
- err = json.Unmarshal(goodManifestBytes, &goodSignedManifest) |
|
| 145 |
- if err != nil {
|
|
| 146 |
- t.Fatal("error unmarshaling manifest:", err)
|
|
| 147 |
- } |
|
| 148 |
- |
|
| 149 |
- verifiedManifest, err := verifySchema1Manifest(ctx, &goodSignedManifest, expectedDigest) |
|
| 150 |
- if err != nil {
|
|
| 151 |
- t.Fatal("validateManifest failed:", err)
|
|
| 152 |
- } |
|
| 153 |
- |
|
| 154 |
- if verifiedManifest.FSLayers[0].BlobSum != expectedFSLayer0 {
|
|
| 155 |
- t.Fatal("unexpected FSLayer in good manifest")
|
|
| 156 |
- } |
|
| 157 |
- |
|
| 158 |
- // "Extra data" manifest |
|
| 159 |
- |
|
| 160 |
- extraDataManifestBytes, err := os.ReadFile("fixtures/validate_manifest/extra_data_manifest")
|
|
| 161 |
- if err != nil {
|
|
| 162 |
- t.Fatal("error reading fixture:", err)
|
|
| 163 |
- } |
|
| 164 |
- |
|
| 165 |
- var extraDataSignedManifest schema1.SignedManifest |
|
| 166 |
- err = json.Unmarshal(extraDataManifestBytes, &extraDataSignedManifest) |
|
| 167 |
- if err != nil {
|
|
| 168 |
- t.Fatal("error unmarshaling manifest:", err)
|
|
| 169 |
- } |
|
| 170 |
- |
|
| 171 |
- verifiedManifest, err = verifySchema1Manifest(ctx, &extraDataSignedManifest, expectedDigest) |
|
| 172 |
- if err != nil {
|
|
| 173 |
- t.Fatal("validateManifest failed:", err)
|
|
| 174 |
- } |
|
| 175 |
- |
|
| 176 |
- if verifiedManifest.FSLayers[0].BlobSum != expectedFSLayer0 {
|
|
| 177 |
- t.Fatal("unexpected FSLayer in extra data manifest")
|
|
| 178 |
- } |
|
| 179 |
- |
|
| 180 |
- // Bad manifest |
|
| 181 |
- |
|
| 182 |
- badManifestBytes, err := os.ReadFile("fixtures/validate_manifest/bad_manifest")
|
|
| 183 |
- if err != nil {
|
|
| 184 |
- t.Fatal("error reading fixture:", err)
|
|
| 185 |
- } |
|
| 186 |
- |
|
| 187 |
- var badSignedManifest schema1.SignedManifest |
|
| 188 |
- err = json.Unmarshal(badManifestBytes, &badSignedManifest) |
|
| 189 |
- if err != nil {
|
|
| 190 |
- t.Fatal("error unmarshaling manifest:", err)
|
|
| 191 |
- } |
|
| 192 |
- |
|
| 193 |
- _, err = verifySchema1Manifest(ctx, &badSignedManifest, expectedDigest) |
|
| 194 |
- if err == nil || !strings.HasPrefix(err.Error(), "image verification failed for digest") {
|
|
| 195 |
- t.Fatal("expected validateManifest to fail with digest error")
|
|
| 196 |
- } |
|
| 197 |
-} |
|
| 198 |
- |
|
| 199 | 28 |
func TestNoMatchesErr(t *testing.T) {
|
| 200 | 29 |
err := noMatchesErr{}
|
| 201 | 30 |
assert.Check(t, is.ErrorContains(err, "no matching manifest for "+runtime.GOOS)) |
| ... | ... |
@@ -40,15 +40,9 @@ fi |
| 40 | 40 |
# intentionally open a couple bogus file descriptors to help test that they get scrubbed in containers |
| 41 | 41 |
exec 41>&1 42>&2 |
| 42 | 42 |
|
| 43 |
-# Allow pushing manifest v2 schema 1 images, as they're used to push |
|
| 44 |
-# images to our test-registries for testing _pulling_ schema 2v1 images. |
|
| 45 |
-export DOCKER_ALLOW_SCHEMA1_PUSH_DONOTUSE=1 |
|
| 46 | 43 |
export DOCKER_GRAPHDRIVER=${DOCKER_GRAPHDRIVER:-vfs}
|
| 47 | 44 |
export DOCKER_USERLANDPROXY=${DOCKER_USERLANDPROXY:-true}
|
| 48 | 45 |
|
| 49 |
-# Allow testing push/pull of legacy image formats |
|
| 50 |
-export DOCKER_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE=1 |
|
| 51 |
- |
|
| 52 | 46 |
# example usage: DOCKER_STORAGE_OPTS="dm.basesize=20G,dm.loopdatasize=200G" |
| 53 | 47 |
storage_params="" |
| 54 | 48 |
if [ -n "$DOCKER_STORAGE_OPTS" ]; then |
| ... | ... |
@@ -28,7 +28,6 @@ import ( |
| 28 | 28 |
"go.opentelemetry.io/otel/attribute" |
| 29 | 29 |
"go.opentelemetry.io/otel/codes" |
| 30 | 30 |
"gotest.tools/v3/assert" |
| 31 |
- "gotest.tools/v3/skip" |
|
| 32 | 31 |
) |
| 33 | 32 |
|
| 34 | 33 |
const ( |
| ... | ... |
@@ -364,13 +363,6 @@ func TestDockerRegistrySuite(t *testing.T) {
|
| 364 | 364 |
suite.Run(ctx, t, &DockerRegistrySuite{ds: &DockerSuite{}})
|
| 365 | 365 |
} |
| 366 | 366 |
|
| 367 |
-func TestDockerSchema1RegistrySuite(t *testing.T) {
|
|
| 368 |
- skip.If(t, testEnv.UsingSnapshotter()) |
|
| 369 |
- ctx := testutil.StartSpan(baseContext, t) |
|
| 370 |
- ensureTestEnvSetup(ctx, t) |
|
| 371 |
- suite.Run(ctx, t, &DockerSchema1RegistrySuite{ds: &DockerSuite{}})
|
|
| 372 |
-} |
|
| 373 |
- |
|
| 374 | 367 |
func TestDockerRegistryAuthHtpasswdSuite(t *testing.T) {
|
| 375 | 368 |
ctx := testutil.StartSpan(baseContext, t) |
| 376 | 369 |
ensureTestEnvSetup(ctx, t) |
| ... | ... |
@@ -478,33 +470,6 @@ func (s *DockerRegistrySuite) TearDownTest(ctx context.Context, c *testing.T) {
|
| 478 | 478 |
s.ds.TearDownTest(ctx, c) |
| 479 | 479 |
} |
| 480 | 480 |
|
| 481 |
-type DockerSchema1RegistrySuite struct {
|
|
| 482 |
- ds *DockerSuite |
|
| 483 |
- reg *registry.V2 |
|
| 484 |
- d *daemon.Daemon |
|
| 485 |
-} |
|
| 486 |
- |
|
| 487 |
-func (s *DockerSchema1RegistrySuite) OnTimeout(c *testing.T) {
|
|
| 488 |
- s.d.DumpStackAndQuit() |
|
| 489 |
-} |
|
| 490 |
- |
|
| 491 |
-func (s *DockerSchema1RegistrySuite) SetUpTest(ctx context.Context, c *testing.T) {
|
|
| 492 |
- testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64, testEnv.IsLocalDaemon) |
|
| 493 |
- s.reg = registry.NewV2(c, registry.Schema1) |
|
| 494 |
- s.reg.WaitReady(c) |
|
| 495 |
- s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) |
|
| 496 |
-} |
|
| 497 |
- |
|
| 498 |
-func (s *DockerSchema1RegistrySuite) TearDownTest(ctx context.Context, c *testing.T) {
|
|
| 499 |
- if s.reg != nil {
|
|
| 500 |
- s.reg.Close() |
|
| 501 |
- } |
|
| 502 |
- if s.d != nil {
|
|
| 503 |
- s.d.Stop(c) |
|
| 504 |
- } |
|
| 505 |
- s.ds.TearDownTest(ctx, c) |
|
| 506 |
-} |
|
| 507 |
- |
|
| 508 | 481 |
type DockerRegistryAuthHtpasswdSuite struct {
|
| 509 | 482 |
ds *DockerSuite |
| 510 | 483 |
reg *registry.V2 |
| ... | ... |
@@ -9,7 +9,6 @@ import ( |
| 9 | 9 |
"strings" |
| 10 | 10 |
"testing" |
| 11 | 11 |
|
| 12 |
- "github.com/docker/distribution/manifest/schema1" |
|
| 13 | 12 |
"github.com/docker/distribution/manifest/schema2" |
| 14 | 13 |
"github.com/docker/docker/api/types/image" |
| 15 | 14 |
"github.com/docker/docker/integration-cli/cli" |
| ... | ... |
@@ -63,7 +62,7 @@ func setupImageWithTag(c *testing.T, tag string) (digest.Digest, error) {
|
| 63 | 63 |
return digest.Digest(pushDigest), nil |
| 64 | 64 |
} |
| 65 | 65 |
|
| 66 |
-func testPullByTagDisplaysDigest(c *testing.T) {
|
|
| 66 |
+func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *testing.T) {
|
|
| 67 | 67 |
testRequires(c, DaemonIsLinux) |
| 68 | 68 |
pushDigest, err := setupImage(c) |
| 69 | 69 |
assert.NilError(c, err, "error setting up image") |
| ... | ... |
@@ -80,15 +79,7 @@ func testPullByTagDisplaysDigest(c *testing.T) {
|
| 80 | 80 |
assert.Equal(c, pushDigest.String(), pullDigest) |
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 |
-func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *testing.T) {
|
|
| 84 |
- testPullByTagDisplaysDigest(c) |
|
| 85 |
-} |
|
| 86 |
- |
|
| 87 |
-func (s *DockerSchema1RegistrySuite) TestPullByTagDisplaysDigest(c *testing.T) {
|
|
| 88 |
- testPullByTagDisplaysDigest(c) |
|
| 89 |
-} |
|
| 90 |
- |
|
| 91 |
-func testPullByDigest(c *testing.T) {
|
|
| 83 |
+func (s *DockerRegistrySuite) TestPullByDigest(c *testing.T) {
|
|
| 92 | 84 |
testRequires(c, DaemonIsLinux) |
| 93 | 85 |
pushDigest, err := setupImage(c) |
| 94 | 86 |
assert.NilError(c, err, "error setting up image") |
| ... | ... |
@@ -106,15 +97,7 @@ func testPullByDigest(c *testing.T) {
|
| 106 | 106 |
assert.Equal(c, pushDigest.String(), pullDigest) |
| 107 | 107 |
} |
| 108 | 108 |
|
| 109 |
-func (s *DockerRegistrySuite) TestPullByDigest(c *testing.T) {
|
|
| 110 |
- testPullByDigest(c) |
|
| 111 |
-} |
|
| 112 |
- |
|
| 113 |
-func (s *DockerSchema1RegistrySuite) TestPullByDigest(c *testing.T) {
|
|
| 114 |
- testPullByDigest(c) |
|
| 115 |
-} |
|
| 116 |
- |
|
| 117 |
-func testPullByDigestNoFallback(c *testing.T) {
|
|
| 109 |
+func (s *DockerRegistrySuite) TestPullByDigestNoFallback(c *testing.T) {
|
|
| 118 | 110 |
testRequires(c, DaemonIsLinux) |
| 119 | 111 |
// pull from the registry using the <name>@<digest> reference |
| 120 | 112 |
imageReference := fmt.Sprintf("%s@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", repoName)
|
| ... | ... |
@@ -129,14 +112,6 @@ func testPullByDigestNoFallback(c *testing.T) {
|
| 129 | 129 |
assert.Check(c, is.Contains(out, expectedMsg), "expected non-zero exit status and correct error message when pulling non-existing image") |
| 130 | 130 |
} |
| 131 | 131 |
|
| 132 |
-func (s *DockerRegistrySuite) TestPullByDigestNoFallback(c *testing.T) {
|
|
| 133 |
- testPullByDigestNoFallback(c) |
|
| 134 |
-} |
|
| 135 |
- |
|
| 136 |
-func (s *DockerSchema1RegistrySuite) TestPullByDigestNoFallback(c *testing.T) {
|
|
| 137 |
- testPullByDigestNoFallback(c) |
|
| 138 |
-} |
|
| 139 |
- |
|
| 140 | 132 |
func (s *DockerRegistrySuite) TestCreateByDigest(c *testing.T) {
|
| 141 | 133 |
pushDigest, err := setupImage(c) |
| 142 | 134 |
assert.NilError(c, err, "error setting up image") |
| ... | ... |
@@ -581,48 +556,6 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *testing.T) {
|
| 581 | 581 |
} |
| 582 | 582 |
} |
| 583 | 583 |
|
| 584 |
-// TestPullFailsWithAlteredManifest tests that a `docker pull` fails when |
|
| 585 |
-// we have modified a manifest blob and its digest cannot be verified. |
|
| 586 |
-// This is the schema1 version of the test. |
|
| 587 |
-func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *testing.T) {
|
|
| 588 |
- testRequires(c, DaemonIsLinux) |
|
| 589 |
- manifestDigest, err := setupImage(c) |
|
| 590 |
- assert.Assert(c, err == nil, "error setting up image") |
|
| 591 |
- |
|
| 592 |
- // Load the target manifest blob. |
|
| 593 |
- manifestBlob := s.reg.ReadBlobContents(c, manifestDigest) |
|
| 594 |
- |
|
| 595 |
- var imgManifest schema1.Manifest |
|
| 596 |
- err = json.Unmarshal(manifestBlob, &imgManifest) |
|
| 597 |
- assert.Assert(c, err == nil, "unable to decode image manifest from blob") |
|
| 598 |
- |
|
| 599 |
- // Change a layer in the manifest. |
|
| 600 |
- imgManifest.FSLayers[0] = schema1.FSLayer{
|
|
| 601 |
- BlobSum: digest.Digest("sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"),
|
|
| 602 |
- } |
|
| 603 |
- |
|
| 604 |
- // Move the existing data file aside, so that we can replace it with a |
|
| 605 |
- // malicious blob of data. NOTE: we defer the returned undo func. |
|
| 606 |
- undo := s.reg.TempMoveBlobData(c, manifestDigest) |
|
| 607 |
- defer undo() |
|
| 608 |
- |
|
| 609 |
- alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", " ") |
|
| 610 |
- assert.Assert(c, err == nil, "unable to encode altered image manifest to JSON") |
|
| 611 |
- |
|
| 612 |
- s.reg.WriteBlobContents(c, manifestDigest, alteredManifestBlob) |
|
| 613 |
- |
|
| 614 |
- // Now try pulling that image by digest. We should get an error about |
|
| 615 |
- // digest verification for the manifest digest. |
|
| 616 |
- |
|
| 617 |
- // Pull from the registry using the <name>@<digest> reference. |
|
| 618 |
- imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
|
|
| 619 |
- out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
|
|
| 620 |
- assert.Assert(c, exitStatus != 0) |
|
| 621 |
- |
|
| 622 |
- expectedErrorMsg := fmt.Sprintf("image verification failed for digest %s", manifestDigest)
|
|
| 623 |
- assert.Assert(c, is.Contains(out, expectedErrorMsg)) |
|
| 624 |
-} |
|
| 625 |
- |
|
| 626 | 584 |
// TestPullFailsWithAlteredLayer tests that a `docker pull` fails when |
| 627 | 585 |
// we have modified a layer blob and its digest cannot be verified. |
| 628 | 586 |
// This is the schema2 version of the test. |
| ... | ... |
@@ -667,46 +600,3 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *testing.T) {
|
| 667 | 667 |
expectedErrorMsg := fmt.Sprintf("filesystem layer verification failed for digest %s", targetLayerDigest)
|
| 668 | 668 |
assert.Assert(c, strings.Contains(out, expectedErrorMsg), "expected error message in output: %s", out) |
| 669 | 669 |
} |
| 670 |
- |
|
| 671 |
-// TestPullFailsWithAlteredLayer tests that a `docker pull` fails when |
|
| 672 |
-// we have modified a layer blob and its digest cannot be verified. |
|
| 673 |
-// This is the schema1 version of the test. |
|
| 674 |
-func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredLayer(c *testing.T) {
|
|
| 675 |
- testRequires(c, DaemonIsLinux) |
|
| 676 |
- manifestDigest, err := setupImage(c) |
|
| 677 |
- assert.NilError(c, err) |
|
| 678 |
- |
|
| 679 |
- // Load the target manifest blob. |
|
| 680 |
- manifestBlob := s.reg.ReadBlobContents(c, manifestDigest) |
|
| 681 |
- |
|
| 682 |
- var imgManifest schema1.Manifest |
|
| 683 |
- err = json.Unmarshal(manifestBlob, &imgManifest) |
|
| 684 |
- assert.NilError(c, err) |
|
| 685 |
- |
|
| 686 |
- // Next, get the digest of one of the layers from the manifest. |
|
| 687 |
- targetLayerDigest := imgManifest.FSLayers[0].BlobSum |
|
| 688 |
- |
|
| 689 |
- // Move the existing data file aside, so that we can replace it with a |
|
| 690 |
- // malicious blob of data. NOTE: we defer the returned undo func. |
|
| 691 |
- undo := s.reg.TempMoveBlobData(c, targetLayerDigest) |
|
| 692 |
- defer undo() |
|
| 693 |
- |
|
| 694 |
- // Now make a fake data blob in this directory. |
|
| 695 |
- s.reg.WriteBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
|
|
| 696 |
- |
|
| 697 |
- // Now try pulling that image by digest. We should get an error about |
|
| 698 |
- // digest verification for the target layer digest. |
|
| 699 |
- |
|
| 700 |
- // Remove distribution cache to force a re-pull of the blobs |
|
| 701 |
- if err := os.RemoveAll(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "image", s.d.StorageDriver(), "distribution")); err != nil {
|
|
| 702 |
- c.Fatalf("error clearing distribution cache: %v", err)
|
|
| 703 |
- } |
|
| 704 |
- |
|
| 705 |
- // Pull from the registry using the <name>@<digest> reference. |
|
| 706 |
- imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
|
|
| 707 |
- out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
|
|
| 708 |
- assert.Assert(c, exitStatus != 0, "expected a non-zero exit status") |
|
| 709 |
- |
|
| 710 |
- expectedErrorMsg := fmt.Sprintf("filesystem layer verification failed for digest %s", targetLayerDigest)
|
|
| 711 |
- assert.Assert(c, strings.Contains(out, expectedErrorMsg), "expected error message in output: %s", out) |
|
| 712 |
-} |
| ... | ... |
@@ -26,7 +26,7 @@ import ( |
| 26 | 26 |
// tags for the same image) are not also pulled down. |
| 27 | 27 |
// |
| 28 | 28 |
// Ref: docker/docker#8141 |
| 29 |
-func testPullImageWithAliases(c *testing.T) {
|
|
| 29 |
+func (s *DockerRegistrySuite) TestPullImageWithAliases(c *testing.T) {
|
|
| 30 | 30 |
const imgRepo = privateRegistryURL + "/dockercli/busybox" |
| 31 | 31 |
|
| 32 | 32 |
var repos []string |
| ... | ... |
@@ -53,16 +53,8 @@ func testPullImageWithAliases(c *testing.T) {
|
| 53 | 53 |
} |
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 |
-func (s *DockerRegistrySuite) TestPullImageWithAliases(c *testing.T) {
|
|
| 57 |
- testPullImageWithAliases(c) |
|
| 58 |
-} |
|
| 59 |
- |
|
| 60 |
-func (s *DockerSchema1RegistrySuite) TestPullImageWithAliases(c *testing.T) {
|
|
| 61 |
- testPullImageWithAliases(c) |
|
| 62 |
-} |
|
| 63 |
- |
|
| 64 |
-// testConcurrentPullWholeRepo pulls the same repo concurrently. |
|
| 65 |
-func testConcurrentPullWholeRepo(c *testing.T) {
|
|
| 56 |
+// TestConcurrentPullWholeRepo pulls the same repo concurrently. |
|
| 57 |
+func (s *DockerRegistrySuite) TestConcurrentPullWholeRepo(c *testing.T) {
|
|
| 66 | 58 |
const imgRepo = privateRegistryURL + "/dockercli/busybox" |
| 67 | 59 |
|
| 68 | 60 |
var repos []string |
| ... | ... |
@@ -109,16 +101,8 @@ func testConcurrentPullWholeRepo(c *testing.T) {
|
| 109 | 109 |
} |
| 110 | 110 |
} |
| 111 | 111 |
|
| 112 |
-func (s *DockerRegistrySuite) TestConcurrentPullWholeRepo(c *testing.T) {
|
|
| 113 |
- testConcurrentPullWholeRepo(c) |
|
| 114 |
-} |
|
| 115 |
- |
|
| 116 |
-func (s *DockerSchema1RegistrySuite) TestConcurrentPullWholeRepo(c *testing.T) {
|
|
| 117 |
- testConcurrentPullWholeRepo(c) |
|
| 118 |
-} |
|
| 119 |
- |
|
| 120 |
-// testConcurrentFailingPull tries a concurrent pull that doesn't succeed. |
|
| 121 |
-func testConcurrentFailingPull(c *testing.T) {
|
|
| 112 |
+// TestConcurrentFailingPull tries a concurrent pull that doesn't succeed. |
|
| 113 |
+func (s *DockerRegistrySuite) TestConcurrentFailingPull(c *testing.T) {
|
|
| 122 | 114 |
const imgRepo = privateRegistryURL + "/dockercli/busybox" |
| 123 | 115 |
|
| 124 | 116 |
// Run multiple pulls concurrently |
| ... | ... |
@@ -140,17 +124,9 @@ func testConcurrentFailingPull(c *testing.T) {
|
| 140 | 140 |
} |
| 141 | 141 |
} |
| 142 | 142 |
|
| 143 |
-func (s *DockerRegistrySuite) TestConcurrentFailingPull(c *testing.T) {
|
|
| 144 |
- testConcurrentFailingPull(c) |
|
| 145 |
-} |
|
| 146 |
- |
|
| 147 |
-func (s *DockerSchema1RegistrySuite) TestConcurrentFailingPull(c *testing.T) {
|
|
| 148 |
- testConcurrentFailingPull(c) |
|
| 149 |
-} |
|
| 150 |
- |
|
| 151 |
-// testConcurrentPullMultipleTags pulls multiple tags from the same repo |
|
| 143 |
+// TestConcurrentPullMultipleTags pulls multiple tags from the same repo |
|
| 152 | 144 |
// concurrently. |
| 153 |
-func testConcurrentPullMultipleTags(c *testing.T) {
|
|
| 145 |
+func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *testing.T) {
|
|
| 154 | 146 |
const imgRepo = privateRegistryURL + "/dockercli/busybox" |
| 155 | 147 |
|
| 156 | 148 |
var repos []string |
| ... | ... |
@@ -196,17 +172,9 @@ func testConcurrentPullMultipleTags(c *testing.T) {
|
| 196 | 196 |
} |
| 197 | 197 |
} |
| 198 | 198 |
|
| 199 |
-func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *testing.T) {
|
|
| 200 |
- testConcurrentPullMultipleTags(c) |
|
| 201 |
-} |
|
| 202 |
- |
|
| 203 |
-func (s *DockerSchema1RegistrySuite) TestConcurrentPullMultipleTags(c *testing.T) {
|
|
| 204 |
- testConcurrentPullMultipleTags(c) |
|
| 205 |
-} |
|
| 206 |
- |
|
| 207 |
-// testPullIDStability verifies that pushing an image and pulling it back |
|
| 199 |
+// TestPullIDStability verifies that pushing an image and pulling it back |
|
| 208 | 200 |
// preserves the image ID. |
| 209 |
-func testPullIDStability(c *testing.T) {
|
|
| 201 |
+func (s *DockerRegistrySuite) TestPullIDStability(c *testing.T) {
|
|
| 210 | 202 |
const derivedImage = privateRegistryURL + "/dockercli/id-stability" |
| 211 | 203 |
const baseImage = "busybox" |
| 212 | 204 |
|
| ... | ... |
@@ -256,16 +224,8 @@ func testPullIDStability(c *testing.T) {
|
| 256 | 256 |
} |
| 257 | 257 |
} |
| 258 | 258 |
|
| 259 |
-func (s *DockerRegistrySuite) TestPullIDStability(c *testing.T) {
|
|
| 260 |
- testPullIDStability(c) |
|
| 261 |
-} |
|
| 262 |
- |
|
| 263 |
-func (s *DockerSchema1RegistrySuite) TestPullIDStability(c *testing.T) {
|
|
| 264 |
- testPullIDStability(c) |
|
| 265 |
-} |
|
| 266 |
- |
|
| 267 | 259 |
// #21213 |
| 268 |
-func testPullNoLayers(c *testing.T) {
|
|
| 260 |
+func (s *DockerRegistrySuite) TestPullNoLayers(c *testing.T) {
|
|
| 269 | 261 |
const imgRepo = privateRegistryURL + "/dockercli/scratch" |
| 270 | 262 |
|
| 271 | 263 |
buildImageSuccessfully(c, imgRepo, build.WithDockerfile(` |
| ... | ... |
@@ -276,14 +236,6 @@ func testPullNoLayers(c *testing.T) {
|
| 276 | 276 |
cli.DockerCmd(c, "pull", imgRepo) |
| 277 | 277 |
} |
| 278 | 278 |
|
| 279 |
-func (s *DockerRegistrySuite) TestPullNoLayers(c *testing.T) {
|
|
| 280 |
- testPullNoLayers(c) |
|
| 281 |
-} |
|
| 282 |
- |
|
| 283 |
-func (s *DockerSchema1RegistrySuite) TestPullNoLayers(c *testing.T) {
|
|
| 284 |
- testPullNoLayers(c) |
|
| 285 |
-} |
|
| 286 |
- |
|
| 287 | 279 |
func (s *DockerRegistrySuite) TestPullManifestList(c *testing.T) {
|
| 288 | 280 |
skip.If(c, testEnv.UsingSnapshotter(), "containerd knows how to pull manifest lists") |
| 289 | 281 |
pushDigest, err := setupImage(c) |
| ... | ... |
@@ -58,6 +58,18 @@ func TestConfigDaemonID(t *testing.T) {
|
| 58 | 58 |
info = d.Info(t) |
| 59 | 59 |
assert.Equal(t, info.ID, engineID) |
| 60 | 60 |
d.Stop(t) |
| 61 |
+ |
|
| 62 |
+ // Verify that engine-id file is created if it doesn't exist |
|
| 63 |
+ err = os.Remove(idFile) |
|
| 64 |
+ assert.NilError(t, err) |
|
| 65 |
+ |
|
| 66 |
+ d.Start(t, "--iptables=false") |
|
| 67 |
+ id, err := os.ReadFile(idFile) |
|
| 68 |
+ assert.NilError(t, err) |
|
| 69 |
+ |
|
| 70 |
+ info = d.Info(t) |
|
| 71 |
+ assert.Equal(t, string(id), info.ID) |
|
| 72 |
+ d.Stop(t) |
|
| 61 | 73 |
} |
| 62 | 74 |
|
| 63 | 75 |
func TestDaemonConfigValidation(t *testing.T) {
|
| ... | ... |
@@ -16,9 +16,7 @@ import ( |
| 16 | 16 |
|
| 17 | 17 |
const ( |
| 18 | 18 |
// V2binary is the name of the registry v2 binary |
| 19 |
- V2binary = "registry-v2" |
|
| 20 |
- // V2binarySchema1 is the name of the registry that serve schema1 |
|
| 21 |
- V2binarySchema1 = "registry-v2-schema1" |
|
| 19 |
+ V2binary = "registry" |
|
| 22 | 20 |
// DefaultURL is the default url that will be used by the registry (if not specified otherwise) |
| 23 | 21 |
DefaultURL = "127.0.0.1:5000" |
| 24 | 22 |
) |
| ... | ... |
@@ -36,7 +34,6 @@ type V2 struct {
|
| 36 | 36 |
|
| 37 | 37 |
// Config contains the test registry configuration |
| 38 | 38 |
type Config struct {
|
| 39 |
- schema1 bool |
|
| 40 | 39 |
auth string |
| 41 | 40 |
tokenURL string |
| 42 | 41 |
registryURL string |
| ... | ... |
@@ -106,13 +103,7 @@ http: |
| 106 | 106 |
t.Fatal(err) |
| 107 | 107 |
} |
| 108 | 108 |
|
| 109 |
- binary := V2binary |
|
| 110 |
- args := []string{"serve", confPath}
|
|
| 111 |
- if c.schema1 {
|
|
| 112 |
- binary = V2binarySchema1 |
|
| 113 |
- args = []string{confPath}
|
|
| 114 |
- } |
|
| 115 |
- cmd := exec.Command(binary, args...) |
|
| 109 |
+ cmd := exec.Command(V2binary, "serve", confPath) |
|
| 116 | 110 |
cmd.Stdout = c.stdout |
| 117 | 111 |
cmd.Stderr = c.stderr |
| 118 | 112 |
if err := cmd.Start(); err != nil {
|
| ... | ... |
@@ -44,7 +44,6 @@ require ( |
| 44 | 44 |
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c |
| 45 | 45 |
github.com/docker/go-metrics v0.0.1 |
| 46 | 46 |
github.com/docker/go-units v0.5.0 |
| 47 |
- github.com/docker/libtrust v0.0.0-20150526203908-9cbd2a1374f4 |
|
| 48 | 47 |
github.com/fluent/fluent-logger-golang v1.9.0 |
| 49 | 48 |
github.com/godbus/dbus/v5 v5.1.0 |
| 50 | 49 |
github.com/gogo/protobuf v1.3.2 |
| ... | ... |
@@ -160,6 +159,7 @@ require ( |
| 160 | 160 |
github.com/cyphar/filepath-securejoin v0.4.1 // indirect |
| 161 | 161 |
github.com/davecgh/go-spew v1.1.1 // indirect |
| 162 | 162 |
github.com/dimchansky/utfbom v1.1.1 // indirect |
| 163 |
+ github.com/docker/libtrust v0.0.0-20150526203908-9cbd2a1374f4 // indirect |
|
| 163 | 164 |
github.com/dustin/go-humanize v1.0.0 // indirect |
| 164 | 165 |
github.com/felixge/httpsnoop v1.0.4 // indirect |
| 165 | 166 |
github.com/fernet/fernet-go v0.0.0-20211208181803-9f70042a33ee // indirect |