123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- package main
- import (
- "fmt"
- "os/exec"
- "strings"
- "github.com/docker/docker/pkg/integration/checker"
- "github.com/go-check/check"
- )
- // TestPullImageWithAliases pulls a specific image tag and verifies that any aliases (i.e., other
- // tags for the same image) are not also pulled down.
- //
- // Ref: docker/docker#8141
- func (s *DockerRegistrySuite) TestPullImageWithAliases(c *check.C) {
- repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
- repos := []string{}
- for _, tag := range []string{"recent", "fresh"} {
- repos = append(repos, fmt.Sprintf("%v:%v", repoName, tag))
- }
- // Tag and push the same image multiple times.
- for _, repo := range repos {
- dockerCmd(c, "tag", "busybox", repo)
- dockerCmd(c, "push", repo)
- }
- // Clear local images store.
- args := append([]string{"rmi"}, repos...)
- dockerCmd(c, args...)
- // Pull a single tag and verify it doesn't bring down all aliases.
- dockerCmd(c, "pull", repos[0])
- dockerCmd(c, "inspect", repos[0])
- for _, repo := range repos[1:] {
- _, _, err := dockerCmdWithError("inspect", repo)
- c.Assert(err, checker.NotNil, check.Commentf("Image %v shouldn't have been pulled down", repo))
- }
- }
- // TestConcurrentPullWholeRepo pulls the same repo concurrently.
- func (s *DockerRegistrySuite) TestConcurrentPullWholeRepo(c *check.C) {
- repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
- repos := []string{}
- for _, tag := range []string{"recent", "fresh", "todays"} {
- repo := fmt.Sprintf("%v:%v", repoName, tag)
- _, err := buildImage(repo, fmt.Sprintf(`
- FROM busybox
- ENTRYPOINT ["/bin/echo"]
- ENV FOO foo
- ENV BAR bar
- CMD echo %s
- `, repo), true)
- c.Assert(err, checker.IsNil)
- dockerCmd(c, "push", repo)
- repos = append(repos, repo)
- }
- // Clear local images store.
- args := append([]string{"rmi"}, repos...)
- dockerCmd(c, args...)
- // Run multiple re-pulls concurrently
- results := make(chan error)
- numPulls := 3
- for i := 0; i != numPulls; i++ {
- go func() {
- _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", "-a", repoName))
- results <- err
- }()
- }
- // These checks are separate from the loop above because the check
- // package is not goroutine-safe.
- for i := 0; i != numPulls; i++ {
- err := <-results
- c.Assert(err, checker.IsNil, check.Commentf("concurrent pull failed with error: %v", err))
- }
- // Ensure all tags were pulled successfully
- for _, repo := range repos {
- dockerCmd(c, "inspect", repo)
- out, _ := dockerCmd(c, "run", "--rm", repo)
- c.Assert(strings.TrimSpace(out), checker.Equals, "/bin/sh -c echo "+repo)
- }
- }
- // TestConcurrentFailingPull tries a concurrent pull that doesn't succeed.
- func (s *DockerRegistrySuite) TestConcurrentFailingPull(c *check.C) {
- repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
- // Run multiple pulls concurrently
- results := make(chan error)
- numPulls := 3
- for i := 0; i != numPulls; i++ {
- go func() {
- _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repoName+":asdfasdf"))
- results <- err
- }()
- }
- // These checks are separate from the loop above because the check
- // package is not goroutine-safe.
- for i := 0; i != numPulls; i++ {
- err := <-results
- c.Assert(err, checker.NotNil, check.Commentf("expected pull to fail"))
- }
- }
- // TestConcurrentPullMultipleTags pulls multiple tags from the same repo
- // concurrently.
- func (s *DockerRegistrySuite) TestConcurrentPullMultipleTags(c *check.C) {
- repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
- repos := []string{}
- for _, tag := range []string{"recent", "fresh", "todays"} {
- repo := fmt.Sprintf("%v:%v", repoName, tag)
- _, err := buildImage(repo, fmt.Sprintf(`
- FROM busybox
- ENTRYPOINT ["/bin/echo"]
- ENV FOO foo
- ENV BAR bar
- CMD echo %s
- `, repo), true)
- c.Assert(err, checker.IsNil)
- dockerCmd(c, "push", repo)
- repos = append(repos, repo)
- }
- // Clear local images store.
- args := append([]string{"rmi"}, repos...)
- dockerCmd(c, args...)
- // Re-pull individual tags, in parallel
- results := make(chan error)
- for _, repo := range repos {
- go func(repo string) {
- _, _, err := runCommandWithOutput(exec.Command(dockerBinary, "pull", repo))
- results <- err
- }(repo)
- }
- // These checks are separate from the loop above because the check
- // package is not goroutine-safe.
- for range repos {
- err := <-results
- c.Assert(err, checker.IsNil, check.Commentf("concurrent pull failed with error: %v", err))
- }
- // Ensure all tags were pulled successfully
- for _, repo := range repos {
- dockerCmd(c, "inspect", repo)
- out, _ := dockerCmd(c, "run", "--rm", repo)
- c.Assert(strings.TrimSpace(out), checker.Equals, "/bin/sh -c echo "+repo)
- }
- }
- // TestPullIDStability verifies that pushing an image and pulling it back
- // preserves the image ID.
- func (s *DockerRegistrySuite) TestPullIDStability(c *check.C) {
- derivedImage := privateRegistryURL + "/dockercli/id-stability"
- baseImage := "busybox"
- _, err := buildImage(derivedImage, fmt.Sprintf(`
- FROM %s
- ENV derived true
- ENV asdf true
- RUN dd if=/dev/zero of=/file bs=1024 count=1024
- CMD echo %s
- `, baseImage, derivedImage), true)
- if err != nil {
- c.Fatal(err)
- }
- originalID, err := getIDByName(derivedImage)
- if err != nil {
- c.Fatalf("error inspecting: %v", err)
- }
- dockerCmd(c, "push", derivedImage)
- // Pull
- out, _ := dockerCmd(c, "pull", derivedImage)
- if strings.Contains(out, "Pull complete") {
- c.Fatalf("repull redownloaded a layer: %s", out)
- }
- derivedIDAfterPull, err := getIDByName(derivedImage)
- if err != nil {
- c.Fatalf("error inspecting: %v", err)
- }
- if derivedIDAfterPull != originalID {
- c.Fatal("image's ID unexpectedly changed after a repush/repull")
- }
- // Make sure the image runs correctly
- out, _ = dockerCmd(c, "run", "--rm", derivedImage)
- if strings.TrimSpace(out) != derivedImage {
- c.Fatalf("expected %s; got %s", derivedImage, out)
- }
- // Confirm that repushing and repulling does not change the computed ID
- dockerCmd(c, "push", derivedImage)
- dockerCmd(c, "rmi", derivedImage)
- dockerCmd(c, "pull", derivedImage)
- derivedIDAfterPull, err = getIDByName(derivedImage)
- if err != nil {
- c.Fatalf("error inspecting: %v", err)
- }
- if derivedIDAfterPull != originalID {
- c.Fatal("image's ID unexpectedly changed after a repush/repull")
- }
- if err != nil {
- c.Fatalf("error inspecting: %v", err)
- }
- // Make sure the image still runs
- out, _ = dockerCmd(c, "run", "--rm", derivedImage)
- if strings.TrimSpace(out) != derivedImage {
- c.Fatalf("expected %s; got %s", derivedImage, out)
- }
- }
- // TestPullFallbackOn404 tries to pull a nonexistent manifest and confirms that
- // the pull falls back to the v1 protocol.
- //
- // Ref: docker/docker#18832
- func (s *DockerRegistrySuite) TestPullFallbackOn404(c *check.C) {
- repoName := fmt.Sprintf("%v/does/not/exist", privateRegistryURL)
- out, _, _ := dockerCmdWithError("pull", repoName)
- c.Assert(out, checker.Contains, "v1 ping attempt")
- }
|