Some systems (at least, Centos 7, aarch64) block the membarrier() syscall via seccomp. This causes Scylla or unit tests to burn cpu instead of sleeping when there is nothing to do. Fix by instructing podman/docker not to block any syscalls. I tested this with podman, and it appears [1] to be supported on docker. [1] https://docs.docker.com/engine/security/seccomp/#run-without-the-default-seccomp-profile Closes #7661
233 lines
5.4 KiB
Bash
Executable File
233 lines
5.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
if [[ -f ~/.config/scylladb/dbuild ]]; then
|
|
. ~/.config/scylladb/dbuild
|
|
fi
|
|
|
|
if which docker >/dev/null 2>&1 ; then
|
|
tool=${DBUILD_TOOL-docker}
|
|
elif which podman >/dev/null 2>&1 ; then
|
|
tool=${DBUILD_TOOL-podman}
|
|
else
|
|
die "Please make sure you install either podman or docker on this machine to run 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
|
|
}
|
|
|
|
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 ! $tool image inspect "$image" >/dev/null && ! $tool 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="$($tool --help | grep -o podman)"
|
|
|
|
docker_common_args=()
|
|
|
|
docker_common_args+=("${SCYLLADB_DBUILD[@]}")
|
|
|
|
if [ -z "$is_podman" ]; then
|
|
unset TMP_PASSWD
|
|
docker_common_args+=(
|
|
-u "$(id -u):$(id -g)"
|
|
"${group_args[@]}"
|
|
-v /etc/passwd:/etc/passwd:ro
|
|
-v /etc/group:/etc/group:ro
|
|
)
|
|
else
|
|
TMP_PASSWD=$(mktemp --tmpdir passwd.XXXXXX)
|
|
FULLNAME=$(getent passwd $USER | cut -d ':' -f 5)
|
|
echo "$USER:x:0:0:$FULLNAME:$HOME:/bin/bash" > "$TMP_PASSWD"
|
|
docker_common_args+=(-v "$TMP_PASSWD:/etc/passwd: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+=(
|
|
--security-opt seccomp=unconfined \
|
|
--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="$HOME" \
|
|
"${docker_args[@]}" \
|
|
"$image" \
|
|
"${args[@]}"
|
|
)
|
|
|
|
cleanup() {
|
|
rm -rf "$tmpdir"
|
|
if [ -v TMP_PASSWD ]; then
|
|
rm -f "$TMP_PASSWD"
|
|
fi
|
|
}
|
|
|
|
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.
|
|
$tool run --rm "${docker_common_args[@]}"
|
|
ret=$?
|
|
cleanup
|
|
exit $ret
|
|
fi
|
|
|
|
container=$(
|
|
$tool run \
|
|
"--detach=true" \
|
|
"${docker_common_args[@]}"
|
|
)
|
|
|
|
kill_it() {
|
|
if [[ -n "$container" ]]; then
|
|
$tool rm -f "$container" > /dev/null
|
|
container=
|
|
fi
|
|
cleanup
|
|
}
|
|
|
|
trap kill_it SIGTERM SIGINT SIGHUP EXIT
|
|
|
|
$tool logs --follow "$container"
|
|
|
|
if [[ -n "$container" ]]; then
|
|
exitcode="$($tool 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"
|