github.com/shishir-a412ed/docker@v1.3.2-0.20180103180333-fda904911d87/integration-cli/docker_cli_pull_trusted_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  
     7  	"github.com/docker/docker/integration-cli/checker"
     8  	"github.com/docker/docker/integration-cli/cli"
     9  	"github.com/docker/docker/integration-cli/cli/build"
    10  	"github.com/go-check/check"
    11  	"github.com/gotestyourself/gotestyourself/icmd"
    12  )
    13  
    14  func (s *DockerTrustSuite) TestTrustedPull(c *check.C) {
    15  	repoName := s.setupTrustedImage(c, "trusted-pull")
    16  
    17  	// Try pull
    18  	cli.Docker(cli.Args("pull", repoName), trustedCmd).Assert(c, SuccessTagging)
    19  
    20  	cli.DockerCmd(c, "rmi", repoName)
    21  	// Try untrusted pull to ensure we pushed the tag to the registry
    22  	cli.Docker(cli.Args("pull", "--disable-content-trust=true", repoName), trustedCmd).Assert(c, SuccessDownloaded)
    23  }
    24  
    25  func (s *DockerTrustSuite) TestTrustedIsolatedPull(c *check.C) {
    26  	repoName := s.setupTrustedImage(c, "trusted-isolated-pull")
    27  
    28  	// Try pull (run from isolated directory without trust information)
    29  	cli.Docker(cli.Args("--config", "/tmp/docker-isolated", "pull", repoName), trustedCmd).Assert(c, SuccessTagging)
    30  
    31  	cli.DockerCmd(c, "rmi", repoName)
    32  }
    33  
    34  func (s *DockerTrustSuite) TestUntrustedPull(c *check.C) {
    35  	repoName := fmt.Sprintf("%v/dockercliuntrusted/pulltest:latest", privateRegistryURL)
    36  	// tag the image and upload it to the private registry
    37  	cli.DockerCmd(c, "tag", "busybox", repoName)
    38  	cli.DockerCmd(c, "push", repoName)
    39  	cli.DockerCmd(c, "rmi", repoName)
    40  
    41  	// Try trusted pull on untrusted tag
    42  	cli.Docker(cli.Args("pull", repoName), trustedCmd).Assert(c, icmd.Expected{
    43  		ExitCode: 1,
    44  		Err:      "Error: remote trust data does not exist",
    45  	})
    46  }
    47  
    48  func (s *DockerTrustSuite) TestTrustedPullFromBadTrustServer(c *check.C) {
    49  	repoName := fmt.Sprintf("%v/dockerclievilpull/trusted:latest", privateRegistryURL)
    50  	evilLocalConfigDir, err := ioutil.TempDir("", "evil-local-config-dir")
    51  	if err != nil {
    52  		c.Fatalf("Failed to create local temp dir")
    53  	}
    54  
    55  	// tag the image and upload it to the private registry
    56  	cli.DockerCmd(c, "tag", "busybox", repoName)
    57  
    58  	cli.Docker(cli.Args("push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing)
    59  	cli.DockerCmd(c, "rmi", repoName)
    60  
    61  	// Try pull
    62  	cli.Docker(cli.Args("pull", repoName), trustedCmd).Assert(c, SuccessTagging)
    63  	cli.DockerCmd(c, "rmi", repoName)
    64  
    65  	// Kill the notary server, start a new "evil" one.
    66  	s.not.Close()
    67  	s.not, err = newTestNotary(c)
    68  
    69  	c.Assert(err, check.IsNil, check.Commentf("Restarting notary server failed."))
    70  
    71  	// In order to make an evil server, lets re-init a client (with a different trust dir) and push new data.
    72  	// tag an image and upload it to the private registry
    73  	cli.DockerCmd(c, "--config", evilLocalConfigDir, "tag", "busybox", repoName)
    74  
    75  	// Push up to the new server
    76  	cli.Docker(cli.Args("--config", evilLocalConfigDir, "push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing)
    77  
    78  	// Now, try pulling with the original client from this new trust server. This should fail because the new root is invalid.
    79  	cli.Docker(cli.Args("pull", repoName), trustedCmd).Assert(c, icmd.Expected{
    80  		ExitCode: 1,
    81  		Err:      "could not rotate trust to a new trusted root",
    82  	})
    83  }
    84  
    85  func (s *DockerTrustSuite) TestTrustedOfflinePull(c *check.C) {
    86  	repoName := s.setupTrustedImage(c, "trusted-offline-pull")
    87  
    88  	cli.Docker(cli.Args("pull", repoName), trustedCmdWithServer("https://invalidnotaryserver")).Assert(c, icmd.Expected{
    89  		ExitCode: 1,
    90  		Err:      "error contacting notary server",
    91  	})
    92  	// Do valid trusted pull to warm cache
    93  	cli.Docker(cli.Args("pull", repoName), trustedCmd).Assert(c, SuccessTagging)
    94  	cli.DockerCmd(c, "rmi", repoName)
    95  
    96  	// Try pull again with invalid notary server, should use cache
    97  	cli.Docker(cli.Args("pull", repoName), trustedCmdWithServer("https://invalidnotaryserver")).Assert(c, SuccessTagging)
    98  }
    99  
   100  func (s *DockerTrustSuite) TestTrustedPullDelete(c *check.C) {
   101  	repoName := fmt.Sprintf("%v/dockercli/%s:latest", privateRegistryURL, "trusted-pull-delete")
   102  	// tag the image and upload it to the private registry
   103  	cli.BuildCmd(c, repoName, build.WithDockerfile(`
   104                      FROM busybox
   105                      CMD echo trustedpulldelete
   106                  `))
   107  	cli.Docker(cli.Args("push", repoName), trustedCmd).Assert(c, SuccessSigningAndPushing)
   108  
   109  	cli.DockerCmd(c, "rmi", repoName)
   110  
   111  	// Try pull
   112  	result := cli.Docker(cli.Args("pull", repoName), trustedCmd).Assert(c, icmd.Success)
   113  
   114  	matches := digestRegex.FindStringSubmatch(result.Combined())
   115  	c.Assert(matches, checker.HasLen, 2, check.Commentf("unable to parse digest from pull output: %s", result.Combined()))
   116  	pullDigest := matches[1]
   117  
   118  	imageID := inspectField(c, repoName, "Id")
   119  
   120  	imageByDigest := repoName + "@" + pullDigest
   121  	byDigestID := inspectField(c, imageByDigest, "Id")
   122  
   123  	c.Assert(byDigestID, checker.Equals, imageID)
   124  
   125  	// rmi of tag should also remove the digest reference
   126  	cli.DockerCmd(c, "rmi", repoName)
   127  
   128  	_, err := inspectFieldWithError(imageByDigest, "Id")
   129  	c.Assert(err, checker.NotNil, check.Commentf("digest reference should have been removed"))
   130  
   131  	_, err = inspectFieldWithError(imageID, "Id")
   132  	c.Assert(err, checker.NotNil, check.Commentf("image should have been deleted"))
   133  }
   134  
   135  func (s *DockerTrustSuite) TestTrustedPullReadsFromReleasesRole(c *check.C) {
   136  	testRequires(c, NotaryHosting)
   137  	repoName := fmt.Sprintf("%v/dockerclireleasesdelegationpulling/trusted", privateRegistryURL)
   138  	targetName := fmt.Sprintf("%s:latest", repoName)
   139  
   140  	// Push with targets first, initializing the repo
   141  	cli.DockerCmd(c, "tag", "busybox", targetName)
   142  	cli.Docker(cli.Args("push", targetName), trustedCmd).Assert(c, icmd.Success)
   143  	s.assertTargetInRoles(c, repoName, "latest", "targets")
   144  
   145  	// Try pull, check we retrieve from targets role
   146  	cli.Docker(cli.Args("-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{
   147  		Err: "retrieving target for targets role",
   148  	})
   149  
   150  	// Now we'll create the releases role, and try pushing and pulling
   151  	s.notaryCreateDelegation(c, repoName, "targets/releases", s.not.keys[0].Public)
   152  	s.notaryImportKey(c, repoName, "targets/releases", s.not.keys[0].Private)
   153  	s.notaryPublish(c, repoName)
   154  
   155  	// try a pull, check that we can still pull because we can still read the
   156  	// old tag in the targets role
   157  	cli.Docker(cli.Args("-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{
   158  		Err: "retrieving target for targets role",
   159  	})
   160  
   161  	// try a pull -a, check that it succeeds because we can still pull from the
   162  	// targets role
   163  	cli.Docker(cli.Args("-D", "pull", "-a", repoName), trustedCmd).Assert(c, icmd.Success)
   164  
   165  	// Push, should sign with targets/releases
   166  	cli.DockerCmd(c, "tag", "busybox", targetName)
   167  	cli.Docker(cli.Args("push", targetName), trustedCmd).Assert(c, icmd.Success)
   168  	s.assertTargetInRoles(c, repoName, "latest", "targets", "targets/releases")
   169  
   170  	// Try pull, check we retrieve from targets/releases role
   171  	cli.Docker(cli.Args("-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{
   172  		Err: "retrieving target for targets/releases role",
   173  	})
   174  
   175  	// Create another delegation that we'll sign with
   176  	s.notaryCreateDelegation(c, repoName, "targets/other", s.not.keys[1].Public)
   177  	s.notaryImportKey(c, repoName, "targets/other", s.not.keys[1].Private)
   178  	s.notaryPublish(c, repoName)
   179  
   180  	cli.DockerCmd(c, "tag", "busybox", targetName)
   181  	cli.Docker(cli.Args("push", targetName), trustedCmd).Assert(c, icmd.Success)
   182  	s.assertTargetInRoles(c, repoName, "latest", "targets", "targets/releases", "targets/other")
   183  
   184  	// Try pull, check we retrieve from targets/releases role
   185  	cli.Docker(cli.Args("-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{
   186  		Err: "retrieving target for targets/releases role",
   187  	})
   188  }
   189  
   190  func (s *DockerTrustSuite) TestTrustedPullIgnoresOtherDelegationRoles(c *check.C) {
   191  	testRequires(c, NotaryHosting)
   192  	repoName := fmt.Sprintf("%v/dockerclipullotherdelegation/trusted", privateRegistryURL)
   193  	targetName := fmt.Sprintf("%s:latest", repoName)
   194  
   195  	// We'll create a repo first with a non-release delegation role, so that when we
   196  	// push we'll sign it into the delegation role
   197  	s.notaryInitRepo(c, repoName)
   198  	s.notaryCreateDelegation(c, repoName, "targets/other", s.not.keys[0].Public)
   199  	s.notaryImportKey(c, repoName, "targets/other", s.not.keys[0].Private)
   200  	s.notaryPublish(c, repoName)
   201  
   202  	// Push should write to the delegation role, not targets
   203  	cli.DockerCmd(c, "tag", "busybox", targetName)
   204  	cli.Docker(cli.Args("push", targetName), trustedCmd).Assert(c, icmd.Success)
   205  	s.assertTargetInRoles(c, repoName, "latest", "targets/other")
   206  	s.assertTargetNotInRoles(c, repoName, "latest", "targets")
   207  
   208  	// Try pull - we should fail, since pull will only pull from the targets/releases
   209  	// role or the targets role
   210  	cli.DockerCmd(c, "tag", "busybox", targetName)
   211  	cli.Docker(cli.Args("-D", "pull", repoName), trustedCmd).Assert(c, icmd.Expected{
   212  		ExitCode: 1,
   213  		Err:      "No trust data for",
   214  	})
   215  
   216  	// try a pull -a: we should fail since pull will only pull from the targets/releases
   217  	// role or the targets role
   218  	cli.Docker(cli.Args("-D", "pull", "-a", repoName), trustedCmd).Assert(c, icmd.Expected{
   219  		ExitCode: 1,
   220  		Err:      "No trusted tags for",
   221  	})
   222  }