Browse code

Merge pull request #29799 from vdemeester/integration-registry-package

[test-integration] Add a registry package with registry v1/v2 code

Sebastiaan van Stijn authored on 2017/01/02 23:37:09
Showing 15 changed files
... ...
@@ -16,6 +16,7 @@ import (
16 16
 	cliconfig "github.com/docker/docker/cli/config"
17 17
 	"github.com/docker/docker/integration-cli/daemon"
18 18
 	"github.com/docker/docker/integration-cli/environment"
19
+	"github.com/docker/docker/integration-cli/registry"
19 20
 	"github.com/docker/docker/pkg/reexec"
20 21
 	"github.com/go-check/check"
21 22
 )
... ...
@@ -172,7 +173,7 @@ func init() {
172 172
 
173 173
 type DockerRegistrySuite struct {
174 174
 	ds  *DockerSuite
175
-	reg *testRegistryV2
175
+	reg *registry.V2
176 176
 	d   *daemon.Daemon
177 177
 }
178 178
 
... ...
@@ -181,7 +182,7 @@ func (s *DockerRegistrySuite) OnTimeout(c *check.C) {
181 181
 }
182 182
 
183 183
 func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
184
-	testRequires(c, DaemonIsLinux, RegistryHosting)
184
+	testRequires(c, DaemonIsLinux, registry.Hosting)
185 185
 	s.reg = setupRegistry(c, false, "", "")
186 186
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
187 187
 		Experimental: experimentalDaemon,
... ...
@@ -206,7 +207,7 @@ func init() {
206 206
 
207 207
 type DockerSchema1RegistrySuite struct {
208 208
 	ds  *DockerSuite
209
-	reg *testRegistryV2
209
+	reg *registry.V2
210 210
 	d   *daemon.Daemon
211 211
 }
212 212
 
... ...
@@ -215,7 +216,7 @@ func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) {
215 215
 }
216 216
 
217 217
 func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
218
-	testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64)
218
+	testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64)
219 219
 	s.reg = setupRegistry(c, true, "", "")
220 220
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
221 221
 		Experimental: experimentalDaemon,
... ...
@@ -240,7 +241,7 @@ func init() {
240 240
 
241 241
 type DockerRegistryAuthHtpasswdSuite struct {
242 242
 	ds  *DockerSuite
243
-	reg *testRegistryV2
243
+	reg *registry.V2
244 244
 	d   *daemon.Daemon
245 245
 }
246 246
 
... ...
@@ -249,7 +250,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) OnTimeout(c *check.C) {
249 249
 }
250 250
 
251 251
 func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) {
252
-	testRequires(c, DaemonIsLinux, RegistryHosting)
252
+	testRequires(c, DaemonIsLinux, registry.Hosting)
253 253
 	s.reg = setupRegistry(c, false, "htpasswd", "")
254 254
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
255 255
 		Experimental: experimentalDaemon,
... ...
@@ -276,7 +277,7 @@ func init() {
276 276
 
277 277
 type DockerRegistryAuthTokenSuite struct {
278 278
 	ds  *DockerSuite
279
-	reg *testRegistryV2
279
+	reg *registry.V2
280 280
 	d   *daemon.Daemon
281 281
 }
282 282
 
... ...
@@ -285,7 +286,7 @@ func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *check.C) {
285 285
 }
286 286
 
287 287
 func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) {
288
-	testRequires(c, DaemonIsLinux, RegistryHosting)
288
+	testRequires(c, DaemonIsLinux, registry.Hosting)
289 289
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
290 290
 		Experimental: experimentalDaemon,
291 291
 	})
... ...
@@ -449,12 +450,12 @@ func init() {
449 449
 
450 450
 type DockerTrustSuite struct {
451 451
 	ds  *DockerSuite
452
-	reg *testRegistryV2
452
+	reg *registry.V2
453 453
 	not *testNotary
454 454
 }
455 455
 
456 456
 func (s *DockerTrustSuite) SetUpTest(c *check.C) {
457
-	testRequires(c, RegistryHosting, NotaryServerHosting)
457
+	testRequires(c, registry.Hosting, NotaryServerHosting)
458 458
 	s.reg = setupRegistry(c, false, "", "")
459 459
 	s.not = setupNotary(c)
460 460
 }
... ...
@@ -487,7 +488,7 @@ func init() {
487 487
 type DockerTrustedSwarmSuite struct {
488 488
 	swarmSuite DockerSwarmSuite
489 489
 	trustSuite DockerTrustSuite
490
-	reg        *testRegistryV2
490
+	reg        *registry.V2
491 491
 	not        *testNotary
492 492
 }
493 493
 
... ...
@@ -6580,7 +6580,7 @@ func (s *DockerSuite) TestBuildLabelOverwrite(c *check.C) {
6580 6580
 }
6581 6581
 
6582 6582
 func (s *DockerRegistryAuthHtpasswdSuite) TestBuildFromAuthenticatedRegistry(c *check.C) {
6583
-	dockerCmd(c, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
6583
+	dockerCmd(c, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
6584 6584
 
6585 6585
 	baseImage := privateRegistryURL + "/baseimage"
6586 6586
 
... ...
@@ -6625,7 +6625,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestBuildWithExternalAuth(c *check.C)
6625 6625
 	err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
6626 6626
 	c.Assert(err, checker.IsNil)
6627 6627
 
6628
-	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
6628
+	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
6629 6629
 
6630 6630
 	b, err := ioutil.ReadFile(configPath)
6631 6631
 	c.Assert(err, checker.IsNil)
... ...
@@ -533,7 +533,7 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
533 533
 	c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
534 534
 
535 535
 	// Load the target manifest blob.
536
-	manifestBlob := s.reg.readBlobContents(c, manifestDigest)
536
+	manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
537 537
 
538 538
 	var imgManifest schema2.Manifest
539 539
 	err = json.Unmarshal(manifestBlob, &imgManifest)
... ...
@@ -544,13 +544,13 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
544 544
 
545 545
 	// Move the existing data file aside, so that we can replace it with a
546 546
 	// malicious blob of data. NOTE: we defer the returned undo func.
547
-	undo := s.reg.tempMoveBlobData(c, manifestDigest)
547
+	undo := s.reg.TempMoveBlobData(c, manifestDigest)
548 548
 	defer undo()
549 549
 
550 550
 	alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", "   ")
551 551
 	c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
552 552
 
553
-	s.reg.writeBlobContents(c, manifestDigest, alteredManifestBlob)
553
+	s.reg.WriteBlobContents(c, manifestDigest, alteredManifestBlob)
554 554
 
555 555
 	// Now try pulling that image by digest. We should get an error about
556 556
 	// digest verification for the manifest digest.
... ...
@@ -573,7 +573,7 @@ func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *check.C
573 573
 	c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
574 574
 
575 575
 	// Load the target manifest blob.
576
-	manifestBlob := s.reg.readBlobContents(c, manifestDigest)
576
+	manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
577 577
 
578 578
 	var imgManifest schema1.Manifest
579 579
 	err = json.Unmarshal(manifestBlob, &imgManifest)
... ...
@@ -586,13 +586,13 @@ func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *check.C
586 586
 
587 587
 	// Move the existing data file aside, so that we can replace it with a
588 588
 	// malicious blob of data. NOTE: we defer the returned undo func.
589
-	undo := s.reg.tempMoveBlobData(c, manifestDigest)
589
+	undo := s.reg.TempMoveBlobData(c, manifestDigest)
590 590
 	defer undo()
591 591
 
592 592
 	alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", "   ")
593 593
 	c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
594 594
 
595
-	s.reg.writeBlobContents(c, manifestDigest, alteredManifestBlob)
595
+	s.reg.WriteBlobContents(c, manifestDigest, alteredManifestBlob)
596 596
 
597 597
 	// Now try pulling that image by digest. We should get an error about
598 598
 	// digest verification for the manifest digest.
... ...
@@ -615,7 +615,7 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
615 615
 	c.Assert(err, checker.IsNil)
616 616
 
617 617
 	// Load the target manifest blob.
618
-	manifestBlob := s.reg.readBlobContents(c, manifestDigest)
618
+	manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
619 619
 
620 620
 	var imgManifest schema2.Manifest
621 621
 	err = json.Unmarshal(manifestBlob, &imgManifest)
... ...
@@ -626,11 +626,11 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
626 626
 
627 627
 	// Move the existing data file aside, so that we can replace it with a
628 628
 	// malicious blob of data. NOTE: we defer the returned undo func.
629
-	undo := s.reg.tempMoveBlobData(c, targetLayerDigest)
629
+	undo := s.reg.TempMoveBlobData(c, targetLayerDigest)
630 630
 	defer undo()
631 631
 
632 632
 	// Now make a fake data blob in this directory.
633
-	s.reg.writeBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
633
+	s.reg.WriteBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
634 634
 
635 635
 	// Now try pulling that image by digest. We should get an error about
636 636
 	// digest verification for the target layer digest.
... ...
@@ -658,7 +658,7 @@ func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
658 658
 	c.Assert(err, checker.IsNil)
659 659
 
660 660
 	// Load the target manifest blob.
661
-	manifestBlob := s.reg.readBlobContents(c, manifestDigest)
661
+	manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
662 662
 
663 663
 	var imgManifest schema1.Manifest
664 664
 	err = json.Unmarshal(manifestBlob, &imgManifest)
... ...
@@ -669,11 +669,11 @@ func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
669 669
 
670 670
 	// Move the existing data file aside, so that we can replace it with a
671 671
 	// malicious blob of data. NOTE: we defer the returned undo func.
672
-	undo := s.reg.tempMoveBlobData(c, targetLayerDigest)
672
+	undo := s.reg.TempMoveBlobData(c, targetLayerDigest)
673 673
 	defer undo()
674 674
 
675 675
 	// Now make a fake data blob in this directory.
676
-	s.reg.writeBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
676
+	s.reg.WriteBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
677 677
 
678 678
 	// Now try pulling that image by digest. We should get an error about
679 679
 	// digest verification for the target layer digest.
... ...
@@ -21,10 +21,10 @@ func (s *DockerSuite) TestLoginWithoutTTY(c *check.C) {
21 21
 
22 22
 func (s *DockerRegistryAuthHtpasswdSuite) TestLoginToPrivateRegistry(c *check.C) {
23 23
 	// wrong credentials
24
-	out, _, err := dockerCmdWithError("login", "-u", s.reg.username, "-p", "WRONGPASSWORD", privateRegistryURL)
24
+	out, _, err := dockerCmdWithError("login", "-u", s.reg.Username(), "-p", "WRONGPASSWORD", privateRegistryURL)
25 25
 	c.Assert(err, checker.NotNil, check.Commentf(out))
26 26
 	c.Assert(out, checker.Contains, "401 Unauthorized")
27 27
 
28 28
 	// now it's fine
29
-	dockerCmd(c, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
29
+	dockerCmd(c, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
30 30
 }
... ...
@@ -35,7 +35,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *check.C)
35 35
 	err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
36 36
 	c.Assert(err, checker.IsNil)
37 37
 
38
-	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
38
+	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
39 39
 
40 40
 	b, err := ioutil.ReadFile(configPath)
41 41
 	c.Assert(err, checker.IsNil)
... ...
@@ -71,7 +71,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithWrongHostnamesStored(c *
71 71
 	os.Setenv("PATH", testPath)
72 72
 
73 73
 	cmd := exec.Command("docker-credential-shell-test", "store")
74
-	stdin := bytes.NewReader([]byte(fmt.Sprintf(`{"ServerURL": "https://%s", "Username": "%s", "Secret": "%s"}`, privateRegistryURL, s.reg.username, s.reg.password)))
74
+	stdin := bytes.NewReader([]byte(fmt.Sprintf(`{"ServerURL": "https://%s", "Username": "%s", "Secret": "%s"}`, privateRegistryURL, s.reg.Username(), s.reg.Password())))
75 75
 	cmd.Stdin = stdin
76 76
 	c.Assert(cmd.Run(), checker.IsNil)
77 77
 
... ...
@@ -84,7 +84,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithWrongHostnamesStored(c *
84 84
 	err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
85 85
 	c.Assert(err, checker.IsNil)
86 86
 
87
-	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
87
+	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
88 88
 
89 89
 	b, err := ioutil.ReadFile(configPath)
90 90
 	c.Assert(err, checker.IsNil)
... ...
@@ -347,7 +347,7 @@ func (s *DockerRegistrySuite) TestPullManifestList(c *check.C) {
347 347
 	manifestListDigest := digest.FromBytes(manifestListJSON)
348 348
 	hexDigest := manifestListDigest.Hex()
349 349
 
350
-	registryV2Path := filepath.Join(s.reg.dir, "docker", "registry", "v2")
350
+	registryV2Path := s.reg.Path()
351 351
 
352 352
 	// Write manifest list to blob store
353 353
 	blobDir := filepath.Join(registryV2Path, "blobs", "sha256", hexDigest[:2], hexDigest)
... ...
@@ -411,7 +411,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullWithExternalAuthLoginWithSchem
411 411
 	err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
412 412
 	c.Assert(err, checker.IsNil)
413 413
 
414
-	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
414
+	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
415 415
 
416 416
 	b, err := ioutil.ReadFile(configPath)
417 417
 	c.Assert(err, checker.IsNil)
... ...
@@ -421,7 +421,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullWithExternalAuthLoginWithSchem
421 421
 	dockerCmd(c, "--config", tmp, "push", repoName)
422 422
 
423 423
 	dockerCmd(c, "--config", tmp, "logout", privateRegistryURL)
424
-	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, "https://"+privateRegistryURL)
424
+	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), "https://"+privateRegistryURL)
425 425
 	dockerCmd(c, "--config", tmp, "pull", repoName)
426 426
 
427 427
 	// likewise push should work
... ...
@@ -456,7 +456,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullWithExternalAuth(c *check.C) {
456 456
 	err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
457 457
 	c.Assert(err, checker.IsNil)
458 458
 
459
-	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
459
+	dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
460 460
 
461 461
 	b, err := ioutil.ReadFile(configPath)
462 462
 	c.Assert(err, checker.IsNil)
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"net/http"
6 6
 	"regexp"
7 7
 
8
+	"github.com/docker/docker/integration-cli/registry"
8 9
 	"github.com/go-check/check"
9 10
 )
10 11
 
... ...
@@ -46,8 +47,8 @@ func regexpCheckUA(c *check.C, ua string) {
46 46
 	c.Assert(bMatchUpstreamUA, check.Equals, true, check.Commentf("(Upstream) Docker Client User-Agent malformed"))
47 47
 }
48 48
 
49
-func registerUserAgentHandler(reg *testRegistry, result *string) {
50
-	reg.registerHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
49
+func registerUserAgentHandler(reg *registry.Mock, result *string) {
50
+	reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
51 51
 		w.WriteHeader(404)
52 52
 		var ua string
53 53
 		for k, v := range r.Header {
... ...
@@ -70,30 +71,30 @@ func (s *DockerRegistrySuite) TestUserAgentPassThrough(c *check.C) {
70 70
 		loginUA string
71 71
 	)
72 72
 
73
-	buildReg, err := newTestRegistry(c)
73
+	buildReg, err := registry.NewMock(c)
74 74
 	c.Assert(err, check.IsNil)
75 75
 	registerUserAgentHandler(buildReg, &buildUA)
76
-	buildRepoName := fmt.Sprintf("%s/busybox", buildReg.hostport)
76
+	buildRepoName := fmt.Sprintf("%s/busybox", buildReg.URL())
77 77
 
78
-	pullReg, err := newTestRegistry(c)
78
+	pullReg, err := registry.NewMock(c)
79 79
 	c.Assert(err, check.IsNil)
80 80
 	registerUserAgentHandler(pullReg, &pullUA)
81
-	pullRepoName := fmt.Sprintf("%s/busybox", pullReg.hostport)
81
+	pullRepoName := fmt.Sprintf("%s/busybox", pullReg.URL())
82 82
 
83
-	pushReg, err := newTestRegistry(c)
83
+	pushReg, err := registry.NewMock(c)
84 84
 	c.Assert(err, check.IsNil)
85 85
 	registerUserAgentHandler(pushReg, &pushUA)
86
-	pushRepoName := fmt.Sprintf("%s/busybox", pushReg.hostport)
86
+	pushRepoName := fmt.Sprintf("%s/busybox", pushReg.URL())
87 87
 
88
-	loginReg, err := newTestRegistry(c)
88
+	loginReg, err := registry.NewMock(c)
89 89
 	c.Assert(err, check.IsNil)
90 90
 	registerUserAgentHandler(loginReg, &loginUA)
91 91
 
92 92
 	s.d.Start(c,
93
-		"--insecure-registry", buildReg.hostport,
94
-		"--insecure-registry", pullReg.hostport,
95
-		"--insecure-registry", pushReg.hostport,
96
-		"--insecure-registry", loginReg.hostport,
93
+		"--insecure-registry", buildReg.URL(),
94
+		"--insecure-registry", pullReg.URL(),
95
+		"--insecure-registry", pushReg.URL(),
96
+		"--insecure-registry", loginReg.URL(),
97 97
 		"--disable-legacy-registry=true")
98 98
 
99 99
 	dockerfileName, cleanup1, err := makefile(fmt.Sprintf("FROM %s", buildRepoName))
... ...
@@ -102,7 +103,7 @@ func (s *DockerRegistrySuite) TestUserAgentPassThrough(c *check.C) {
102 102
 	s.d.Cmd("build", "--file", dockerfileName, ".")
103 103
 	regexpCheckUA(c, buildUA)
104 104
 
105
-	s.d.Cmd("login", "-u", "richard", "-p", "testtest", loginReg.hostport)
105
+	s.d.Cmd("login", "-u", "richard", "-p", "testtest", loginReg.URL())
106 106
 	regexpCheckUA(c, loginUA)
107 107
 
108 108
 	s.d.Cmd("pull", pullRepoName)
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"net/http"
7 7
 	"os"
8 8
 
9
+	"github.com/docker/docker/integration-cli/registry"
9 10
 	"github.com/go-check/check"
10 11
 )
11 12
 
... ...
@@ -36,29 +37,29 @@ func makefile(contents string) (string, func(), error) {
36 36
 // TestV2Only ensures that a daemon in v2-only mode does not
37 37
 // attempt to contact any v1 registry endpoints.
38 38
 func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
39
-	reg, err := newTestRegistry(c)
39
+	reg, err := registry.NewMock(c)
40 40
 	c.Assert(err, check.IsNil)
41 41
 
42
-	reg.registerHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
42
+	reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
43 43
 		w.WriteHeader(404)
44 44
 	})
45 45
 
46
-	reg.registerHandler("/v1/.*", func(w http.ResponseWriter, r *http.Request) {
46
+	reg.RegisterHandler("/v1/.*", func(w http.ResponseWriter, r *http.Request) {
47 47
 		c.Fatal("V1 registry contacted")
48 48
 	})
49 49
 
50
-	repoName := fmt.Sprintf("%s/busybox", reg.hostport)
50
+	repoName := fmt.Sprintf("%s/busybox", reg.URL())
51 51
 
52
-	s.d.Start(c, "--insecure-registry", reg.hostport, "--disable-legacy-registry=true")
52
+	s.d.Start(c, "--insecure-registry", reg.URL(), "--disable-legacy-registry=true")
53 53
 
54
-	dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.hostport))
54
+	dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.URL()))
55 55
 	c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
56 56
 	defer cleanup()
57 57
 
58 58
 	s.d.Cmd("build", "--file", dockerfileName, ".")
59 59
 
60 60
 	s.d.Cmd("run", repoName)
61
-	s.d.Cmd("login", "-u", "richard", "-p", "testtest", "-e", "testuser@testdomain.com", reg.hostport)
61
+	s.d.Cmd("login", "-u", "richard", "-p", "testtest", "-e", "testuser@testdomain.com", reg.URL())
62 62
 	s.d.Cmd("tag", "busybox", repoName)
63 63
 	s.d.Cmd("push", repoName)
64 64
 	s.d.Cmd("pull", repoName)
... ...
@@ -68,49 +69,49 @@ func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
68 68
 // and ensure v1 endpoints are hit for the following operations:
69 69
 // login, push, pull, build & run
70 70
 func (s *DockerRegistrySuite) TestV1(c *check.C) {
71
-	reg, err := newTestRegistry(c)
71
+	reg, err := registry.NewMock(c)
72 72
 	c.Assert(err, check.IsNil)
73 73
 
74 74
 	v2Pings := 0
75
-	reg.registerHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
75
+	reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
76 76
 		v2Pings++
77 77
 		// V2 ping 404 causes fallback to v1
78 78
 		w.WriteHeader(404)
79 79
 	})
80 80
 
81 81
 	v1Pings := 0
82
-	reg.registerHandler("/v1/_ping", func(w http.ResponseWriter, r *http.Request) {
82
+	reg.RegisterHandler("/v1/_ping", func(w http.ResponseWriter, r *http.Request) {
83 83
 		v1Pings++
84 84
 	})
85 85
 
86 86
 	v1Logins := 0
87
-	reg.registerHandler("/v1/users/", func(w http.ResponseWriter, r *http.Request) {
87
+	reg.RegisterHandler("/v1/users/", func(w http.ResponseWriter, r *http.Request) {
88 88
 		v1Logins++
89 89
 	})
90 90
 
91 91
 	v1Repo := 0
92
-	reg.registerHandler("/v1/repositories/busybox/", func(w http.ResponseWriter, r *http.Request) {
92
+	reg.RegisterHandler("/v1/repositories/busybox/", func(w http.ResponseWriter, r *http.Request) {
93 93
 		v1Repo++
94 94
 	})
95 95
 
96
-	reg.registerHandler("/v1/repositories/busybox/images", func(w http.ResponseWriter, r *http.Request) {
96
+	reg.RegisterHandler("/v1/repositories/busybox/images", func(w http.ResponseWriter, r *http.Request) {
97 97
 		v1Repo++
98 98
 	})
99 99
 
100
-	s.d.Start(c, "--insecure-registry", reg.hostport, "--disable-legacy-registry=false")
100
+	s.d.Start(c, "--insecure-registry", reg.URL(), "--disable-legacy-registry=false")
101 101
 
102
-	dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.hostport))
102
+	dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.URL()))
103 103
 	c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
104 104
 	defer cleanup()
105 105
 
106 106
 	s.d.Cmd("build", "--file", dockerfileName, ".")
107 107
 	c.Assert(v1Repo, check.Equals, 1, check.Commentf("Expected v1 repository access after build"))
108 108
 
109
-	repoName := fmt.Sprintf("%s/busybox", reg.hostport)
109
+	repoName := fmt.Sprintf("%s/busybox", reg.URL())
110 110
 	s.d.Cmd("run", repoName)
111 111
 	c.Assert(v1Repo, check.Equals, 2, check.Commentf("Expected v1 repository access after run"))
112 112
 
113
-	s.d.Cmd("login", "-u", "richard", "-p", "testtest", reg.hostport)
113
+	s.d.Cmd("login", "-u", "richard", "-p", "testtest", reg.URL())
114 114
 	c.Assert(v1Logins, check.Equals, 1, check.Commentf("Expected v1 login attempt"))
115 115
 
116 116
 	s.d.Cmd("tag", "busybox", repoName)
... ...
@@ -25,6 +25,7 @@ import (
25 25
 	volumetypes "github.com/docker/docker/api/types/volume"
26 26
 	"github.com/docker/docker/integration-cli/checker"
27 27
 	"github.com/docker/docker/integration-cli/daemon"
28
+	"github.com/docker/docker/integration-cli/registry"
28 29
 	"github.com/docker/docker/opts"
29 30
 	"github.com/docker/docker/pkg/ioutils"
30 31
 	"github.com/docker/docker/pkg/stringutils"
... ...
@@ -1083,8 +1084,8 @@ func parseEventTime(t time.Time) string {
1083 1083
 	return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond()))
1084 1084
 }
1085 1085
 
1086
-func setupRegistry(c *check.C, schema1 bool, auth, tokenURL string) *testRegistryV2 {
1087
-	reg, err := newTestRegistryV2(c, schema1, auth, tokenURL)
1086
+func setupRegistry(c *check.C, schema1 bool, auth, tokenURL string) *registry.V2 {
1087
+	reg, err := registry.NewV2(schema1, auth, tokenURL, privateRegistryURL)
1088 1088
 	c.Assert(err, check.IsNil)
1089 1089
 
1090 1090
 	// Wait for registry to be ready to serve requests.
1091 1091
new file mode 100644
... ...
@@ -0,0 +1,208 @@
0
+package registry
1
+
2
+import (
3
+	"fmt"
4
+	"io/ioutil"
5
+	"net/http"
6
+	"os"
7
+	"os/exec"
8
+	"path/filepath"
9
+
10
+	"github.com/docker/distribution/digest"
11
+)
12
+
13
+const (
14
+	v2binary        = "registry-v2"
15
+	v2binarySchema1 = "registry-v2-schema1"
16
+)
17
+
18
+type testingT interface {
19
+	logT
20
+	Fatal(...interface{})
21
+	Fatalf(string, ...interface{})
22
+}
23
+
24
+type logT interface {
25
+	Logf(string, ...interface{})
26
+}
27
+
28
+// V2 represent a registry version 2
29
+type V2 struct {
30
+	cmd         *exec.Cmd
31
+	registryURL string
32
+	dir         string
33
+	auth        string
34
+	username    string
35
+	password    string
36
+	email       string
37
+}
38
+
39
+// NewV2 creates a v2 registry server
40
+func NewV2(schema1 bool, auth, tokenURL, registryURL string) (*V2, error) {
41
+	tmp, err := ioutil.TempDir("", "registry-test-")
42
+	if err != nil {
43
+		return nil, err
44
+	}
45
+	template := `version: 0.1
46
+loglevel: debug
47
+storage:
48
+    filesystem:
49
+        rootdirectory: %s
50
+http:
51
+    addr: %s
52
+%s`
53
+	var (
54
+		authTemplate string
55
+		username     string
56
+		password     string
57
+		email        string
58
+	)
59
+	switch auth {
60
+	case "htpasswd":
61
+		htpasswdPath := filepath.Join(tmp, "htpasswd")
62
+		// generated with: htpasswd -Bbn testuser testpassword
63
+		userpasswd := "testuser:$2y$05$sBsSqk0OpSD1uTZkHXc4FeJ0Z70wLQdAX/82UiHuQOKbNbBrzs63m"
64
+		username = "testuser"
65
+		password = "testpassword"
66
+		email = "test@test.org"
67
+		if err := ioutil.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644)); err != nil {
68
+			return nil, err
69
+		}
70
+		authTemplate = fmt.Sprintf(`auth:
71
+    htpasswd:
72
+        realm: basic-realm
73
+        path: %s
74
+`, htpasswdPath)
75
+	case "token":
76
+		authTemplate = fmt.Sprintf(`auth:
77
+    token:
78
+        realm: %s
79
+        service: "registry"
80
+        issuer: "auth-registry"
81
+        rootcertbundle: "fixtures/registry/cert.pem"
82
+`, tokenURL)
83
+	}
84
+
85
+	confPath := filepath.Join(tmp, "config.yaml")
86
+	config, err := os.Create(confPath)
87
+	if err != nil {
88
+		return nil, err
89
+	}
90
+	defer config.Close()
91
+
92
+	if _, err := fmt.Fprintf(config, template, tmp, registryURL, authTemplate); err != nil {
93
+		os.RemoveAll(tmp)
94
+		return nil, err
95
+	}
96
+
97
+	binary := v2binary
98
+	if schema1 {
99
+		binary = v2binarySchema1
100
+	}
101
+	cmd := exec.Command(binary, confPath)
102
+	if err := cmd.Start(); err != nil {
103
+		os.RemoveAll(tmp)
104
+		return nil, err
105
+	}
106
+	return &V2{
107
+		cmd:         cmd,
108
+		dir:         tmp,
109
+		auth:        auth,
110
+		username:    username,
111
+		password:    password,
112
+		email:       email,
113
+		registryURL: registryURL,
114
+	}, nil
115
+}
116
+
117
+// Ping sends an http request to the current registry, and fail if it doesn't respond correctly
118
+func (r *V2) Ping() error {
119
+	// We always ping through HTTP for our test registry.
120
+	resp, err := http.Get(fmt.Sprintf("http://%s/v2/", r.registryURL))
121
+	if err != nil {
122
+		return err
123
+	}
124
+	resp.Body.Close()
125
+
126
+	fail := resp.StatusCode != http.StatusOK
127
+	if r.auth != "" {
128
+		// unauthorized is a _good_ status when pinging v2/ and it needs auth
129
+		fail = fail && resp.StatusCode != http.StatusUnauthorized
130
+	}
131
+	if fail {
132
+		return fmt.Errorf("registry ping replied with an unexpected status code %d", resp.StatusCode)
133
+	}
134
+	return nil
135
+}
136
+
137
+// Close kills the registry server
138
+func (r *V2) Close() {
139
+	r.cmd.Process.Kill()
140
+	os.RemoveAll(r.dir)
141
+}
142
+
143
+func (r *V2) getBlobFilename(blobDigest digest.Digest) string {
144
+	// Split the digest into its algorithm and hex components.
145
+	dgstAlg, dgstHex := blobDigest.Algorithm(), blobDigest.Hex()
146
+
147
+	// The path to the target blob data looks something like:
148
+	//   baseDir + "docker/registry/v2/blobs/sha256/a3/a3ed...46d4/data"
149
+	return fmt.Sprintf("%s/docker/registry/v2/blobs/%s/%s/%s/data", r.dir, dgstAlg, dgstHex[:2], dgstHex)
150
+}
151
+
152
+// ReadBlobContents read the file corresponding to the specified digest
153
+func (r *V2) ReadBlobContents(t testingT, blobDigest digest.Digest) []byte {
154
+	// Load the target manifest blob.
155
+	manifestBlob, err := ioutil.ReadFile(r.getBlobFilename(blobDigest))
156
+	if err != nil {
157
+		t.Fatalf("unable to read blob: %s", err)
158
+	}
159
+
160
+	return manifestBlob
161
+}
162
+
163
+// WriteBlobContents write the file corresponding to the specified digest with the given content
164
+func (r *V2) WriteBlobContents(t testingT, blobDigest digest.Digest, data []byte) {
165
+	if err := ioutil.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644)); err != nil {
166
+		t.Fatalf("unable to write malicious data blob: %s", err)
167
+	}
168
+}
169
+
170
+// TempMoveBlobData moves the existing data file aside, so that we can replace it with a
171
+// malicious blob of data for example.
172
+func (r *V2) TempMoveBlobData(t testingT, blobDigest digest.Digest) (undo func()) {
173
+	tempFile, err := ioutil.TempFile("", "registry-temp-blob-")
174
+	if err != nil {
175
+		t.Fatalf("unable to get temporary blob file: %s", err)
176
+	}
177
+	tempFile.Close()
178
+
179
+	blobFilename := r.getBlobFilename(blobDigest)
180
+
181
+	// Move the existing data file aside, so that we can replace it with a
182
+	// another blob of data.
183
+	if err := os.Rename(blobFilename, tempFile.Name()); err != nil {
184
+		os.Remove(tempFile.Name())
185
+		t.Fatalf("unable to move data blob: %s", err)
186
+	}
187
+
188
+	return func() {
189
+		os.Rename(tempFile.Name(), blobFilename)
190
+		os.Remove(tempFile.Name())
191
+	}
192
+}
193
+
194
+// Username returns the configured user name of the server
195
+func (r *V2) Username() string {
196
+	return r.username
197
+}
198
+
199
+// Password returns the configured password of the server
200
+func (r *V2) Password() string {
201
+	return r.password
202
+}
203
+
204
+// Path returns the path where the registry write data
205
+func (r *V2) Path() string {
206
+	return filepath.Join(r.dir, "docker", "registry", "v2")
207
+}
0 208
new file mode 100644
... ...
@@ -0,0 +1,61 @@
0
+package registry
1
+
2
+import (
3
+	"net/http"
4
+	"net/http/httptest"
5
+	"regexp"
6
+	"strings"
7
+	"sync"
8
+)
9
+
10
+type handlerFunc func(w http.ResponseWriter, r *http.Request)
11
+
12
+// Mock represent a registry mock
13
+type Mock struct {
14
+	server   *httptest.Server
15
+	hostport string
16
+	handlers map[string]handlerFunc
17
+	mu       sync.Mutex
18
+}
19
+
20
+// RegisterHandler register the specified handler for the registry mock
21
+func (tr *Mock) RegisterHandler(path string, h handlerFunc) {
22
+	tr.mu.Lock()
23
+	defer tr.mu.Unlock()
24
+	tr.handlers[path] = h
25
+}
26
+
27
+// NewMock creates a registry mock
28
+func NewMock(t testingT) (*Mock, error) {
29
+	testReg := &Mock{handlers: make(map[string]handlerFunc)}
30
+
31
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
32
+		url := r.URL.String()
33
+
34
+		var matched bool
35
+		var err error
36
+		for re, function := range testReg.handlers {
37
+			matched, err = regexp.MatchString(re, url)
38
+			if err != nil {
39
+				t.Fatal("Error with handler regexp")
40
+			}
41
+			if matched {
42
+				function(w, r)
43
+				break
44
+			}
45
+		}
46
+
47
+		if !matched {
48
+			t.Fatalf("Unable to match %s with regexp", url)
49
+		}
50
+	}))
51
+
52
+	testReg.server = ts
53
+	testReg.hostport = strings.Replace(ts.URL, "http://", "", 1)
54
+	return testReg, nil
55
+}
56
+
57
+// URL returns the url of the registry
58
+func (tr *Mock) URL() string {
59
+	return tr.hostport
60
+}
0 61
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+package registry
1
+
2
+import "os/exec"
3
+
4
+// Hosting returns wether the host can host a registry (v2) or not
5
+func Hosting() bool {
6
+	// for now registry binary is built only if we're running inside
7
+	// container through `make test`. Figure that out by testing if
8
+	// registry binary is in PATH.
9
+	_, err := exec.LookPath(v2binary)
10
+	return err == nil
11
+}
0 12
deleted file mode 100644
... ...
@@ -1,55 +0,0 @@
1
-package main
2
-
3
-import (
4
-	"net/http"
5
-	"net/http/httptest"
6
-	"regexp"
7
-	"strings"
8
-	"sync"
9
-
10
-	"github.com/go-check/check"
11
-)
12
-
13
-type handlerFunc func(w http.ResponseWriter, r *http.Request)
14
-
15
-type testRegistry struct {
16
-	server   *httptest.Server
17
-	hostport string
18
-	handlers map[string]handlerFunc
19
-	mu       sync.Mutex
20
-}
21
-
22
-func (tr *testRegistry) registerHandler(path string, h handlerFunc) {
23
-	tr.mu.Lock()
24
-	defer tr.mu.Unlock()
25
-	tr.handlers[path] = h
26
-}
27
-
28
-func newTestRegistry(c *check.C) (*testRegistry, error) {
29
-	testReg := &testRegistry{handlers: make(map[string]handlerFunc)}
30
-
31
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
32
-		url := r.URL.String()
33
-
34
-		var matched bool
35
-		var err error
36
-		for re, function := range testReg.handlers {
37
-			matched, err = regexp.MatchString(re, url)
38
-			if err != nil {
39
-				c.Fatal("Error with handler regexp")
40
-			}
41
-			if matched {
42
-				function(w, r)
43
-				break
44
-			}
45
-		}
46
-
47
-		if !matched {
48
-			c.Fatalf("Unable to match %s with regexp", url)
49
-		}
50
-	}))
51
-
52
-	testReg.server = ts
53
-	testReg.hostport = strings.Replace(ts.URL, "http://", "", 1)
54
-	return testReg, nil
55
-}
56 1
deleted file mode 100644
... ...
@@ -1,177 +0,0 @@
1
-package main
2
-
3
-import (
4
-	"fmt"
5
-	"io/ioutil"
6
-	"net/http"
7
-	"os"
8
-	"os/exec"
9
-	"path/filepath"
10
-
11
-	"github.com/docker/distribution/digest"
12
-	"github.com/go-check/check"
13
-)
14
-
15
-const (
16
-	v2binary        = "registry-v2"
17
-	v2binarySchema1 = "registry-v2-schema1"
18
-)
19
-
20
-type testRegistryV2 struct {
21
-	cmd      *exec.Cmd
22
-	dir      string
23
-	auth     string
24
-	username string
25
-	password string
26
-	email    string
27
-}
28
-
29
-func newTestRegistryV2(c *check.C, schema1 bool, auth, tokenURL string) (*testRegistryV2, error) {
30
-	tmp, err := ioutil.TempDir("", "registry-test-")
31
-	if err != nil {
32
-		return nil, err
33
-	}
34
-	template := `version: 0.1
35
-loglevel: debug
36
-storage:
37
-    filesystem:
38
-        rootdirectory: %s
39
-http:
40
-    addr: %s
41
-%s`
42
-	var (
43
-		authTemplate string
44
-		username     string
45
-		password     string
46
-		email        string
47
-	)
48
-	switch auth {
49
-	case "htpasswd":
50
-		htpasswdPath := filepath.Join(tmp, "htpasswd")
51
-		// generated with: htpasswd -Bbn testuser testpassword
52
-		userpasswd := "testuser:$2y$05$sBsSqk0OpSD1uTZkHXc4FeJ0Z70wLQdAX/82UiHuQOKbNbBrzs63m"
53
-		username = "testuser"
54
-		password = "testpassword"
55
-		email = "test@test.org"
56
-		if err := ioutil.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644)); err != nil {
57
-			return nil, err
58
-		}
59
-		authTemplate = fmt.Sprintf(`auth:
60
-    htpasswd:
61
-        realm: basic-realm
62
-        path: %s
63
-`, htpasswdPath)
64
-	case "token":
65
-		authTemplate = fmt.Sprintf(`auth:
66
-    token:
67
-        realm: %s
68
-        service: "registry"
69
-        issuer: "auth-registry"
70
-        rootcertbundle: "fixtures/registry/cert.pem"
71
-`, tokenURL)
72
-	}
73
-
74
-	confPath := filepath.Join(tmp, "config.yaml")
75
-	config, err := os.Create(confPath)
76
-	if err != nil {
77
-		return nil, err
78
-	}
79
-	defer config.Close()
80
-
81
-	if _, err := fmt.Fprintf(config, template, tmp, privateRegistryURL, authTemplate); err != nil {
82
-		os.RemoveAll(tmp)
83
-		return nil, err
84
-	}
85
-
86
-	binary := v2binary
87
-	if schema1 {
88
-		binary = v2binarySchema1
89
-	}
90
-	cmd := exec.Command(binary, confPath)
91
-	if err := cmd.Start(); err != nil {
92
-		os.RemoveAll(tmp)
93
-		if os.IsNotExist(err) {
94
-			c.Skip(err.Error())
95
-		}
96
-		return nil, err
97
-	}
98
-	return &testRegistryV2{
99
-		cmd:      cmd,
100
-		dir:      tmp,
101
-		auth:     auth,
102
-		username: username,
103
-		password: password,
104
-		email:    email,
105
-	}, nil
106
-}
107
-
108
-func (t *testRegistryV2) Ping() error {
109
-	// We always ping through HTTP for our test registry.
110
-	resp, err := http.Get(fmt.Sprintf("http://%s/v2/", privateRegistryURL))
111
-	if err != nil {
112
-		return err
113
-	}
114
-	resp.Body.Close()
115
-
116
-	fail := resp.StatusCode != http.StatusOK
117
-	if t.auth != "" {
118
-		// unauthorized is a _good_ status when pinging v2/ and it needs auth
119
-		fail = fail && resp.StatusCode != http.StatusUnauthorized
120
-	}
121
-	if fail {
122
-		return fmt.Errorf("registry ping replied with an unexpected status code %d", resp.StatusCode)
123
-	}
124
-	return nil
125
-}
126
-
127
-func (t *testRegistryV2) Close() {
128
-	t.cmd.Process.Kill()
129
-	os.RemoveAll(t.dir)
130
-}
131
-
132
-func (t *testRegistryV2) getBlobFilename(blobDigest digest.Digest) string {
133
-	// Split the digest into its algorithm and hex components.
134
-	dgstAlg, dgstHex := blobDigest.Algorithm(), blobDigest.Hex()
135
-
136
-	// The path to the target blob data looks something like:
137
-	//   baseDir + "docker/registry/v2/blobs/sha256/a3/a3ed...46d4/data"
138
-	return fmt.Sprintf("%s/docker/registry/v2/blobs/%s/%s/%s/data", t.dir, dgstAlg, dgstHex[:2], dgstHex)
139
-}
140
-
141
-func (t *testRegistryV2) readBlobContents(c *check.C, blobDigest digest.Digest) []byte {
142
-	// Load the target manifest blob.
143
-	manifestBlob, err := ioutil.ReadFile(t.getBlobFilename(blobDigest))
144
-	if err != nil {
145
-		c.Fatalf("unable to read blob: %s", err)
146
-	}
147
-
148
-	return manifestBlob
149
-}
150
-
151
-func (t *testRegistryV2) writeBlobContents(c *check.C, blobDigest digest.Digest, data []byte) {
152
-	if err := ioutil.WriteFile(t.getBlobFilename(blobDigest), data, os.FileMode(0644)); err != nil {
153
-		c.Fatalf("unable to write malicious data blob: %s", err)
154
-	}
155
-}
156
-
157
-func (t *testRegistryV2) tempMoveBlobData(c *check.C, blobDigest digest.Digest) (undo func()) {
158
-	tempFile, err := ioutil.TempFile("", "registry-temp-blob-")
159
-	if err != nil {
160
-		c.Fatalf("unable to get temporary blob file: %s", err)
161
-	}
162
-	tempFile.Close()
163
-
164
-	blobFilename := t.getBlobFilename(blobDigest)
165
-
166
-	// Move the existing data file aside, so that we can replace it with a
167
-	// another blob of data.
168
-	if err := os.Rename(blobFilename, tempFile.Name()); err != nil {
169
-		os.Remove(tempFile.Name())
170
-		c.Fatalf("unable to move data blob: %s", err)
171
-	}
172
-
173
-	return func() {
174
-		os.Rename(tempFile.Name(), blobFilename)
175
-		os.Remove(tempFile.Name())
176
-	}
177
-}
... ...
@@ -105,14 +105,6 @@ func Apparmor() bool {
105 105
 	return err == nil && len(buf) > 1 && buf[0] == 'Y'
106 106
 }
107 107
 
108
-func RegistryHosting() bool {
109
-	// for now registry binary is built only if we're running inside
110
-	// container through `make test`. Figure that out by testing if
111
-	// registry binary is in PATH.
112
-	_, err := exec.LookPath(v2binary)
113
-	return err == nil
114
-}
115
-
116 108
 func NotaryHosting() bool {
117 109
 	// for now notary binary is built only if we're running inside
118 110
 	// container through `make test`. Figure that out by testing if