mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-18 14:54:19 +01:00
In order to run kata metrics we need to check that the containerd config file is properly set. When this is not the case, we need to remove that file, and generate a valid one. This PR runs rm -f in order to ignore errors in case the file to delete does not exist. Fixes: #7336 Signed-off-by: David Esparza <david.esparza.borquez@intel.com>
314 lines
9.5 KiB
Bash
314 lines
9.5 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# Copyright (c) 2018-2019 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
# This file contains common functions that
|
|
# are being used by our metrics and integration tests
|
|
|
|
# Kata tests directory used for storing various test-related artifacts.
|
|
KATA_TESTS_BASEDIR="${KATA_TESTS_BASEDIR:-/var/log/kata-tests}"
|
|
|
|
# Directory that can be used for storing test logs.
|
|
KATA_TESTS_LOGDIR="${KATA_TESTS_LOGDIR:-${KATA_TESTS_BASEDIR}/logs}"
|
|
|
|
# Directory that can be used for storing test data.
|
|
KATA_TESTS_DATADIR="${KATA_TESTS_DATADIR:-${KATA_TESTS_BASEDIR}/data}"
|
|
|
|
# Directory that can be used for storing cache kata components
|
|
KATA_TESTS_CACHEDIR="${KATA_TESTS_CACHEDIR:-${KATA_TESTS_BASEDIR}/cache}"
|
|
|
|
KATA_HYPERVISOR="${KATA_HYPERVISOR:-qemu}"
|
|
|
|
RUNTIME="${RUNTIME:-containerd-shim-kata-v2}"
|
|
|
|
function die() {
|
|
local msg="$*"
|
|
echo -e "[$(basename $0):${BASH_LINENO[0]}] ERROR: $msg" >&2
|
|
exit 1
|
|
}
|
|
|
|
function warn() {
|
|
local msg="$*"
|
|
echo -e "[$(basename $0):${BASH_LINENO[0]}] WARNING: $msg"
|
|
}
|
|
|
|
function info() {
|
|
local msg="$*"
|
|
echo -e "[$(basename $0):${BASH_LINENO[0]}] INFO: $msg"
|
|
}
|
|
|
|
function handle_error() {
|
|
local exit_code="${?}"
|
|
local line_number="${1:-}"
|
|
echo -e "[$(basename $0):$line_number] ERROR: $(eval echo "$BASH_COMMAND")"
|
|
exit "${exit_code}"
|
|
}
|
|
trap 'handle_error $LINENO' ERR
|
|
|
|
function waitForProcess() {
|
|
wait_time="$1"
|
|
sleep_time="$2"
|
|
cmd="$3"
|
|
while [ "$wait_time" -gt 0 ]; do
|
|
if eval "$cmd"; then
|
|
return 0
|
|
else
|
|
sleep "$sleep_time"
|
|
wait_time=$((wait_time-sleep_time))
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Check if the $1 argument is the name of a 'known'
|
|
# Kata runtime. Of course, the end user can choose any name they
|
|
# want in reality, but this function knows the names of the default
|
|
# and recommended Kata docker runtime install names.
|
|
function is_a_kata_runtime() {
|
|
if [ "$1" = "containerd-shim-kata-v2" ] || [ "$1" = "io.containerd.kata.v2" ]; then
|
|
echo "1"
|
|
else
|
|
echo "0"
|
|
fi
|
|
}
|
|
|
|
# Gets versions and paths of all the components
|
|
# list in kata-env
|
|
function extract_kata_env() {
|
|
RUNTIME_CONFIG_PATH=$(kata-runtime kata-env --json | jq -r .Runtime.Config.Path)
|
|
RUNTIME_VERSION=$(kata-runtime kata-env --json | jq -r .Runtime.Version | grep Semver | cut -d'"' -f4)
|
|
RUNTIME_COMMIT=$(kata-runtime kata-env --json | jq -r .Runtime.Version | grep Commit | cut -d'"' -f4)
|
|
RUNTIME_PATH=$(kata-runtime kata-env --json | jq -r .Runtime.Path)
|
|
|
|
# Shimv2 path is being affected by https://github.com/kata-containers/kata-containers/issues/1151
|
|
SHIM_PATH=$(readlink $(command -v containerd-shim-kata-v2))
|
|
SHIM_VERSION=${RUNTIME_VERSION}
|
|
|
|
HYPERVISOR_PATH=$(kata-runtime kata-env --json | jq -r .Hypervisor.Path)
|
|
# TODO: there is no kata-runtime of rust version currently
|
|
if [ "${KATA_HYPERVISOR}" != "dragonball" ]; then
|
|
HYPERVISOR_VERSION=$(sudo -E ${HYPERVISOR_PATH} --version | head -n1)
|
|
fi
|
|
VIRTIOFSD_PATH=$(kata-runtime kata-env --json | jq -r .Hypervisor.VirtioFSDaemon)
|
|
|
|
INITRD_PATH=$(kata-runtime kata-env --json | jq -r .Initrd.Path)
|
|
}
|
|
|
|
# Checks that processes are not running
|
|
function check_processes() {
|
|
extract_kata_env
|
|
|
|
# Only check the kata-env if we have managed to find the kata executable...
|
|
if [ -x "$RUNTIME_PATH" ]; then
|
|
local vsock_configured=$($RUNTIME_PATH kata-env | awk '/UseVSock/ {print $3}')
|
|
local vsock_supported=$($RUNTIME_PATH kata-env | awk '/SupportVSock/ {print $3}')
|
|
else
|
|
local vsock_configured="false"
|
|
local vsock_supported="false"
|
|
fi
|
|
|
|
general_processes=( ${HYPERVISOR_PATH} ${SHIM_PATH} )
|
|
|
|
for i in "${general_processes[@]}"; do
|
|
if pgrep -f "$i"; then
|
|
die "Found unexpected ${i} present"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Clean environment, this function will try to remove all
|
|
# stopped/running containers.
|
|
function clean_env()
|
|
{
|
|
# If the timeout has not been set, default it to 30s
|
|
# Docker has a built in 10s default timeout, so make ours
|
|
# longer than that.
|
|
KATA_DOCKER_TIMEOUT=${KATA_DOCKER_TIMEOUT:-30}
|
|
containers_running=$(sudo timeout ${KATA_DOCKER_TIMEOUT} docker ps -q)
|
|
|
|
if [ ! -z "$containers_running" ]; then
|
|
# First stop all containers that are running
|
|
# Use kill, as the containers are generally benign, and most
|
|
# of the time our 'stop' request ends up doing a `kill` anyway
|
|
sudo timeout ${KATA_DOCKER_TIMEOUT} docker kill $containers_running
|
|
|
|
# Remove all containers
|
|
sudo timeout ${KATA_DOCKER_TIMEOUT} docker rm -f $(docker ps -qa)
|
|
fi
|
|
}
|
|
|
|
function clean_env_ctr()
|
|
{
|
|
local count_running="$(sudo ctr c list -q | wc -l)"
|
|
local remaining_attempts=10
|
|
declare -a running_tasks=()
|
|
local count_tasks=0
|
|
local sleep_time=1
|
|
local time_out=10
|
|
|
|
[ "$count_running" -eq "0" ] && return 0
|
|
|
|
readarray -t running_tasks < <(sudo ctr t list -q)
|
|
|
|
info "Wait until the containers gets removed"
|
|
|
|
for task_id in "${running_tasks[@]}"; do
|
|
sudo ctr t kill -a -s SIGTERM ${task_id} >/dev/null 2>&1
|
|
sleep 0.5
|
|
done
|
|
|
|
# do not stop if the command fails, it will be evaluated by waitForProcess
|
|
local cmd="[[ $(sudo ctr tasks list | grep -c "STOPPED") == "$count_running" ]]" || true
|
|
|
|
local res="ok"
|
|
waitForProcess "${time_out}" "${sleep_time}" "$cmd" || res="fail"
|
|
|
|
[ "$res" == "ok" ] || sudo systemctl restart containerd
|
|
|
|
while (( remaining_attempts > 0 )); do
|
|
[ "${RUNTIME}" == "runc" ] && sudo ctr tasks rm -f $(sudo ctr task list -q)
|
|
sudo ctr c rm $(sudo ctr c list -q) >/dev/null 2>&1
|
|
|
|
count_running="$(sudo ctr c list -q | wc -l)"
|
|
|
|
[ "$count_running" -eq 0 ] && break
|
|
|
|
remaining_attempts=$((remaining_attempts-1))
|
|
done
|
|
|
|
count_tasks="$(sudo ctr t list -q | wc -l)"
|
|
|
|
if (( count_tasks > 0 )); then
|
|
die "Can't remove running contaienrs."
|
|
fi
|
|
}
|
|
|
|
# Restarts a systemd service while ensuring the start-limit-burst is set to 0.
|
|
# Outputs warnings to stdio if something has gone wrong.
|
|
#
|
|
# Returns 0 on success, 1 otherwise
|
|
function restart_systemd_service_with_no_burst_limit() {
|
|
local service=$1
|
|
info "restart $service service"
|
|
|
|
local active=$(systemctl show "$service.service" -p ActiveState | cut -d'=' -f2)
|
|
[ "$active" == "active" ] || warn "Service $service is not active"
|
|
|
|
local start_burst=$(systemctl show "$service".service -p StartLimitBurst | cut -d'=' -f2)
|
|
if [ "$start_burst" -ne 0 ]
|
|
then
|
|
local unit_file=$(systemctl show "$service.service" -p FragmentPath | cut -d'=' -f2)
|
|
[ -f "$unit_file" ] || { warn "Can't find $service's unit file: $unit_file"; return 1; }
|
|
|
|
local start_burst_set=$(sudo grep StartLimitBurst $unit_file | wc -l)
|
|
if [ "$start_burst_set" -eq 0 ]
|
|
then
|
|
sudo sed -i '/\[Service\]/a StartLimitBurst=0' "$unit_file"
|
|
else
|
|
sudo sed -i 's/StartLimitBurst.*$/StartLimitBurst=0/g' "$unit_file"
|
|
fi
|
|
|
|
sudo systemctl daemon-reload
|
|
fi
|
|
|
|
sudo systemctl restart "$service"
|
|
|
|
local state=$(systemctl show "$service.service" -p SubState | cut -d'=' -f2)
|
|
[ "$state" == "running" ] || { warn "Can't restart the $service service"; return 1; }
|
|
|
|
start_burst=$(systemctl show "$service.service" -p StartLimitBurst | cut -d'=' -f2)
|
|
[ "$start_burst" -eq 0 ] || { warn "Can't set start burst limit for $service service"; return 1; }
|
|
|
|
return 0
|
|
}
|
|
|
|
function restart_containerd_service() {
|
|
restart_systemd_service_with_no_burst_limit containerd || return 1
|
|
|
|
local retries=5
|
|
local counter=0
|
|
until [ "$counter" -ge "$retries" ] || sudo ctr --connect-timeout 1s version > /dev/null 2>&1
|
|
do
|
|
info "Waiting for containerd socket..."
|
|
((counter++))
|
|
done
|
|
|
|
[ "$counter" -ge "$retries" ] && { warn "Can't connect to containerd socket"; return 1; }
|
|
|
|
clean_env_ctr
|
|
return 0
|
|
}
|
|
|
|
function create_symbolic_links() {
|
|
local KATA_HYPERVISOR="${1}"
|
|
|
|
local link_configuration_file="/opt/kata/share/defaults/kata-containers/configuration.toml"
|
|
local source_configuration_file="/opt/kata/share/defaults/kata-containers/configuration-${KATA_HYPERVISOR}.toml"
|
|
|
|
if [ "${KATA_HYPERVISOR}" != 'qemu' ] && [ "${KATA_HYPERVISOR}" != 'clh' ]; then
|
|
die "Failed to set the configuration.toml: '${KATA_HYPERVISOR}' is not recognized as a valid hypervisor name."
|
|
fi
|
|
|
|
sudo ln -sf "${source_configuration_file}" "${link_configuration_file}"
|
|
}
|
|
|
|
# Configures containerd
|
|
function overwrite_containerd_config() {
|
|
containerd_config="/etc/containerd/config.toml"
|
|
sudo rm -f "${containerd_config}"
|
|
sudo tee "${containerd_config}" << EOF
|
|
version = 2
|
|
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
|
|
SystemdCgroup = true
|
|
|
|
[plugins]
|
|
[plugins."io.containerd.grpc.v1.cri"]
|
|
[plugins."io.containerd.grpc.v1.cri".containerd]
|
|
default_runtime_name = "kata"
|
|
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
|
|
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata]
|
|
runtime_type = "io.containerd.kata.v2"
|
|
EOF
|
|
}
|
|
|
|
function install_kata() {
|
|
local kata_tarball="kata-static.tar.xz"
|
|
declare -r katadir="/opt/kata"
|
|
declare -r destdir="/"
|
|
declare -r local_bin_dir="/usr/local/bin/"
|
|
|
|
# Removing previous kata installation
|
|
sudo rm -rf "${katadir}"
|
|
|
|
pushd "${kata_tarball_dir}"
|
|
sudo tar -xvf "${kata_tarball}" -C "${destdir}"
|
|
popd
|
|
|
|
# create symbolic links to kata components
|
|
for b in "${katadir}/bin/*" ; do
|
|
sudo ln -sf "${b}" "${local_bin_dir}/$(basename $b)"
|
|
done
|
|
|
|
check_containerd_config_for_kata
|
|
restart_containerd_service
|
|
install_checkmetrics
|
|
}
|
|
|
|
function check_containerd_config_for_kata() {
|
|
# check containerd config
|
|
declare -r line1="default_runtime_name = \"kata\""
|
|
declare -r line2="runtime_type = \"io.containerd.kata.v2\""
|
|
declare -r num_lines_containerd=2
|
|
declare -r containerd_path="/etc/containerd/config.toml"
|
|
local count_matches=$(grep -ic "$line1\|$line2" "${containerd_path}")
|
|
|
|
if [ "${count_matches}" = "${num_lines_containerd}" ]; then
|
|
info "containerd ok"
|
|
else
|
|
info "overwriting containerd configuration w/ a valid one"
|
|
overwrite_containerd_config
|
|
fi
|
|
}
|