github.com/damirazo/docker@v1.9.0/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 "strings" 10 "time" 11 12 "github.com/go-check/check" 13 ) 14 15 // Pushing an image to a private registry. 16 func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) { 17 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 18 // tag the image to upload it to the private registry 19 dockerCmd(c, "tag", "busybox", repoName) 20 // push the image to the registry 21 dockerCmd(c, "push", repoName) 22 } 23 24 // pushing an image without a prefix should throw an error 25 func (s *DockerSuite) TestPushUnprefixedRepo(c *check.C) { 26 if out, _, err := dockerCmdWithError("push", "busybox"); err == nil { 27 c.Fatalf("pushing an unprefixed repo didn't result in a non-zero exit status: %s", out) 28 } 29 } 30 31 func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) { 32 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 33 34 expected := "Repository does not exist" 35 if out, _, err := dockerCmdWithError("push", repoName); err == nil { 36 c.Fatalf("pushing the image to the private registry should have failed: output %q", out) 37 } else if !strings.Contains(out, expected) { 38 c.Fatalf("pushing the image failed with an unexpected message: expected %q, got %q", expected, out) 39 } 40 } 41 42 func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) { 43 repoName := fmt.Sprintf("%v/dockercli/busybox:latest", privateRegistryURL) 44 45 expected := "does not exist" 46 47 if out, _, err := dockerCmdWithError("push", repoName); err == nil { 48 c.Fatalf("pushing the image to the private registry should have failed: output %q", out) 49 } else if !strings.Contains(out, expected) { 50 c.Fatalf("pushing the image failed with an unexpected message: expected %q, got %q", expected, out) 51 } 52 } 53 54 func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) { 55 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 56 repoTag1 := fmt.Sprintf("%v/dockercli/busybox:t1", privateRegistryURL) 57 repoTag2 := fmt.Sprintf("%v/dockercli/busybox:t2", privateRegistryURL) 58 // tag the image and upload it to the private registry 59 dockerCmd(c, "tag", "busybox", repoTag1) 60 61 dockerCmd(c, "tag", "busybox", repoTag2) 62 63 dockerCmd(c, "push", repoName) 64 65 // Ensure layer list is equivalent for repoTag1 and repoTag2 66 out1, _ := dockerCmd(c, "pull", repoTag1) 67 if strings.Contains(out1, "Tag t1 not found") { 68 c.Fatalf("Unable to pull pushed image: %s", out1) 69 } 70 imageAlreadyExists := ": Image already exists" 71 var out1Lines []string 72 for _, outputLine := range strings.Split(out1, "\n") { 73 if strings.Contains(outputLine, imageAlreadyExists) { 74 out1Lines = append(out1Lines, outputLine) 75 } 76 } 77 78 out2, _ := dockerCmd(c, "pull", repoTag2) 79 if strings.Contains(out2, "Tag t2 not found") { 80 c.Fatalf("Unable to pull pushed image: %s", out1) 81 } 82 var out2Lines []string 83 for _, outputLine := range strings.Split(out2, "\n") { 84 if strings.Contains(outputLine, imageAlreadyExists) { 85 out1Lines = append(out1Lines, outputLine) 86 } 87 } 88 89 if len(out1Lines) != len(out2Lines) { 90 c.Fatalf("Mismatched output length:\n%s\n%s", out1, out2) 91 } 92 93 for i := range out1Lines { 94 if out1Lines[i] != out2Lines[i] { 95 c.Fatalf("Mismatched output line:\n%s\n%s", out1Lines[i], out2Lines[i]) 96 } 97 } 98 } 99 100 func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) { 101 repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL) 102 emptyTarball, err := ioutil.TempFile("", "empty_tarball") 103 if err != nil { 104 c.Fatalf("Unable to create test file: %v", err) 105 } 106 tw := tar.NewWriter(emptyTarball) 107 err = tw.Close() 108 if err != nil { 109 c.Fatalf("Error creating empty tarball: %v", err) 110 } 111 freader, err := os.Open(emptyTarball.Name()) 112 if err != nil { 113 c.Fatalf("Could not open test tarball: %v", err) 114 } 115 116 importCmd := exec.Command(dockerBinary, "import", "-", repoName) 117 importCmd.Stdin = freader 118 out, _, err := runCommandWithOutput(importCmd) 119 if err != nil { 120 c.Errorf("import failed with errors: %v, output: %q", err, out) 121 } 122 123 // Now verify we can push it 124 if out, _, err := dockerCmdWithError("push", repoName); err != nil { 125 c.Fatalf("pushing the image to the private registry has failed: %s, %v", out, err) 126 } 127 } 128 129 func (s *DockerTrustSuite) TestTrustedPush(c *check.C) { 130 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 131 // tag the image and upload it to the private registry 132 dockerCmd(c, "tag", "busybox", repoName) 133 134 pushCmd := exec.Command(dockerBinary, "push", repoName) 135 s.trustedCmd(pushCmd) 136 out, _, err := runCommandWithOutput(pushCmd) 137 if err != nil { 138 c.Fatalf("Error running trusted push: %s\n%s", err, out) 139 } 140 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 141 c.Fatalf("Missing expected output on trusted push:\n%s", out) 142 } 143 } 144 145 func (s *DockerTrustSuite) TestTrustedPushWithEnvPasswords(c *check.C) { 146 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 147 // tag the image and upload it to the private registry 148 dockerCmd(c, "tag", "busybox", repoName) 149 150 pushCmd := exec.Command(dockerBinary, "push", repoName) 151 s.trustedCmdWithPassphrases(pushCmd, "12345678", "12345678") 152 out, _, err := runCommandWithOutput(pushCmd) 153 if err != nil { 154 c.Fatalf("Error running trusted push: %s\n%s", err, out) 155 } 156 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 157 c.Fatalf("Missing expected output on trusted push:\n%s", out) 158 } 159 } 160 161 // This test ensures backwards compatibility with old ENV variables. Should be 162 // deprecated by 1.10 163 func (s *DockerTrustSuite) TestTrustedPushWithDeprecatedEnvPasswords(c *check.C) { 164 repoName := fmt.Sprintf("%v/dockercli/trusteddeprecated:latest", privateRegistryURL) 165 // tag the image and upload it to the private registry 166 dockerCmd(c, "tag", "busybox", repoName) 167 168 pushCmd := exec.Command(dockerBinary, "push", repoName) 169 s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "12345678") 170 out, _, err := runCommandWithOutput(pushCmd) 171 if err != nil { 172 c.Fatalf("Error running trusted push: %s\n%s", err, out) 173 } 174 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 175 c.Fatalf("Missing expected output on trusted push:\n%s", out) 176 } 177 } 178 179 func (s *DockerTrustSuite) TestTrustedPushWithFaillingServer(c *check.C) { 180 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 181 // tag the image and upload it to the private registry 182 dockerCmd(c, "tag", "busybox", repoName) 183 184 pushCmd := exec.Command(dockerBinary, "push", repoName) 185 s.trustedCmdWithServer(pushCmd, "https://example.com:81/") 186 out, _, err := runCommandWithOutput(pushCmd) 187 if err == nil { 188 c.Fatalf("Missing error while running trusted push w/ no server") 189 } 190 191 if !strings.Contains(string(out), "error contacting notary server") { 192 c.Fatalf("Missing expected output on trusted push:\n%s", out) 193 } 194 } 195 196 func (s *DockerTrustSuite) TestTrustedPushWithoutServerAndUntrusted(c *check.C) { 197 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 198 // tag the image and upload it to the private registry 199 dockerCmd(c, "tag", "busybox", repoName) 200 201 pushCmd := exec.Command(dockerBinary, "push", "--disable-content-trust", repoName) 202 s.trustedCmdWithServer(pushCmd, "https://example.com/") 203 out, _, err := runCommandWithOutput(pushCmd) 204 if err != nil { 205 c.Fatalf("trusted push with no server and --disable-content-trust failed: %s\n%s", err, out) 206 } 207 208 if strings.Contains(string(out), "Error establishing connection to notary repository") { 209 c.Fatalf("Missing expected output on trusted push with --disable-content-trust:\n%s", out) 210 } 211 } 212 213 func (s *DockerTrustSuite) TestTrustedPushWithExistingTag(c *check.C) { 214 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 215 // tag the image and upload it to the private registry 216 dockerCmd(c, "tag", "busybox", repoName) 217 dockerCmd(c, "push", repoName) 218 219 pushCmd := exec.Command(dockerBinary, "push", repoName) 220 s.trustedCmd(pushCmd) 221 out, _, err := runCommandWithOutput(pushCmd) 222 if err != nil { 223 c.Fatalf("trusted push failed: %s\n%s", err, out) 224 } 225 226 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 227 c.Fatalf("Missing expected output on trusted push with existing tag:\n%s", out) 228 } 229 } 230 231 func (s *DockerTrustSuite) TestTrustedPushWithExistingSignedTag(c *check.C) { 232 repoName := fmt.Sprintf("%v/dockerclipushpush/trusted:latest", privateRegistryURL) 233 // tag the image and upload it to the private registry 234 dockerCmd(c, "tag", "busybox", repoName) 235 236 // Do a trusted push 237 pushCmd := exec.Command(dockerBinary, "push", repoName) 238 s.trustedCmd(pushCmd) 239 out, _, err := runCommandWithOutput(pushCmd) 240 if err != nil { 241 c.Fatalf("trusted push failed: %s\n%s", err, out) 242 } 243 244 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 245 c.Fatalf("Missing expected output on trusted push with existing tag:\n%s", out) 246 } 247 248 // Do another trusted push 249 pushCmd = exec.Command(dockerBinary, "push", repoName) 250 s.trustedCmd(pushCmd) 251 out, _, err = runCommandWithOutput(pushCmd) 252 if err != nil { 253 c.Fatalf("trusted push failed: %s\n%s", err, out) 254 } 255 256 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 257 c.Fatalf("Missing expected output on trusted push with existing tag:\n%s", out) 258 } 259 260 dockerCmd(c, "rmi", repoName) 261 262 // Try pull to ensure the double push did not break our ability to pull 263 pullCmd := exec.Command(dockerBinary, "pull", repoName) 264 s.trustedCmd(pullCmd) 265 out, _, err = runCommandWithOutput(pullCmd) 266 if err != nil { 267 c.Fatalf("Error running trusted pull: %s\n%s", err, out) 268 } 269 270 if !strings.Contains(string(out), "Status: Downloaded") { 271 c.Fatalf("Missing expected output on trusted pull with --disable-content-trust:\n%s", out) 272 } 273 } 274 275 func (s *DockerTrustSuite) TestTrustedPushWithIncorrectPassphraseForNonRoot(c *check.C) { 276 repoName := fmt.Sprintf("%v/dockercliincorretpwd/trusted:latest", privateRegistryURL) 277 // tag the image and upload it to the private registry 278 dockerCmd(c, "tag", "busybox", repoName) 279 280 // Push with default passphrases 281 pushCmd := exec.Command(dockerBinary, "push", repoName) 282 s.trustedCmd(pushCmd) 283 out, _, err := runCommandWithOutput(pushCmd) 284 if err != nil { 285 c.Fatalf("trusted push failed: %s\n%s", err, out) 286 } 287 288 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 289 c.Fatalf("Missing expected output on trusted push:\n%s", out) 290 } 291 292 // Push with wrong passphrases 293 pushCmd = exec.Command(dockerBinary, "push", repoName) 294 s.trustedCmdWithPassphrases(pushCmd, "12345678", "87654321") 295 out, _, err = runCommandWithOutput(pushCmd) 296 if err == nil { 297 c.Fatalf("Error missing from trusted push with short targets passphrase: \n%s", out) 298 } 299 300 if !strings.Contains(string(out), "password invalid, operation has failed") { 301 c.Fatalf("Missing expected output on trusted push with short targets/snapsnot passphrase:\n%s", out) 302 } 303 } 304 305 // This test ensures backwards compatibility with old ENV variables. Should be 306 // deprecated by 1.10 307 func (s *DockerTrustSuite) TestTrustedPushWithIncorrectDeprecatedPassphraseForNonRoot(c *check.C) { 308 repoName := fmt.Sprintf("%v/dockercliincorretdeprecatedpwd/trusted:latest", privateRegistryURL) 309 // tag the image and upload it to the private registry 310 dockerCmd(c, "tag", "busybox", repoName) 311 312 // Push with default passphrases 313 pushCmd := exec.Command(dockerBinary, "push", repoName) 314 s.trustedCmd(pushCmd) 315 out, _, err := runCommandWithOutput(pushCmd) 316 if err != nil { 317 c.Fatalf("trusted push failed: %s\n%s", err, out) 318 } 319 320 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 321 c.Fatalf("Missing expected output on trusted push:\n%s", out) 322 } 323 324 // Push with wrong passphrases 325 pushCmd = exec.Command(dockerBinary, "push", repoName) 326 s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "87654321") 327 out, _, err = runCommandWithOutput(pushCmd) 328 if err == nil { 329 c.Fatalf("Error missing from trusted push with short targets passphrase: \n%s", out) 330 } 331 332 if !strings.Contains(string(out), "password invalid, operation has failed") { 333 c.Fatalf("Missing expected output on trusted push with short targets/snapsnot passphrase:\n%s", out) 334 } 335 } 336 337 func (s *DockerTrustSuite) TestTrustedPushWithExpiredSnapshot(c *check.C) { 338 c.Skip("Currently changes system time, causing instability") 339 repoName := fmt.Sprintf("%v/dockercliexpiredsnapshot/trusted:latest", privateRegistryURL) 340 // tag the image and upload it to the private registry 341 dockerCmd(c, "tag", "busybox", repoName) 342 343 // Push with default passphrases 344 pushCmd := exec.Command(dockerBinary, "push", repoName) 345 s.trustedCmd(pushCmd) 346 out, _, err := runCommandWithOutput(pushCmd) 347 if err != nil { 348 c.Fatalf("trusted push failed: %s\n%s", err, out) 349 } 350 351 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 352 c.Fatalf("Missing expected output on trusted push:\n%s", out) 353 } 354 355 // Snapshots last for three years. This should be expired 356 fourYearsLater := time.Now().Add(time.Hour * 24 * 365 * 4) 357 358 runAtDifferentDate(fourYearsLater, func() { 359 // Push with wrong passphrases 360 pushCmd = exec.Command(dockerBinary, "push", repoName) 361 s.trustedCmd(pushCmd) 362 out, _, err = runCommandWithOutput(pushCmd) 363 if err == nil { 364 c.Fatalf("Error missing from trusted push with expired snapshot: \n%s", out) 365 } 366 367 if !strings.Contains(string(out), "repository out-of-date") { 368 c.Fatalf("Missing expected output on trusted push with expired snapshot:\n%s", out) 369 } 370 }) 371 } 372 373 func (s *DockerTrustSuite) TestTrustedPushWithExpiredTimestamp(c *check.C) { 374 c.Skip("Currently changes system time, causing instability") 375 repoName := fmt.Sprintf("%v/dockercliexpiredtimestamppush/trusted:latest", privateRegistryURL) 376 // tag the image and upload it to the private registry 377 dockerCmd(c, "tag", "busybox", repoName) 378 379 // Push with default passphrases 380 pushCmd := exec.Command(dockerBinary, "push", repoName) 381 s.trustedCmd(pushCmd) 382 out, _, err := runCommandWithOutput(pushCmd) 383 if err != nil { 384 c.Fatalf("trusted push failed: %s\n%s", err, out) 385 } 386 387 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 388 c.Fatalf("Missing expected output on trusted push:\n%s", out) 389 } 390 391 // The timestamps expire in two weeks. Lets check three 392 threeWeeksLater := time.Now().Add(time.Hour * 24 * 21) 393 394 // Should succeed because the server transparently re-signs one 395 runAtDifferentDate(threeWeeksLater, func() { 396 pushCmd := exec.Command(dockerBinary, "push", repoName) 397 s.trustedCmd(pushCmd) 398 out, _, err := runCommandWithOutput(pushCmd) 399 if err != nil { 400 c.Fatalf("Error running trusted push: %s\n%s", err, out) 401 } 402 if !strings.Contains(string(out), "Signing and pushing trust metadata") { 403 c.Fatalf("Missing expected output on trusted push with expired timestamp:\n%s", out) 404 } 405 }) 406 }