github.com/gdm85/docker@v1.10.2/integration-cli/docker_cli_push_test.go (about) 1 package main 2 3 import ( 4 "archive/tar" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "os/exec" 9 "path/filepath" 10 "strings" 11 "time" 12 13 "github.com/docker/distribution/digest" 14 "github.com/docker/docker/cliconfig" 15 "github.com/docker/docker/pkg/integration/checker" 16 "github.com/go-check/check" 17 ) 18 19 // Pushing an image to a private registry. 20 func testPushBusyboxImage(c *check.C) { 21 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 22 // tag the image to upload it to the private registry 23 dockerCmd(c, "tag", "busybox", repoName) 24 // push the image to the registry 25 dockerCmd(c, "push", repoName) 26 } 27 28 func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) { 29 testPushBusyboxImage(c) 30 } 31 32 func (s *DockerSchema1RegistrySuite) TestPushBusyboxImage(c *check.C) { 33 testPushBusyboxImage(c) 34 } 35 36 // pushing an image without a prefix should throw an error 37 func (s *DockerSuite) TestPushUnprefixedRepo(c *check.C) { 38 out, _, err := dockerCmdWithError("push", "busybox") 39 c.Assert(err, check.NotNil, check.Commentf("pushing an unprefixed repo didn't result in a non-zero exit status: %s", out)) 40 } 41 42 func testPushUntagged(c *check.C) { 43 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 44 expected := "Repository does not exist" 45 46 out, _, err := dockerCmdWithError("push", repoName) 47 c.Assert(err, check.NotNil, check.Commentf("pushing the image to the private registry should have failed: output %q", out)) 48 c.Assert(out, checker.Contains, expected, check.Commentf("pushing the image failed")) 49 } 50 51 func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) { 52 testPushUntagged(c) 53 } 54 55 func (s *DockerSchema1RegistrySuite) TestPushUntagged(c *check.C) { 56 testPushUntagged(c) 57 } 58 59 func testPushBadTag(c *check.C) { 60 repoName := fmt.Sprintf("%v/dockercli/busybox:latest", privateRegistryURL) 61 expected := "does not exist" 62 63 out, _, err := dockerCmdWithError("push", repoName) 64 c.Assert(err, check.NotNil, check.Commentf("pushing the image to the private registry should have failed: output %q", out)) 65 c.Assert(out, checker.Contains, expected, check.Commentf("pushing the image failed")) 66 } 67 68 func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) { 69 testPushBadTag(c) 70 } 71 72 func (s *DockerSchema1RegistrySuite) TestPushBadTag(c *check.C) { 73 testPushBadTag(c) 74 } 75 76 func testPushMultipleTags(c *check.C) { 77 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 78 repoTag1 := fmt.Sprintf("%v/dockercli/busybox:t1", privateRegistryURL) 79 repoTag2 := fmt.Sprintf("%v/dockercli/busybox:t2", privateRegistryURL) 80 // tag the image and upload it to the private registry 81 dockerCmd(c, "tag", "busybox", repoTag1) 82 83 dockerCmd(c, "tag", "busybox", repoTag2) 84 85 dockerCmd(c, "push", repoName) 86 87 // Ensure layer list is equivalent for repoTag1 and repoTag2 88 out1, _ := dockerCmd(c, "pull", repoTag1) 89 90 imageAlreadyExists := ": Image already exists" 91 var out1Lines []string 92 for _, outputLine := range strings.Split(out1, "\n") { 93 if strings.Contains(outputLine, imageAlreadyExists) { 94 out1Lines = append(out1Lines, outputLine) 95 } 96 } 97 98 out2, _ := dockerCmd(c, "pull", repoTag2) 99 100 var out2Lines []string 101 for _, outputLine := range strings.Split(out2, "\n") { 102 if strings.Contains(outputLine, imageAlreadyExists) { 103 out1Lines = append(out1Lines, outputLine) 104 } 105 } 106 c.Assert(out2Lines, checker.HasLen, len(out1Lines)) 107 108 for i := range out1Lines { 109 c.Assert(out1Lines[i], checker.Equals, out2Lines[i]) 110 } 111 } 112 113 func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) { 114 testPushMultipleTags(c) 115 } 116 117 func (s *DockerSchema1RegistrySuite) TestPushMultipleTags(c *check.C) { 118 testPushMultipleTags(c) 119 } 120 121 func testPushEmptyLayer(c *check.C) { 122 repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL) 123 emptyTarball, err := ioutil.TempFile("", "empty_tarball") 124 c.Assert(err, check.IsNil, check.Commentf("Unable to create test file")) 125 126 tw := tar.NewWriter(emptyTarball) 127 err = tw.Close() 128 c.Assert(err, check.IsNil, check.Commentf("Error creating empty tarball")) 129 130 freader, err := os.Open(emptyTarball.Name()) 131 c.Assert(err, check.IsNil, check.Commentf("Could not open test tarball")) 132 133 importCmd := exec.Command(dockerBinary, "import", "-", repoName) 134 importCmd.Stdin = freader 135 out, _, err := runCommandWithOutput(importCmd) 136 c.Assert(err, check.IsNil, check.Commentf("import failed: %q", out)) 137 138 // Now verify we can push it 139 out, _, err = dockerCmdWithError("push", repoName) 140 c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out)) 141 } 142 143 func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) { 144 testPushEmptyLayer(c) 145 } 146 147 func (s *DockerSchema1RegistrySuite) TestPushEmptyLayer(c *check.C) { 148 testPushEmptyLayer(c) 149 } 150 151 func (s *DockerRegistrySuite) TestCrossRepositoryLayerPush(c *check.C) { 152 sourceRepoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 153 // tag the image to upload it to the private registry 154 dockerCmd(c, "tag", "busybox", sourceRepoName) 155 // push the image to the registry 156 out1, _, err := dockerCmdWithError("push", sourceRepoName) 157 c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out1)) 158 // ensure that none of the layers were mounted from another repository during push 159 c.Assert(strings.Contains(out1, "Mounted from"), check.Equals, false) 160 161 digest1 := digest.DigestRegexp.FindString(out1) 162 c.Assert(len(digest1), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest")) 163 164 destRepoName := fmt.Sprintf("%v/dockercli/crossrepopush", privateRegistryURL) 165 // retag the image to upload the same layers to another repo in the same registry 166 dockerCmd(c, "tag", "busybox", destRepoName) 167 // push the image to the registry 168 out2, _, err := dockerCmdWithError("push", destRepoName) 169 c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out2)) 170 // ensure that layers were mounted from the first repo during push 171 c.Assert(strings.Contains(out2, "Mounted from dockercli/busybox"), check.Equals, true) 172 173 digest2 := digest.DigestRegexp.FindString(out2) 174 c.Assert(len(digest2), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest")) 175 c.Assert(digest1, check.Equals, digest2) 176 177 // ensure that we can pull and run the cross-repo-pushed repository 178 dockerCmd(c, "rmi", destRepoName) 179 dockerCmd(c, "pull", destRepoName) 180 out3, _ := dockerCmd(c, "run", destRepoName, "echo", "-n", "hello world") 181 c.Assert(out3, check.Equals, "hello world") 182 } 183 184 func (s *DockerSchema1RegistrySuite) TestCrossRepositoryLayerPushNotSupported(c *check.C) { 185 sourceRepoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 186 // tag the image to upload it to the private registry 187 dockerCmd(c, "tag", "busybox", sourceRepoName) 188 // push the image to the registry 189 out1, _, err := dockerCmdWithError("push", sourceRepoName) 190 c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out1)) 191 // ensure that none of the layers were mounted from another repository during push 192 c.Assert(strings.Contains(out1, "Mounted from"), check.Equals, false) 193 194 digest1 := digest.DigestRegexp.FindString(out1) 195 c.Assert(len(digest1), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest")) 196 197 destRepoName := fmt.Sprintf("%v/dockercli/crossrepopush", privateRegistryURL) 198 // retag the image to upload the same layers to another repo in the same registry 199 dockerCmd(c, "tag", "busybox", destRepoName) 200 // push the image to the registry 201 out2, _, err := dockerCmdWithError("push", destRepoName) 202 c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out2)) 203 // schema1 registry should not support cross-repo layer mounts, so ensure that this does not happen 204 c.Assert(strings.Contains(out2, "Mounted from dockercli/busybox"), check.Equals, false) 205 206 digest2 := digest.DigestRegexp.FindString(out2) 207 c.Assert(len(digest2), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest")) 208 c.Assert(digest1, check.Equals, digest2) 209 210 // ensure that we can pull and run the second pushed repository 211 dockerCmd(c, "rmi", destRepoName) 212 dockerCmd(c, "pull", destRepoName) 213 out3, _ := dockerCmd(c, "run", destRepoName, "echo", "-n", "hello world") 214 c.Assert(out3, check.Equals, "hello world") 215 } 216 217 func (s *DockerTrustSuite) TestTrustedPush(c *check.C) { 218 repoName := fmt.Sprintf("%v/dockerclitrusted/pushtest:latest", privateRegistryURL) 219 // tag the image and upload it to the private registry 220 dockerCmd(c, "tag", "busybox", repoName) 221 222 pushCmd := exec.Command(dockerBinary, "push", repoName) 223 s.trustedCmd(pushCmd) 224 out, _, err := runCommandWithOutput(pushCmd) 225 c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) 226 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 227 228 // Try pull after push 229 pullCmd := exec.Command(dockerBinary, "pull", repoName) 230 s.trustedCmd(pullCmd) 231 out, _, err = runCommandWithOutput(pullCmd) 232 c.Assert(err, check.IsNil, check.Commentf(out)) 233 c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out)) 234 } 235 236 func (s *DockerTrustSuite) TestTrustedPushWithEnvPasswords(c *check.C) { 237 repoName := fmt.Sprintf("%v/dockerclienv/trusted:latest", privateRegistryURL) 238 // tag the image and upload it to the private registry 239 dockerCmd(c, "tag", "busybox", repoName) 240 241 pushCmd := exec.Command(dockerBinary, "push", repoName) 242 s.trustedCmdWithPassphrases(pushCmd, "12345678", "12345678") 243 out, _, err := runCommandWithOutput(pushCmd) 244 c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) 245 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 246 247 // Try pull after push 248 pullCmd := exec.Command(dockerBinary, "pull", repoName) 249 s.trustedCmd(pullCmd) 250 out, _, err = runCommandWithOutput(pullCmd) 251 c.Assert(err, check.IsNil, check.Commentf(out)) 252 c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out)) 253 } 254 255 // This test ensures backwards compatibility with old ENV variables. Should be 256 // deprecated by 1.10 257 func (s *DockerTrustSuite) TestTrustedPushWithDeprecatedEnvPasswords(c *check.C) { 258 repoName := fmt.Sprintf("%v/dockercli/trusteddeprecated:latest", privateRegistryURL) 259 // tag the image and upload it to the private registry 260 dockerCmd(c, "tag", "busybox", repoName) 261 262 pushCmd := exec.Command(dockerBinary, "push", repoName) 263 s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "12345678") 264 out, _, err := runCommandWithOutput(pushCmd) 265 c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) 266 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 267 } 268 269 func (s *DockerTrustSuite) TestTrustedPushWithFailingServer(c *check.C) { 270 repoName := fmt.Sprintf("%v/dockerclitrusted/failingserver:latest", privateRegistryURL) 271 // tag the image and upload it to the private registry 272 dockerCmd(c, "tag", "busybox", repoName) 273 274 pushCmd := exec.Command(dockerBinary, "push", repoName) 275 s.trustedCmdWithServer(pushCmd, "https://example.com:81/") 276 out, _, err := runCommandWithOutput(pushCmd) 277 c.Assert(err, check.NotNil, check.Commentf("Missing error while running trusted push w/ no server")) 278 c.Assert(out, checker.Contains, "error contacting notary server", check.Commentf("Missing expected output on trusted push")) 279 } 280 281 func (s *DockerTrustSuite) TestTrustedPushWithoutServerAndUntrusted(c *check.C) { 282 repoName := fmt.Sprintf("%v/dockerclitrusted/trustedandnot:latest", privateRegistryURL) 283 // tag the image and upload it to the private registry 284 dockerCmd(c, "tag", "busybox", repoName) 285 286 pushCmd := exec.Command(dockerBinary, "push", "--disable-content-trust", repoName) 287 s.trustedCmdWithServer(pushCmd, "https://example.com/") 288 out, _, err := runCommandWithOutput(pushCmd) 289 c.Assert(err, check.IsNil, check.Commentf("trusted push with no server and --disable-content-trust failed: %s\n%s", err, out)) 290 c.Assert(out, check.Not(checker.Contains), "Error establishing connection to notary repository", check.Commentf("Missing expected output on trusted push with --disable-content-trust:")) 291 } 292 293 func (s *DockerTrustSuite) TestTrustedPushWithExistingTag(c *check.C) { 294 repoName := fmt.Sprintf("%v/dockerclitag/trusted:latest", privateRegistryURL) 295 // tag the image and upload it to the private registry 296 dockerCmd(c, "tag", "busybox", repoName) 297 dockerCmd(c, "push", repoName) 298 299 pushCmd := exec.Command(dockerBinary, "push", repoName) 300 s.trustedCmd(pushCmd) 301 out, _, err := runCommandWithOutput(pushCmd) 302 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 303 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) 304 305 // Try pull after push 306 pullCmd := exec.Command(dockerBinary, "pull", repoName) 307 s.trustedCmd(pullCmd) 308 out, _, err = runCommandWithOutput(pullCmd) 309 c.Assert(err, check.IsNil, check.Commentf(out)) 310 c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out)) 311 } 312 313 func (s *DockerTrustSuite) TestTrustedPushWithExistingSignedTag(c *check.C) { 314 repoName := fmt.Sprintf("%v/dockerclipushpush/trusted:latest", privateRegistryURL) 315 // tag the image and upload it to the private registry 316 dockerCmd(c, "tag", "busybox", repoName) 317 318 // Do a trusted push 319 pushCmd := exec.Command(dockerBinary, "push", repoName) 320 s.trustedCmd(pushCmd) 321 out, _, err := runCommandWithOutput(pushCmd) 322 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 323 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) 324 325 // Do another trusted push 326 pushCmd = exec.Command(dockerBinary, "push", repoName) 327 s.trustedCmd(pushCmd) 328 out, _, err = runCommandWithOutput(pushCmd) 329 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 330 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) 331 332 dockerCmd(c, "rmi", repoName) 333 334 // Try pull to ensure the double push did not break our ability to pull 335 pullCmd := exec.Command(dockerBinary, "pull", repoName) 336 s.trustedCmd(pullCmd) 337 out, _, err = runCommandWithOutput(pullCmd) 338 c.Assert(err, check.IsNil, check.Commentf("Error running trusted pull: %s\n%s", err, out)) 339 c.Assert(out, checker.Contains, "Status: Downloaded", check.Commentf("Missing expected output on trusted pull with --disable-content-trust")) 340 341 } 342 343 func (s *DockerTrustSuite) TestTrustedPushWithIncorrectPassphraseForNonRoot(c *check.C) { 344 repoName := fmt.Sprintf("%v/dockercliincorretpwd/trusted:latest", privateRegistryURL) 345 // tag the image and upload it to the private registry 346 dockerCmd(c, "tag", "busybox", repoName) 347 348 // Push with default passphrases 349 pushCmd := exec.Command(dockerBinary, "push", repoName) 350 s.trustedCmd(pushCmd) 351 out, _, err := runCommandWithOutput(pushCmd) 352 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 353 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push:\n%s", out)) 354 355 // Push with wrong passphrases 356 pushCmd = exec.Command(dockerBinary, "push", repoName) 357 s.trustedCmdWithPassphrases(pushCmd, "12345678", "87654321") 358 out, _, err = runCommandWithOutput(pushCmd) 359 c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with short targets passphrase: \n%s", out)) 360 c.Assert(out, checker.Contains, "could not find necessary signing keys", check.Commentf("Missing expected output on trusted push with short targets/snapsnot passphrase")) 361 } 362 363 // This test ensures backwards compatibility with old ENV variables. Should be 364 // deprecated by 1.10 365 func (s *DockerTrustSuite) TestTrustedPushWithIncorrectDeprecatedPassphraseForNonRoot(c *check.C) { 366 repoName := fmt.Sprintf("%v/dockercliincorretdeprecatedpwd/trusted:latest", privateRegistryURL) 367 // tag the image and upload it to the private registry 368 dockerCmd(c, "tag", "busybox", repoName) 369 370 // Push with default passphrases 371 pushCmd := exec.Command(dockerBinary, "push", repoName) 372 s.trustedCmd(pushCmd) 373 out, _, err := runCommandWithOutput(pushCmd) 374 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 375 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 376 377 // Push with wrong passphrases 378 pushCmd = exec.Command(dockerBinary, "push", repoName) 379 s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "87654321") 380 out, _, err = runCommandWithOutput(pushCmd) 381 c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with short targets passphrase: \n%s", out)) 382 c.Assert(out, checker.Contains, "could not find necessary signing keys", check.Commentf("Missing expected output on trusted push with short targets/snapsnot passphrase")) 383 } 384 385 func (s *DockerTrustSuite) TestTrustedPushWithExpiredSnapshot(c *check.C) { 386 c.Skip("Currently changes system time, causing instability") 387 repoName := fmt.Sprintf("%v/dockercliexpiredsnapshot/trusted:latest", privateRegistryURL) 388 // tag the image and upload it to the private registry 389 dockerCmd(c, "tag", "busybox", repoName) 390 391 // Push with default passphrases 392 pushCmd := exec.Command(dockerBinary, "push", repoName) 393 s.trustedCmd(pushCmd) 394 out, _, err := runCommandWithOutput(pushCmd) 395 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 396 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 397 398 // Snapshots last for three years. This should be expired 399 fourYearsLater := time.Now().Add(time.Hour * 24 * 365 * 4) 400 401 runAtDifferentDate(fourYearsLater, func() { 402 // Push with wrong passphrases 403 pushCmd = exec.Command(dockerBinary, "push", repoName) 404 s.trustedCmd(pushCmd) 405 out, _, err = runCommandWithOutput(pushCmd) 406 c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with expired snapshot: \n%s", out)) 407 c.Assert(out, checker.Contains, "repository out-of-date", check.Commentf("Missing expected output on trusted push with expired snapshot")) 408 }) 409 } 410 411 func (s *DockerTrustSuite) TestTrustedPushWithExpiredTimestamp(c *check.C) { 412 c.Skip("Currently changes system time, causing instability") 413 repoName := fmt.Sprintf("%v/dockercliexpiredtimestamppush/trusted:latest", privateRegistryURL) 414 // tag the image and upload it to the private registry 415 dockerCmd(c, "tag", "busybox", repoName) 416 417 // Push with default passphrases 418 pushCmd := exec.Command(dockerBinary, "push", repoName) 419 s.trustedCmd(pushCmd) 420 out, _, err := runCommandWithOutput(pushCmd) 421 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 422 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 423 424 // The timestamps expire in two weeks. Lets check three 425 threeWeeksLater := time.Now().Add(time.Hour * 24 * 21) 426 427 // Should succeed because the server transparently re-signs one 428 runAtDifferentDate(threeWeeksLater, func() { 429 pushCmd := exec.Command(dockerBinary, "push", repoName) 430 s.trustedCmd(pushCmd) 431 out, _, err := runCommandWithOutput(pushCmd) 432 c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) 433 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with expired timestamp")) 434 }) 435 } 436 437 func (s *DockerTrustSuite) TestTrustedPushWithReleasesDelegation(c *check.C) { 438 repoName := fmt.Sprintf("%v/dockerclireleasedelegation/trusted", privateRegistryURL) 439 targetName := fmt.Sprintf("%s:latest", repoName) 440 pwd := "12345678" 441 s.setupDelegations(c, repoName, pwd) 442 443 // tag the image and upload it to the private registry 444 dockerCmd(c, "tag", "busybox", targetName) 445 446 pushCmd := exec.Command(dockerBinary, "-D", "push", targetName) 447 s.trustedCmdWithPassphrases(pushCmd, pwd, pwd) 448 out, _, err := runCommandWithOutput(pushCmd) 449 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 450 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) 451 452 // Try pull after push 453 pullCmd := exec.Command(dockerBinary, "pull", targetName) 454 s.trustedCmd(pullCmd) 455 out, _, err = runCommandWithOutput(pullCmd) 456 c.Assert(err, check.IsNil, check.Commentf(out)) 457 c.Assert(string(out), checker.Contains, "Status: Downloaded", check.Commentf(out)) 458 459 // check to make sure that the target has been added to targets/releases and not targets 460 contents, err := ioutil.ReadFile(filepath.Join(cliconfig.ConfigDir(), "trust/tuf", repoName, "metadata/targets.json")) 461 c.Assert(err, check.IsNil, check.Commentf("Unable to read targets metadata")) 462 c.Assert(strings.Contains(string(contents), `"latest"`), checker.False, check.Commentf(string(contents))) 463 464 contents, err = ioutil.ReadFile(filepath.Join(cliconfig.ConfigDir(), "trust/tuf", repoName, "metadata/targets/releases.json")) 465 c.Assert(err, check.IsNil, check.Commentf("Unable to read targets/releases metadata")) 466 c.Assert(string(contents), checker.Contains, `"latest"`, check.Commentf(string(contents))) 467 }