Skip to content

Instantly share code, notes, and snippets.

@terabyte
Created October 27, 2017 21:58
Show Gist options
  • Save terabyte/6e31801224d34d9cb0cc2ebd6dae094c to your computer and use it in GitHub Desktop.
Save terabyte/6e31801224d34d9cb0cc2ebd6dae094c to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# Copyright (c) 2017 Cloudera, Inc. All rights reserved.
set -ex
# Usage: ./docker.sh
# Usage: ./docker.sh test/test.sh
# Usage: INTERACTIVE=1 ./docker.sh
# This script invokes the docker container, does the needful to ensure the
# external user matches the internal user, maps in the kitchen/tools repo, then
# runs test.sh
KT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
DEFAULT_SCRIPT="test/test.sh"
SCRIPT_TO_RUN="$DEFAULT_SCRIPT"
if [[ -f "$KT_DIR/$1" ]]; then
if [[ -x "$KT_DIR/$1" ]]; then
# if the argument is a file and executable, run it, otherwise use default
# this enables testing a specific entrypoint
SCRIPT_TO_RUN="$1"
fi
fi
echo "Invoking script $KT_DIR/$SCRIPT_TO_RUN in docker..."
DOCKER_BIN="$(which docker)" || /bin/true
if [[ ! -x "$DOCKER_BIN" ]]; then
echo "This script requires that docker be on your path" 1>&2
exit 1
fi
$DOCKER_BIN build -f $KT_DIR/test/Dockerfile $KT_DIR | tee $KT_DIR/test/docker.log
IMAGE="$(cat $KT_DIR/test/docker.log | grep "^Successfully built" | cut -d' ' -f3)"
# it is bad practice for a build to rely upon or alter the user's homedir, but
# many tools do write to or read from caches in the user's homedir, including
# maven. We avoid this by creating an empty home dir for the user and map it in.
TMP_USER_HOME="$(mktemp -d)"
function cleanup() {
rm -rf $TMP_USER_HOME
}
trap cleanup EXIT
# PRO TIP: Did you know that maven (and possibly other java things) IGNORE $HOME and instead read /etc/passwd?
# For this reason, we can't just leak the hosts's /etc/passwd into the container, we need to control it.
# Same as Cauldron, we grab the container's /etc/passwd and /etc/group and modify them and overwrite them into the container.
NEWPW="$KT_DIR/test/.passwd"
NEWGRP="$KT_DIR/test/.group"
$DOCKER_BIN run $IMAGE /bin/bash -c "cat /etc/passwd" | grep -v "^$USER" > $NEWPW
$DOCKER_BIN run $IMAGE /bin/bash -c "cat /etc/group" | grep -v "^$USER" > $NEWGRP
echo "$USER:x:$UID:$GID:Test User,,,:/home/$USER:/bin/bash" >> $NEWPW
echo "$USER:x:$GID:$USER" >> $NEWGRP
# NOTE: docs encourage use of --mount over --volume, but the version of docker
# in our images is too old to support --mount.
MOUNTS="--volume $TMP_USER_HOME:/home/$USER"
# TODO: docker copies these files out of the image, edits them, then maps them
# back in. We should do that, probably reusing the code from cdh/cdh, but for
# now, this suffices.
MOUNTS="$MOUNTS --volume $NEWPW:/etc/passwd:ro"
MOUNTS="$MOUNTS --volume $NEWGRP:/etc/group:ro"
MOUNTS="$MOUNTS --volume /etc/localtime:/etc/localtime:ro"
MOUNTS="$MOUNTS --volume $KT_DIR:/kitchen-tools"
if [[ -n "$INTERACTIVE" ]]; then
echo "Running bash in interactive mode. The script that would have been run is: /kitchen-tools/$SCRIPT_TO_RUN"
$DOCKER_BIN run -i -t $MOUNTS -u $(id -u):$(id -g) -e USER="$USER" -e HOME="/home/$USER" "$IMAGE" /bin/bash
else
$DOCKER_BIN run $MOUNTS -u $(id -u):$(id -g) -e USER="$USER" -e HOME="/home/$USER" "$IMAGE" "/kitchen-tools/$SCRIPT_TO_RUN"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment