diff --git a/e2e/container/pull_test.go b/e2e/container/pull_test.go deleted file mode 100644 index 8cb8129354..0000000000 --- a/e2e/container/pull_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package container - -import ( - "fmt" - "os" - "strings" - "testing" - - "github.com/gotestyourself/gotestyourself/icmd" -) - -const notaryURL = "https://notary-server:4443" -const registryPrefix = "registry:5000" - -func TestPullWithContentTrust(t *testing.T) { - image := createTrustedRemoteImage(t, "trust", "latest") - icmd.RunCmd(trustedCmdNoPassphrases(icmd.Command("docker", "pull", image))).Assert(t, icmd.Success) - - // test that pulling without the tag defaults to latest - imageWithoutTag := strings.TrimSuffix(image, ":latest") - icmd.RunCmd(trustedCmdNoPassphrases(icmd.Command("docker", "pull", imageWithoutTag))).Assert(t, icmd.Success) -} - -func createTrustedRemoteImage(t *testing.T, repo, tag string) string { - image := fmt.Sprintf("%s/%s:%s", registryPrefix, repo, tag) - icmd.RunCommand("docker", "pull", alpineImage).Assert(t, icmd.Success) - icmd.RunCommand("docker", "tag", alpineImage, image).Assert(t, icmd.Success) - icmd.RunCmd(trustedCmdWithPassphrases(icmd.Command("docker", "push", image), "root_password", "repo_password")).Assert(t, icmd.Success) - icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) - return image -} - -func trustedCmdWithPassphrases(cmd icmd.Cmd, rootPwd, repositoryPwd string) icmd.Cmd { - env := append(os.Environ(), []string{ - "DOCKER_CONTENT_TRUST=1", - fmt.Sprintf("DOCKER_CONTENT_TRUST_SERVER=%s", notaryURL), - fmt.Sprintf("DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE=%s", rootPwd), - fmt.Sprintf("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE=%s", repositoryPwd), - }...) - cmd.Env = append(cmd.Env, env...) - return cmd -} - -func trustedCmdNoPassphrases(cmd icmd.Cmd) icmd.Cmd { - env := append(os.Environ(), []string{ - "DOCKER_CONTENT_TRUST=1", - fmt.Sprintf("DOCKER_CONTENT_TRUST_SERVER=%s", notaryURL), - }...) - cmd.Env = append(cmd.Env, env...) - return cmd -} diff --git a/e2e/image/main_test.go b/e2e/image/main_test.go new file mode 100644 index 0000000000..4638467a01 --- /dev/null +++ b/e2e/image/main_test.go @@ -0,0 +1,17 @@ +package image + +import ( + "fmt" + "os" + "testing" + + "github.com/docker/cli/internal/test/environment" +) + +func TestMain(m *testing.M) { + if err := environment.Setup(); err != nil { + fmt.Println(err.Error()) + os.Exit(3) + } + os.Exit(m.Run()) +} diff --git a/e2e/image/pull_test.go b/e2e/image/pull_test.go new file mode 100644 index 0000000000..3855bf3a43 --- /dev/null +++ b/e2e/image/pull_test.go @@ -0,0 +1,75 @@ +package image + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/gotestyourself/gotestyourself/icmd" + "github.com/stretchr/testify/require" +) + +const notaryURL = "https://notary-server:4443" +const registryPrefix = "registry:5000" + +const alpineImage = "registry:5000/alpine:3.6" +const busyboxImage = "registry:5000/busybox:1.27.2" + +func TestPullWithContentTrust(t *testing.T) { + image := createTrustedRemoteImage(t, "trust", "latest") + + // test that pulling without the tag defaults to latest + imageWithoutTag := strings.TrimSuffix(image, ":latest") + icmd.RunCmd(trustedCmdNoPassphrases(icmd.Command("docker", "pull", imageWithoutTag))).Assert(t, icmd.Success) + icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) + + // try pulling with the tag, record output for comparison later + result := icmd.RunCmd(trustedCmdNoPassphrases(icmd.Command("docker", "pull", image))) + result.Assert(t, icmd.Success) + firstPullOutput := result.String() + icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) + + // push an unsigned image on the same reference name, but with different content (busybox) + icmd.RunCommand("docker", "pull", busyboxImage).Assert(t, icmd.Success) + icmd.RunCommand("docker", "tag", busyboxImage, image).Assert(t, icmd.Success) + icmd.RunCommand("docker", "push", image).Assert(t, icmd.Success) + icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) + + // now pull with content trust + result = icmd.RunCmd(trustedCmdNoPassphrases(icmd.Command("docker", "pull", image))) + result.Assert(t, icmd.Success) + secondPullOutput := result.String() + + // assert that the digest and other output is the same since we ignore the unsigned image + require.Equal(t, firstPullOutput, secondPullOutput) +} + +func createTrustedRemoteImage(t *testing.T, repo, tag string) string { + image := fmt.Sprintf("%s/%s:%s", registryPrefix, repo, tag) + icmd.RunCommand("docker", "pull", alpineImage).Assert(t, icmd.Success) + icmd.RunCommand("docker", "tag", alpineImage, image).Assert(t, icmd.Success) + icmd.RunCmd(trustedCmdWithPassphrases(icmd.Command("docker", "push", image), "root_password", "repo_password")).Assert(t, icmd.Success) + icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) + return image +} + +func trustedCmdWithPassphrases(cmd icmd.Cmd, rootPwd, repositoryPwd string) icmd.Cmd { + env := append(os.Environ(), []string{ + "DOCKER_CONTENT_TRUST=1", + "DOCKER_CONTENT_TRUST_SERVER=" + notaryURL, + "DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE=" + rootPwd, + "DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE=" + repositoryPwd, + }...) + cmd.Env = append(cmd.Env, env...) + return cmd +} + +func trustedCmdNoPassphrases(cmd icmd.Cmd) icmd.Cmd { + env := append(os.Environ(), []string{ + "DOCKER_CONTENT_TRUST=1", + "DOCKER_CONTENT_TRUST_SERVER=" + notaryURL, + }...) + cmd.Env = append(cmd.Env, env...) + return cmd +} diff --git a/scripts/test/e2e/load-busybox b/scripts/test/e2e/load-busybox new file mode 100755 index 0000000000..b9eed04612 --- /dev/null +++ b/scripts/test/e2e/load-busybox @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -eu -o pipefail + +src=busybox@sha256:3e8fa85ddfef1af9ca85a5cfb714148956984e02f00bec3f7f49d3925a91e0e7 +dest=registry:5000/busybox:1.27.2 +docker pull $src +docker tag $src $dest +docker push $dest diff --git a/scripts/test/e2e/run b/scripts/test/e2e/run index 9994d4863a..6874458de5 100755 --- a/scripts/test/e2e/run +++ b/scripts/test/e2e/run @@ -23,6 +23,7 @@ function setup { export DOCKER_HOST="$engine_host" timeout -t 200 ./scripts/test/e2e/wait-on-daemon ./scripts/test/e2e/load-alpine + ./scripts/test/e2e/load-busybox is_swarm_enabled || docker swarm init ) >&2 echo "$engine_host" diff --git a/scripts/test/e2e/wrapper b/scripts/test/e2e/wrapper index 47a18487b6..175d513229 100755 --- a/scripts/test/e2e/wrapper +++ b/scripts/test/e2e/wrapper @@ -23,7 +23,7 @@ docker build \ -f dockerfiles/Dockerfile.dev . notary_volume="${unique_id}_notary-fixtures" -docker volume create "$notary_volume" +docker volume create --name "$notary_volume" docker run --rm \ -v "$PWD:/go/src/github.com/docker/cli" \ -v "$notary_volume:/data" \