From b1ed40ffed9252386d93b0128f778a19d43e808f Mon Sep 17 00:00:00 2001 From: Tom Chauveau Date: Sat, 12 Jun 2021 17:11:27 +0200 Subject: [PATCH] Improve #docker.Push definition : - Push to private registry - Output ref and digest - Update doc - Add tests to universe.bats Signed-off-by: Tom Chauveau --- docs/reference/universe/docker/README.md | 18 +++-- stdlib/.dagger/env/docker-pull/.gitignore | 2 + stdlib/.dagger/env/docker-pull/plan/pull.cue | 26 +++++++ stdlib/.dagger/env/docker-pull/values.yaml | 24 +++++++ .../env/docker-push-invalid-creds/.gitignore | 2 + .../docker-push-invalid-creds/plan/push.cue | 34 +++++++++ .../env/docker-push-invalid-creds/values.yaml | 26 +++++++ stdlib/.dagger/env/docker-push/.gitignore | 2 + stdlib/.dagger/env/docker-push/plan/push.cue | 63 +++++++++++++++++ stdlib/.dagger/env/docker-push/values.yaml | 26 +++++++ stdlib/docker/docker.cue | 70 +++++++++++++++++-- stdlib/universe.bats | 17 +++++ 12 files changed, 297 insertions(+), 13 deletions(-) create mode 100644 stdlib/.dagger/env/docker-pull/.gitignore create mode 100644 stdlib/.dagger/env/docker-pull/plan/pull.cue create mode 100644 stdlib/.dagger/env/docker-pull/values.yaml create mode 100644 stdlib/.dagger/env/docker-push-invalid-creds/.gitignore create mode 100644 stdlib/.dagger/env/docker-push-invalid-creds/plan/push.cue create mode 100644 stdlib/.dagger/env/docker-push-invalid-creds/values.yaml create mode 100644 stdlib/.dagger/env/docker-push/.gitignore create mode 100644 stdlib/.dagger/env/docker-push/plan/push.cue create mode 100644 stdlib/.dagger/env/docker-push/values.yaml diff --git a/docs/reference/universe/docker/README.md b/docs/reference/universe/docker/README.md index 6ec5f28c..dc00527a 100644 --- a/docs/reference/universe/docker/README.md +++ b/docs/reference/universe/docker/README.md @@ -70,18 +70,24 @@ _No output._ ## docker.#Push -Push a docker image +Push a docker image to remote registry ### docker.#Push Inputs -| Name | Type | Description | -| ------------- |:-------------: |:-------------: | -|*ref* | `string` |Remote ref (example: "index.docker.io/alpine:latest") | -|*source* | `dagger.#Artifact` |Image | +| Name | Type | Description | +| ------------- |:-------------: |:-------------: | +|*name* | `string` |Remote name (example: "index.docker.io/alpine:latest") | +|*source* | `dagger.#Artifact` |Image source | +|*registry.target* | `*"https://index.docker.io/v1/" \| string` |Remote registry | +|*registry.username* | `string` |Username | +|*registry.secret* | `(string\|bytes)` |Password or secret | ### docker.#Push Outputs -_No output._ +| Name | Type | Description | +| ------------- |:-------------: |:-------------: | +|*out.ref* | `string` |Image ref | +|*out.digest* | `string` |Image digest | ## docker.#Run diff --git a/stdlib/.dagger/env/docker-pull/.gitignore b/stdlib/.dagger/env/docker-pull/.gitignore new file mode 100644 index 00000000..01ec19b0 --- /dev/null +++ b/stdlib/.dagger/env/docker-pull/.gitignore @@ -0,0 +1,2 @@ +# dagger state +state/** diff --git a/stdlib/.dagger/env/docker-pull/plan/pull.cue b/stdlib/.dagger/env/docker-pull/plan/pull.cue new file mode 100644 index 00000000..e0bb462e --- /dev/null +++ b/stdlib/.dagger/env/docker-pull/plan/pull.cue @@ -0,0 +1,26 @@ +package docker + +import ( + "dagger.io/docker" + "dagger.io/dagger/op" + "dagger.io/alpine" +) + +ref: string @dagger(input) + +TestPull: { + pull: docker.#Pull & {from: ref} + + check: #up: [ + op.#Load & {from: alpine.#Image}, + op.#Exec & { + always: true + args: [ + "sh", "-c", """ + grep -q "test" /src/test.txt + """, + ] + mount: "/src": from: pull + }, + ] +} diff --git a/stdlib/.dagger/env/docker-pull/values.yaml b/stdlib/.dagger/env/docker-pull/values.yaml new file mode 100644 index 00000000..bd89b103 --- /dev/null +++ b/stdlib/.dagger/env/docker-pull/values.yaml @@ -0,0 +1,24 @@ +name: docker-pull +inputs: + ref: + text: docker.io/daggerio/ci-test:qhkmeqmhmnqn@sha256:96640793ed325f893608508f1b60b9c19b547c178e45639a249989545894eed4 +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0WFI2ZGFUOWgvNkdlZ3Na + dEE5dTlVQi8vUVJqcHUxWE9GSmdnNmZLMHhRCm1sbFlJbEw1ZVFSVXU4MCtkT09l + dVR1WE5XUkVpSXA3aXN5TzZLaWJRNnMKLS0tIDZINGpzODdXVUdKVVpFMjFUbUFO + SG1raUVNTzZIWDltV1pOS3hySHlJeWcKg3blmstOGcxtPww513+mAEA0MWOXwNAT + 5ngRvG6MraW3g9dhIuUYOwjuJyz1Z07/DBEocSxnjSyw45ZCkM1/9Q== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2021-06-12T15:01:07Z" + mac: ENC[AES256_GCM,data:kmryJiX4cnZTeyRcH+TljCj+m5kEA4yPu0gQkqS3apEolfNFWzkdlvRS2P+9EYO19iT1FxpNRwrs+G9qGeISubc48u2++Yb/mAUU4ilIu8flIPs3s63Ep8FeRv+hI3Govljjbjyds+3mR+o0Iv+KhpKBPDboXyRpWGlIijpBzLQ=,iv:ROAK7qmGn0jWDZp8uPLVbReqdgO9qw8EESkYdPjxLDk=,tag:8CrydkWN9xtJX8yItgjz+A==,type:str] + pgp: [] + encrypted_suffix: secret + version: 3.7.1 diff --git a/stdlib/.dagger/env/docker-push-invalid-creds/.gitignore b/stdlib/.dagger/env/docker-push-invalid-creds/.gitignore new file mode 100644 index 00000000..01ec19b0 --- /dev/null +++ b/stdlib/.dagger/env/docker-push-invalid-creds/.gitignore @@ -0,0 +1,2 @@ +# dagger state +state/** diff --git a/stdlib/.dagger/env/docker-push-invalid-creds/plan/push.cue b/stdlib/.dagger/env/docker-push-invalid-creds/plan/push.cue new file mode 100644 index 00000000..83e283a7 --- /dev/null +++ b/stdlib/.dagger/env/docker-push-invalid-creds/plan/push.cue @@ -0,0 +1,34 @@ +package docker + +import ( + "dagger.io/docker" + "dagger.io/random" +) + +TestRegistry: { + username: string @dagger(input) + secret: string @dagger(input) +} + +TestPush: { + tag: random.#String & {seed: "docker push and pull should fail"} + + name: "daggerio/ci-test:\(tag.out)" + + image: docker.#ImageFromDockerfile & { + dockerfile: """ + FROM alpine + RUN echo "test" > /test.txt + """ + context: "" + } + + push: docker.#Push & { + "name": name + source: image + registry: { + username: TestRegistry.username + secret: TestRegistry.secret + } + } +} diff --git a/stdlib/.dagger/env/docker-push-invalid-creds/values.yaml b/stdlib/.dagger/env/docker-push-invalid-creds/values.yaml new file mode 100644 index 00000000..9f227119 --- /dev/null +++ b/stdlib/.dagger/env/docker-push-invalid-creds/values.yaml @@ -0,0 +1,26 @@ +name: docker-push-invalid-creds +inputs: + TestRegistry.secret: + text: ENC[AES256_GCM,data:QOkT,iv:MUV92Llmt8pskd1AUjnvpQ+B3Ws1wLKIuzy7SVhHRME=,tag:StNvPnmz89GcLb1Cro3O9g==,type:str] + TestRegistry.username: + text: john +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3MC9DZGU1Tm5Ta2ttNUph + ZGxZaGxLMklRRWVaVmtzdEdqbnlkYmIvK2hNClVKd2RCak1GYXlvZWQxaHlzQUNw + Y2czeEdXZnQxT2dVQ01GY0NTcGNkMnMKLS0tIGwwa0xXVEZQUVUzdUpOQUJFTUxy + ZzZNNk1xb0F4cWVQRjh4aUJSUzExd2cKl0Ka0Qcc2KNOQjl3Bhnb1sGuJCZ6iDs4 + Hz2EldaxWJHZxuS18uNC38NxufG02ULJqJb2QC4cOzPrTeeKVE6Qlg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2021-06-12T15:03:49Z" + mac: ENC[AES256_GCM,data:o2fTjTnDgSX4f2jSjs1LSKJ7eTrTmFV44gyZdYCdYnb6eyXpFuT4Bru8ERuJlTvUSc3wx4js14BlxS3T0tX0aBV39ScBlzQOC4Ulyvh4KOKEH9uUl7YmGrFlNH4yQ7DYoezxCqwxlLZGavDaSXUszvKWlcdMsTm3L/4LkfHQzWk=,iv:E1gyYQ0+02bIQguvN0w+wp8RS6uyT17tXp18e5riXmg=,tag:Azjz4ZivYmjC/7eMc6SfSQ==,type:str] + pgp: [] + encrypted_suffix: secret + version: 3.7.1 diff --git a/stdlib/.dagger/env/docker-push/.gitignore b/stdlib/.dagger/env/docker-push/.gitignore new file mode 100644 index 00000000..01ec19b0 --- /dev/null +++ b/stdlib/.dagger/env/docker-push/.gitignore @@ -0,0 +1,2 @@ +# dagger state +state/** diff --git a/stdlib/.dagger/env/docker-push/plan/push.cue b/stdlib/.dagger/env/docker-push/plan/push.cue new file mode 100644 index 00000000..60ba10e7 --- /dev/null +++ b/stdlib/.dagger/env/docker-push/plan/push.cue @@ -0,0 +1,63 @@ +package docker + +import ( + "dagger.io/dagger/op" + "dagger.io/dagger" + "dagger.io/docker" + "dagger.io/alpine" + "dagger.io/random" +) + +TestRegistry: { + username: string @dagger(input) + secret: dagger.#Secret @dagger(input) +} + +#TestGetSecret: { + secret: dagger.#Artifact + + out: { + string + + #up: [ + op.#Load & {from: alpine.#Image}, + + op.#Exec & { + always: true + args: ["sh", "-c", "cp /input/secret /secret"] + mount: "/input/secret": "secret": secret + }, + + op.#Export & { + source: "/secret" + }, + ] + } +} + +TestPush: { + tag: random.#String & {seed: "docker push and pull"} + + name: "daggerio/ci-test:\(tag.out)" + + secret: #TestGetSecret & { + secret: TestRegistry.secret + } + + image: docker.#ImageFromDockerfile & { + dockerfile: """ + FROM alpine + RUN echo "test" > /test.txt + """ + context: "" + } + + push: docker.#Push & { + "name": name + source: image + registry: { + username: TestRegistry.username + "secret": secret.out + } + } +} diff --git a/stdlib/.dagger/env/docker-push/values.yaml b/stdlib/.dagger/env/docker-push/values.yaml new file mode 100644 index 00000000..35280cde --- /dev/null +++ b/stdlib/.dagger/env/docker-push/values.yaml @@ -0,0 +1,26 @@ +name: docker-push +inputs: + TestRegistry.secret: + secret: ENC[AES256_GCM,data:ooc+0IjYtX9tkM7q1i4Ws6CorZsWtGQzHbjGx+j892iTZC7Q,iv:asdJzuRAHBRhD/FlkEd1VvX1tIz/qupBL7sMQWxZL5E=,tag:yuTyDx7hZeC+cmHx6tspmQ==,type:str] + TestRegistry.username: + text: daggertest +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrcnpRZ203QzhtKzc3bzF4 + Y002V0JUUnNZMks2VS83SjBOdVZid1dxbTJjCmc5VGtvM3lOejEvQ3VMZ1ZyZElZ + Skd3ZWxRMHdQRHdtZFBYUFMweDFlL28KLS0tIHhHeUh4a2gvb2w3UTEyNFZaK0dS + UjFJYTc1UUUzSFVkZjQ2blRsSGpVdVEKOanMR3+WlAgoDfqTUW7WPW1ytT3NdkTX + 4Rqo49QmnuKFJ9tKoBFQOqgIo8E/lpcOkeIUiy5e/35FvsZ/KFk/pg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2021-06-12T13:31:57Z" + mac: ENC[AES256_GCM,data:TrLGfqDj3lvZKroaPtlDuR0Ki+yoFDYFqIhW+g7iasVOzvDaqHepX8X/aLiHX+XHdTqGH6ehfu1k1BSaz6xKqqdIai9NIyokgIKXR1F5mRgK/aDhc6x/YvX3dSl79/4zBBblDpYNFhCarQMxeTSFP9GfW+e0+T/z10fHHlQub8o=,iv:Pab2qkZTqP/6j4LV0B97SACQm/UZPMkeahGjZLJ2fFg=,tag:r4IW1WRipuC/MdtwEzzEpA==,type:str] + pgp: [] + encrypted_suffix: secret + version: 3.7.1 diff --git a/stdlib/docker/docker.cue b/stdlib/docker/docker.cue index 4ddc4475..5fcc0384 100644 --- a/stdlib/docker/docker.cue +++ b/stdlib/docker/docker.cue @@ -3,6 +3,7 @@ package docker import ( "alpha.dagger.io/dagger" + "alpha.dagger.io/alpine" "alpha.dagger.io/dagger/op" ) @@ -28,18 +29,73 @@ import ( ] } -// Push a docker image +// Push a docker image to remote registry #Push: { - // Remote ref (example: "index.docker.io/alpine:latest") - ref: string @dagger(input) + // Remote name (example: "index.docker.io/alpine:latest") + name: string @dagger(input) - // Image + // Image source source: dagger.#Artifact @dagger(input) - #up: [ - op.#Load & {from: source}, - op.#PushContainer & {"ref": ref}, + // Image registry + registry: { + // Remote registry + target: string | *"https://index.docker.io/v1/" @dagger(input) + + // Username + username: string @dagger(input) + + // Password or secret + secret: string | bytes @dagger(input) + } + + push: #up: [ + op.#Load & {from: source}, + + if registry != _|_ { + op.#DockerLogin & { + target: registry.target + username: registry.username + secret: registry.secret + } + }, + + op.#PushContainer & {ref: name}, + op.#Subdir & {dir: "/dagger"}, ] + + out: { + // Image ref + ref: string @dagger(output) + + // Image digest + digest: string @dagger(output) + + #up: [ + op.#Load & {from: alpine.#Image & { + package: { + bash: true + jq: true + } + }}, + + op.#Exec & { + always: true + args: ["/bin/bash", "-c", #""" + jq --arg key0 'ref' --arg value0 $(cat /dagger/image_ref) \ + --arg key1 'digest' --arg value1 $(cat /dagger/image_digest) \ + '. | .[$key0]=$value0 | .[$key1]=$value1 '<<< '{}' > /out + """#, + ] + mount: "/dagger": from: push + }, + + op.#Export & { + source: "/out" + format: "json" + }, + ] + } } #Run: { diff --git a/stdlib/universe.bats b/stdlib/universe.bats index 2ff76e4a..05f527ba 100644 --- a/stdlib/universe.bats +++ b/stdlib/universe.bats @@ -62,6 +62,23 @@ setup() { dagger -e docker-build up } +@test "docker push and pull" { + # Push image + dagger -e docker-push up + + # Get image reference + dagger -e docker-pull input text ref "$(dagger -e docker-push query -c TestPush.push.out.ref | tr -d '\n' | tr -d '\"')" + + # Pull image + dagger -e docker-pull up +} + +@test "docker push and pull: invalid credential" { + # Push image (SHOULD FAIL) + run docker -e docker-push-invalid-creds up + assert_failure +} + @test "docker command: ssh" { dagger -e docker-command-ssh up }