Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Commit

Permalink
Add image_aliases and hook script support (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
rnorth authored Aug 27, 2020
2 parents 02ae82a + dc9e0f7 commit 65fbbf9
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 23 deletions.
7 changes: 5 additions & 2 deletions .drone.example.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
pipeline:
build:
image: quay.io/testcontainers/dind-drone-plugin
build_image: openjdk:8-jdk
cmd: java -v
build_image: alpine:fake
cmd: cat /etc/issue
image_aliases:
alpine:3.5: alpine:fake
alpine:3.6: alpine:fake2
11 changes: 7 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
FROM docker:19.03.0-dind

RUN apk add --no-cache bash
RUN apk add --no-cache bash jq

#### Script that starts docker in docker
ADD command.sh /command.sh
RUN chmod +x /command.sh
ADD command.sh /dind-drone-plugin/command.sh
RUN chmod +x /dind-drone-plugin/command.sh

ENTRYPOINT ["/command.sh"]
#### Hook scripts
ADD hooks /dind-drone-plugin/hooks

ENTRYPOINT ["/dind-drone-plugin/command.sh"]
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,21 @@ pipeline:
build:
image: quay.io/testcontainers/dind-drone-plugin
build_image: openjdk:8-jdk-alpine
# This specifies the command that should be executed to perform build, test and integration tests. Not to be confused with Drone's `command`:
# This specifies the command that should be executed to perform build, test and
# integration tests. Not to be confused with Drone's `command`:
cmd: ./gradlew clean check --info
# Not mandatory, but enables pre-fetching of images in parallel with the build, so may save time:
# Not mandatory; enables pre-fetching of images in parallel with the build, so may save
# time:
prefetch_images:
- "redis:4.0.6"
# Not mandatory; sets up image name 'aliases' by pulling from one registry and tagging
# as a different name. Intended as a simplistic mechanism for using a private registry
# rather than Docker Hub for a known set of images. Accepts a dictionary of
# private registry image name to the Docker Hub image that it is a substitute for.
# Note that all images are pulled synchronously before the build starts, so this is
# inefficient if any unnecessary images are listed.
image_aliases:
someregistry.com/redis:4.0.6: redis:4.0.6
```
When migrating to use this plugin from an ordinary build step, note that:
Expand All @@ -41,8 +51,16 @@ When migrating to use this plugin from an ordinary build step, note that:
* `image` should be changed to `build_image`
* `prefetch_images` is optional, but recommended. This specifies a list of images that should be pulled in parallel with your build process, thus saving some time.

## Extending

Users with custom requirements can build a new image using this as a base image.

This image uses hook scripts, if present, to perform custom actions. Such scripts may be placed as executable files in any of `/dind-drone-plugin/hooks/{pre_daemon_start,post_daemon_start,pre_run,post_run}`, depending on which phase they are required to run in.

Some initial hook scripts already exist, which should be overwritten or removed if needed.

## Copyright

This repository contains code which was mainly developed at [Skyscanner](https://www.skyscanner.net/jobs/), and is licenced under the [Apache 2.0 Licence](LICENSE).

(c) 2017-2019 Skyscanner Ltd.
(c) 2017-2020 Skyscanner Ltd.
33 changes: 19 additions & 14 deletions command.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

set -euo pipefail # Abort on error, strict variable interpolation, fail if piped command fails

run_hook_scripts() {
for HOOK_SCRIPT in /dind-drone-plugin/hooks/$1/*; do
if [[ -x $HOOK_SCRIPT ]]; then
echo "📄 Running $1 hook script $HOOK_SCRIPT"
/bin/bash $HOOK_SCRIPT || exit 1
fi
done
}

if [[ "${PLUGIN_CMD:-}" == "" ]]; then
echo "One or more cmd arguments must be provided"
exit 1
Expand All @@ -13,6 +22,8 @@ export PLUGIN_CMD=${PLUGIN_CMD//,/ && }
# Wrap command scriptlet in an invocation of sh
export PLUGIN_CMD="sh -c '${PLUGIN_CMD}'"

run_hook_scripts pre_daemon_start

echo "📦 Starting dind-drone-plugin"

echo "🐳 Starting docker-in-docker daemon"
Expand All @@ -32,24 +43,13 @@ done
docker ps &> /dev/null || exit 1
echo "✅ Docker-in-Docker is running..."

if [[ "${PLUGIN_DOCKER_LOGIN_COMMAND:-}" != "" ]]; then
echo "🛠 Executing Docker login command"
sh -c "${PLUGIN_DOCKER_LOGIN_COMMAND}" 2>&1 | sed "s/^/ /g"
fi
run_hook_scripts post_daemon_start

if [[ "${PLUGIN_PREFETCH_IMAGES:-}" != "" ]]; then
echo "🚚 Prefetching images in background:"
for IMG in $(echo ${PLUGIN_PREFETCH_IMAGES} | sed "s/,/ /g"); do
echo " $IMG"
$(docker pull "$IMG" > /dev/null) &
done
fi
echo " Available images before build:"
docker image ls 2>&1 | sed 's/^/ /g'

cd ${CI_WORKSPACE}

echo "🚚 Pulling build image: ${PLUGIN_BUILD_IMAGE}"
docker pull ${PLUGIN_BUILD_IMAGE} 2>&1 | sed 's/^/ /g'

# Ensure that secrets (passed through as env vars) are available. Iterate and purposefully omit newlines.
for k in $(compgen -e); do
echo $k=${!k} >> ${PWD}/outer_env_vars.env
Expand All @@ -65,6 +65,9 @@ echo "ℹ️ DOCKER_HOST will be set to tcp://${DOCKER_IP}:2375"
echo "ℹ️ Containers spawned by the build container will be accessible at ${DOCKER_IP} (do not hardcode this value)"

echo -e "\n\n"

run_hook_scripts pre_run

MSG="🚀 About to run command: ${PLUGIN_CMD} on image ${PLUGIN_BUILD_IMAGE} inside Docker-in-Docker"
echo -e $MSG
echo -n " $MSG" | sed 's/./=/g'
Expand All @@ -85,6 +88,8 @@ CMD_EXIT_CODE=$?
echo; echo
echo "🏁 Exit code: $CMD_EXIT_CODE"

run_hook_scripts post_run

rm outer_env_vars.env

exit $CMD_EXIT_CODE
Empty file.
6 changes: 6 additions & 0 deletions hooks/post_daemon_start/10-docker-login-command.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

if [[ "${PLUGIN_DOCKER_LOGIN_COMMAND:-}" != "" ]]; then
echo "🛠 Executing Docker login command"
sh -c "${PLUGIN_DOCKER_LOGIN_COMMAND}" 2>&1 | sed "s/^/ /g"
fi
7 changes: 7 additions & 0 deletions hooks/post_daemon_start/20-image-aliases.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

echo $PLUGIN_IMAGE_ALIASES | jq -r 'to_entries[] | [.key, .value] | @tsv' | while read ORIGINAL NEW; do
echo "🐑 Pulling image $ORIGINAL and retagging as $NEW"
docker pull $ORIGINAL 2>&1 | sed 's/^/ /g'
docker tag $ORIGINAL $NEW 2>&1 | sed 's/^/ /g'
done
18 changes: 18 additions & 0 deletions hooks/post_daemon_start/30-image-prefetch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

pull_if_absent() {
if [[ $(docker images ${1} | wc -l) < 2 ]]; then
echo "🚚 Pulling image: ${1}"
docker pull ${1} 2>&1 | sed 's/^/ /g'
fi
}

if [[ "${PLUGIN_PREFETCH_IMAGES:-}" != "" ]]; then
echo "🚚 Prefetching images in background:"
for IMG in $(echo ${PLUGIN_PREFETCH_IMAGES} | sed "s/,/ /g"); do
echo " $IMG"
pull_if_absent "$IMG" > /dev/null &
done
fi

pull_if_absent ${PLUGIN_BUILD_IMAGE}
Empty file added hooks/post_run/.gitkeep
Empty file.
Empty file added hooks/pre_daemon_start/.gitkeep
Empty file.
Empty file added hooks/pre_run/.gitkeep
Empty file.

0 comments on commit 65fbbf9

Please sign in to comment.