From 067fff8b03dae2be7e1c98b6d2974c046702e3f7 Mon Sep 17 00:00:00 2001 From: Riyaz Faizullabhoy Date: Fri, 6 Oct 2017 14:46:17 -0700 Subject: [PATCH 1/7] trust: update references when pulling Signed-off-by: Riyaz Faizullabhoy --- cli/command/image/pull.go | 4 ++++ cli/command/image/trust.go | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cli/command/image/pull.go b/cli/command/image/pull.go index 0cf3df609d..9d77e04696 100644 --- a/cli/command/image/pull.go +++ b/cli/command/image/pull.go @@ -54,6 +54,10 @@ func runPull(cli command.Cli, opts pullOptions) error { if !opts.all && reference.IsNameOnly(distributionRef) { distributionRef = reference.TagNameOnly(distributionRef) + imgRefAndAuth, err = trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), distributionRef.String()) + if err != nil { + return err + } if tagged, ok := distributionRef.(reference.Tagged); ok { fmt.Fprintf(cli.Out(), "Using default tag: %s\n", tagged.Tag()) } diff --git a/cli/command/image/trust.go b/cli/command/image/trust.go index f2847e954b..85f816e219 100644 --- a/cli/command/image/trust.go +++ b/cli/command/image/trust.go @@ -200,7 +200,11 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image if err != nil { return err } - if err := imagePullPrivileged(ctx, cli, imgRefAndAuth, false); err != nil { + updatedImgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), trustedRef.String()) + if err != nil { + return err + } + if err := imagePullPrivileged(ctx, cli, updatedImgRefAndAuth, false); err != nil { return err } From 6e3bafd06b7c24385a2213158c393c58ec59ae58 Mon Sep 17 00:00:00 2001 From: Riyaz Faizullabhoy Date: Fri, 6 Oct 2017 14:46:02 -0700 Subject: [PATCH 2/7] update e2e tests for content trust tests Signed-off-by: Riyaz Faizullabhoy --- dockerfiles/Dockerfile.test-e2e-env | 5 +- e2e/compose-env.yaml | 8 ++++ e2e/container/pull_test.go | 51 +++++++++++++++++++++ e2e/testdata/notary/notary-config.json | 19 ++++++++ e2e/testdata/notary/notary-server.cert | 63 ++++++++++++++++++++++++++ e2e/testdata/notary/notary-server.key | 28 ++++++++++++ e2e/testdata/notary/root-ca.cert | 32 +++++++++++++ 7 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 e2e/container/pull_test.go create mode 100644 e2e/testdata/notary/notary-config.json create mode 100644 e2e/testdata/notary/notary-server.cert create mode 100644 e2e/testdata/notary/notary-server.key create mode 100644 e2e/testdata/notary/root-ca.cert diff --git a/dockerfiles/Dockerfile.test-e2e-env b/dockerfiles/Dockerfile.test-e2e-env index 3c672f4e8c..1098d5927a 100644 --- a/dockerfiles/Dockerfile.test-e2e-env +++ b/dockerfiles/Dockerfile.test-e2e-env @@ -1,6 +1,6 @@ FROM docker/compose:1.15.0 -RUN apk add -U bash curl +RUN apk add -U bash curl ca-certificates ARG DOCKER_CHANNEL=edge ARG DOCKER_VERSION=17.06.0-ce @@ -13,5 +13,8 @@ ENV DISABLE_WARN_OUTSIDE_CONTAINER=1 WORKDIR /work COPY scripts/test/e2e scripts/test/e2e COPY e2e/compose-env.yaml e2e/compose-env.yaml +COPY e2e/testdata e2e/testdata +COPY e2e/testdata/notary/root-ca.cert /usr/local/share/ca-certificates/notary.cert +RUN update-ca-certificates ENTRYPOINT ["bash", "/work/scripts/test/e2e/run"] diff --git a/e2e/compose-env.yaml b/e2e/compose-env.yaml index afc95e3af0..739343d27b 100644 --- a/e2e/compose-env.yaml +++ b/e2e/compose-env.yaml @@ -8,3 +8,11 @@ services: image: 'docker:${TEST_ENGINE_VERSION:-edge-dind}' privileged: true command: ['--insecure-registry=registry:5000'] + + notary-server: + image: 'notary:server-0.4.2' + ports: + - 4443:4443 + volumes: + - ./testdata/notary:/fixtures + command: ['notary-server', '-config=/fixtures/notary-config.json'] diff --git a/e2e/container/pull_test.go b/e2e/container/pull_test.go new file mode 100644 index 0000000000..8cb8129354 --- /dev/null +++ b/e2e/container/pull_test.go @@ -0,0 +1,51 @@ +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/testdata/notary/notary-config.json b/e2e/testdata/notary/notary-config.json new file mode 100644 index 0000000000..a4aed592a6 --- /dev/null +++ b/e2e/testdata/notary/notary-config.json @@ -0,0 +1,19 @@ +{ + "server": { + "http_addr": "notary-server:4443", + "tls_key_file": "./notary-server.key", + "tls_cert_file": "./notary-server.cert" + }, + "trust_service": { + "type": "local", + "hostname": "", + "port": "", + "key_algorithm": "ed25519" + }, + "logging": { + "level": "debug" + }, + "storage": { + "backend": "memory" + } +} diff --git a/e2e/testdata/notary/notary-server.cert b/e2e/testdata/notary/notary-server.cert new file mode 100644 index 0000000000..2573d00218 --- /dev/null +++ b/e2e/testdata/notary/notary-server.cert @@ -0,0 +1,63 @@ +-----BEGIN CERTIFICATE----- +MIIFBDCCAuygAwIBAgIJAPlHYZzp1daGMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV +BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEPMA0G +A1UEChMGRG9ja2VyMScwJQYDVQQDEx5Ob3RhcnkgSW50ZXJtZWRpYXRlIFRlc3Rp +bmcgQ0EwHhcNMTcwMjE3MDA0MzE3WhcNMTkwMzA5MDA0MzE3WjBbMQswCQYDVQQG +EwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xDzANBgNV +BAoTBkRvY2tlcjEWMBQGA1UEAxMNbm90YXJ5LXNlcnZlcjCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKjbeflOtVrOv0IOeJGKfi5LHH3Di0O2nlZu8AIT +SJbDZPSXoYc+cprpoEWYncbFFC3C94z5xBW5vcAqMhLs50ml5ADl86umcLl2C/mX +8NuZnlIevMCb0mBiavDtSPV3J5DqOk+trgKEXs9g4hyh5Onh5Y5InPO1lDJ+2cEt +VGBMhhddfWRVlV9ZUWxPYVCTt6L0bD9SeyXJVB0dnFhr3xICayhDlhlvcjXVOTUs +ewJLo/L2nq0ve93Jb2smKio27ZGE79bCGqJK213/FNqfAlGUPkhYTfYJTcgjhS1p +lmtgN6KZF6RVXvOrCBMEDM2yZq1mEPWjoT0tn0MkWErDANcCAwEAAaOBuTCBtjAf +BgNVHSMEGDAWgBS6l0MbzVfv/9OdgJ2V2t/f3oOJ3TAMBgNVHRMBAf8EAjAAMB0G +A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCBaAwNwYD +VR0RBDAwLoINbm90YXJ5LXNlcnZlcoIMbm90YXJ5c2VydmVygglsb2NhbGhvc3SH +BH8AAAEwHQYDVR0OBBYEFBQcColyhey0o0RTLiiGAtaRhUIuMA0GCSqGSIb3DQEB +CwUAA4ICAQB04WZaMeF90mQDqiRVhBUkp8HvfEqchP6QLwprZmgbaRi75JksK59x +ynaqgQj61hvN2RzpA1V/YXagmD6dk+GqhgiR+O++k+wb26446qQTSP6jkYRQGUT6 +s2Qp0fhgV9eHHZ/27Cl4rEpjYtxd6yVN/DNQapj/h3qejuZ1UDIZhvswfEgiL57f +0W0huPNS6LnSOwoKKgSlA38OGs993BwMJkc+1ikzEcpVcn4l+kjeefnDmguBrxFv +5il7yQ45BxGwR/SLobpehV+XodjNUd8mpdoF9QWr8kibaDPNndhdJLHuzyYatnRe +hDqFA5DqZ+uaSwPyixilDoAXFs81P6UTkGh3EjP7rMbZNYnIHYFYIKpYVu23vbh+ +eriCw61YvEcIxqfvtIAVfbxwnXExQWGIDXgkJlfskHh/c4hQ1CWHCgqmO8Hvix1u +OMfhB5LygX+4QANoKMkUUlKv2MC5HXQ7Bg6rCfPioju2nzGIbbUK043UnfJ2yXIh +5g0bKGGdWMr5Qw0at8A2NvR6WvXm6+9gu94rNDGoIPn6umTmFjJCbGhjcyyjxg+k +DO0uhoilX2OkvQHeaBwiy1WM2ETMQBKvkUfq6EUoLsWQTT2NOZiwwEMywwJCb853 +LuQjsvxfOFuqEgXEWjrEnhjwDCJFEDqaJAgajmBZ9xU+yUco44U9zQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +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 +ALNmRewqFkXD +-----END CERTIFICATE----- diff --git a/e2e/testdata/notary/notary-server.key b/e2e/testdata/notary/notary-server.key new file mode 100644 index 0000000000..871d41f643 --- /dev/null +++ b/e2e/testdata/notary/notary-server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCo23n5TrVazr9C +DniRin4uSxx9w4tDtp5WbvACE0iWw2T0l6GHPnKa6aBFmJ3GxRQtwveM+cQVub3A +KjIS7OdJpeQA5fOrpnC5dgv5l/DbmZ5SHrzAm9JgYmrw7Uj1dyeQ6jpPra4ChF7P +YOIcoeTp4eWOSJzztZQyftnBLVRgTIYXXX1kVZVfWVFsT2FQk7ei9Gw/UnslyVQd +HZxYa98SAmsoQ5YZb3I11Tk1LHsCS6Py9p6tL3vdyW9rJioqNu2RhO/WwhqiSttd +/xTanwJRlD5IWE32CU3II4UtaZZrYDeimRekVV7zqwgTBAzNsmatZhD1o6E9LZ9D +JFhKwwDXAgMBAAECggEAbqa0PV0IlqMYze6xr53zpd5uozM61XqcM8Oq35FHZhRQ +2b9riDax3zXtYu3pplGLMZmrouQhTKNU5tI/0gsQXUCqMrR9gyQkhkQHAN5CZYU7 +LFEcG5OAvsx/i7XSs5gLg3kaERCdEOUxQ/AW+/BTE7iGN0D6KPH6VUSu6VoNCrTK +PmYvgta7hwebnvo65/OAc4inp9C19FUkhcNbaCKduWBgUt348+IzVEw9H8+PrdVZ +dYGfVXAsDFY3zz0ThUbaZ52XS1pCCQ1Df9bQnTgqJNc+u1xQHLYAageKS83uAbtS +nYjBFFuxeRR2FA1n8echCWQV+16Kqq31U1E2yLfWcQKBgQDSoT73pO9h/yN5myqu +XxhAC+Ndas0DTl4pmVPpybpenJerba/0KCfYpcSFHAdkXZ1DYL7U+9uh5NRul09f +WdjayFjn0vv63rwX+PGi1yPHTIv5kLvjYXJtaxzxSzQivYMPmD/7QX4tEsUkpJ8k +90vMSS/C5ieWbpFwWVvEjFbqHQKBgQDNOsTq6USE3R8p4lj9Ror/waUuWVdzZnm3 +uZGJw3WzvzaXmqLSfVHntUnD8TPHgk3WZxDhrF73POMADkl9IN/JPI150/Uo6YJo +qYGoZr0mmnEZxVCkwODz5C9icnyjklcRdIRM6eljhFMQDVEacDkptsntHUyIdQZc +L2eLNUfEgwKBgHxy7UNg3lemag110rgIU8mzvHj7m3oymYw2nc/qcwVnvG17d5Tp +DPICr6R+NRfl//9JcDdjQBfdnm5hVHJgIbLS4UTH8j390GDRo+O0/dzJq4KfM4Rb +lUJ1ITqoVnuYQZG7QUJxJd330yedZLJwswZWz7N2TTmixqf9BC2TRd85AoGAN+Qh +bLhKaMSvkACMq61ifXSHP7AlGNB3pYlsEVCh5WnVvEPow9pNTAUbKbmumE7sU8+N +0WfYFQ0H5SP+74zcZTmQbfVDdvjhAw/mt64DJVg6JQKPi87bdJBYNz9mokVgYOiS +fz/Ux71pwZ1e0QxvBOU66NBp31+/c6uVT1wbR3ECgYAdye1+UPpS9Dn89g6Ks0kv +UaFKykXu7vY2uxiNqhmWzze4iq5wmIHmEwc6+rVMluXQPAME7Iya3mBmto9AHQ/n +/ka+fGoaUgAojCLZW5DZcelIETw+Dk+95vyyAUsWfAvn4nKo4/rkBXcSHlvgElzq +SorPiBWYosFB6jqUTXew2w== +-----END PRIVATE KEY----- diff --git a/e2e/testdata/notary/root-ca.cert b/e2e/testdata/notary/root-ca.cert new file mode 100644 index 0000000000..2f5b58bbee --- /dev/null +++ b/e2e/testdata/notary/root-ca.cert @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFhjCCA26gAwIBAgIJAI/HWUuNSUQjMA0GCSqGSIb3DQEBCwUAMF8xCzAJBgNV +BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEPMA0G +A1UEChMGRG9ja2VyMRowGAYDVQQDExFOb3RhcnkgVGVzdGluZyBDQTAeFw0xNzAy +MTcwMDQzMTNaFw0yNzAyMTUwMDQzMTNaMF8xCzAJBgNVBAYTAlVTMQswCQYDVQQI +EwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRow +GAYDVQQDExFOb3RhcnkgVGVzdGluZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAPPHnaVuLXmF0fQ2LY9CSf2HjZKofabwjt7b6gH7132dcDqBzWbJ +BTiRo0oze9LHV6P1AT4rvahM93SnWVpn5gHHnprMnFyG/PRpB0NjvkexSGFqUH/Q +3B9xXkczh0BYGQquR56qCQr3oQKsu5vlIhcvQb6QrOB4Vm/AO9BtYicPcI6O2c5p +ZQgh9Ih62JQQa97dDQc8/5JbC+WcXudPO2o+uyU9f1P0OpXh5AWc/N4HGIwJGDzJ +i24U4R04jq0HQ1BMT0Q3EuGc0pPt9XxIzBj5qKtCQC2sChGZV8uLHVKMW3vgdpi8 +ZFbRjYkiSfiQ8+FIV4+2+MRF6jPm8VIrpqxaZHS6/SLfsCv0+bhXC/3CcxQYXLe0 +DR3D5JZAMyqVCaUVVJBi3tPqgv3GCG5VuKSe8gAww9SNDVT2PMQ2L1Z3PL3+09I1 +sed56ftC/zrZY3NYaD8f+9mOjR/yWyRM3cO7/TIe3riY/G1RVHAeL0HU/QVcWAZN +CPJziKH+hMwEjIDFiMf8nY43EUn/hKx39oqPnLdw0aQRSfg/+052P15wTFSdjjhQ +t9Z5ofw8vD4jaB9dXCry0iJ+kiaBDRS74awRCLKn7WwuXREveMcRJlYGooZskQLE +EgMnMOuE0W2dw0hLsgImC3resdAd2UKnfdNO+5Wc7SuaxLsD3Th1B543AgMBAAGj +RTBDMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgFGMB0GA1UdDgQW +BBTF2uV1/m2uSX9GEbi+lKo7VEEuWTANBgkqhkiG9w0BAQsFAAOCAgEAecm3BGLW +igmsNIeO+Pn01v+EiPFQDBS4LkRiY/OH1lOEbskT8bHOVbKKBzcTI/0i8oRtn8CX +faGYv0xRCfmM0ZKy73HD6FteObWiUessdLKbXFRc9p02QBvzU8rJ/yZyZjb2Bn7g +KDylhmNmygQNvpy0TBCMA9l2pgokN5RD4zbY88DTrdYetkdBV70QFTUn3Za1Y3z0 +ZAigKyA9U1FUnRIgZprkliVJiBzv+JVD5uFIxut5nVoKaEuQ/EoM89BMJXEmlm2T +LDmfJ2pSm4rjvt+V+jfR/f8lCwsqJ/DqnbxCbpCoMegJSoaSGvL0yWvfCTuiDzRk +tAcz4v/bZ6mtH4pYJLQ1xswrDUW+3loCjB+9bU1185X7hZo2nkan409zqQ2gPWKR +0qaVC1KnvsQaVupd7j4mYr/AzBNugR7PZpNKmBomLVZx/HLRAW7Qkz9wrXl3pcW7 +rXU5R3Z8NygRbzRadG2pXcmZqOTEM/3El5LOQs2bxb2/Qr7YAz957xEZBtZbRlMt +lhWyA0PnlewJ2NeIBwf1WAw8lYXJMQnibCCHXsPh0A864F95QJAopVrsx0w+Junz +C5rBWBS2H5c9cDA+BrIEV6SE94AvPs7OxEMCFDrqybZh/Q0xD4ADlm6EJoRvgtN/ +rba7O3YGSuScQakjt9mw2Q5ISwImkRHF3qE= +-----END CERTIFICATE----- From ade675d36cebb996044a1ee913c3004e0a4f274c Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 6 Oct 2017 19:11:01 -0400 Subject: [PATCH 3/7] get e2e working with notary service Signed-off-by: Daniel Nephin --- dockerfiles/Dockerfile.dev | 2 +- dockerfiles/Dockerfile.test-e2e-env | 5 +---- e2e/compose-env.yaml | 5 ++++- scripts/test/e2e/run | 4 +++- scripts/test/e2e/wrapper | 10 ++++++++++ 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/dockerfiles/Dockerfile.dev b/dockerfiles/Dockerfile.dev index 8ee2e905b3..1651ad1eb0 100644 --- a/dockerfiles/Dockerfile.dev +++ b/dockerfiles/Dockerfile.dev @@ -1,7 +1,7 @@ FROM golang:1.8.4-alpine -RUN apk add -U git make bash coreutils +RUN apk add -U git make bash coreutils ca-certificates ARG VNDR_SHA=a6e196d8b4b0cbbdc29aebdb20c59ac6926bb384 RUN go get -d github.com/LK4D4/vndr && \ diff --git a/dockerfiles/Dockerfile.test-e2e-env b/dockerfiles/Dockerfile.test-e2e-env index 1098d5927a..3c672f4e8c 100644 --- a/dockerfiles/Dockerfile.test-e2e-env +++ b/dockerfiles/Dockerfile.test-e2e-env @@ -1,6 +1,6 @@ FROM docker/compose:1.15.0 -RUN apk add -U bash curl ca-certificates +RUN apk add -U bash curl ARG DOCKER_CHANNEL=edge ARG DOCKER_VERSION=17.06.0-ce @@ -13,8 +13,5 @@ ENV DISABLE_WARN_OUTSIDE_CONTAINER=1 WORKDIR /work COPY scripts/test/e2e scripts/test/e2e COPY e2e/compose-env.yaml e2e/compose-env.yaml -COPY e2e/testdata e2e/testdata -COPY e2e/testdata/notary/root-ca.cert /usr/local/share/ca-certificates/notary.cert -RUN update-ca-certificates ENTRYPOINT ["bash", "/work/scripts/test/e2e/run"] diff --git a/e2e/compose-env.yaml b/e2e/compose-env.yaml index 739343d27b..d77427a253 100644 --- a/e2e/compose-env.yaml +++ b/e2e/compose-env.yaml @@ -14,5 +14,8 @@ services: ports: - 4443:4443 volumes: - - ./testdata/notary:/fixtures + - notary-fixtures:/fixtures command: ['notary-server', '-config=/fixtures/notary-config.json'] + +volumes: + notary-fixtures: {} diff --git a/scripts/test/e2e/run b/scripts/test/e2e/run index 4010e756c4..9994d4863a 100755 --- a/scripts/test/e2e/run +++ b/scripts/test/e2e/run @@ -33,12 +33,14 @@ function is_swarm_enabled { } function cleanup { - COMPOSE_PROJECT_NAME=$1 COMPOSE_FILE=$2 docker-compose down >&2 + COMPOSE_PROJECT_NAME=$1 COMPOSE_FILE=$2 docker-compose down -v >&2 } function runtests { local engine_host=$1 + # TODO: only run if inside a container + update-ca-certificates # shellcheck disable=SC2086 env -i \ TEST_DOCKER_HOST="$engine_host" \ diff --git a/scripts/test/e2e/wrapper b/scripts/test/e2e/wrapper index 0f85f43283..47a18487b6 100755 --- a/scripts/test/e2e/wrapper +++ b/scripts/test/e2e/wrapper @@ -22,13 +22,23 @@ docker build \ -t "$dev_image" \ -f dockerfiles/Dockerfile.dev . +notary_volume="${unique_id}_notary-fixtures" +docker volume create "$notary_volume" +docker run --rm \ + -v "$PWD:/go/src/github.com/docker/cli" \ + -v "$notary_volume:/data" \ + "$dev_image" \ + cp -r ./e2e/testdata/notary/* /data/ + engine_host=$(run_in_env setup) testexit=0 docker run -i --rm \ -v "$PWD:/go/src/github.com/docker/cli" \ + -v "$PWD/e2e/testdata/notary/root-ca.cert:/usr/local/share/ca-certificates/notary.cert" \ --network "${unique_id}_default" \ -e TESTFLAGS \ "$dev_image" \ ./scripts/test/e2e/run test "$engine_host" || testexit="$?" + run_in_env cleanup exit "$testexit" From 46f3d8bb7f73eec26d70853f53d5f5723e3e7a7e Mon Sep 17 00:00:00 2001 From: Riyaz Faizullabhoy Date: Fri, 6 Oct 2017 16:32:57 -0700 Subject: [PATCH 4/7] update image pull tests Signed-off-by: Riyaz Faizullabhoy --- e2e/container/pull_test.go | 51 ------------------------ e2e/image/main_test.go | 17 ++++++++ e2e/image/pull_test.go | 75 +++++++++++++++++++++++++++++++++++ scripts/test/e2e/load-busybox | 8 ++++ scripts/test/e2e/run | 1 + scripts/test/e2e/wrapper | 2 +- 6 files changed, 102 insertions(+), 52 deletions(-) delete mode 100644 e2e/container/pull_test.go create mode 100644 e2e/image/main_test.go create mode 100644 e2e/image/pull_test.go create mode 100755 scripts/test/e2e/load-busybox 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" \ From 7dda6fc3c96badad2f363ae04aecefca1c3dd25d Mon Sep 17 00:00:00 2001 From: Riyaz Faizullabhoy Date: Tue, 10 Oct 2017 12:00:52 -0700 Subject: [PATCH 5/7] factor out rigging for pushing unsigned busybox image Signed-off-by: Riyaz Faizullabhoy --- e2e/image/pull_test.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/e2e/image/pull_test.go b/e2e/image/pull_test.go index 3855bf3a43..2815672117 100644 --- a/e2e/image/pull_test.go +++ b/e2e/image/pull_test.go @@ -31,10 +31,7 @@ func TestPullWithContentTrust(t *testing.T) { 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) + createNamedUnsignedImageFromBusyBox(t, image) // now pull with content trust result = icmd.RunCmd(trustedCmdNoPassphrases(icmd.Command("docker", "pull", image))) @@ -54,6 +51,13 @@ func createTrustedRemoteImage(t *testing.T, repo, tag string) string { return image } +func createNamedUnsignedImageFromBusyBox(t *testing.T, image string) { + 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) +} + func trustedCmdWithPassphrases(cmd icmd.Cmd, rootPwd, repositoryPwd string) icmd.Cmd { env := append(os.Environ(), []string{ "DOCKER_CONTENT_TRUST=1", From e54886148182109f1bc5ab470770c7a13f6e020b Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Tue, 10 Oct 2017 15:57:16 -0400 Subject: [PATCH 6/7] Refactor runPull to remove second GetImageReferencesAndAuth Fix unit tests to catch the regression. Signed-off-by: Daniel Nephin --- cli/command/image/pull.go | 25 +++++++++++-------------- cli/command/image/pull_test.go | 25 ++++++++++++++++++------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/cli/command/image/pull.go b/cli/command/image/pull.go index 9d77e04696..1824de2a9b 100644 --- a/cli/command/image/pull.go +++ b/cli/command/image/pull.go @@ -41,28 +41,25 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command { } func runPull(cli command.Cli, opts pullOptions) error { - ctx := context.Background() - imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), opts.remote) - if err != nil { + distributionRef, err := reference.ParseNormalizedNamed(opts.remote) + switch { + case err != nil: return err - } - - distributionRef := imgRefAndAuth.Reference() - if opts.all && !reference.IsNameOnly(distributionRef) { + case opts.all && !reference.IsNameOnly(distributionRef): return errors.New("tag can't be used with --all-tags/-a") - } - - if !opts.all && reference.IsNameOnly(distributionRef) { + case !opts.all && reference.IsNameOnly(distributionRef): distributionRef = reference.TagNameOnly(distributionRef) - imgRefAndAuth, err = trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), distributionRef.String()) - if err != nil { - return err - } if tagged, ok := distributionRef.(reference.Tagged); ok { fmt.Fprintf(cli.Out(), "Using default tag: %s\n", tagged.Tag()) } } + ctx := context.Background() + imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), distributionRef.String()) + if err != nil { + return err + } + // Check if reference has a digest _, isCanonical := distributionRef.(reference.Canonical) if command.IsTrusted() && !isCanonical { diff --git a/cli/command/image/pull_test.go b/cli/command/image/pull_test.go index ec83ba1f35..b0e9929abe 100644 --- a/cli/command/image/pull_test.go +++ b/cli/command/image/pull_test.go @@ -2,11 +2,14 @@ package image import ( "fmt" + "io" "io/ioutil" + "strings" "testing" "github.com/docker/cli/internal/test" "github.com/docker/cli/internal/test/testutil" + "github.com/docker/docker/api/types" "github.com/gotestyourself/gotestyourself/golden" "github.com/stretchr/testify/assert" ) @@ -44,20 +47,28 @@ func TestNewPullCommandErrors(t *testing.T) { func TestNewPullCommandSuccess(t *testing.T) { testCases := []struct { - name string - args []string + name string + args []string + expectedTag string }{ { - name: "simple", - args: []string{"image:tag"}, + name: "simple", + args: []string{"image:tag"}, + expectedTag: "image:tag", }, { - name: "simple-no-tag", - args: []string{"image"}, + name: "simple-no-tag", + args: []string{"image"}, + expectedTag: "image:latest", }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{}) + cli := test.NewFakeCli(&fakeClient{ + imagePullFunc: func(ref string, options types.ImagePullOptions) (io.ReadCloser, error) { + assert.Equal(t, tc.expectedTag, ref, tc.name) + return ioutil.NopCloser(strings.NewReader("")), nil + }, + }) cmd := NewPullCommand(cli) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) From b11c11ea74079d5592357351d2555cd6ffe678b0 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Tue, 10 Oct 2017 17:04:32 -0400 Subject: [PATCH 7/7] Update e2e test for image pull to check stdout Also add TEST_DEBUG env variable for debugging E2E tests. And change icmd environment helpers to fit the CmdOp interface os they can be passed to 'icmd.RunCmd()' Signed-off-by: Daniel Nephin --- e2e/image/pull_test.go | 66 ++++++++----------- .../testdata/pull-with-content-trust.golden | 5 ++ scripts/test/e2e/run | 3 + scripts/test/e2e/wrapper | 10 ++- 4 files changed, 46 insertions(+), 38 deletions(-) create mode 100644 e2e/image/testdata/pull-with-content-trust.golden diff --git a/e2e/image/pull_test.go b/e2e/image/pull_test.go index 2815672117..4da6748be2 100644 --- a/e2e/image/pull_test.go +++ b/e2e/image/pull_test.go @@ -3,11 +3,10 @@ package image import ( "fmt" "os" - "strings" "testing" + "github.com/gotestyourself/gotestyourself/golden" "github.com/gotestyourself/gotestyourself/icmd" - "github.com/stretchr/testify/require" ) const notaryURL = "https://notary-server:4443" @@ -17,36 +16,29 @@ 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") + image := createMaskedTrustedRemoteImage(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) + result := icmd.RunCmd(icmd.Command("docker", "pull", image), withTrustNoPassphrase) + result.Assert(t, icmd.Expected{Err: icmd.None}) + golden.Assert(t, result.Stdout(), "pull-with-content-trust.golden") +} - // 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) +// createMaskedTrustedRemoteImage creates a remote image that is signed with +// content trust, then pushes a different untrusted image at the same tag. +func createMaskedTrustedRemoteImage(t *testing.T, repo, tag string) string { + image := createTrustedRemoteImage(t, repo, tag) createNamedUnsignedImageFromBusyBox(t, image) - - // 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) + return image } 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) + result := icmd.RunCmd( + icmd.Command("docker", "push", image), + withTrustAndPassphrase("root_password", "repo_password")) + result.Assert(t, icmd.Success) icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) return image } @@ -58,22 +50,22 @@ func createNamedUnsignedImageFromBusyBox(t *testing.T, image string) { icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success) } -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 withTrustAndPassphrase(rootPwd, repositoryPwd string) func(cmd *icmd.Cmd) { + return func(cmd *icmd.Cmd) { + env := append(os.Environ(), + "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...) + } } -func trustedCmdNoPassphrases(cmd icmd.Cmd) icmd.Cmd { - env := append(os.Environ(), []string{ +func withTrustNoPassphrase(cmd *icmd.Cmd) { + env := append(os.Environ(), "DOCKER_CONTENT_TRUST=1", - "DOCKER_CONTENT_TRUST_SERVER=" + notaryURL, - }...) + "DOCKER_CONTENT_TRUST_SERVER="+notaryURL, + ) cmd.Env = append(cmd.Env, env...) - return cmd } diff --git a/e2e/image/testdata/pull-with-content-trust.golden b/e2e/image/testdata/pull-with-content-trust.golden new file mode 100644 index 0000000000..85a043aca6 --- /dev/null +++ b/e2e/image/testdata/pull-with-content-trust.golden @@ -0,0 +1,5 @@ +Pull (1 of 1): registry:5000/trust:latest@sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d +sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d: Pulling from trust +Digest: sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d +Status: Downloaded newer image for registry:5000/trust@sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d +Tagging registry:5000/trust@sha256:641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d as registry:5000/trust:latest diff --git a/scripts/test/e2e/run b/scripts/test/e2e/run index 6874458de5..2229eb2964 100755 --- a/scripts/test/e2e/run +++ b/scripts/test/e2e/run @@ -80,6 +80,9 @@ case "$cmd" in cleanup "$unique_id" "$compose_env_file" exit $testexit ;; + shell) + $SHELL + ;; *) echo "Unknown command: $cmd" echo "Usage: " diff --git a/scripts/test/e2e/wrapper b/scripts/test/e2e/wrapper index 175d513229..1e4cb117ff 100755 --- a/scripts/test/e2e/wrapper +++ b/scripts/test/e2e/wrapper @@ -32,13 +32,21 @@ docker run --rm \ engine_host=$(run_in_env setup) testexit=0 + + +test_cmd="test" +if [[ -n "${TEST_DEBUG-}" ]]; then + test_cmd="shell" +fi + docker run -i --rm \ -v "$PWD:/go/src/github.com/docker/cli" \ -v "$PWD/e2e/testdata/notary/root-ca.cert:/usr/local/share/ca-certificates/notary.cert" \ --network "${unique_id}_default" \ -e TESTFLAGS \ + -e ENGINE_HOST="$engine_host" \ "$dev_image" \ - ./scripts/test/e2e/run test "$engine_host" || testexit="$?" + ./scripts/test/e2e/run "$test_cmd" "$engine_host" || testexit="$?" run_in_env cleanup exit "$testexit"