Skip to content

Commit

Permalink
Merge pull request #366 from EENCloud/jdictos/docker-secrets
Browse files Browse the repository at this point in the history
Add secrets support
  • Loading branch information
xtremerui authored Apr 23, 2024
2 parents c87d1c0 + d6b861c commit 93a4fe2
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,22 @@ version is the image's digest.
{ "EMAIL": "me@yopmail.com", "HOW_MANY_THINGS": 1, "DO_THING": false }
```

* `secrets`: *Optional.* A map of Docker build-time secrets. These will be
available as mounted paths only during the docker build phase.

Secrets are not stored in any metadata or layers, so they are safe to use for
access tokens and the like during the build.

Example:

```yaml
secrets:
secret1:
env: BUILD_ID
secret2:
source: /a/secret/file.txt
```

* `cache`: *Optional.* Default `false`. When the `build` parameter is set,
first pull `image:tag` from the Docker registry (so as to use cached
intermediate images when building). This will cause the resource to fail
Expand Down
29 changes: 28 additions & 1 deletion assets/out
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ tag_prefix=$(jq -r '.params.tag_prefix // ""' < $payload)
additional_tags=$(jq -r '.params.additional_tags // ""' < $payload)
need_tag_as_latest=$(jq -r '.params.tag_as_latest // "false"' < $payload)
build_args=$(jq -r '.params.build_args // {}' < $payload)
secrets=$(jq -r '.params.secrets // {}' < $payload)
build_args_file=$(jq -r '.params.build_args_file // ""' < $payload)
labels=$(jq -r '.params.labels // {}' < $payload)
labels_file=$(jq -r '.params.labels_file // ""' < $payload)
Expand Down Expand Up @@ -215,6 +216,32 @@ elif [ -n "$build" ]; then
fi
fi

expanded_secrets=()

secret_keys=($(echo "$secrets" | jq -r 'keys | join(" ")'))
if [ "${#secret_keys[@]}" -gt 0 ]; then
# Force buildkit on
export DOCKER_BUILDKIT=1
for key in "${secret_keys[@]}"; do
value=$(echo "$secrets" | jq -r --arg "k" "$key" '.[$k]')
for var in BUILD_ID BUILD_NAME BUILD_JOB_NAME BUILD_PIPELINE_NAME BUILD_TEAM_NAME ATC_EXTERNAL_URL; do
value="${value//\$$var/${!var:-}}"
value="${value//\$\{$var\}/${!var:-}}"
done
secret="id=${key}"
sub=$(jq -r ".params.secrets.${key} // {}" < $payload)
sub_keys=($(echo "$sub" | jq -r 'keys | join(" ")'))
if [ "${#sub_keys[@]}" -gt 0 ]; then
expanded_secrets+=("--secret")
for key in "${sub_keys[@]}"; do
value=$(echo "$sub" | jq -r --arg "k" "$key" '.[$k]')
secret="${secret},${key}=${value}"
done
expanded_secrets+=("${secret}")
fi
done
fi

expanded_labels=()

label_keys=($(echo "$labels" | jq -r 'keys | join(" ")'))
Expand Down Expand Up @@ -261,7 +288,7 @@ elif [ -n "$build" ]; then
# NOTE: deactivate amazon-ecr-credential-helper so that builds go through with the DOCKER_BUILDKIT set
cp ~/.docker/config.json ~/.docker/config.json.bak
cat <<< "$(jq 'del(.credsStore)' ~/.docker/config.json)" > ~/.docker/config.json
docker build -t "${repository}:${tag_name}" "${target[@]}" "${expanded_build_args[@]}" "${expanded_labels[@]}" "${ssh_args[@]}" -f "$dockerfile" $cache_from "$build"
docker build -t "${repository}:${tag_name}" "${target[@]}" "${expanded_build_args[@]}" "${expanded_secrets[@]}" "${expanded_labels[@]}" "${ssh_args[@]}" -f "$dockerfile" $cache_from "$build"
mv ~/.docker/config.json.bak ~/.docker/config.json # This restores the credsStore: ecr-login to config.json if needed

elif [ -n "$load_file" ]; then
Expand Down
31 changes: 31 additions & 0 deletions tests/out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,37 @@ var _ = Describe("Out", func() {
})
})

Context("when secrets are provided", func() {
It("passes the arguments correctly to the docker daemon", func() {
session := put(map[string]interface{}{
"source": map[string]interface{}{
"repository": "test",
},
"params": map[string]interface{}{
"build": "/docker-image-resource/tests/fixtures/build",
"secrets": map[string]interface{}{
"secret1": map[string]interface{}{
"env": "GITHUB_TOKEN",
},
"secret2": map[string]interface{}{
"source": "/a/file/path.txt",
},
"secret3": map[string]interface{}{
"source": "/a/file/path with a space in it.txt",
},
},
},
})

Expect(session.Err).To(gbytes.Say(dockerarg(`--secret`)))
Expect(session.Err).To(gbytes.Say(dockerarg(`id=secret1,env=GITHUB_TOKEN`)))
Expect(session.Err).To(gbytes.Say(dockerarg(`--secret`)))
Expect(session.Err).To(gbytes.Say(dockerarg(`id=secret2,source=/a/file/path.txt`)))
Expect(session.Err).To(gbytes.Say(dockerarg(`--secret`)))
Expect(session.Err).To(gbytes.Say(dockerarg(`id=secret3,source=/a/file/path with a space in it.txt`)))
})
})

Context("when labels are provided", func() {
It("passes the labels correctly to the docker daemon", func() {
session := put(map[string]interface{}{
Expand Down

0 comments on commit 93a4fe2

Please sign in to comment.