Files
scylladb/tools/toolchain/dbuild
Andrei Chekun bbb6c3c2ff test.py: Add resource consumption metrics
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
2024-09-17 15:22:34 +03:00

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"