Browse code

Revert "Remove Schema1 integration test suite"

This reverts commit 13b7d11be1a97ebe82b3a0f0b5db9b873a481637.

Signed-off-by: Tibor Vass <tibor@docker.com>

Tibor Vass authored on 2019/06/18 06:50:31
Showing 7 changed files
... ...
@@ -51,6 +51,11 @@ RUN apt-get update && apt-get install -y \
51 51
 	&& make PREFIX=/build/ install-criu
52 52
 
53 53
 FROM base AS registry
54
+# Install two versions of the registry. The first is an older version that
55
+# only supports schema1 manifests. The second is a newer version that supports
56
+# both. This allows integration-cli tests to cover push/pull with both schema1
57
+# and schema2 manifests.
58
+ENV REGISTRY_COMMIT_SCHEMA1 ec87e9b6971d831f0eff752ddb54fb64693e51cd
54 59
 ENV REGISTRY_COMMIT 47a064d4195a9b56133891bbb13620c3ac83a827
55 60
 RUN set -x \
56 61
 	&& export GOPATH="$(mktemp -d)" \
... ...
@@ -58,6 +63,13 @@ RUN set -x \
58 58
 	&& (cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT") \
59 59
 	&& GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" \
60 60
 		go build -buildmode=pie -o /build/registry-v2 github.com/docker/distribution/cmd/registry \
61
+	&& case $(dpkg --print-architecture) in \
62
+		amd64|ppc64*|s390x) \
63
+		(cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT_SCHEMA1"); \
64
+		GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH"; \
65
+			go build -buildmode=pie -o /build/registry-v2-schema1 github.com/docker/distribution/cmd/registry; \
66
+		;; \
67
+	   esac \
61 68
 	&& rm -rf "$GOPATH"
62 69
 
63 70
 
... ...
@@ -142,6 +142,39 @@ func (s *DockerRegistrySuite) TearDownTest(c *check.C) {
142 142
 }
143 143
 
144 144
 func init() {
145
+	check.Suite(&DockerSchema1RegistrySuite{
146
+		ds: &DockerSuite{},
147
+	})
148
+}
149
+
150
+type DockerSchema1RegistrySuite struct {
151
+	ds  *DockerSuite
152
+	reg *registry.V2
153
+	d   *daemon.Daemon
154
+}
155
+
156
+func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) {
157
+	s.d.DumpStackAndQuit()
158
+}
159
+
160
+func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
161
+	testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64, testEnv.IsLocalDaemon)
162
+	s.reg = registry.NewV2(c, registry.Schema1)
163
+	s.reg.WaitReady(c)
164
+	s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution))
165
+}
166
+
167
+func (s *DockerSchema1RegistrySuite) TearDownTest(c *check.C) {
168
+	if s.reg != nil {
169
+		s.reg.Close()
170
+	}
171
+	if s.d != nil {
172
+		s.d.Stop(c)
173
+	}
174
+	s.ds.TearDownTest(c)
175
+}
176
+
177
+func init() {
145 178
 	check.Suite(&DockerRegistryAuthHtpasswdSuite{
146 179
 		ds: &DockerSuite{},
147 180
 	})
... ...
@@ -3,9 +3,12 @@ package main
3 3
 import (
4 4
 	"encoding/json"
5 5
 	"fmt"
6
+	"os"
7
+	"path/filepath"
6 8
 	"regexp"
7 9
 	"strings"
8 10
 
11
+	"github.com/docker/distribution/manifest/schema1"
9 12
 	"github.com/docker/distribution/manifest/schema2"
10 13
 	"github.com/docker/docker/api/types"
11 14
 	"github.com/docker/docker/integration-cli/checker"
... ...
@@ -77,6 +80,10 @@ func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
77 77
 	testPullByTagDisplaysDigest(c)
78 78
 }
79 79
 
80
+func (s *DockerSchema1RegistrySuite) TestPullByTagDisplaysDigest(c *check.C) {
81
+	testPullByTagDisplaysDigest(c)
82
+}
83
+
80 84
 func testPullByDigest(c *check.C) {
81 85
 	testRequires(c, DaemonIsLinux)
82 86
 	pushDigest, err := setupImage(c)
... ...
@@ -99,6 +106,10 @@ func (s *DockerRegistrySuite) TestPullByDigest(c *check.C) {
99 99
 	testPullByDigest(c)
100 100
 }
101 101
 
102
+func (s *DockerSchema1RegistrySuite) TestPullByDigest(c *check.C) {
103
+	testPullByDigest(c)
104
+}
105
+
102 106
 func testPullByDigestNoFallback(c *check.C) {
103 107
 	testRequires(c, DaemonIsLinux)
104 108
 	// pull from the registry using the <name>@<digest> reference
... ...
@@ -112,6 +123,10 @@ func (s *DockerRegistrySuite) TestPullByDigestNoFallback(c *check.C) {
112 112
 	testPullByDigestNoFallback(c)
113 113
 }
114 114
 
115
+func (s *DockerSchema1RegistrySuite) TestPullByDigestNoFallback(c *check.C) {
116
+	testPullByDigestNoFallback(c)
117
+}
118
+
115 119
 func (s *DockerRegistrySuite) TestCreateByDigest(c *check.C) {
116 120
 	pushDigest, err := setupImage(c)
117 121
 	assert.NilError(c, err, "error setting up image")
... ...
@@ -546,3 +561,131 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
546 546
 	expectedErrorMsg := fmt.Sprintf("manifest verification failed for digest %s", manifestDigest)
547 547
 	assert.Assert(c, is.Contains(out, expectedErrorMsg))
548 548
 }
549
+
550
+// TestPullFailsWithAlteredManifest tests that a `docker pull` fails when
551
+// we have modified a manifest blob and its digest cannot be verified.
552
+// This is the schema1 version of the test.
553
+func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
554
+	testRequires(c, DaemonIsLinux)
555
+	manifestDigest, err := setupImage(c)
556
+	c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
557
+
558
+	// Load the target manifest blob.
559
+	manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
560
+
561
+	var imgManifest schema1.Manifest
562
+	err = json.Unmarshal(manifestBlob, &imgManifest)
563
+	c.Assert(err, checker.IsNil, check.Commentf("unable to decode image manifest from blob"))
564
+
565
+	// Change a layer in the manifest.
566
+	imgManifest.FSLayers[0] = schema1.FSLayer{
567
+		BlobSum: digest.Digest("sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"),
568
+	}
569
+
570
+	// Move the existing data file aside, so that we can replace it with a
571
+	// malicious blob of data. NOTE: we defer the returned undo func.
572
+	undo := s.reg.TempMoveBlobData(c, manifestDigest)
573
+	defer undo()
574
+
575
+	alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", "   ")
576
+	c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
577
+
578
+	s.reg.WriteBlobContents(c, manifestDigest, alteredManifestBlob)
579
+
580
+	// Now try pulling that image by digest. We should get an error about
581
+	// digest verification for the manifest digest.
582
+
583
+	// Pull from the registry using the <name>@<digest> reference.
584
+	imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
585
+	out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
586
+	c.Assert(exitStatus, checker.Not(check.Equals), 0)
587
+
588
+	expectedErrorMsg := fmt.Sprintf("image verification failed for digest %s", manifestDigest)
589
+	c.Assert(out, checker.Contains, expectedErrorMsg)
590
+}
591
+
592
+// TestPullFailsWithAlteredLayer tests that a `docker pull` fails when
593
+// we have modified a layer blob and its digest cannot be verified.
594
+// This is the schema2 version of the test.
595
+func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
596
+	testRequires(c, DaemonIsLinux)
597
+	manifestDigest, err := setupImage(c)
598
+	c.Assert(err, checker.IsNil)
599
+
600
+	// Load the target manifest blob.
601
+	manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
602
+
603
+	var imgManifest schema2.Manifest
604
+	err = json.Unmarshal(manifestBlob, &imgManifest)
605
+	c.Assert(err, checker.IsNil)
606
+
607
+	// Next, get the digest of one of the layers from the manifest.
608
+	targetLayerDigest := imgManifest.Layers[0].Digest
609
+
610
+	// Move the existing data file aside, so that we can replace it with a
611
+	// malicious blob of data. NOTE: we defer the returned undo func.
612
+	undo := s.reg.TempMoveBlobData(c, targetLayerDigest)
613
+	defer undo()
614
+
615
+	// Now make a fake data blob in this directory.
616
+	s.reg.WriteBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
617
+
618
+	// Now try pulling that image by digest. We should get an error about
619
+	// digest verification for the target layer digest.
620
+
621
+	// Remove distribution cache to force a re-pull of the blobs
622
+	if err := os.RemoveAll(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "image", s.d.StorageDriver(), "distribution")); err != nil {
623
+		c.Fatalf("error clearing distribution cache: %v", err)
624
+	}
625
+
626
+	// Pull from the registry using the <name>@<digest> reference.
627
+	imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
628
+	out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
629
+	c.Assert(exitStatus, checker.Not(check.Equals), 0, check.Commentf("expected a non-zero exit status"))
630
+
631
+	expectedErrorMsg := fmt.Sprintf("filesystem layer verification failed for digest %s", targetLayerDigest)
632
+	c.Assert(out, checker.Contains, expectedErrorMsg, check.Commentf("expected error message in output: %s", out))
633
+}
634
+
635
+// TestPullFailsWithAlteredLayer tests that a `docker pull` fails when
636
+// we have modified a layer blob and its digest cannot be verified.
637
+// This is the schema1 version of the test.
638
+func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
639
+	testRequires(c, DaemonIsLinux)
640
+	manifestDigest, err := setupImage(c)
641
+	c.Assert(err, checker.IsNil)
642
+
643
+	// Load the target manifest blob.
644
+	manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
645
+
646
+	var imgManifest schema1.Manifest
647
+	err = json.Unmarshal(manifestBlob, &imgManifest)
648
+	c.Assert(err, checker.IsNil)
649
+
650
+	// Next, get the digest of one of the layers from the manifest.
651
+	targetLayerDigest := imgManifest.FSLayers[0].BlobSum
652
+
653
+	// Move the existing data file aside, so that we can replace it with a
654
+	// malicious blob of data. NOTE: we defer the returned undo func.
655
+	undo := s.reg.TempMoveBlobData(c, targetLayerDigest)
656
+	defer undo()
657
+
658
+	// Now make a fake data blob in this directory.
659
+	s.reg.WriteBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
660
+
661
+	// Now try pulling that image by digest. We should get an error about
662
+	// digest verification for the target layer digest.
663
+
664
+	// Remove distribution cache to force a re-pull of the blobs
665
+	if err := os.RemoveAll(filepath.Join(testEnv.DaemonInfo.DockerRootDir, "image", s.d.StorageDriver(), "distribution")); err != nil {
666
+		c.Fatalf("error clearing distribution cache: %v", err)
667
+	}
668
+
669
+	// Pull from the registry using the <name>@<digest> reference.
670
+	imageReference := fmt.Sprintf("%s@%s", repoName, manifestDigest)
671
+	out, exitStatus, _ := dockerCmdWithError("pull", imageReference)
672
+	c.Assert(exitStatus, checker.Not(check.Equals), 0, check.Commentf("expected a non-zero exit status"))
673
+
674
+	expectedErrorMsg := fmt.Sprintf("filesystem layer verification failed for digest %s", targetLayerDigest)
675
+	c.Assert(out, checker.Contains, expectedErrorMsg, check.Commentf("expected error message in output: %s", out))
676
+}
... ...
@@ -18,6 +18,7 @@ import (
18 18
 	"path"
19 19
 	"path/filepath"
20 20
 	"regexp"
21
+	"runtime"
21 22
 	"strconv"
22 23
 	"strings"
23 24
 	"sync"
... ...
@@ -550,6 +551,26 @@ func (s *DockerDaemonSuite) TestDaemonAllocatesListeningPort(c *check.C) {
550 550
 	}
551 551
 }
552 552
 
553
+func (s *DockerDaemonSuite) TestDaemonUUIDGeneration(c *check.C) {
554
+	dir := "/var/lib/docker"
555
+	if runtime.GOOS == "windows" {
556
+		dir = filepath.Join(os.Getenv("programdata"), "docker")
557
+	}
558
+	file := filepath.Join(dir, "engine_uuid")
559
+	os.Remove(file)
560
+	s.d.Start(c)
561
+	s.d.Stop(c)
562
+
563
+	fi, err := os.Stat(file)
564
+	if err != nil {
565
+		c.Fatalf("Error opening uuid file")
566
+	}
567
+	// Test for uuid length
568
+	if fi.Size() != 36 {
569
+		c.Fatalf("Bad UUID size %d", fi.Size())
570
+	}
571
+}
572
+
553 573
 // GH#11320 - verify that the daemon exits on failure properly
554 574
 // Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means
555 575
 // to get a daemon init failure; no other tests for -b/--bip conflict are therefore required
... ...
@@ -1174,6 +1195,59 @@ func (s *DockerDaemonSuite) TestDaemonUnixSockCleanedUp(c *check.C) {
1174 1174
 	}
1175 1175
 }
1176 1176
 
1177
+func (s *DockerDaemonSuite) TestDaemonWithWrongkey(c *check.C) {
1178
+	type Config struct {
1179
+		Crv string `json:"crv"`
1180
+		D   string `json:"d"`
1181
+		Kid string `json:"kid"`
1182
+		Kty string `json:"kty"`
1183
+		X   string `json:"x"`
1184
+		Y   string `json:"y"`
1185
+	}
1186
+
1187
+	os.Remove("/etc/docker/key.json")
1188
+	s.d.Start(c)
1189
+	s.d.Stop(c)
1190
+
1191
+	config := &Config{}
1192
+	bytes, err := ioutil.ReadFile("/etc/docker/key.json")
1193
+	if err != nil {
1194
+		c.Fatalf("Error reading key.json file: %s", err)
1195
+	}
1196
+
1197
+	// byte[] to Data-Struct
1198
+	if err := json.Unmarshal(bytes, &config); err != nil {
1199
+		c.Fatalf("Error Unmarshal: %s", err)
1200
+	}
1201
+
1202
+	//replace config.Kid with the fake value
1203
+	config.Kid = "VSAJ:FUYR:X3H2:B2VZ:KZ6U:CJD5:K7BX:ZXHY:UZXT:P4FT:MJWG:HRJ4"
1204
+
1205
+	// NEW Data-Struct to byte[]
1206
+	newBytes, err := json.Marshal(&config)
1207
+	if err != nil {
1208
+		c.Fatalf("Error Marshal: %s", err)
1209
+	}
1210
+
1211
+	// write back
1212
+	if err := ioutil.WriteFile("/etc/docker/key.json", newBytes, 0400); err != nil {
1213
+		c.Fatalf("Error ioutil.WriteFile: %s", err)
1214
+	}
1215
+
1216
+	defer os.Remove("/etc/docker/key.json")
1217
+
1218
+	if err := s.d.StartWithError(); err == nil {
1219
+		c.Fatalf("It should not be successful to start daemon with wrong key: %v", err)
1220
+	}
1221
+
1222
+	content, err := s.d.ReadLogFile()
1223
+	c.Assert(err, checker.IsNil)
1224
+
1225
+	if !strings.Contains(string(content), "Public Key ID does not match") {
1226
+		c.Fatalf("Missing KeyID message from daemon logs: %s", string(content))
1227
+	}
1228
+}
1229
+
1177 1230
 func (s *DockerDaemonSuite) TestDaemonRestartKillWait(c *check.C) {
1178 1231
 	s.d.StartWithBusybox(c)
1179 1232
 
... ...
@@ -56,6 +56,10 @@ func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) {
56 56
 	testPullImageWithAliases(c)
57 57
 }
58 58
 
59
+func (s *DockerSchema1RegistrySuite) TestPullImageWithAliases(c *check.C) {
60
+	testPullImageWithAliases(c)
61
+}
62
+
59 63
 // testConcurrentPullWholeRepo pulls the same repo concurrently.
60 64
 func testConcurrentPullWholeRepo(c *check.C) {
61 65
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
... ...
@@ -108,6 +112,10 @@ func (s *DockerRegistrySuite) testConcurrentPullWholeRepo(c *check.C) {
108 108
 	testConcurrentPullWholeRepo(c)
109 109
 }
110 110
 
111
+func (s *DockerSchema1RegistrySuite) testConcurrentPullWholeRepo(c *check.C) {
112
+	testConcurrentPullWholeRepo(c)
113
+}
114
+
111 115
 // testConcurrentFailingPull tries a concurrent pull that doesn't succeed.
112 116
 func testConcurrentFailingPull(c *check.C) {
113 117
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
... ...
@@ -135,6 +143,10 @@ func (s *DockerRegistrySuite) testConcurrentFailingPull(c *check.C) {
135 135
 	testConcurrentFailingPull(c)
136 136
 }
137 137
 
138
+func (s *DockerSchema1RegistrySuite) testConcurrentFailingPull(c *check.C) {
139
+	testConcurrentFailingPull(c)
140
+}
141
+
138 142
 // testConcurrentPullMultipleTags pulls multiple tags from the same repo
139 143
 // concurrently.
140 144
 func testConcurrentPullMultipleTags(c *check.C) {
... ...
@@ -187,6 +199,10 @@ func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
187 187
 	testConcurrentPullMultipleTags(c)
188 188
 }
189 189
 
190
+func (s *DockerSchema1RegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
191
+	testConcurrentPullMultipleTags(c)
192
+}
193
+
190 194
 // testPullIDStability verifies that pushing an image and pulling it back
191 195
 // preserves the image ID.
192 196
 func testPullIDStability(c *check.C) {
... ...
@@ -244,6 +260,10 @@ func (s *DockerRegistrySuite) TestPullIDStability(c *check.C) {
244 244
 	testPullIDStability(c)
245 245
 }
246 246
 
247
+func (s *DockerSchema1RegistrySuite) TestPullIDStability(c *check.C) {
248
+	testPullIDStability(c)
249
+}
250
+
247 251
 // #21213
248 252
 func testPullNoLayers(c *check.C) {
249 253
 	repoName := fmt.Sprintf("%v/dockercli/scratch", privateRegistryURL)
... ...
@@ -260,6 +280,10 @@ func (s *DockerRegistrySuite) TestPullNoLayers(c *check.C) {
260 260
 	testPullNoLayers(c)
261 261
 }
262 262
 
263
+func (s *DockerSchema1RegistrySuite) TestPullNoLayers(c *check.C) {
264
+	testPullNoLayers(c)
265
+}
266
+
263 267
 func (s *DockerRegistrySuite) TestPullManifestList(c *check.C) {
264 268
 	testRequires(c, NotArm)
265 269
 	pushDigest, err := setupImage(c)
... ...
@@ -30,6 +30,10 @@ func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) {
30 30
 	testPushBusyboxImage(c)
31 31
 }
32 32
 
33
+func (s *DockerSchema1RegistrySuite) TestPushBusyboxImage(c *check.C) {
34
+	testPushBusyboxImage(c)
35
+}
36
+
33 37
 // pushing an image without a prefix should throw an error
34 38
 func (s *DockerSuite) TestPushUnprefixedRepo(c *check.C) {
35 39
 	out, _, err := dockerCmdWithError("push", "busybox")
... ...
@@ -49,6 +53,10 @@ func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) {
49 49
 	testPushUntagged(c)
50 50
 }
51 51
 
52
+func (s *DockerSchema1RegistrySuite) TestPushUntagged(c *check.C) {
53
+	testPushUntagged(c)
54
+}
55
+
52 56
 func testPushBadTag(c *check.C) {
53 57
 	repoName := fmt.Sprintf("%v/dockercli/busybox:latest", privateRegistryURL)
54 58
 	expected := "does not exist"
... ...
@@ -62,6 +70,10 @@ func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) {
62 62
 	testPushBadTag(c)
63 63
 }
64 64
 
65
+func (s *DockerSchema1RegistrySuite) TestPushBadTag(c *check.C) {
66
+	testPushBadTag(c)
67
+}
68
+
65 69
 func testPushMultipleTags(c *check.C) {
66 70
 	repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
67 71
 	repoTag1 := fmt.Sprintf("%v/dockercli/busybox:t1", privateRegistryURL)
... ...
@@ -103,6 +115,10 @@ func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) {
103 103
 	testPushMultipleTags(c)
104 104
 }
105 105
 
106
+func (s *DockerSchema1RegistrySuite) TestPushMultipleTags(c *check.C) {
107
+	testPushMultipleTags(c)
108
+}
109
+
106 110
 func testPushEmptyLayer(c *check.C) {
107 111
 	repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL)
108 112
 	emptyTarball, err := ioutil.TempFile("", "empty_tarball")
... ...
@@ -130,6 +146,10 @@ func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) {
130 130
 	testPushEmptyLayer(c)
131 131
 }
132 132
 
133
+func (s *DockerSchema1RegistrySuite) TestPushEmptyLayer(c *check.C) {
134
+	testPushEmptyLayer(c)
135
+}
136
+
133 137
 // testConcurrentPush pushes multiple tags to the same repo
134 138
 // concurrently.
135 139
 func testConcurrentPush(c *check.C) {
... ...
@@ -180,6 +200,10 @@ func (s *DockerRegistrySuite) TestConcurrentPush(c *check.C) {
180 180
 	testConcurrentPush(c)
181 181
 }
182 182
 
183
+func (s *DockerSchema1RegistrySuite) TestConcurrentPush(c *check.C) {
184
+	testConcurrentPush(c)
185
+}
186
+
183 187
 func (s *DockerRegistrySuite) TestCrossRepositoryLayerPush(c *check.C) {
184 188
 	sourceRepoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
185 189
 	// tag the image to upload it to the private registry
... ...
@@ -222,6 +246,39 @@ func (s *DockerRegistrySuite) TestCrossRepositoryLayerPush(c *check.C) {
222 222
 	assert.Equal(c, out4, "hello world")
223 223
 }
224 224
 
225
+func (s *DockerSchema1RegistrySuite) TestCrossRepositoryLayerPushNotSupported(c *check.C) {
226
+	sourceRepoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
227
+	// tag the image to upload it to the private registry
228
+	dockerCmd(c, "tag", "busybox", sourceRepoName)
229
+	// push the image to the registry
230
+	out1, _, err := dockerCmdWithError("push", sourceRepoName)
231
+	c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out1))
232
+	// ensure that none of the layers were mounted from another repository during push
233
+	c.Assert(strings.Contains(out1, "Mounted from"), check.Equals, false)
234
+
235
+	digest1 := reference.DigestRegexp.FindString(out1)
236
+	c.Assert(len(digest1), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
237
+
238
+	destRepoName := fmt.Sprintf("%v/dockercli/crossrepopush", privateRegistryURL)
239
+	// retag the image to upload the same layers to another repo in the same registry
240
+	dockerCmd(c, "tag", "busybox", destRepoName)
241
+	// push the image to the registry
242
+	out2, _, err := dockerCmdWithError("push", destRepoName)
243
+	c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out2))
244
+	// schema1 registry should not support cross-repo layer mounts, so ensure that this does not happen
245
+	c.Assert(strings.Contains(out2, "Mounted from"), check.Equals, false)
246
+
247
+	digest2 := reference.DigestRegexp.FindString(out2)
248
+	c.Assert(len(digest2), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
249
+	c.Assert(digest1, check.Not(check.Equals), digest2)
250
+
251
+	// ensure that we can pull and run the second pushed repository
252
+	dockerCmd(c, "rmi", destRepoName)
253
+	dockerCmd(c, "pull", destRepoName)
254
+	out3, _ := dockerCmd(c, "run", destRepoName, "echo", "-n", "hello world")
255
+	c.Assert(out3, check.Equals, "hello world")
256
+}
257
+
225 258
 func (s *DockerRegistryAuthHtpasswdSuite) TestPushNoCredentialsNoRetry(c *check.C) {
226 259
 	repoName := fmt.Sprintf("%s/busybox", privateRegistryURL)
227 260
 	dockerCmd(c, "tag", "busybox", repoName)
228 261
deleted file mode 100644
... ...
@@ -1,23 +0,0 @@
1
-package system
2
-
3
-import (
4
-	"context"
5
-	"testing"
6
-
7
-	"github.com/docker/docker/api/types/versions"
8
-	"github.com/google/uuid"
9
-	"gotest.tools/assert"
10
-	"gotest.tools/skip"
11
-)
12
-
13
-func TestUUIDGeneration(t *testing.T) {
14
-	skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.40"), "ID format changed")
15
-	defer setupTest(t)()
16
-
17
-	c := testEnv.APIClient()
18
-	info, err := c.Info(context.Background())
19
-	assert.NilError(t, err)
20
-
21
-	_, err = uuid.Parse(info.ID)
22
-	assert.NilError(t, err, info.ID)
23
-}