github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/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/docker/docker/pkg/integration/checker" 13 "github.com/go-check/check" 14 ) 15 16 // Pushing an image to a private registry. 17 func (s *DockerRegistrySuite) TestPushBusyboxImage(c *check.C) { 18 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 19 // tag the image to upload it to the private registry 20 dockerCmd(c, "tag", "busybox", repoName) 21 // push the image to the registry 22 dockerCmd(c, "push", repoName) 23 } 24 25 // pushing an image without a prefix should throw an error 26 func (s *DockerSuite) TestPushUnprefixedRepo(c *check.C) { 27 out, _, err := dockerCmdWithError("push", "busybox") 28 c.Assert(err, check.NotNil, check.Commentf("pushing an unprefixed repo didn't result in a non-zero exit status: %s", out)) 29 } 30 31 func (s *DockerRegistrySuite) TestPushUntagged(c *check.C) { 32 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 33 expected := "Repository does not exist" 34 35 out, _, err := dockerCmdWithError("push", repoName) 36 c.Assert(err, check.NotNil, check.Commentf("pushing the image to the private registry should have failed: output %q", out)) 37 c.Assert(out, checker.Contains, expected, check.Commentf("pushing the image failed")) 38 } 39 40 func (s *DockerRegistrySuite) TestPushBadTag(c *check.C) { 41 repoName := fmt.Sprintf("%v/dockercli/busybox:latest", privateRegistryURL) 42 expected := "does not exist" 43 44 out, _, err := dockerCmdWithError("push", repoName) 45 c.Assert(err, check.NotNil, check.Commentf("pushing the image to the private registry should have failed: output %q", out)) 46 c.Assert(out, checker.Contains, expected, check.Commentf("pushing the image failed")) 47 } 48 49 func (s *DockerRegistrySuite) TestPushMultipleTags(c *check.C) { 50 repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) 51 repoTag1 := fmt.Sprintf("%v/dockercli/busybox:t1", privateRegistryURL) 52 repoTag2 := fmt.Sprintf("%v/dockercli/busybox:t2", privateRegistryURL) 53 // tag the image and upload it to the private registry 54 dockerCmd(c, "tag", "busybox", repoTag1) 55 56 dockerCmd(c, "tag", "busybox", repoTag2) 57 58 dockerCmd(c, "push", repoName) 59 60 // Ensure layer list is equivalent for repoTag1 and repoTag2 61 out1, _ := dockerCmd(c, "pull", repoTag1) 62 63 imageAlreadyExists := ": Image already exists" 64 var out1Lines []string 65 for _, outputLine := range strings.Split(out1, "\n") { 66 if strings.Contains(outputLine, imageAlreadyExists) { 67 out1Lines = append(out1Lines, outputLine) 68 } 69 } 70 71 out2, _ := dockerCmd(c, "pull", repoTag2) 72 73 var out2Lines []string 74 for _, outputLine := range strings.Split(out2, "\n") { 75 if strings.Contains(outputLine, imageAlreadyExists) { 76 out1Lines = append(out1Lines, outputLine) 77 } 78 } 79 c.Assert(out2Lines, checker.HasLen, len(out1Lines)) 80 81 for i := range out1Lines { 82 c.Assert(out1Lines[i], checker.Equals, out2Lines[i]) 83 } 84 } 85 86 func (s *DockerRegistrySuite) TestPushEmptyLayer(c *check.C) { 87 repoName := fmt.Sprintf("%v/dockercli/emptylayer", privateRegistryURL) 88 emptyTarball, err := ioutil.TempFile("", "empty_tarball") 89 c.Assert(err, check.IsNil, check.Commentf("Unable to create test file")) 90 91 tw := tar.NewWriter(emptyTarball) 92 err = tw.Close() 93 c.Assert(err, check.IsNil, check.Commentf("Error creating empty tarball")) 94 95 freader, err := os.Open(emptyTarball.Name()) 96 c.Assert(err, check.IsNil, check.Commentf("Could not open test tarball")) 97 98 importCmd := exec.Command(dockerBinary, "import", "-", repoName) 99 importCmd.Stdin = freader 100 out, _, err := runCommandWithOutput(importCmd) 101 c.Assert(err, check.IsNil, check.Commentf("import failed: %q", out)) 102 103 // Now verify we can push it 104 out, _, err = dockerCmdWithError("push", repoName) 105 c.Assert(err, check.IsNil, check.Commentf("pushing the image to the private registry has failed: %s", out)) 106 } 107 108 func (s *DockerTrustSuite) TestTrustedPush(c *check.C) { 109 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 110 // tag the image and upload it to the private registry 111 dockerCmd(c, "tag", "busybox", repoName) 112 113 pushCmd := exec.Command(dockerBinary, "push", repoName) 114 s.trustedCmd(pushCmd) 115 out, _, err := runCommandWithOutput(pushCmd) 116 c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) 117 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 118 } 119 120 func (s *DockerTrustSuite) TestTrustedPushWithEnvPasswords(c *check.C) { 121 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 122 // tag the image and upload it to the private registry 123 dockerCmd(c, "tag", "busybox", repoName) 124 125 pushCmd := exec.Command(dockerBinary, "push", repoName) 126 s.trustedCmdWithPassphrases(pushCmd, "12345678", "12345678") 127 out, _, err := runCommandWithOutput(pushCmd) 128 c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) 129 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 130 } 131 132 // This test ensures backwards compatibility with old ENV variables. Should be 133 // deprecated by 1.10 134 func (s *DockerTrustSuite) TestTrustedPushWithDeprecatedEnvPasswords(c *check.C) { 135 repoName := fmt.Sprintf("%v/dockercli/trusteddeprecated:latest", privateRegistryURL) 136 // tag the image and upload it to the private registry 137 dockerCmd(c, "tag", "busybox", repoName) 138 139 pushCmd := exec.Command(dockerBinary, "push", repoName) 140 s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "12345678") 141 out, _, err := runCommandWithOutput(pushCmd) 142 c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %s\n%s", err, out)) 143 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 144 } 145 146 func (s *DockerTrustSuite) TestTrustedPushWithFailingServer(c *check.C) { 147 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 148 // tag the image and upload it to the private registry 149 dockerCmd(c, "tag", "busybox", repoName) 150 151 pushCmd := exec.Command(dockerBinary, "push", repoName) 152 s.trustedCmdWithServer(pushCmd, "https://example.com:81/") 153 out, _, err := runCommandWithOutput(pushCmd) 154 c.Assert(err, check.NotNil, check.Commentf("Missing error while running trusted push w/ no server")) 155 c.Assert(out, checker.Contains, "error contacting notary server", check.Commentf("Missing expected output on trusted push")) 156 } 157 158 func (s *DockerTrustSuite) TestTrustedPushWithoutServerAndUntrusted(c *check.C) { 159 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 160 // tag the image and upload it to the private registry 161 dockerCmd(c, "tag", "busybox", repoName) 162 163 pushCmd := exec.Command(dockerBinary, "push", "--disable-content-trust", repoName) 164 s.trustedCmdWithServer(pushCmd, "https://example.com/") 165 out, _, err := runCommandWithOutput(pushCmd) 166 c.Assert(err, check.IsNil, check.Commentf("trusted push with no server and --disable-content-trust failed: %s\n%s", err, out)) 167 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:")) 168 } 169 170 func (s *DockerTrustSuite) TestTrustedPushWithExistingTag(c *check.C) { 171 repoName := fmt.Sprintf("%v/dockercli/trusted:latest", privateRegistryURL) 172 // tag the image and upload it to the private registry 173 dockerCmd(c, "tag", "busybox", repoName) 174 dockerCmd(c, "push", repoName) 175 176 pushCmd := exec.Command(dockerBinary, "push", repoName) 177 s.trustedCmd(pushCmd) 178 out, _, err := runCommandWithOutput(pushCmd) 179 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 180 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) 181 } 182 183 func (s *DockerTrustSuite) TestTrustedPushWithExistingSignedTag(c *check.C) { 184 repoName := fmt.Sprintf("%v/dockerclipushpush/trusted:latest", privateRegistryURL) 185 // tag the image and upload it to the private registry 186 dockerCmd(c, "tag", "busybox", repoName) 187 188 // Do a trusted push 189 pushCmd := exec.Command(dockerBinary, "push", repoName) 190 s.trustedCmd(pushCmd) 191 out, _, err := runCommandWithOutput(pushCmd) 192 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 193 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) 194 195 // Do another trusted push 196 pushCmd = exec.Command(dockerBinary, "push", repoName) 197 s.trustedCmd(pushCmd) 198 out, _, err = runCommandWithOutput(pushCmd) 199 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 200 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push with existing tag")) 201 202 dockerCmd(c, "rmi", repoName) 203 204 // Try pull to ensure the double push did not break our ability to pull 205 pullCmd := exec.Command(dockerBinary, "pull", repoName) 206 s.trustedCmd(pullCmd) 207 out, _, err = runCommandWithOutput(pullCmd) 208 c.Assert(err, check.IsNil, check.Commentf("Error running trusted pull: %s\n%s", err, out)) 209 c.Assert(out, checker.Contains, "Status: Downloaded", check.Commentf("Missing expected output on trusted pull with --disable-content-trust")) 210 211 } 212 213 func (s *DockerTrustSuite) TestTrustedPushWithIncorrectPassphraseForNonRoot(c *check.C) { 214 repoName := fmt.Sprintf("%v/dockercliincorretpwd/trusted:latest", privateRegistryURL) 215 // tag the image and upload it to the private registry 216 dockerCmd(c, "tag", "busybox", repoName) 217 218 // Push with default passphrases 219 pushCmd := exec.Command(dockerBinary, "push", repoName) 220 s.trustedCmd(pushCmd) 221 out, _, err := runCommandWithOutput(pushCmd) 222 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 223 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push:\n%s", out)) 224 225 // Push with wrong passphrases 226 pushCmd = exec.Command(dockerBinary, "push", repoName) 227 s.trustedCmdWithPassphrases(pushCmd, "12345678", "87654321") 228 out, _, err = runCommandWithOutput(pushCmd) 229 c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with short targets passphrase: \n%s", out)) 230 c.Assert(out, checker.Contains, "could not find necessary signing keys", check.Commentf("Missing expected output on trusted push with short targets/snapsnot passphrase")) 231 } 232 233 // This test ensures backwards compatibility with old ENV variables. Should be 234 // deprecated by 1.10 235 func (s *DockerTrustSuite) TestTrustedPushWithIncorrectDeprecatedPassphraseForNonRoot(c *check.C) { 236 repoName := fmt.Sprintf("%v/dockercliincorretdeprecatedpwd/trusted:latest", privateRegistryURL) 237 // tag the image and upload it to the private registry 238 dockerCmd(c, "tag", "busybox", repoName) 239 240 // Push with default passphrases 241 pushCmd := exec.Command(dockerBinary, "push", repoName) 242 s.trustedCmd(pushCmd) 243 out, _, err := runCommandWithOutput(pushCmd) 244 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %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 // Push with wrong passphrases 248 pushCmd = exec.Command(dockerBinary, "push", repoName) 249 s.trustedCmdWithDeprecatedEnvPassphrases(pushCmd, "12345678", "87654321") 250 out, _, err = runCommandWithOutput(pushCmd) 251 c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with short targets passphrase: \n%s", out)) 252 c.Assert(out, checker.Contains, "could not find necessary signing keys", check.Commentf("Missing expected output on trusted push with short targets/snapsnot passphrase")) 253 } 254 255 func (s *DockerTrustSuite) TestTrustedPushWithExpiredSnapshot(c *check.C) { 256 c.Skip("Currently changes system time, causing instability") 257 repoName := fmt.Sprintf("%v/dockercliexpiredsnapshot/trusted:latest", privateRegistryURL) 258 // tag the image and upload it to the private registry 259 dockerCmd(c, "tag", "busybox", repoName) 260 261 // Push with default passphrases 262 pushCmd := exec.Command(dockerBinary, "push", repoName) 263 s.trustedCmd(pushCmd) 264 out, _, err := runCommandWithOutput(pushCmd) 265 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %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 // Snapshots last for three years. This should be expired 269 fourYearsLater := time.Now().Add(time.Hour * 24 * 365 * 4) 270 271 runAtDifferentDate(fourYearsLater, func() { 272 // Push with wrong passphrases 273 pushCmd = exec.Command(dockerBinary, "push", repoName) 274 s.trustedCmd(pushCmd) 275 out, _, err = runCommandWithOutput(pushCmd) 276 c.Assert(err, check.NotNil, check.Commentf("Error missing from trusted push with expired snapshot: \n%s", out)) 277 c.Assert(out, checker.Contains, "repository out-of-date", check.Commentf("Missing expected output on trusted push with expired snapshot")) 278 }) 279 } 280 281 func (s *DockerTrustSuite) TestTrustedPushWithExpiredTimestamp(c *check.C) { 282 c.Skip("Currently changes system time, causing instability") 283 repoName := fmt.Sprintf("%v/dockercliexpiredtimestamppush/trusted:latest", privateRegistryURL) 284 // tag the image and upload it to the private registry 285 dockerCmd(c, "tag", "busybox", repoName) 286 287 // Push with default passphrases 288 pushCmd := exec.Command(dockerBinary, "push", repoName) 289 s.trustedCmd(pushCmd) 290 out, _, err := runCommandWithOutput(pushCmd) 291 c.Assert(err, check.IsNil, check.Commentf("trusted push failed: %s\n%s", err, out)) 292 c.Assert(out, checker.Contains, "Signing and pushing trust metadata", check.Commentf("Missing expected output on trusted push")) 293 294 // The timestamps expire in two weeks. Lets check three 295 threeWeeksLater := time.Now().Add(time.Hour * 24 * 21) 296 297 // Should succeed because the server transparently re-signs one 298 runAtDifferentDate(threeWeeksLater, func() { 299 pushCmd := exec.Command(dockerBinary, "push", repoName) 300 s.trustedCmd(pushCmd) 301 out, _, err := runCommandWithOutput(pushCmd) 302 c.Assert(err, check.IsNil, check.Commentf("Error running trusted push: %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 expired timestamp")) 304 }) 305 }