This PR adds the possibility to gather resource consumption metrics. The collected metrics can be used to compare performance before and after specific changes aimed at increasing performance. Currently, this functionality works only in manual mode, and this is just raw data. Later on, these metrics can be used in Jupyter notebook to analyze and visualize how the resources are used and can provide the insight on how to improve it. This PR is a first insight after gathering these metrics. Add the possibility to gather resource consumption for the test.py execution. SQLite DB will be created with different performance metrics that will allow comparing the resource consumption between changes. The DB will be in the tmp directory that by default set to testlog. Across the runs, the DB will not be deleted, so each new run will just add information to the existing DB. Parameter --get-metrics was added to switch on or off the metrics gathering. By default, it's switched on. Closes: scylladb/qa-tasks#1666 Closes: scylladb/qa-tasks#1707 Closes scylladb/scylladb#19881
269 lines
6.5 KiB
Bash
Executable File
269 lines
6.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
if [[ -f ~/.config/scylladb/dbuild ]]; then
|
|
. ~/.config/scylladb/dbuild
|
|
fi
|
|
|
|
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 which podman >/dev/null 2>&1 ; then
|
|
tool=${DBUILD_TOOL-podman}
|
|
elif which docker >/dev/null 2>&1 ; then
|
|
tool=${DBUILD_TOOL-docker}
|
|
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
|
|
}
|
|
|
|
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"
|
|
|
|
if [[ -z "$CARGO_HOME" ]]; then
|
|
export CARGO_HOME="$HOME/.cargo"
|
|
mkdir -p "$CARGO_HOME"
|
|
fi
|
|
|
|
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
|
|
--pids-limit -1
|
|
)
|
|
else
|
|
docker_common_args+=(
|
|
--userns keep-id)
|
|
# --pids-limit is not supported on podman with cgroupsv1
|
|
# detection code from
|
|
# https://unix.stackexchange.com/questions/617764/how-do-i-check-if-system-is-using-cgroupv1
|
|
if grep -q 'cgroup2.*/sys/fs/cgroup ' /proc/mounts; then
|
|
docker_common_args+=(
|
|
--pids-limit -1
|
|
--annotation run.oci.keep_original_groups=1
|
|
)
|
|
fi
|
|
# if --pids-limit is not supported, add
|
|
# [containers]
|
|
# pids_limit = 0
|
|
#
|
|
# to /etc/containers/containers.conf
|
|
fi
|
|
|
|
if [ "$PWD" != "$toplevel" ]; then
|
|
docker_common_args+=(-v "$toplevel:$toplevel")
|
|
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)
|
|
|
|
if [ -e ~/.gdbinit ]; then
|
|
docker_common_args+=(-v "$HOME/.gdbinit:$HOME/.gdbinit:ro")
|
|
fi
|
|
|
|
# By default use "unlimited" as the hard limit
|
|
hard_limit=$(ulimit -Hn)
|
|
if [[ "${OSTYPE}" == "darwin"* ]]; then
|
|
# Docker-on-osx cannot parse "unlimited" as hard limit value, hence set to a high value
|
|
hard_limit=1024000
|
|
fi
|
|
|
|
if [[ -n "$interactive" || -t 0 ]]; then
|
|
docker_common_args+=("--tty")
|
|
fi
|
|
|
|
docker_common_args+=(
|
|
--security-opt seccomp=unconfined \
|
|
--security-opt label=disable \
|
|
--network host \
|
|
--cap-add SYS_PTRACE \
|
|
--privileged \
|
|
--ulimit nofile=$(ulimit -Sn):$hard_limit \
|
|
-v "$PWD:$PWD" \
|
|
-v "$tmpdir:/tmp" \
|
|
-v "$MAVEN_LOCAL_REPO:$MAVEN_LOCAL_REPO" \
|
|
-v /etc/localtime:/etc/localtime:ro \
|
|
--env CARGO_HOME \
|
|
-v "${CARGO_HOME}:${CARGO_HOME}" \
|
|
-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"
|