mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add a registry package with registry v1/v2 code
This extract what was in registry_test.go and registry_mock_test.go. This also move `RegistryHosting` requirement to `registry.Hosting` Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
parent
5374d53322
commit
4300e5e881
13 changed files with 168 additions and 123 deletions
|
@ -16,6 +16,7 @@ import (
|
||||||
cliconfig "github.com/docker/docker/cli/config"
|
cliconfig "github.com/docker/docker/cli/config"
|
||||||
"github.com/docker/docker/integration-cli/daemon"
|
"github.com/docker/docker/integration-cli/daemon"
|
||||||
"github.com/docker/docker/integration-cli/environment"
|
"github.com/docker/docker/integration-cli/environment"
|
||||||
|
"github.com/docker/docker/integration-cli/registry"
|
||||||
"github.com/docker/docker/pkg/reexec"
|
"github.com/docker/docker/pkg/reexec"
|
||||||
"github.com/go-check/check"
|
"github.com/go-check/check"
|
||||||
)
|
)
|
||||||
|
@ -172,7 +173,7 @@ func init() {
|
||||||
|
|
||||||
type DockerRegistrySuite struct {
|
type DockerRegistrySuite struct {
|
||||||
ds *DockerSuite
|
ds *DockerSuite
|
||||||
reg *testRegistryV2
|
reg *registry.V2
|
||||||
d *daemon.Daemon
|
d *daemon.Daemon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +182,7 @@ func (s *DockerRegistrySuite) OnTimeout(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
|
func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
|
||||||
testRequires(c, DaemonIsLinux, RegistryHosting)
|
testRequires(c, DaemonIsLinux, registry.Hosting)
|
||||||
s.reg = setupRegistry(c, false, "", "")
|
s.reg = setupRegistry(c, false, "", "")
|
||||||
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||||
Experimental: experimentalDaemon,
|
Experimental: experimentalDaemon,
|
||||||
|
@ -206,7 +207,7 @@ func init() {
|
||||||
|
|
||||||
type DockerSchema1RegistrySuite struct {
|
type DockerSchema1RegistrySuite struct {
|
||||||
ds *DockerSuite
|
ds *DockerSuite
|
||||||
reg *testRegistryV2
|
reg *registry.V2
|
||||||
d *daemon.Daemon
|
d *daemon.Daemon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +216,7 @@ func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
|
func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
|
||||||
testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64)
|
testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64)
|
||||||
s.reg = setupRegistry(c, true, "", "")
|
s.reg = setupRegistry(c, true, "", "")
|
||||||
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||||
Experimental: experimentalDaemon,
|
Experimental: experimentalDaemon,
|
||||||
|
@ -240,7 +241,7 @@ func init() {
|
||||||
|
|
||||||
type DockerRegistryAuthHtpasswdSuite struct {
|
type DockerRegistryAuthHtpasswdSuite struct {
|
||||||
ds *DockerSuite
|
ds *DockerSuite
|
||||||
reg *testRegistryV2
|
reg *registry.V2
|
||||||
d *daemon.Daemon
|
d *daemon.Daemon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +250,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) OnTimeout(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) {
|
func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) {
|
||||||
testRequires(c, DaemonIsLinux, RegistryHosting)
|
testRequires(c, DaemonIsLinux, registry.Hosting)
|
||||||
s.reg = setupRegistry(c, false, "htpasswd", "")
|
s.reg = setupRegistry(c, false, "htpasswd", "")
|
||||||
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||||
Experimental: experimentalDaemon,
|
Experimental: experimentalDaemon,
|
||||||
|
@ -276,7 +277,7 @@ func init() {
|
||||||
|
|
||||||
type DockerRegistryAuthTokenSuite struct {
|
type DockerRegistryAuthTokenSuite struct {
|
||||||
ds *DockerSuite
|
ds *DockerSuite
|
||||||
reg *testRegistryV2
|
reg *registry.V2
|
||||||
d *daemon.Daemon
|
d *daemon.Daemon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +286,7 @@ func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) {
|
func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) {
|
||||||
testRequires(c, DaemonIsLinux, RegistryHosting)
|
testRequires(c, DaemonIsLinux, registry.Hosting)
|
||||||
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||||
Experimental: experimentalDaemon,
|
Experimental: experimentalDaemon,
|
||||||
})
|
})
|
||||||
|
@ -449,12 +450,12 @@ func init() {
|
||||||
|
|
||||||
type DockerTrustSuite struct {
|
type DockerTrustSuite struct {
|
||||||
ds *DockerSuite
|
ds *DockerSuite
|
||||||
reg *testRegistryV2
|
reg *registry.V2
|
||||||
not *testNotary
|
not *testNotary
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerTrustSuite) SetUpTest(c *check.C) {
|
func (s *DockerTrustSuite) SetUpTest(c *check.C) {
|
||||||
testRequires(c, RegistryHosting, NotaryServerHosting)
|
testRequires(c, registry.Hosting, NotaryServerHosting)
|
||||||
s.reg = setupRegistry(c, false, "", "")
|
s.reg = setupRegistry(c, false, "", "")
|
||||||
s.not = setupNotary(c)
|
s.not = setupNotary(c)
|
||||||
}
|
}
|
||||||
|
@ -487,7 +488,7 @@ func init() {
|
||||||
type DockerTrustedSwarmSuite struct {
|
type DockerTrustedSwarmSuite struct {
|
||||||
swarmSuite DockerSwarmSuite
|
swarmSuite DockerSwarmSuite
|
||||||
trustSuite DockerTrustSuite
|
trustSuite DockerTrustSuite
|
||||||
reg *testRegistryV2
|
reg *registry.V2
|
||||||
not *testNotary
|
not *testNotary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6580,7 +6580,7 @@ func (s *DockerSuite) TestBuildLabelOverwrite(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DockerRegistryAuthHtpasswdSuite) TestBuildFromAuthenticatedRegistry(c *check.C) {
|
func (s *DockerRegistryAuthHtpasswdSuite) TestBuildFromAuthenticatedRegistry(c *check.C) {
|
||||||
dockerCmd(c, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
|
dockerCmd(c, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
|
||||||
|
|
||||||
baseImage := privateRegistryURL + "/baseimage"
|
baseImage := privateRegistryURL + "/baseimage"
|
||||||
|
|
||||||
|
@ -6625,7 +6625,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestBuildWithExternalAuth(c *check.C)
|
||||||
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
|
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(configPath)
|
b, err := ioutil.ReadFile(configPath)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
|
@ -533,7 +533,7 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||||
|
|
||||||
// Load the target manifest blob.
|
// Load the target manifest blob.
|
||||||
manifestBlob := s.reg.readBlobContents(c, manifestDigest)
|
manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
|
||||||
|
|
||||||
var imgManifest schema2.Manifest
|
var imgManifest schema2.Manifest
|
||||||
err = json.Unmarshal(manifestBlob, &imgManifest)
|
err = json.Unmarshal(manifestBlob, &imgManifest)
|
||||||
|
@ -544,13 +544,13 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredManifest(c *check.C) {
|
||||||
|
|
||||||
// Move the existing data file aside, so that we can replace it with a
|
// Move the existing data file aside, so that we can replace it with a
|
||||||
// malicious blob of data. NOTE: we defer the returned undo func.
|
// malicious blob of data. NOTE: we defer the returned undo func.
|
||||||
undo := s.reg.tempMoveBlobData(c, manifestDigest)
|
undo := s.reg.TempMoveBlobData(c, manifestDigest)
|
||||||
defer undo()
|
defer undo()
|
||||||
|
|
||||||
alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", " ")
|
alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", " ")
|
||||||
c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
|
c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
|
||||||
|
|
||||||
s.reg.writeBlobContents(c, manifestDigest, alteredManifestBlob)
|
s.reg.WriteBlobContents(c, manifestDigest, alteredManifestBlob)
|
||||||
|
|
||||||
// Now try pulling that image by digest. We should get an error about
|
// Now try pulling that image by digest. We should get an error about
|
||||||
// digest verification for the manifest digest.
|
// digest verification for the manifest digest.
|
||||||
|
@ -573,7 +573,7 @@ func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *check.C
|
||||||
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
|
||||||
|
|
||||||
// Load the target manifest blob.
|
// Load the target manifest blob.
|
||||||
manifestBlob := s.reg.readBlobContents(c, manifestDigest)
|
manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
|
||||||
|
|
||||||
var imgManifest schema1.Manifest
|
var imgManifest schema1.Manifest
|
||||||
err = json.Unmarshal(manifestBlob, &imgManifest)
|
err = json.Unmarshal(manifestBlob, &imgManifest)
|
||||||
|
@ -586,13 +586,13 @@ func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredManifest(c *check.C
|
||||||
|
|
||||||
// Move the existing data file aside, so that we can replace it with a
|
// Move the existing data file aside, so that we can replace it with a
|
||||||
// malicious blob of data. NOTE: we defer the returned undo func.
|
// malicious blob of data. NOTE: we defer the returned undo func.
|
||||||
undo := s.reg.tempMoveBlobData(c, manifestDigest)
|
undo := s.reg.TempMoveBlobData(c, manifestDigest)
|
||||||
defer undo()
|
defer undo()
|
||||||
|
|
||||||
alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", " ")
|
alteredManifestBlob, err := json.MarshalIndent(imgManifest, "", " ")
|
||||||
c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
|
c.Assert(err, checker.IsNil, check.Commentf("unable to encode altered image manifest to JSON"))
|
||||||
|
|
||||||
s.reg.writeBlobContents(c, manifestDigest, alteredManifestBlob)
|
s.reg.WriteBlobContents(c, manifestDigest, alteredManifestBlob)
|
||||||
|
|
||||||
// Now try pulling that image by digest. We should get an error about
|
// Now try pulling that image by digest. We should get an error about
|
||||||
// digest verification for the manifest digest.
|
// digest verification for the manifest digest.
|
||||||
|
@ -615,7 +615,7 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
// Load the target manifest blob.
|
// Load the target manifest blob.
|
||||||
manifestBlob := s.reg.readBlobContents(c, manifestDigest)
|
manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
|
||||||
|
|
||||||
var imgManifest schema2.Manifest
|
var imgManifest schema2.Manifest
|
||||||
err = json.Unmarshal(manifestBlob, &imgManifest)
|
err = json.Unmarshal(manifestBlob, &imgManifest)
|
||||||
|
@ -626,11 +626,11 @@ func (s *DockerRegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
|
||||||
|
|
||||||
// Move the existing data file aside, so that we can replace it with a
|
// Move the existing data file aside, so that we can replace it with a
|
||||||
// malicious blob of data. NOTE: we defer the returned undo func.
|
// malicious blob of data. NOTE: we defer the returned undo func.
|
||||||
undo := s.reg.tempMoveBlobData(c, targetLayerDigest)
|
undo := s.reg.TempMoveBlobData(c, targetLayerDigest)
|
||||||
defer undo()
|
defer undo()
|
||||||
|
|
||||||
// Now make a fake data blob in this directory.
|
// Now make a fake data blob in this directory.
|
||||||
s.reg.writeBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
|
s.reg.WriteBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
|
||||||
|
|
||||||
// Now try pulling that image by digest. We should get an error about
|
// Now try pulling that image by digest. We should get an error about
|
||||||
// digest verification for the target layer digest.
|
// digest verification for the target layer digest.
|
||||||
|
@ -658,7 +658,7 @@ func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
// Load the target manifest blob.
|
// Load the target manifest blob.
|
||||||
manifestBlob := s.reg.readBlobContents(c, manifestDigest)
|
manifestBlob := s.reg.ReadBlobContents(c, manifestDigest)
|
||||||
|
|
||||||
var imgManifest schema1.Manifest
|
var imgManifest schema1.Manifest
|
||||||
err = json.Unmarshal(manifestBlob, &imgManifest)
|
err = json.Unmarshal(manifestBlob, &imgManifest)
|
||||||
|
@ -669,11 +669,11 @@ func (s *DockerSchema1RegistrySuite) TestPullFailsWithAlteredLayer(c *check.C) {
|
||||||
|
|
||||||
// Move the existing data file aside, so that we can replace it with a
|
// Move the existing data file aside, so that we can replace it with a
|
||||||
// malicious blob of data. NOTE: we defer the returned undo func.
|
// malicious blob of data. NOTE: we defer the returned undo func.
|
||||||
undo := s.reg.tempMoveBlobData(c, targetLayerDigest)
|
undo := s.reg.TempMoveBlobData(c, targetLayerDigest)
|
||||||
defer undo()
|
defer undo()
|
||||||
|
|
||||||
// Now make a fake data blob in this directory.
|
// Now make a fake data blob in this directory.
|
||||||
s.reg.writeBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
|
s.reg.WriteBlobContents(c, targetLayerDigest, []byte("This is not the data you are looking for."))
|
||||||
|
|
||||||
// Now try pulling that image by digest. We should get an error about
|
// Now try pulling that image by digest. We should get an error about
|
||||||
// digest verification for the target layer digest.
|
// digest verification for the target layer digest.
|
||||||
|
|
|
@ -21,10 +21,10 @@ func (s *DockerSuite) TestLoginWithoutTTY(c *check.C) {
|
||||||
|
|
||||||
func (s *DockerRegistryAuthHtpasswdSuite) TestLoginToPrivateRegistry(c *check.C) {
|
func (s *DockerRegistryAuthHtpasswdSuite) TestLoginToPrivateRegistry(c *check.C) {
|
||||||
// wrong credentials
|
// wrong credentials
|
||||||
out, _, err := dockerCmdWithError("login", "-u", s.reg.username, "-p", "WRONGPASSWORD", privateRegistryURL)
|
out, _, err := dockerCmdWithError("login", "-u", s.reg.Username(), "-p", "WRONGPASSWORD", privateRegistryURL)
|
||||||
c.Assert(err, checker.NotNil, check.Commentf(out))
|
c.Assert(err, checker.NotNil, check.Commentf(out))
|
||||||
c.Assert(out, checker.Contains, "401 Unauthorized")
|
c.Assert(out, checker.Contains, "401 Unauthorized")
|
||||||
|
|
||||||
// now it's fine
|
// now it's fine
|
||||||
dockerCmd(c, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
|
dockerCmd(c, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithExternalAuth(c *check.C)
|
||||||
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
|
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(configPath)
|
b, err := ioutil.ReadFile(configPath)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
@ -71,7 +71,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithWrongHostnamesStored(c *
|
||||||
os.Setenv("PATH", testPath)
|
os.Setenv("PATH", testPath)
|
||||||
|
|
||||||
cmd := exec.Command("docker-credential-shell-test", "store")
|
cmd := exec.Command("docker-credential-shell-test", "store")
|
||||||
stdin := bytes.NewReader([]byte(fmt.Sprintf(`{"ServerURL": "https://%s", "Username": "%s", "Secret": "%s"}`, privateRegistryURL, s.reg.username, s.reg.password)))
|
stdin := bytes.NewReader([]byte(fmt.Sprintf(`{"ServerURL": "https://%s", "Username": "%s", "Secret": "%s"}`, privateRegistryURL, s.reg.Username(), s.reg.Password())))
|
||||||
cmd.Stdin = stdin
|
cmd.Stdin = stdin
|
||||||
c.Assert(cmd.Run(), checker.IsNil)
|
c.Assert(cmd.Run(), checker.IsNil)
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestLogoutWithWrongHostnamesStored(c *
|
||||||
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
|
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(configPath)
|
b, err := ioutil.ReadFile(configPath)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
|
@ -347,7 +347,7 @@ func (s *DockerRegistrySuite) TestPullManifestList(c *check.C) {
|
||||||
manifestListDigest := digest.FromBytes(manifestListJSON)
|
manifestListDigest := digest.FromBytes(manifestListJSON)
|
||||||
hexDigest := manifestListDigest.Hex()
|
hexDigest := manifestListDigest.Hex()
|
||||||
|
|
||||||
registryV2Path := filepath.Join(s.reg.dir, "docker", "registry", "v2")
|
registryV2Path := s.reg.Path()
|
||||||
|
|
||||||
// Write manifest list to blob store
|
// Write manifest list to blob store
|
||||||
blobDir := filepath.Join(registryV2Path, "blobs", "sha256", hexDigest[:2], hexDigest)
|
blobDir := filepath.Join(registryV2Path, "blobs", "sha256", hexDigest[:2], hexDigest)
|
||||||
|
@ -411,7 +411,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullWithExternalAuthLoginWithSchem
|
||||||
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
|
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(configPath)
|
b, err := ioutil.ReadFile(configPath)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
@ -421,7 +421,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullWithExternalAuthLoginWithSchem
|
||||||
dockerCmd(c, "--config", tmp, "push", repoName)
|
dockerCmd(c, "--config", tmp, "push", repoName)
|
||||||
|
|
||||||
dockerCmd(c, "--config", tmp, "logout", privateRegistryURL)
|
dockerCmd(c, "--config", tmp, "logout", privateRegistryURL)
|
||||||
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, "https://"+privateRegistryURL)
|
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), "https://"+privateRegistryURL)
|
||||||
dockerCmd(c, "--config", tmp, "pull", repoName)
|
dockerCmd(c, "--config", tmp, "pull", repoName)
|
||||||
|
|
||||||
// likewise push should work
|
// likewise push should work
|
||||||
|
@ -456,7 +456,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) TestPullWithExternalAuth(c *check.C) {
|
||||||
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
err = ioutil.WriteFile(configPath, []byte(externalAuthConfig), 0644)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.username, "-p", s.reg.password, privateRegistryURL)
|
dockerCmd(c, "--config", tmp, "login", "-u", s.reg.Username(), "-p", s.reg.Password(), privateRegistryURL)
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(configPath)
|
b, err := ioutil.ReadFile(configPath)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/docker/docker/integration-cli/registry"
|
||||||
"github.com/go-check/check"
|
"github.com/go-check/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,8 +47,8 @@ func regexpCheckUA(c *check.C, ua string) {
|
||||||
c.Assert(bMatchUpstreamUA, check.Equals, true, check.Commentf("(Upstream) Docker Client User-Agent malformed"))
|
c.Assert(bMatchUpstreamUA, check.Equals, true, check.Commentf("(Upstream) Docker Client User-Agent malformed"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerUserAgentHandler(reg *testRegistry, result *string) {
|
func registerUserAgentHandler(reg *registry.Mock, result *string) {
|
||||||
reg.registerHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
|
reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(404)
|
w.WriteHeader(404)
|
||||||
var ua string
|
var ua string
|
||||||
for k, v := range r.Header {
|
for k, v := range r.Header {
|
||||||
|
@ -70,30 +71,30 @@ func (s *DockerRegistrySuite) TestUserAgentPassThrough(c *check.C) {
|
||||||
loginUA string
|
loginUA string
|
||||||
)
|
)
|
||||||
|
|
||||||
buildReg, err := newTestRegistry(c)
|
buildReg, err := registry.NewMock(c)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
registerUserAgentHandler(buildReg, &buildUA)
|
registerUserAgentHandler(buildReg, &buildUA)
|
||||||
buildRepoName := fmt.Sprintf("%s/busybox", buildReg.hostport)
|
buildRepoName := fmt.Sprintf("%s/busybox", buildReg.URL())
|
||||||
|
|
||||||
pullReg, err := newTestRegistry(c)
|
pullReg, err := registry.NewMock(c)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
registerUserAgentHandler(pullReg, &pullUA)
|
registerUserAgentHandler(pullReg, &pullUA)
|
||||||
pullRepoName := fmt.Sprintf("%s/busybox", pullReg.hostport)
|
pullRepoName := fmt.Sprintf("%s/busybox", pullReg.URL())
|
||||||
|
|
||||||
pushReg, err := newTestRegistry(c)
|
pushReg, err := registry.NewMock(c)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
registerUserAgentHandler(pushReg, &pushUA)
|
registerUserAgentHandler(pushReg, &pushUA)
|
||||||
pushRepoName := fmt.Sprintf("%s/busybox", pushReg.hostport)
|
pushRepoName := fmt.Sprintf("%s/busybox", pushReg.URL())
|
||||||
|
|
||||||
loginReg, err := newTestRegistry(c)
|
loginReg, err := registry.NewMock(c)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
registerUserAgentHandler(loginReg, &loginUA)
|
registerUserAgentHandler(loginReg, &loginUA)
|
||||||
|
|
||||||
s.d.Start(c,
|
s.d.Start(c,
|
||||||
"--insecure-registry", buildReg.hostport,
|
"--insecure-registry", buildReg.URL(),
|
||||||
"--insecure-registry", pullReg.hostport,
|
"--insecure-registry", pullReg.URL(),
|
||||||
"--insecure-registry", pushReg.hostport,
|
"--insecure-registry", pushReg.URL(),
|
||||||
"--insecure-registry", loginReg.hostport,
|
"--insecure-registry", loginReg.URL(),
|
||||||
"--disable-legacy-registry=true")
|
"--disable-legacy-registry=true")
|
||||||
|
|
||||||
dockerfileName, cleanup1, err := makefile(fmt.Sprintf("FROM %s", buildRepoName))
|
dockerfileName, cleanup1, err := makefile(fmt.Sprintf("FROM %s", buildRepoName))
|
||||||
|
@ -102,7 +103,7 @@ func (s *DockerRegistrySuite) TestUserAgentPassThrough(c *check.C) {
|
||||||
s.d.Cmd("build", "--file", dockerfileName, ".")
|
s.d.Cmd("build", "--file", dockerfileName, ".")
|
||||||
regexpCheckUA(c, buildUA)
|
regexpCheckUA(c, buildUA)
|
||||||
|
|
||||||
s.d.Cmd("login", "-u", "richard", "-p", "testtest", loginReg.hostport)
|
s.d.Cmd("login", "-u", "richard", "-p", "testtest", loginReg.URL())
|
||||||
regexpCheckUA(c, loginUA)
|
regexpCheckUA(c, loginUA)
|
||||||
|
|
||||||
s.d.Cmd("pull", pullRepoName)
|
s.d.Cmd("pull", pullRepoName)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/docker/docker/integration-cli/registry"
|
||||||
"github.com/go-check/check"
|
"github.com/go-check/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,29 +37,29 @@ func makefile(contents string) (string, func(), error) {
|
||||||
// TestV2Only ensures that a daemon in v2-only mode does not
|
// TestV2Only ensures that a daemon in v2-only mode does not
|
||||||
// attempt to contact any v1 registry endpoints.
|
// attempt to contact any v1 registry endpoints.
|
||||||
func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
|
func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
|
||||||
reg, err := newTestRegistry(c)
|
reg, err := registry.NewMock(c)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
reg.registerHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
|
reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(404)
|
w.WriteHeader(404)
|
||||||
})
|
})
|
||||||
|
|
||||||
reg.registerHandler("/v1/.*", func(w http.ResponseWriter, r *http.Request) {
|
reg.RegisterHandler("/v1/.*", func(w http.ResponseWriter, r *http.Request) {
|
||||||
c.Fatal("V1 registry contacted")
|
c.Fatal("V1 registry contacted")
|
||||||
})
|
})
|
||||||
|
|
||||||
repoName := fmt.Sprintf("%s/busybox", reg.hostport)
|
repoName := fmt.Sprintf("%s/busybox", reg.URL())
|
||||||
|
|
||||||
s.d.Start(c, "--insecure-registry", reg.hostport, "--disable-legacy-registry=true")
|
s.d.Start(c, "--insecure-registry", reg.URL(), "--disable-legacy-registry=true")
|
||||||
|
|
||||||
dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.hostport))
|
dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.URL()))
|
||||||
c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
|
c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
s.d.Cmd("build", "--file", dockerfileName, ".")
|
s.d.Cmd("build", "--file", dockerfileName, ".")
|
||||||
|
|
||||||
s.d.Cmd("run", repoName)
|
s.d.Cmd("run", repoName)
|
||||||
s.d.Cmd("login", "-u", "richard", "-p", "testtest", "-e", "testuser@testdomain.com", reg.hostport)
|
s.d.Cmd("login", "-u", "richard", "-p", "testtest", "-e", "testuser@testdomain.com", reg.URL())
|
||||||
s.d.Cmd("tag", "busybox", repoName)
|
s.d.Cmd("tag", "busybox", repoName)
|
||||||
s.d.Cmd("push", repoName)
|
s.d.Cmd("push", repoName)
|
||||||
s.d.Cmd("pull", repoName)
|
s.d.Cmd("pull", repoName)
|
||||||
|
@ -68,49 +69,49 @@ func (s *DockerRegistrySuite) TestV2Only(c *check.C) {
|
||||||
// and ensure v1 endpoints are hit for the following operations:
|
// and ensure v1 endpoints are hit for the following operations:
|
||||||
// login, push, pull, build & run
|
// login, push, pull, build & run
|
||||||
func (s *DockerRegistrySuite) TestV1(c *check.C) {
|
func (s *DockerRegistrySuite) TestV1(c *check.C) {
|
||||||
reg, err := newTestRegistry(c)
|
reg, err := registry.NewMock(c)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
v2Pings := 0
|
v2Pings := 0
|
||||||
reg.registerHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
|
reg.RegisterHandler("/v2/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
v2Pings++
|
v2Pings++
|
||||||
// V2 ping 404 causes fallback to v1
|
// V2 ping 404 causes fallback to v1
|
||||||
w.WriteHeader(404)
|
w.WriteHeader(404)
|
||||||
})
|
})
|
||||||
|
|
||||||
v1Pings := 0
|
v1Pings := 0
|
||||||
reg.registerHandler("/v1/_ping", func(w http.ResponseWriter, r *http.Request) {
|
reg.RegisterHandler("/v1/_ping", func(w http.ResponseWriter, r *http.Request) {
|
||||||
v1Pings++
|
v1Pings++
|
||||||
})
|
})
|
||||||
|
|
||||||
v1Logins := 0
|
v1Logins := 0
|
||||||
reg.registerHandler("/v1/users/", func(w http.ResponseWriter, r *http.Request) {
|
reg.RegisterHandler("/v1/users/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
v1Logins++
|
v1Logins++
|
||||||
})
|
})
|
||||||
|
|
||||||
v1Repo := 0
|
v1Repo := 0
|
||||||
reg.registerHandler("/v1/repositories/busybox/", func(w http.ResponseWriter, r *http.Request) {
|
reg.RegisterHandler("/v1/repositories/busybox/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
v1Repo++
|
v1Repo++
|
||||||
})
|
})
|
||||||
|
|
||||||
reg.registerHandler("/v1/repositories/busybox/images", func(w http.ResponseWriter, r *http.Request) {
|
reg.RegisterHandler("/v1/repositories/busybox/images", func(w http.ResponseWriter, r *http.Request) {
|
||||||
v1Repo++
|
v1Repo++
|
||||||
})
|
})
|
||||||
|
|
||||||
s.d.Start(c, "--insecure-registry", reg.hostport, "--disable-legacy-registry=false")
|
s.d.Start(c, "--insecure-registry", reg.URL(), "--disable-legacy-registry=false")
|
||||||
|
|
||||||
dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.hostport))
|
dockerfileName, cleanup, err := makefile(fmt.Sprintf("FROM %s/busybox", reg.URL()))
|
||||||
c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
|
c.Assert(err, check.IsNil, check.Commentf("Unable to create test dockerfile"))
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
s.d.Cmd("build", "--file", dockerfileName, ".")
|
s.d.Cmd("build", "--file", dockerfileName, ".")
|
||||||
c.Assert(v1Repo, check.Equals, 1, check.Commentf("Expected v1 repository access after build"))
|
c.Assert(v1Repo, check.Equals, 1, check.Commentf("Expected v1 repository access after build"))
|
||||||
|
|
||||||
repoName := fmt.Sprintf("%s/busybox", reg.hostport)
|
repoName := fmt.Sprintf("%s/busybox", reg.URL())
|
||||||
s.d.Cmd("run", repoName)
|
s.d.Cmd("run", repoName)
|
||||||
c.Assert(v1Repo, check.Equals, 2, check.Commentf("Expected v1 repository access after run"))
|
c.Assert(v1Repo, check.Equals, 2, check.Commentf("Expected v1 repository access after run"))
|
||||||
|
|
||||||
s.d.Cmd("login", "-u", "richard", "-p", "testtest", reg.hostport)
|
s.d.Cmd("login", "-u", "richard", "-p", "testtest", reg.URL())
|
||||||
c.Assert(v1Logins, check.Equals, 1, check.Commentf("Expected v1 login attempt"))
|
c.Assert(v1Logins, check.Equals, 1, check.Commentf("Expected v1 login attempt"))
|
||||||
|
|
||||||
s.d.Cmd("tag", "busybox", repoName)
|
s.d.Cmd("tag", "busybox", repoName)
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
volumetypes "github.com/docker/docker/api/types/volume"
|
volumetypes "github.com/docker/docker/api/types/volume"
|
||||||
"github.com/docker/docker/integration-cli/daemon"
|
"github.com/docker/docker/integration-cli/daemon"
|
||||||
|
"github.com/docker/docker/integration-cli/registry"
|
||||||
"github.com/docker/docker/opts"
|
"github.com/docker/docker/opts"
|
||||||
"github.com/docker/docker/pkg/integration"
|
"github.com/docker/docker/pkg/integration"
|
||||||
"github.com/docker/docker/pkg/integration/checker"
|
"github.com/docker/docker/pkg/integration/checker"
|
||||||
|
@ -1083,8 +1084,8 @@ func parseEventTime(t time.Time) string {
|
||||||
return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond()))
|
return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupRegistry(c *check.C, schema1 bool, auth, tokenURL string) *testRegistryV2 {
|
func setupRegistry(c *check.C, schema1 bool, auth, tokenURL string) *registry.V2 {
|
||||||
reg, err := newTestRegistryV2(c, schema1, auth, tokenURL)
|
reg, err := registry.NewV2(schema1, auth, tokenURL, privateRegistryURL)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
// Wait for registry to be ready to serve requests.
|
// Wait for registry to be ready to serve requests.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -9,7 +9,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/docker/distribution/digest"
|
"github.com/docker/distribution/digest"
|
||||||
"github.com/go-check/check"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -17,8 +16,20 @@ const (
|
||||||
v2binarySchema1 = "registry-v2-schema1"
|
v2binarySchema1 = "registry-v2-schema1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type testRegistryV2 struct {
|
type testingT interface {
|
||||||
|
logT
|
||||||
|
Fatal(...interface{})
|
||||||
|
Fatalf(string, ...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type logT interface {
|
||||||
|
Logf(string, ...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// V2 represent a registry version 2
|
||||||
|
type V2 struct {
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
|
registryURL string
|
||||||
dir string
|
dir string
|
||||||
auth string
|
auth string
|
||||||
username string
|
username string
|
||||||
|
@ -26,7 +37,8 @@ type testRegistryV2 struct {
|
||||||
email string
|
email string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestRegistryV2(c *check.C, schema1 bool, auth, tokenURL string) (*testRegistryV2, error) {
|
// NewV2 creates a v2 registry server
|
||||||
|
func NewV2(schema1 bool, auth, tokenURL, registryURL string) (*V2, error) {
|
||||||
tmp, err := ioutil.TempDir("", "registry-test-")
|
tmp, err := ioutil.TempDir("", "registry-test-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -78,7 +90,7 @@ http:
|
||||||
}
|
}
|
||||||
defer config.Close()
|
defer config.Close()
|
||||||
|
|
||||||
if _, err := fmt.Fprintf(config, template, tmp, privateRegistryURL, authTemplate); err != nil {
|
if _, err := fmt.Fprintf(config, template, tmp, registryURL, authTemplate); err != nil {
|
||||||
os.RemoveAll(tmp)
|
os.RemoveAll(tmp)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -90,31 +102,30 @@ http:
|
||||||
cmd := exec.Command(binary, confPath)
|
cmd := exec.Command(binary, confPath)
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
os.RemoveAll(tmp)
|
os.RemoveAll(tmp)
|
||||||
if os.IsNotExist(err) {
|
|
||||||
c.Skip(err.Error())
|
|
||||||
}
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &testRegistryV2{
|
return &V2{
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
dir: tmp,
|
dir: tmp,
|
||||||
auth: auth,
|
auth: auth,
|
||||||
username: username,
|
username: username,
|
||||||
password: password,
|
password: password,
|
||||||
email: email,
|
email: email,
|
||||||
|
registryURL: registryURL,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testRegistryV2) Ping() error {
|
// Ping sends an http request to the current registry, and fail if it doesn't respond correctly
|
||||||
|
func (r *V2) Ping() error {
|
||||||
// We always ping through HTTP for our test registry.
|
// We always ping through HTTP for our test registry.
|
||||||
resp, err := http.Get(fmt.Sprintf("http://%s/v2/", privateRegistryURL))
|
resp, err := http.Get(fmt.Sprintf("http://%s/v2/", r.registryURL))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
|
|
||||||
fail := resp.StatusCode != http.StatusOK
|
fail := resp.StatusCode != http.StatusOK
|
||||||
if t.auth != "" {
|
if r.auth != "" {
|
||||||
// unauthorized is a _good_ status when pinging v2/ and it needs auth
|
// unauthorized is a _good_ status when pinging v2/ and it needs auth
|
||||||
fail = fail && resp.StatusCode != http.StatusUnauthorized
|
fail = fail && resp.StatusCode != http.StatusUnauthorized
|
||||||
}
|
}
|
||||||
|
@ -124,50 +135,55 @@ func (t *testRegistryV2) Ping() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testRegistryV2) Close() {
|
// Close kills the registry server
|
||||||
t.cmd.Process.Kill()
|
func (r *V2) Close() {
|
||||||
os.RemoveAll(t.dir)
|
r.cmd.Process.Kill()
|
||||||
|
os.RemoveAll(r.dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testRegistryV2) getBlobFilename(blobDigest digest.Digest) string {
|
func (r *V2) getBlobFilename(blobDigest digest.Digest) string {
|
||||||
// Split the digest into its algorithm and hex components.
|
// Split the digest into its algorithm and hex components.
|
||||||
dgstAlg, dgstHex := blobDigest.Algorithm(), blobDigest.Hex()
|
dgstAlg, dgstHex := blobDigest.Algorithm(), blobDigest.Hex()
|
||||||
|
|
||||||
// The path to the target blob data looks something like:
|
// The path to the target blob data looks something like:
|
||||||
// baseDir + "docker/registry/v2/blobs/sha256/a3/a3ed...46d4/data"
|
// baseDir + "docker/registry/v2/blobs/sha256/a3/a3ed...46d4/data"
|
||||||
return fmt.Sprintf("%s/docker/registry/v2/blobs/%s/%s/%s/data", t.dir, dgstAlg, dgstHex[:2], dgstHex)
|
return fmt.Sprintf("%s/docker/registry/v2/blobs/%s/%s/%s/data", r.dir, dgstAlg, dgstHex[:2], dgstHex)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testRegistryV2) readBlobContents(c *check.C, blobDigest digest.Digest) []byte {
|
// ReadBlobContents read the file corresponding to the specified digest
|
||||||
|
func (r *V2) ReadBlobContents(t testingT, blobDigest digest.Digest) []byte {
|
||||||
// Load the target manifest blob.
|
// Load the target manifest blob.
|
||||||
manifestBlob, err := ioutil.ReadFile(t.getBlobFilename(blobDigest))
|
manifestBlob, err := ioutil.ReadFile(r.getBlobFilename(blobDigest))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fatalf("unable to read blob: %s", err)
|
t.Fatalf("unable to read blob: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return manifestBlob
|
return manifestBlob
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testRegistryV2) writeBlobContents(c *check.C, blobDigest digest.Digest, data []byte) {
|
// WriteBlobContents write the file corresponding to the specified digest with the given content
|
||||||
if err := ioutil.WriteFile(t.getBlobFilename(blobDigest), data, os.FileMode(0644)); err != nil {
|
func (r *V2) WriteBlobContents(t testingT, blobDigest digest.Digest, data []byte) {
|
||||||
c.Fatalf("unable to write malicious data blob: %s", err)
|
if err := ioutil.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644)); err != nil {
|
||||||
|
t.Fatalf("unable to write malicious data blob: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testRegistryV2) tempMoveBlobData(c *check.C, blobDigest digest.Digest) (undo func()) {
|
// TempMoveBlobData moves the existing data file aside, so that we can replace it with a
|
||||||
|
// malicious blob of data for example.
|
||||||
|
func (r *V2) TempMoveBlobData(t testingT, blobDigest digest.Digest) (undo func()) {
|
||||||
tempFile, err := ioutil.TempFile("", "registry-temp-blob-")
|
tempFile, err := ioutil.TempFile("", "registry-temp-blob-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fatalf("unable to get temporary blob file: %s", err)
|
t.Fatalf("unable to get temporary blob file: %s", err)
|
||||||
}
|
}
|
||||||
tempFile.Close()
|
tempFile.Close()
|
||||||
|
|
||||||
blobFilename := t.getBlobFilename(blobDigest)
|
blobFilename := r.getBlobFilename(blobDigest)
|
||||||
|
|
||||||
// Move the existing data file aside, so that we can replace it with a
|
// Move the existing data file aside, so that we can replace it with a
|
||||||
// another blob of data.
|
// another blob of data.
|
||||||
if err := os.Rename(blobFilename, tempFile.Name()); err != nil {
|
if err := os.Rename(blobFilename, tempFile.Name()); err != nil {
|
||||||
os.Remove(tempFile.Name())
|
os.Remove(tempFile.Name())
|
||||||
c.Fatalf("unable to move data blob: %s", err)
|
t.Fatalf("unable to move data blob: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return func() {
|
return func() {
|
||||||
|
@ -175,3 +191,18 @@ func (t *testRegistryV2) tempMoveBlobData(c *check.C, blobDigest digest.Digest)
|
||||||
os.Remove(tempFile.Name())
|
os.Remove(tempFile.Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Username returns the configured user name of the server
|
||||||
|
func (r *V2) Username() string {
|
||||||
|
return r.username
|
||||||
|
}
|
||||||
|
|
||||||
|
// Password returns the configured password of the server
|
||||||
|
func (r *V2) Password() string {
|
||||||
|
return r.password
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path returns the path where the registry write data
|
||||||
|
func (r *V2) Path() string {
|
||||||
|
return filepath.Join(r.dir, "docker", "registry", "v2")
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package registry
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -6,27 +6,28 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/go-check/check"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type handlerFunc func(w http.ResponseWriter, r *http.Request)
|
type handlerFunc func(w http.ResponseWriter, r *http.Request)
|
||||||
|
|
||||||
type testRegistry struct {
|
// Mock represent a registry mock
|
||||||
|
type Mock struct {
|
||||||
server *httptest.Server
|
server *httptest.Server
|
||||||
hostport string
|
hostport string
|
||||||
handlers map[string]handlerFunc
|
handlers map[string]handlerFunc
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr *testRegistry) registerHandler(path string, h handlerFunc) {
|
// RegisterHandler register the specified handler for the registry mock
|
||||||
|
func (tr *Mock) RegisterHandler(path string, h handlerFunc) {
|
||||||
tr.mu.Lock()
|
tr.mu.Lock()
|
||||||
defer tr.mu.Unlock()
|
defer tr.mu.Unlock()
|
||||||
tr.handlers[path] = h
|
tr.handlers[path] = h
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestRegistry(c *check.C) (*testRegistry, error) {
|
// NewMock creates a registry mock
|
||||||
testReg := &testRegistry{handlers: make(map[string]handlerFunc)}
|
func NewMock(t testingT) (*Mock, error) {
|
||||||
|
testReg := &Mock{handlers: make(map[string]handlerFunc)}
|
||||||
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
url := r.URL.String()
|
url := r.URL.String()
|
||||||
|
@ -36,7 +37,7 @@ func newTestRegistry(c *check.C) (*testRegistry, error) {
|
||||||
for re, function := range testReg.handlers {
|
for re, function := range testReg.handlers {
|
||||||
matched, err = regexp.MatchString(re, url)
|
matched, err = regexp.MatchString(re, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fatal("Error with handler regexp")
|
t.Fatal("Error with handler regexp")
|
||||||
}
|
}
|
||||||
if matched {
|
if matched {
|
||||||
function(w, r)
|
function(w, r)
|
||||||
|
@ -45,7 +46,7 @@ func newTestRegistry(c *check.C) (*testRegistry, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !matched {
|
if !matched {
|
||||||
c.Fatalf("Unable to match %s with regexp", url)
|
t.Fatalf("Unable to match %s with regexp", url)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -53,3 +54,8 @@ func newTestRegistry(c *check.C) (*testRegistry, error) {
|
||||||
testReg.hostport = strings.Replace(ts.URL, "http://", "", 1)
|
testReg.hostport = strings.Replace(ts.URL, "http://", "", 1)
|
||||||
return testReg, nil
|
return testReg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// URL returns the url of the registry
|
||||||
|
func (tr *Mock) URL() string {
|
||||||
|
return tr.hostport
|
||||||
|
}
|
12
integration-cli/registry/requirement.go
Normal file
12
integration-cli/registry/requirement.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package registry
|
||||||
|
|
||||||
|
import "os/exec"
|
||||||
|
|
||||||
|
// Hosting returns wether the host can host a registry (v2) or not
|
||||||
|
func Hosting() bool {
|
||||||
|
// for now registry binary is built only if we're running inside
|
||||||
|
// container through `make test`. Figure that out by testing if
|
||||||
|
// registry binary is in PATH.
|
||||||
|
_, err := exec.LookPath(v2binary)
|
||||||
|
return err == nil
|
||||||
|
}
|
|
@ -105,14 +105,6 @@ func Apparmor() bool {
|
||||||
return err == nil && len(buf) > 1 && buf[0] == 'Y'
|
return err == nil && len(buf) > 1 && buf[0] == 'Y'
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegistryHosting() bool {
|
|
||||||
// for now registry binary is built only if we're running inside
|
|
||||||
// container through `make test`. Figure that out by testing if
|
|
||||||
// registry binary is in PATH.
|
|
||||||
_, err := exec.LookPath(v2binary)
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NotaryHosting() bool {
|
func NotaryHosting() bool {
|
||||||
// for now notary binary is built only if we're running inside
|
// for now notary binary is built only if we're running inside
|
||||||
// container through `make test`. Figure that out by testing if
|
// container through `make test`. Figure that out by testing if
|
||||||
|
|
Loading…
Add table
Reference in a new issue