Files
scylladb/tools/toolchain/dbuild
Avi Kivity 1c2f538eb3 tools: toolchain: dbuild: allow customization of docker arguments
Introduce ~/.config/scylladb/dbuild configuration file, and
SCYLLADB_DBUILD environment variables, that inject options into
the docker run command. This allows adding bind mounts for ccache
and distcc directories, as well as any local scripts and PATH
or other environment configuration to suit the user's needs.

Message-Id: <20200521133529.25880-1-avi@scylladb.com>
2020-05-22 13:52:21 +03:00

213 lines
4.9 KiB
Bash
Executable File

#!/bin/bash
if [[ -f ~/.config/scylladb/dbuild ]]; then
. ~/.config/scylladb/dbuild
fi
here="$(realpath $(dirname "$0"))"
toplevel="$(realpath "$here/../..")"
group_args=()
docker_args=()
image="$(<"$here/image")"
for gid in $(id -G); do
group_args+=(--group-add "$gid")
done
interactive=
function help () {
cat <<EOF 1>&2
NAME
$(basename $0) - Run a command in scylla's frozen toolchain docker build image.
SYNOPSIS
$0 [OPTIONS --] [command [arg ...]]
DESCRIPTION
$(basename $0) is used mainly to build scylla in a docker image containing
a frozen version of the toolchain.
When no command is provided, $(basename $0) runs an interactive shell in
the docker instance. The image to use is taken by default from "$(dirname $0)/image".
It may be overriden using the --image option.
When providing docker options, the options list must be terminated with \`--'.
OPTIONS
-h | --help
Print this help message.
--image [IMAGE]
Use the specified docker IMAGE.
If omitted, list the available images using \`docker image ls'
-i | --interactive
Run an interactive session.
See \`docker help run' for available options.
ENVIRONMENT
SCYLLADB_DBUILD this variable, which can be a string or a bash
array, is prepended to the parmeters passed to
docker. This can be used to mount the ccache
directory (~/.ccache) and set up environment
variables (e.g. CCACHE_PREFIX)
If the file ~/.config/scylladb/dbuild exists, it is sourced. This can
be used to set up the SCYLLADB_DBUILD environment variable.
EOF
exit 0
}
function die () {
msg="$1"
if [[ -n "$msg" ]]; then
echo "$(basename $0): $msg." 1>&2
fi
cat <<EOF 1>&2
Run \`$0 --help' to print the full help message.
EOF
exit 1
}
docker --version >/dev/null 2>&1 || die "Please install Docker on this machine to run dbuild"
if [[ $# -eq 0 ]]; then
interactive=y
docker_args=(-it)
elif [[ "$1" = -* ]]; then
while [[ "$1" != "--" && $# != 0 ]]; do
case "$1" in
-h|--help)
help
;;
--image)
image="$2"
shift 2
if [[ -z "$image" ]]; then
die "Expected docker image identifier to follow the --image option"
fi
if ! docker image inspect "$image" >/dev/null && ! docker image pull "$image"; then
die
fi
continue
;;
--*)
if [[ "$1" = --interactive || "$1" = --interactive=true ]]; then
interactive=y
fi
;;
-*)
if [[ "$1" = -*i* ]]; then
interactive=y
fi
;;
*)
;;
esac
docker_args+=("$1")
shift
done
if [[ "$1" != "--" ]]; then
die "Expected '--' to terminate docker flag list"
fi
shift
fi
if [[ $# != 0 ]]; then
args=("$@")
else
args=(/bin/bash -i)
fi
MAVEN_LOCAL_REPO="$HOME/.m2"
mkdir -p "$MAVEN_LOCAL_REPO"
is_podman="$(docker --help | grep -o podman)"
docker_common_args=()
docker_common_args+=("${SCYLLADB_DBUILD[@]}")
if [ -z "$is_podman" ]; then
docker_common_args+=(
-u "$(id -u):$(id -g)"
"${group_args[@]}"
-v /etc/passwd:/etc/passwd:ro
-v /etc/group:/etc/group:ro
)
fi
if [ "$PWD" != "$toplevel" ]; then
docker_common_args+=(-v "$toplevel:$toplevel:z")
fi
# podman cannot relabel system directories like /tmp, but it can
# relable directories we own, so we map a temporary directory to /tmp
tmpdir=$(mktemp -d)
docker_common_args+=(
--pids-limit -1 \
--network host \
--cap-add SYS_PTRACE \
-v "$PWD:$PWD:z" \
-v "$tmpdir:/tmp:z" \
-v "$MAVEN_LOCAL_REPO:$MAVEN_LOCAL_REPO:z" \
-v /etc/localtime:/etc/localtime:ro \
-w "$PWD" \
-e HOME \
"${docker_args[@]}" \
"$image" \
"${args[@]}"
)
if [[ -n "$interactive" || -n "$is_podman" ]]; then
# If --interactive was given on the command line, we can't run in detached mode
# as it will be impossible to interact with the container.
# We also avoid detached mode with podman, which doesn't need it
# (it does not proxy SIGTERM) and doesn't work well with it.
docker run --rm "${docker_common_args[@]}"
ret=$?
rm -rf "$tmpdir"
exit $ret
fi
container=$(
docker run \
"--detach=true" \
"${docker_common_args[@]}"
)
kill_it() {
if [[ -n "$container" ]]; then
docker rm -f "$container" > /dev/null
container=
fi
rm -rf "$tmpdir"
}
trap kill_it SIGTERM SIGINT SIGHUP EXIT
docker logs --follow "$container"
if [[ -n "$container" ]]; then
exitcode="$(docker wait "$container")"
else
exitcode=99
fi
kill_it
trap - SIGTERM SIGINT SIGHUP EXIT
# after "docker kill", docker wait will not print anything
[[ -z "$exitcode" ]] && exitcode=1
exit "$exitcode"