mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Pull, Pull-A, and Build will only pull tags from the targets role or the targets/releases role.
It will ignore tags in all other delegation roles. Signed-off-by: cyli <cyli@twistedmatrix.com>
This commit is contained in:
parent
ca57f4e6a8
commit
623ccc2f31
5 changed files with 259 additions and 85 deletions
|
@ -259,6 +259,11 @@ func (cli *DockerCli) trustedReference(ref reference.NamedTagged) (reference.Can
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Only list tags in the top level targets role or the releases delegation role - ignore
|
||||
// all other delegation roles
|
||||
if t.Role != releasesRole && t.Role != data.CanonicalTargetsRole {
|
||||
return nil, notaryError(repoInfo.FullName(), fmt.Errorf("No trust data for %s", ref.Tag()))
|
||||
}
|
||||
r, err := convertTarget(t.Target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -332,13 +337,27 @@ func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registr
|
|||
fmt.Fprintf(cli.out, "Skipping target for %q\n", repoInfo.Name())
|
||||
continue
|
||||
}
|
||||
// Only list tags in the top level targets role or the releases delegation role - ignore
|
||||
// all other delegation roles
|
||||
if tgt.Role != releasesRole && tgt.Role != data.CanonicalTargetsRole {
|
||||
continue
|
||||
}
|
||||
refs = append(refs, t)
|
||||
}
|
||||
if len(refs) == 0 {
|
||||
return notaryError(repoInfo.FullName(), fmt.Errorf("No trusted tags for %s", repoInfo.FullName()))
|
||||
}
|
||||
} else {
|
||||
t, err := notaryRepo.GetTargetByName(ref.String(), releasesRole, data.CanonicalTargetsRole)
|
||||
if err != nil {
|
||||
return notaryError(repoInfo.FullName(), err)
|
||||
}
|
||||
// Only get the tag if it's in the top level targets role or the releases delegation role
|
||||
// ignore it if it's in any other delegation roles
|
||||
if t.Role != releasesRole && t.Role != data.CanonicalTargetsRole {
|
||||
return notaryError(repoInfo.FullName(), fmt.Errorf("No trust data for %s", ref.String()))
|
||||
}
|
||||
|
||||
logrus.Debugf("retrieving target for %s role\n", t.Role)
|
||||
r, err := convertTarget(t.Target)
|
||||
if err != nil {
|
||||
|
@ -496,9 +515,9 @@ func (cli *DockerCli) addTargetToAllSignableRoles(repo *client.NotaryRepository,
|
|||
var signableRoles []string
|
||||
|
||||
// translate the full key names, which includes the GUN, into just the key IDs
|
||||
allCanonicalKeyIDs := make(map[string]string)
|
||||
allCanonicalKeyIDs := make(map[string]struct{})
|
||||
for fullKeyID := range repo.CryptoService.ListAllKeys() {
|
||||
allCanonicalKeyIDs[path.Base(fullKeyID)] = ""
|
||||
allCanonicalKeyIDs[path.Base(fullKeyID)] = struct{}{}
|
||||
}
|
||||
|
||||
allDelegationRoles, err := repo.GetDelegationRoles()
|
||||
|
@ -506,6 +525,13 @@ func (cli *DockerCli) addTargetToAllSignableRoles(repo *client.NotaryRepository,
|
|||
return err
|
||||
}
|
||||
|
||||
// if there are no delegation roles, then just try to sign it into the targets role
|
||||
if len(allDelegationRoles) == 0 {
|
||||
return repo.AddTarget(target, data.CanonicalTargetsRole)
|
||||
}
|
||||
|
||||
// there are delegation roles, find every delegation role we have a key for, and
|
||||
// attempt to sign into into all those roles.
|
||||
for _, delegationRole := range allDelegationRoles {
|
||||
// We do not support signing any delegation role that isn't a direct child of the targets role.
|
||||
// Also don't bother checking the keys if we can't add the target
|
||||
|
@ -517,11 +543,12 @@ func (cli *DockerCli) addTargetToAllSignableRoles(repo *client.NotaryRepository,
|
|||
for _, canonicalKeyID := range delegationRole.KeyIDs {
|
||||
if _, ok := allCanonicalKeyIDs[canonicalKeyID]; ok {
|
||||
signableRoles = append(signableRoles, delegationRole.Name)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(allDelegationRoles) > 0 && len(signableRoles) == 0 {
|
||||
if len(signableRoles) == 0 {
|
||||
return fmt.Errorf("no valid signing keys for delegation roles")
|
||||
}
|
||||
|
||||
|
|
|
@ -5799,6 +5799,83 @@ func (s *DockerTrustSuite) TestBuildContextDirIsSymlink(c *check.C) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedBuildTagFromReleasesRole(c *check.C) {
|
||||
testRequires(c, NotaryHosting)
|
||||
|
||||
latestTag := s.setupTrustedImage(c, "trusted-build-releases-role")
|
||||
repoName := strings.TrimSuffix(latestTag, ":latest")
|
||||
|
||||
// Now create the releases role
|
||||
s.notaryCreateDelegation(c, repoName, "targets/releases", s.not.keys[0].Public)
|
||||
s.notaryImportKey(c, repoName, "targets/releases", s.not.keys[0].Private)
|
||||
s.notaryPublish(c, repoName)
|
||||
|
||||
// push a different tag to the releases role
|
||||
otherTag := fmt.Sprintf("%s:other", repoName)
|
||||
dockerCmd(c, "tag", "busybox", otherTag)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", otherTag)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Trusted push failed: %s", out))
|
||||
s.assertTargetInRoles(c, repoName, "other", "targets/releases")
|
||||
s.assertTargetNotInRoles(c, repoName, "other", "targets")
|
||||
|
||||
out, status := dockerCmd(c, "rmi", otherTag)
|
||||
c.Assert(status, check.Equals, 0, check.Commentf("docker rmi failed: %s", out))
|
||||
|
||||
dockerFile := fmt.Sprintf(`
|
||||
FROM %s
|
||||
RUN []
|
||||
`, otherTag)
|
||||
|
||||
name := "testtrustedbuildreleasesrole"
|
||||
|
||||
buildCmd := buildImageCmd(name, dockerFile, true)
|
||||
s.trustedCmd(buildCmd)
|
||||
out, _, err = runCommandWithOutput(buildCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Trusted build failed: %s", out))
|
||||
c.Assert(out, checker.Contains, fmt.Sprintf("FROM %s@sha", repoName))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedBuildTagIgnoresOtherDelegationRoles(c *check.C) {
|
||||
testRequires(c, NotaryHosting)
|
||||
|
||||
latestTag := s.setupTrustedImage(c, "trusted-build-releases-role")
|
||||
repoName := strings.TrimSuffix(latestTag, ":latest")
|
||||
|
||||
// Now create a non-releases delegation role
|
||||
s.notaryCreateDelegation(c, repoName, "targets/other", s.not.keys[0].Public)
|
||||
s.notaryImportKey(c, repoName, "targets/other", s.not.keys[0].Private)
|
||||
s.notaryPublish(c, repoName)
|
||||
|
||||
// push a different tag to the other role
|
||||
otherTag := fmt.Sprintf("%s:other", repoName)
|
||||
dockerCmd(c, "tag", "busybox", otherTag)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", otherTag)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("Trusted push failed: %s", out))
|
||||
s.assertTargetInRoles(c, repoName, "other", "targets/other")
|
||||
s.assertTargetNotInRoles(c, repoName, "other", "targets")
|
||||
|
||||
out, status := dockerCmd(c, "rmi", otherTag)
|
||||
c.Assert(status, check.Equals, 0, check.Commentf("docker rmi failed: %s", out))
|
||||
|
||||
dockerFile := fmt.Sprintf(`
|
||||
FROM %s
|
||||
RUN []
|
||||
`, otherTag)
|
||||
|
||||
name := "testtrustedbuildotherrole"
|
||||
|
||||
buildCmd := buildImageCmd(name, dockerFile, true)
|
||||
s.trustedCmd(buildCmd)
|
||||
out, _, err = runCommandWithOutput(buildCmd)
|
||||
c.Assert(err, check.NotNil, check.Commentf("Trusted build expected to fail: %s", out))
|
||||
}
|
||||
|
||||
// Issue #15634: COPY fails when path starts with "null"
|
||||
func (s *DockerSuite) TestBuildNullStringInAddCopyVolume(c *check.C) {
|
||||
name := "testbuildnullstringinaddcopyvolume"
|
||||
|
|
|
@ -256,16 +256,17 @@ func (s *DockerTrustSuite) TestTrustedPullDelete(c *check.C) {
|
|||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) {
|
||||
testRequires(c, NotaryHosting)
|
||||
repoName := fmt.Sprintf("%v/dockerclireleasesdelegationpulling/trusted", privateRegistryURL)
|
||||
targetName := fmt.Sprintf("%s:latest", repoName)
|
||||
pwd := "12345678"
|
||||
|
||||
// Push with targets first, initializing the repo
|
||||
dockerCmd(c, "tag", "busybox", targetName)
|
||||
pushCmd := exec.Command(dockerBinary, "push", targetName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, pwd, pwd)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
s.assertTargetInRoles(c, repoName, "latest", "targets")
|
||||
|
||||
// Try pull, check we retrieve from targets role
|
||||
pullCmd := exec.Command(dockerBinary, "-D", "pull", repoName)
|
||||
|
@ -275,15 +276,31 @@ func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) {
|
|||
c.Assert(out, checker.Contains, "retrieving target for targets role")
|
||||
|
||||
// Now we'll create the releases role, and try pushing and pulling
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/releases", s.not.keys[0].Public)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/releases", s.not.keys[0].Public)
|
||||
s.notaryImportKey(c, repoName, "targets/releases", s.not.keys[0].Private)
|
||||
s.notaryPublish(c, repoName, pwd)
|
||||
s.notaryPublish(c, repoName)
|
||||
|
||||
// try a pull, check that we can still pull because we can still read the
|
||||
// old tag in the targets role
|
||||
pullCmd = exec.Command(dockerBinary, "-D", "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "retrieving target for targets role")
|
||||
|
||||
// try a pull -a, check that it succeeds because we can still pull from the
|
||||
// targets role
|
||||
pullCmd = exec.Command(dockerBinary, "-D", "pull", "-a", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
|
||||
// Push, should sign with targets/releases
|
||||
dockerCmd(c, "tag", "busybox", targetName)
|
||||
pushCmd = exec.Command(dockerBinary, "push", targetName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, pwd, pwd)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err = runCommandWithOutput(pushCmd)
|
||||
s.assertTargetInRoles(c, repoName, "latest", "targets", "targets/releases")
|
||||
|
||||
// Try pull, check we retrieve from targets/releases role
|
||||
pullCmd = exec.Command(dockerBinary, "-D", "pull", repoName)
|
||||
|
@ -292,14 +309,15 @@ func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) {
|
|||
c.Assert(out, checker.Contains, "retrieving target for targets/releases role")
|
||||
|
||||
// Create another delegation that we'll sign with
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/other", s.not.keys[1].Public)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/other", s.not.keys[1].Public)
|
||||
s.notaryImportKey(c, repoName, "targets/other", s.not.keys[1].Private)
|
||||
s.notaryPublish(c, repoName, pwd)
|
||||
s.notaryPublish(c, repoName)
|
||||
|
||||
dockerCmd(c, "tag", "busybox", targetName)
|
||||
pushCmd = exec.Command(dockerBinary, "push", targetName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, pwd, pwd)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err = runCommandWithOutput(pushCmd)
|
||||
s.assertTargetInRoles(c, repoName, "latest", "targets", "targets/releases", "targets/other")
|
||||
|
||||
// Try pull, check we retrieve from targets/releases role
|
||||
pullCmd = exec.Command(dockerBinary, "-D", "pull", repoName)
|
||||
|
@ -307,3 +325,41 @@ func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) {
|
|||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(out, checker.Contains, "retrieving target for targets/releases role")
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPullIgnoresOtherDelegationRoles(c *check.C) {
|
||||
testRequires(c, NotaryHosting)
|
||||
repoName := fmt.Sprintf("%v/dockerclipullotherdelegation/trusted", privateRegistryURL)
|
||||
targetName := fmt.Sprintf("%s:latest", repoName)
|
||||
|
||||
// We'll create a repo first with a non-release delegation role, so that when we
|
||||
// push we'll sign it into the delegation role
|
||||
s.notaryInitRepo(c, repoName)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/other", s.not.keys[0].Public)
|
||||
s.notaryImportKey(c, repoName, "targets/other", s.not.keys[0].Private)
|
||||
s.notaryPublish(c, repoName)
|
||||
|
||||
// Push should write to the delegation role, not targets
|
||||
dockerCmd(c, "tag", "busybox", targetName)
|
||||
pushCmd := exec.Command(dockerBinary, "push", targetName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
s.assertTargetInRoles(c, repoName, "latest", "targets/other")
|
||||
s.assertTargetNotInRoles(c, repoName, "latest", "targets")
|
||||
|
||||
// Try pull - we should fail, since pull will only pull from the targets/releases
|
||||
// role or the targets role
|
||||
pullCmd := exec.Command(dockerBinary, "-D", "pull", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "No trust data for")
|
||||
|
||||
// try a pull -a: we should fail since pull will only pull from the targets/releases
|
||||
// role or the targets role
|
||||
pullCmd = exec.Command(dockerBinary, "-D", "pull", "-a", repoName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
c.Assert(out, checker.Contains, "No trusted tags for")
|
||||
}
|
||||
|
|
|
@ -501,10 +501,9 @@ func (s *DockerTrustSuite) TestTrustedPushWithReleasesDelegationOnly(c *check.C)
|
|||
testRequires(c, NotaryHosting)
|
||||
repoName := fmt.Sprintf("%v/dockerclireleasedelegationinitfirst/trusted", privateRegistryURL)
|
||||
targetName := fmt.Sprintf("%s:latest", repoName)
|
||||
pwd := "12345678"
|
||||
s.notaryInitRepo(c, repoName, pwd)
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/releases", s.not.keys[0].Public)
|
||||
s.notaryPublish(c, repoName, pwd)
|
||||
s.notaryInitRepo(c, repoName)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/releases", s.not.keys[0].Public)
|
||||
s.notaryPublish(c, repoName)
|
||||
|
||||
s.notaryImportKey(c, repoName, "targets/releases", s.not.keys[0].Private)
|
||||
|
||||
|
@ -512,10 +511,13 @@ func (s *DockerTrustSuite) TestTrustedPushWithReleasesDelegationOnly(c *check.C)
|
|||
dockerCmd(c, "tag", "busybox", targetName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", targetName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, pwd, pwd)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag"))
|
||||
// check to make sure that the target has been added to targets/releases and not targets
|
||||
s.assertTargetInRoles(c, repoName, "latest", "targets/releases")
|
||||
s.assertTargetNotInRoles(c, repoName, "latest", "targets")
|
||||
|
||||
// Try pull after push
|
||||
os.RemoveAll(filepath.Join(cliconfig.ConfigDir(), "trust"))
|
||||
|
@ -525,103 +527,99 @@ func (s *DockerTrustSuite) TestTrustedPushWithReleasesDelegationOnly(c *check.C)
|
|||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
|
||||
|
||||
// check to make sure that the target has been added to targets/releases and not targets
|
||||
s.assertTargetInDelegationRoles(c, repoName, "latest", "targets/releases")
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushSignsAllFirstLevelRolesWeHaveKeysFor(c *check.C) {
|
||||
testRequires(c, NotaryHosting)
|
||||
repoName := fmt.Sprintf("%v/dockerclimanyroles/trusted", privateRegistryURL)
|
||||
targetName := fmt.Sprintf("%s:latest", repoName)
|
||||
pwd := "12345678"
|
||||
s.notaryInitRepo(c, repoName, pwd)
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/role1", s.not.keys[0].Public)
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/role2", s.not.keys[1].Public)
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/role3", s.not.keys[2].Public)
|
||||
s.notaryInitRepo(c, repoName)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/role1", s.not.keys[0].Public)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/role2", s.not.keys[1].Public)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/role3", s.not.keys[2].Public)
|
||||
|
||||
// import everything except the third key
|
||||
s.notaryImportKey(c, repoName, "targets/role1", s.not.keys[0].Private)
|
||||
s.notaryImportKey(c, repoName, "targets/role2", s.not.keys[1].Private)
|
||||
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/role1/subrole", s.not.keys[3].Public)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/role1/subrole", s.not.keys[3].Public)
|
||||
s.notaryImportKey(c, repoName, "targets/role1/subrole", s.not.keys[3].Private)
|
||||
|
||||
s.notaryPublish(c, repoName, pwd)
|
||||
s.notaryPublish(c, repoName)
|
||||
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", targetName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", targetName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, pwd, pwd)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag"))
|
||||
|
||||
// Try pull after push
|
||||
os.RemoveAll(filepath.Join(cliconfig.ConfigDir(), "trust"))
|
||||
|
||||
pullCmd := exec.Command(dockerBinary, "pull", targetName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
|
||||
|
||||
// check to make sure that the target has been added to targets/role1 and targets/role2, and
|
||||
// not targets (because there are delegations) or targets/role3 (due to missing key) or
|
||||
// targets/role1/subrole (due to it being a second level delegation)
|
||||
s.assertTargetInDelegationRoles(c, repoName, "latest", "targets/role1", "targets/role2")
|
||||
s.assertTargetInRoles(c, repoName, "latest", "targets/role1", "targets/role2")
|
||||
s.assertTargetNotInRoles(c, repoName, "latest", "targets")
|
||||
|
||||
// Try pull after push
|
||||
os.RemoveAll(filepath.Join(cliconfig.ConfigDir(), "trust"))
|
||||
|
||||
// pull should fail because none of these are the releases role
|
||||
pullCmd := exec.Command(dockerBinary, "pull", targetName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushSignsForRolesWithKeysAndValidPaths(c *check.C) {
|
||||
repoName := fmt.Sprintf("%v/dockerclirolesbykeysandpaths/trusted", privateRegistryURL)
|
||||
targetName := fmt.Sprintf("%s:latest", repoName)
|
||||
pwd := "12345678"
|
||||
s.notaryInitRepo(c, repoName, pwd)
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/role1", s.not.keys[0].Public, "l", "z")
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/role2", s.not.keys[1].Public, "x", "y")
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/role3", s.not.keys[2].Public, "latest")
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/role4", s.not.keys[3].Public, "latest")
|
||||
s.notaryInitRepo(c, repoName)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/role1", s.not.keys[0].Public, "l", "z")
|
||||
s.notaryCreateDelegation(c, repoName, "targets/role2", s.not.keys[1].Public, "x", "y")
|
||||
s.notaryCreateDelegation(c, repoName, "targets/role3", s.not.keys[2].Public, "latest")
|
||||
s.notaryCreateDelegation(c, repoName, "targets/role4", s.not.keys[3].Public, "latest")
|
||||
|
||||
// import everything except the third key
|
||||
s.notaryImportKey(c, repoName, "targets/role1", s.not.keys[0].Private)
|
||||
s.notaryImportKey(c, repoName, "targets/role2", s.not.keys[1].Private)
|
||||
s.notaryImportKey(c, repoName, "targets/role4", s.not.keys[3].Private)
|
||||
|
||||
s.notaryPublish(c, repoName, pwd)
|
||||
s.notaryPublish(c, repoName)
|
||||
|
||||
// tag the image and upload it to the private registry
|
||||
dockerCmd(c, "tag", "busybox", targetName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", targetName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, pwd, pwd)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out))
|
||||
c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag"))
|
||||
|
||||
// Try pull after push
|
||||
os.RemoveAll(filepath.Join(cliconfig.ConfigDir(), "trust"))
|
||||
|
||||
pullCmd := exec.Command(dockerBinary, "pull", targetName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.IsNil, check.Commentf(out))
|
||||
c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out))
|
||||
|
||||
// check to make sure that the target has been added to targets/role1 and targets/role4, and
|
||||
// not targets (because there are delegations) or targets/role2 (due to path restrictions) or
|
||||
// targets/role3 (due to missing key)
|
||||
s.assertTargetInDelegationRoles(c, repoName, "latest", "targets/role1", "targets/role4")
|
||||
s.assertTargetInRoles(c, repoName, "latest", "targets/role1", "targets/role4")
|
||||
s.assertTargetNotInRoles(c, repoName, "latest", "targets")
|
||||
|
||||
// Try pull after push
|
||||
os.RemoveAll(filepath.Join(cliconfig.ConfigDir(), "trust"))
|
||||
|
||||
// pull should fail because none of these are the releases role
|
||||
pullCmd := exec.Command(dockerBinary, "pull", targetName)
|
||||
s.trustedCmd(pullCmd)
|
||||
out, _, err = runCommandWithOutput(pullCmd)
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) TestTrustedPushDoesntSignTargetsIfDelegationsExist(c *check.C) {
|
||||
testRequires(c, NotaryHosting)
|
||||
repoName := fmt.Sprintf("%v/dockerclireleasedelegationnotsignable/trusted", privateRegistryURL)
|
||||
targetName := fmt.Sprintf("%s:latest", repoName)
|
||||
pwd := "12345678"
|
||||
s.notaryInitRepo(c, repoName, pwd)
|
||||
s.notaryCreateDelegation(c, repoName, pwd, "targets/role1", s.not.keys[0].Public)
|
||||
s.notaryPublish(c, repoName, pwd)
|
||||
s.notaryInitRepo(c, repoName)
|
||||
s.notaryCreateDelegation(c, repoName, "targets/role1", s.not.keys[0].Public)
|
||||
s.notaryPublish(c, repoName)
|
||||
|
||||
// do not import any delegations key
|
||||
|
||||
|
@ -629,11 +627,13 @@ func (s *DockerTrustSuite) TestTrustedPushDoesntSignTargetsIfDelegationsExist(c
|
|||
dockerCmd(c, "tag", "busybox", targetName)
|
||||
|
||||
pushCmd := exec.Command(dockerBinary, "push", targetName)
|
||||
s.trustedCmdWithPassphrases(pushCmd, pwd, pwd)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
c.Assert(err, check.Not(check.IsNil), check.Commentf("trusted push succeeded but should have failed:\n%s", out))
|
||||
c.Assert(err, check.NotNil, check.Commentf("trusted push succeeded but should have failed:\n%s", out))
|
||||
c.Assert(out, checker.Contains, "no valid signing keys",
|
||||
check.Commentf("Missing expected output on trusted push without keys"))
|
||||
|
||||
s.assertTargetNotInRoles(c, repoName, "latest", "targets", "targets/role1")
|
||||
}
|
||||
|
||||
func (s *DockerRegistryAuthHtpasswdSuite) TestPushNoCredentialsNoRetry(c *check.C) {
|
||||
|
|
|
@ -211,6 +211,7 @@ func (s *DockerTrustSuite) setupTrustedImage(c *check.C, name string) string {
|
|||
pushCmd := exec.Command(dockerBinary, "push", repoName)
|
||||
s.trustedCmd(pushCmd)
|
||||
out, _, err := runCommandWithOutput(pushCmd)
|
||||
|
||||
if err != nil {
|
||||
c.Fatalf("Error running trusted push: %s\n%s", err, out)
|
||||
}
|
||||
|
@ -225,25 +226,26 @@ func (s *DockerTrustSuite) setupTrustedImage(c *check.C, name string) string {
|
|||
return repoName
|
||||
}
|
||||
|
||||
func notaryClientEnv(cmd *exec.Cmd, rootPwd, repositoryPwd string) {
|
||||
func notaryClientEnv(cmd *exec.Cmd) {
|
||||
pwd := "12345678"
|
||||
env := []string{
|
||||
fmt.Sprintf("NOTARY_ROOT_PASSPHRASE=%s", rootPwd),
|
||||
fmt.Sprintf("NOTARY_TARGETS_PASSPHRASE=%s", repositoryPwd),
|
||||
fmt.Sprintf("NOTARY_SNAPSHOT_PASSPHRASE=%s", repositoryPwd),
|
||||
fmt.Sprintf("NOTARY_ROOT_PASSPHRASE=%s", pwd),
|
||||
fmt.Sprintf("NOTARY_TARGETS_PASSPHRASE=%s", pwd),
|
||||
fmt.Sprintf("NOTARY_SNAPSHOT_PASSPHRASE=%s", pwd),
|
||||
}
|
||||
cmd.Env = append(os.Environ(), env...)
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) notaryInitRepo(c *check.C, repoName, pwd string) {
|
||||
func (s *DockerTrustSuite) notaryInitRepo(c *check.C, repoName string) {
|
||||
initCmd := exec.Command(notaryBinary, "-c", filepath.Join(s.not.dir, "client-config.json"), "init", repoName)
|
||||
notaryClientEnv(initCmd, pwd, pwd)
|
||||
notaryClientEnv(initCmd)
|
||||
out, _, err := runCommandWithOutput(initCmd)
|
||||
if err != nil {
|
||||
c.Fatalf("Error initializing notary repository: %s\n", out)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) notaryCreateDelegation(c *check.C, repoName, pwd, role string, pubKey string, paths ...string) {
|
||||
func (s *DockerTrustSuite) notaryCreateDelegation(c *check.C, repoName, role string, pubKey string, paths ...string) {
|
||||
pathsArg := "--all-paths"
|
||||
if len(paths) > 0 {
|
||||
pathsArg = "--paths=" + strings.Join(paths, ",")
|
||||
|
@ -251,16 +253,16 @@ func (s *DockerTrustSuite) notaryCreateDelegation(c *check.C, repoName, pwd, rol
|
|||
|
||||
delgCmd := exec.Command(notaryBinary, "-c", filepath.Join(s.not.dir, "client-config.json"),
|
||||
"delegation", "add", repoName, role, pubKey, pathsArg)
|
||||
notaryClientEnv(delgCmd, pwd, pwd)
|
||||
notaryClientEnv(delgCmd)
|
||||
out, _, err := runCommandWithOutput(delgCmd)
|
||||
if err != nil {
|
||||
c.Fatalf("Error adding %s role to notary repository: %s\n", role, out)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) notaryPublish(c *check.C, repoName, pwd string) {
|
||||
func (s *DockerTrustSuite) notaryPublish(c *check.C, repoName string) {
|
||||
pubCmd := exec.Command(notaryBinary, "-c", filepath.Join(s.not.dir, "client-config.json"), "publish", repoName)
|
||||
notaryClientEnv(pubCmd, pwd, pwd)
|
||||
notaryClientEnv(pubCmd)
|
||||
out, _, err := runCommandWithOutput(pubCmd)
|
||||
if err != nil {
|
||||
c.Fatalf("Error publishing notary repository: %s\n", out)
|
||||
|
@ -270,20 +272,20 @@ func (s *DockerTrustSuite) notaryPublish(c *check.C, repoName, pwd string) {
|
|||
func (s *DockerTrustSuite) notaryImportKey(c *check.C, repoName, role string, privKey string) {
|
||||
impCmd := exec.Command(notaryBinary, "-c", filepath.Join(s.not.dir, "client-config.json"), "key",
|
||||
"import", privKey, "-g", repoName, "-r", role)
|
||||
notaryClientEnv(impCmd, "", "")
|
||||
notaryClientEnv(impCmd)
|
||||
out, _, err := runCommandWithOutput(impCmd)
|
||||
if err != nil {
|
||||
c.Fatalf("Error importing key to notary repository: %s\n", out)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) notaryListTargetsInRoles(c *check.C, repoName, role string) map[string]string {
|
||||
func (s *DockerTrustSuite) notaryListTargetsInRole(c *check.C, repoName, role string) map[string]string {
|
||||
listCmd := exec.Command(notaryBinary, "-c", filepath.Join(s.not.dir, "client-config.json"), "list",
|
||||
repoName, "-r", role)
|
||||
notaryClientEnv(listCmd, "", "")
|
||||
notaryClientEnv(listCmd)
|
||||
out, _, err := runCommandWithOutput(listCmd)
|
||||
if err != nil {
|
||||
c.Fatalf("Error importing key to notary repository: %s\n", out)
|
||||
c.Fatalf("Error listing targets in notary repository: %s\n", out)
|
||||
}
|
||||
|
||||
// should look something like:
|
||||
|
@ -291,10 +293,17 @@ func (s *DockerTrustSuite) notaryListTargetsInRoles(c *check.C, repoName, role s
|
|||
// ------------------------------------------------------------------------------------------------------
|
||||
// latest 24a36bbc059b1345b7e8be0df20f1b23caa3602e85d42fff7ecd9d0bd255de56 1377 targets
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(out), "\n")
|
||||
c.Assert(len(lines), checker.GreaterOrEqualThan, 3)
|
||||
targets := make(map[string]string)
|
||||
|
||||
// no target
|
||||
lines := strings.Split(strings.TrimSpace(out), "\n")
|
||||
if len(lines) == 1 && strings.Contains(out, "No targets present in this repository.") {
|
||||
return targets
|
||||
}
|
||||
|
||||
// otherwise, there is at least one target
|
||||
c.Assert(len(lines), checker.GreaterOrEqualThan, 3)
|
||||
|
||||
for _, line := range lines[2:] {
|
||||
tokens := strings.Fields(line)
|
||||
c.Assert(tokens, checker.HasLen, 4)
|
||||
|
@ -304,18 +313,23 @@ func (s *DockerTrustSuite) notaryListTargetsInRoles(c *check.C, repoName, role s
|
|||
return targets
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) assertTargetInDelegationRoles(c *check.C, repoName, target string, roles ...string) {
|
||||
// assert it's not in the target role
|
||||
targets := s.notaryListTargetsInRoles(c, repoName, "targets")
|
||||
roleName, ok := targets[target]
|
||||
c.Assert(ok, checker.True)
|
||||
c.Assert(roleName, checker.Not(checker.Equals), "targets")
|
||||
|
||||
func (s *DockerTrustSuite) assertTargetInRoles(c *check.C, repoName, target string, roles ...string) {
|
||||
// check all the roles
|
||||
for _, role := range roles {
|
||||
targets := s.notaryListTargetsInRoles(c, repoName, role)
|
||||
targets := s.notaryListTargetsInRole(c, repoName, role)
|
||||
roleName, ok := targets[target]
|
||||
c.Assert(ok, checker.True)
|
||||
c.Assert(roleName, checker.Equals, role)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerTrustSuite) assertTargetNotInRoles(c *check.C, repoName, target string, roles ...string) {
|
||||
targets := s.notaryListTargetsInRole(c, repoName, "targets")
|
||||
|
||||
roleName, ok := targets[target]
|
||||
if ok {
|
||||
for _, role := range roles {
|
||||
c.Assert(roleName, checker.Not(checker.Equals), role)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue