github.com/guilhermebr/docker@v1.4.2-0.20150428121140-67da055cebca/integration-cli/docker_cli_by_digest_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os/exec" 6 "regexp" 7 "strings" 8 9 "github.com/docker/docker/utils" 10 "github.com/go-check/check" 11 ) 12 13 var ( 14 repoName = fmt.Sprintf("%v/dockercli/busybox-by-dgst", privateRegistryURL) 15 digestRegex = regexp.MustCompile("Digest: ([^\n]+)") 16 ) 17 18 func setupImage() (string, error) { 19 return setupImageWithTag("latest") 20 } 21 22 func setupImageWithTag(tag string) (string, error) { 23 containerName := "busyboxbydigest" 24 25 cmd := exec.Command(dockerBinary, "run", "-d", "-e", "digest=1", "--name", containerName, "busybox") 26 if _, err := runCommand(cmd); err != nil { 27 return "", err 28 } 29 30 // tag the image to upload it to the private registry 31 repoAndTag := utils.ImageReference(repoName, tag) 32 cmd = exec.Command(dockerBinary, "commit", containerName, repoAndTag) 33 if out, _, err := runCommandWithOutput(cmd); err != nil { 34 return "", fmt.Errorf("image tagging failed: %s, %v", out, err) 35 } 36 37 // delete the container as we don't need it any more 38 if err := deleteContainer(containerName); err != nil { 39 return "", err 40 } 41 42 // push the image 43 cmd = exec.Command(dockerBinary, "push", repoAndTag) 44 out, _, err := runCommandWithOutput(cmd) 45 if err != nil { 46 return "", fmt.Errorf("pushing the image to the private registry has failed: %s, %v", out, err) 47 } 48 49 // delete our local repo that we previously tagged 50 cmd = exec.Command(dockerBinary, "rmi", repoAndTag) 51 if out, _, err := runCommandWithOutput(cmd); err != nil { 52 return "", fmt.Errorf("error deleting images prior to real test: %s, %v", out, err) 53 } 54 55 // the push output includes "Digest: <digest>", so find that 56 matches := digestRegex.FindStringSubmatch(out) 57 if len(matches) != 2 { 58 return "", fmt.Errorf("unable to parse digest from push output: %s", out) 59 } 60 pushDigest := matches[1] 61 62 return pushDigest, nil 63 } 64 65 func (s *DockerRegistrySuite) TestPullByTagDisplaysDigest(c *check.C) { 66 pushDigest, err := setupImage() 67 if err != nil { 68 c.Fatalf("error setting up image: %v", err) 69 } 70 71 // pull from the registry using the tag 72 cmd := exec.Command(dockerBinary, "pull", repoName) 73 out, _, err := runCommandWithOutput(cmd) 74 if err != nil { 75 c.Fatalf("error pulling by tag: %s, %v", out, err) 76 } 77 78 // the pull output includes "Digest: <digest>", so find that 79 matches := digestRegex.FindStringSubmatch(out) 80 if len(matches) != 2 { 81 c.Fatalf("unable to parse digest from pull output: %s", out) 82 } 83 pullDigest := matches[1] 84 85 // make sure the pushed and pull digests match 86 if pushDigest != pullDigest { 87 c.Fatalf("push digest %q didn't match pull digest %q", pushDigest, pullDigest) 88 } 89 } 90 91 func (s *DockerRegistrySuite) TestPullByDigest(c *check.C) { 92 pushDigest, err := setupImage() 93 if err != nil { 94 c.Fatalf("error setting up image: %v", err) 95 } 96 97 // pull from the registry using the <name>@<digest> reference 98 imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest) 99 cmd := exec.Command(dockerBinary, "pull", imageReference) 100 out, _, err := runCommandWithOutput(cmd) 101 if err != nil { 102 c.Fatalf("error pulling by digest: %s, %v", out, err) 103 } 104 105 // the pull output includes "Digest: <digest>", so find that 106 matches := digestRegex.FindStringSubmatch(out) 107 if len(matches) != 2 { 108 c.Fatalf("unable to parse digest from pull output: %s", out) 109 } 110 pullDigest := matches[1] 111 112 // make sure the pushed and pull digests match 113 if pushDigest != pullDigest { 114 c.Fatalf("push digest %q didn't match pull digest %q", pushDigest, pullDigest) 115 } 116 } 117 118 func (s *DockerRegistrySuite) TestCreateByDigest(c *check.C) { 119 pushDigest, err := setupImage() 120 if err != nil { 121 c.Fatalf("error setting up image: %v", err) 122 } 123 124 imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest) 125 126 containerName := "createByDigest" 127 cmd := exec.Command(dockerBinary, "create", "--name", containerName, imageReference) 128 out, _, err := runCommandWithOutput(cmd) 129 if err != nil { 130 c.Fatalf("error creating by digest: %s, %v", out, err) 131 } 132 133 res, err := inspectField(containerName, "Config.Image") 134 if err != nil { 135 c.Fatalf("failed to get Config.Image: %s, %v", out, err) 136 } 137 if res != imageReference { 138 c.Fatalf("unexpected Config.Image: %s (expected %s)", res, imageReference) 139 } 140 } 141 142 func (s *DockerRegistrySuite) TestRunByDigest(c *check.C) { 143 pushDigest, err := setupImage() 144 if err != nil { 145 c.Fatalf("error setting up image: %v", err) 146 } 147 148 imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest) 149 150 containerName := "runByDigest" 151 cmd := exec.Command(dockerBinary, "run", "--name", containerName, imageReference, "sh", "-c", "echo found=$digest") 152 out, _, err := runCommandWithOutput(cmd) 153 if err != nil { 154 c.Fatalf("error run by digest: %s, %v", out, err) 155 } 156 157 foundRegex := regexp.MustCompile("found=([^\n]+)") 158 matches := foundRegex.FindStringSubmatch(out) 159 if len(matches) != 2 { 160 c.Fatalf("error locating expected 'found=1' output: %s", out) 161 } 162 if matches[1] != "1" { 163 c.Fatalf("Expected %q, got %q", "1", matches[1]) 164 } 165 166 res, err := inspectField(containerName, "Config.Image") 167 if err != nil { 168 c.Fatalf("failed to get Config.Image: %s, %v", out, err) 169 } 170 if res != imageReference { 171 c.Fatalf("unexpected Config.Image: %s (expected %s)", res, imageReference) 172 } 173 } 174 175 func (s *DockerRegistrySuite) TestRemoveImageByDigest(c *check.C) { 176 digest, err := setupImage() 177 if err != nil { 178 c.Fatalf("error setting up image: %v", err) 179 } 180 181 imageReference := fmt.Sprintf("%s@%s", repoName, digest) 182 183 // pull from the registry using the <name>@<digest> reference 184 cmd := exec.Command(dockerBinary, "pull", imageReference) 185 out, _, err := runCommandWithOutput(cmd) 186 if err != nil { 187 c.Fatalf("error pulling by digest: %s, %v", out, err) 188 } 189 190 // make sure inspect runs ok 191 if _, err := inspectField(imageReference, "Id"); err != nil { 192 c.Fatalf("failed to inspect image: %v", err) 193 } 194 195 // do the delete 196 if err := deleteImages(imageReference); err != nil { 197 c.Fatalf("unexpected error deleting image: %v", err) 198 } 199 200 // try to inspect again - it should error this time 201 if _, err := inspectField(imageReference, "Id"); err == nil { 202 c.Fatalf("unexpected nil err trying to inspect what should be a non-existent image") 203 } else if !strings.Contains(err.Error(), "No such image") { 204 c.Fatalf("expected 'No such image' output, got %v", err) 205 } 206 } 207 208 func (s *DockerRegistrySuite) TestBuildByDigest(c *check.C) { 209 digest, err := setupImage() 210 if err != nil { 211 c.Fatalf("error setting up image: %v", err) 212 } 213 214 imageReference := fmt.Sprintf("%s@%s", repoName, digest) 215 216 // pull from the registry using the <name>@<digest> reference 217 cmd := exec.Command(dockerBinary, "pull", imageReference) 218 out, _, err := runCommandWithOutput(cmd) 219 if err != nil { 220 c.Fatalf("error pulling by digest: %s, %v", out, err) 221 } 222 223 // get the image id 224 imageID, err := inspectField(imageReference, "Id") 225 if err != nil { 226 c.Fatalf("error getting image id: %v", err) 227 } 228 229 // do the build 230 name := "buildbydigest" 231 _, err = buildImage(name, fmt.Sprintf( 232 `FROM %s 233 CMD ["/bin/echo", "Hello World"]`, imageReference), 234 true) 235 if err != nil { 236 c.Fatal(err) 237 } 238 239 // get the build's image id 240 res, err := inspectField(name, "Config.Image") 241 if err != nil { 242 c.Fatal(err) 243 } 244 // make sure they match 245 if res != imageID { 246 c.Fatalf("Image %s, expected %s", res, imageID) 247 } 248 } 249 250 func (s *DockerRegistrySuite) TestTagByDigest(c *check.C) { 251 digest, err := setupImage() 252 if err != nil { 253 c.Fatalf("error setting up image: %v", err) 254 } 255 256 imageReference := fmt.Sprintf("%s@%s", repoName, digest) 257 258 // pull from the registry using the <name>@<digest> reference 259 cmd := exec.Command(dockerBinary, "pull", imageReference) 260 out, _, err := runCommandWithOutput(cmd) 261 if err != nil { 262 c.Fatalf("error pulling by digest: %s, %v", out, err) 263 } 264 265 // tag it 266 tag := "tagbydigest" 267 cmd = exec.Command(dockerBinary, "tag", imageReference, tag) 268 if _, err := runCommand(cmd); err != nil { 269 c.Fatalf("unexpected error tagging: %v", err) 270 } 271 272 expectedID, err := inspectField(imageReference, "Id") 273 if err != nil { 274 c.Fatalf("error getting original image id: %v", err) 275 } 276 277 tagID, err := inspectField(tag, "Id") 278 if err != nil { 279 c.Fatalf("error getting tagged image id: %v", err) 280 } 281 282 if tagID != expectedID { 283 c.Fatalf("expected image id %q, got %q", expectedID, tagID) 284 } 285 } 286 287 func (s *DockerRegistrySuite) TestListImagesWithoutDigests(c *check.C) { 288 digest, err := setupImage() 289 if err != nil { 290 c.Fatalf("error setting up image: %v", err) 291 } 292 293 imageReference := fmt.Sprintf("%s@%s", repoName, digest) 294 295 // pull from the registry using the <name>@<digest> reference 296 cmd := exec.Command(dockerBinary, "pull", imageReference) 297 out, _, err := runCommandWithOutput(cmd) 298 if err != nil { 299 c.Fatalf("error pulling by digest: %s, %v", out, err) 300 } 301 302 cmd = exec.Command(dockerBinary, "images") 303 out, _, err = runCommandWithOutput(cmd) 304 if err != nil { 305 c.Fatalf("error listing images: %s, %v", out, err) 306 } 307 308 if strings.Contains(out, "DIGEST") { 309 c.Fatalf("list output should not have contained DIGEST header: %s", out) 310 } 311 312 } 313 314 func (s *DockerRegistrySuite) TestListImagesWithDigests(c *check.C) { 315 316 // setup image1 317 digest1, err := setupImageWithTag("tag1") 318 if err != nil { 319 c.Fatalf("error setting up image: %v", err) 320 } 321 imageReference1 := fmt.Sprintf("%s@%s", repoName, digest1) 322 c.Logf("imageReference1 = %s", imageReference1) 323 324 // pull image1 by digest 325 cmd := exec.Command(dockerBinary, "pull", imageReference1) 326 out, _, err := runCommandWithOutput(cmd) 327 if err != nil { 328 c.Fatalf("error pulling by digest: %s, %v", out, err) 329 } 330 331 // list images 332 cmd = exec.Command(dockerBinary, "images", "--digests") 333 out, _, err = runCommandWithOutput(cmd) 334 if err != nil { 335 c.Fatalf("error listing images: %s, %v", out, err) 336 } 337 338 // make sure repo shown, tag=<none>, digest = $digest1 339 re1 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest1 + `\s`) 340 if !re1.MatchString(out) { 341 c.Fatalf("expected %q: %s", re1.String(), out) 342 } 343 344 // setup image2 345 digest2, err := setupImageWithTag("tag2") 346 if err != nil { 347 c.Fatalf("error setting up image: %v", err) 348 } 349 imageReference2 := fmt.Sprintf("%s@%s", repoName, digest2) 350 c.Logf("imageReference2 = %s", imageReference2) 351 352 // pull image1 by digest 353 cmd = exec.Command(dockerBinary, "pull", imageReference1) 354 out, _, err = runCommandWithOutput(cmd) 355 if err != nil { 356 c.Fatalf("error pulling by digest: %s, %v", out, err) 357 } 358 359 // pull image2 by digest 360 cmd = exec.Command(dockerBinary, "pull", imageReference2) 361 out, _, err = runCommandWithOutput(cmd) 362 if err != nil { 363 c.Fatalf("error pulling by digest: %s, %v", out, err) 364 } 365 366 // list images 367 cmd = exec.Command(dockerBinary, "images", "--digests") 368 out, _, err = runCommandWithOutput(cmd) 369 if err != nil { 370 c.Fatalf("error listing images: %s, %v", out, err) 371 } 372 373 // make sure repo shown, tag=<none>, digest = $digest1 374 if !re1.MatchString(out) { 375 c.Fatalf("expected %q: %s", re1.String(), out) 376 } 377 378 // make sure repo shown, tag=<none>, digest = $digest2 379 re2 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest2 + `\s`) 380 if !re2.MatchString(out) { 381 c.Fatalf("expected %q: %s", re2.String(), out) 382 } 383 384 // pull tag1 385 cmd = exec.Command(dockerBinary, "pull", repoName+":tag1") 386 out, _, err = runCommandWithOutput(cmd) 387 if err != nil { 388 c.Fatalf("error pulling tag1: %s, %v", out, err) 389 } 390 391 // list images 392 cmd = exec.Command(dockerBinary, "images", "--digests") 393 out, _, err = runCommandWithOutput(cmd) 394 if err != nil { 395 c.Fatalf("error listing images: %s, %v", out, err) 396 } 397 398 // make sure image 1 has repo, tag, <none> AND repo, <none>, digest 399 reWithTag1 := regexp.MustCompile(`\s*` + repoName + `\s*tag1\s*<none>\s`) 400 reWithDigest1 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest1 + `\s`) 401 if !reWithTag1.MatchString(out) { 402 c.Fatalf("expected %q: %s", reWithTag1.String(), out) 403 } 404 if !reWithDigest1.MatchString(out) { 405 c.Fatalf("expected %q: %s", reWithDigest1.String(), out) 406 } 407 // make sure image 2 has repo, <none>, digest 408 if !re2.MatchString(out) { 409 c.Fatalf("expected %q: %s", re2.String(), out) 410 } 411 412 // pull tag 2 413 cmd = exec.Command(dockerBinary, "pull", repoName+":tag2") 414 out, _, err = runCommandWithOutput(cmd) 415 if err != nil { 416 c.Fatalf("error pulling tag2: %s, %v", out, err) 417 } 418 419 // list images 420 cmd = exec.Command(dockerBinary, "images", "--digests") 421 out, _, err = runCommandWithOutput(cmd) 422 if err != nil { 423 c.Fatalf("error listing images: %s, %v", out, err) 424 } 425 426 // make sure image 1 has repo, tag, digest 427 if !reWithTag1.MatchString(out) { 428 c.Fatalf("expected %q: %s", re1.String(), out) 429 } 430 431 // make sure image 2 has repo, tag, digest 432 reWithTag2 := regexp.MustCompile(`\s*` + repoName + `\s*tag2\s*<none>\s`) 433 reWithDigest2 := regexp.MustCompile(`\s*` + repoName + `\s*<none>\s*` + digest2 + `\s`) 434 if !reWithTag2.MatchString(out) { 435 c.Fatalf("expected %q: %s", reWithTag2.String(), out) 436 } 437 if !reWithDigest2.MatchString(out) { 438 c.Fatalf("expected %q: %s", reWithDigest2.String(), out) 439 } 440 441 // list images 442 cmd = exec.Command(dockerBinary, "images", "--digests") 443 out, _, err = runCommandWithOutput(cmd) 444 if err != nil { 445 c.Fatalf("error listing images: %s, %v", out, err) 446 } 447 448 // make sure image 1 has repo, tag, digest 449 if !reWithTag1.MatchString(out) { 450 c.Fatalf("expected %q: %s", re1.String(), out) 451 } 452 // make sure image 2 has repo, tag, digest 453 if !reWithTag2.MatchString(out) { 454 c.Fatalf("expected %q: %s", re2.String(), out) 455 } 456 // make sure busybox has tag, but not digest 457 busyboxRe := regexp.MustCompile(`\s*busybox\s*latest\s*<none>\s`) 458 if !busyboxRe.MatchString(out) { 459 c.Fatalf("expected %q: %s", busyboxRe.String(), out) 460 } 461 } 462 463 func (s *DockerRegistrySuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C) { 464 pushDigest, err := setupImage() 465 if err != nil { 466 c.Fatalf("error setting up image: %v", err) 467 } 468 469 // pull from the registry using the <name>@<digest> reference 470 imageReference := fmt.Sprintf("%s@%s", repoName, pushDigest) 471 cmd := exec.Command(dockerBinary, "pull", imageReference) 472 out, _, err := runCommandWithOutput(cmd) 473 if err != nil { 474 c.Fatalf("error pulling by digest: %s, %v", out, err) 475 } 476 // just in case... 477 478 imageID, err := inspectField(imageReference, ".Id") 479 if err != nil { 480 c.Fatalf("error inspecting image id: %v", err) 481 } 482 483 cmd = exec.Command(dockerBinary, "rmi", imageID) 484 if _, err := runCommand(cmd); err != nil { 485 c.Fatalf("error deleting image by id: %v", err) 486 } 487 }