Files
kata-containers/tests/integration/cri-containerd/integration-tests.sh
Fabiano Fidêncio 3ca9eb94b9 cri-containerd: fix v1 sanity-check config generation
Avoid emitting unsupported plugin keys and empty runtime options in the
v1.x config path so containerd 1.7 can load the generated TOML during
runc sanity checks.

While here, let's also dump the temporary cri-integration config on
failure to speed diagnosis.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-06-09 10:46:38 +02:00

850 lines
27 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright (c) 2017-2023 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
# shellcheck disable=SC2154
[[ "${DEBUG}" != "" ]] && set -o xtrace
set -o errexit
set -o nounset
set -o pipefail
set -o errtrace
SCRIPT_PATH=$(dirname "$(readlink -f "$0")")
# shellcheck source=/dev/null
source "${SCRIPT_PATH}/../../common.bash"
# runc is installed in /usr/local/sbin/ add that path
export PATH="${PATH}:/usr/local/sbin"
# golang is installed in /usr/local/go/bin/ add that path
export PATH="${PATH}:/usr/local/go/bin"
#the latest containerd from 2.0 need to set the CGROUP_DRIVER for e2e testing
export CGROUP_DRIVER=""
# Runtime to be used for testing
KATA_HYPERVISOR="${KATA_HYPERVISOR:-qemu}"
RUNTIME=${RUNTIME:-containerd-shim-kata-${KATA_HYPERVISOR}-v2}
FACTORY_TEST=${FACTORY_TEST:-""}
ARCH=$(uname -m)
SANDBOXER=${SANDBOXER:-"podsandbox"}
containerd_runtime_type="io.containerd.kata-${KATA_HYPERVISOR}.v2"
containerd_shim_path="$(command -v containerd-shim || true)"
#containerd config file
tmp_dir=$(mktemp -t -d test-cri-containerd.XXXX)
readonly tmp_dir
export REPORT_DIR="${tmp_dir}"
readonly CONTAINERD_CONFIG_FILE="${tmp_dir}/test-containerd-config.toml"
readonly CONTAINERD_CONF_D="${tmp_dir}/conf.d"
readonly CONTAINERD_SYSTEM_FRAGMENT_PREFIX="${CONTAINERD_SYSTEM_FRAGMENT_PREFIX:-ZZ-cri-integration-test-}"
readonly CONTAINERD_CONFIG_FILE_TEMP="${CONTAINERD_CONFIG_FILE}.temp"
readonly default_containerd_config="/etc/containerd/config.toml"
readonly default_containerd_config_backup="${CONTAINERD_CONFIG_FILE}.backup"
readonly kata_config="/etc/kata-containers/configuration.toml"
readonly kata_config_backup="${kata_config}.backup"
function ci_config() {
sudo mkdir -p "$(dirname "${kata_config}")"
[[ -f "${kata_config}" ]] && sudo cp "${kata_config}" "${kata_config_backup}"
# shellcheck disable=SC2154
sudo cp -f "${KATA_CONFIG_PATH}" "${kata_config}"
source /etc/os-release || source /usr/lib/os-release
ID=${ID:-""}
if [[ "${ID}" == ubuntu ]]; then
# https://github.com/kata-containers/tests/issues/352
if [[ -n "${FACTORY_TEST}" ]]; then
# Handle both commented and uncommented enable_template
sudo sed -i -e 's/^#\?enable_template.*$/enable_template = true/g' "${kata_config}"
echo "init vm template"
sudo -E PATH="${PATH}" "${RUNTIME}" factory init
fi
fi
echo "enable debug for kata-runtime"
# Handle both commented and uncommented enable_debug
sudo sed -i 's/^#\?enable_debug = .*$/enable_debug = true/g' "${kata_config}"
}
function ci_cleanup() {
source /etc/os-release || source /usr/lib/os-release
if [[ -n "${FACTORY_TEST}" ]]; then
echo "destroy vm template"
sudo -E PATH="${PATH}" "${RUNTIME}" factory destroy
fi
if [[ -e "${default_containerd_config_backup}" ]]; then
echo "restore containerd config"
sudo systemctl stop containerd
sudo rm -f /etc/containerd/conf.d/"${CONTAINERD_SYSTEM_FRAGMENT_PREFIX}"*.toml
sudo cp "${default_containerd_config_backup}" "${default_containerd_config}"
fi
if [[ -f "${kata_config_backup}" ]]; then
sudo mv "${kata_config_backup}" "${kata_config}"
else
sudo rm "${kata_config}"
fi
}
function generate_runtime_options_block() {
local runtime="${1:?}"
local pluginid="${2:?}"
local runtime_config_path="${3:-}"
local runtime_binary_path="${4:-}"
if [[ "${runtime}" == "runc" ]]; then
return 0
fi
cat << EOF
[plugins.${pluginid}.containerd.runtimes.${runtime}.options]
ConfigPath = "${runtime_config_path}"
BinaryName = "${runtime_binary_path}"
EOF
}
function create_containerd_config() {
local runtime="$1"
# kata_annotations is set to 1 if caller want containerd setup with
# kata annotations support.
local kata_annotations=${2-0}
[[ -n "${runtime}" ]] || die "need runtime to create config"
local runtime_type="${containerd_runtime_type}"
local runtime_config_path="${kata_config}"
local containerd_runtime
containerd_runtime=$(command -v "containerd-shim-${runtime}-v2")
local runtime_binary_path="${containerd_runtime}"
if [[ "${runtime}" == "runc" ]]; then
runtime_type="io.containerd.runc.v2"
runtime_config_path=""
runtime_binary_path=""
fi
local cfg_schema
cfg_schema="$(_containerd_blob_schema_version "$(PATH="${PATH}:/usr/local/bin:/usr/local/sbin" containerd config default 2>/dev/null || true)")"
[[ "${cfg_schema}" =~ ^[0-9]+$ ]] || die "could not read containerd config schema from config default"
info "Kata Config Path ${runtime_config_path}, Runtime Binary Name ${runtime_binary_path}"
if [[ "${cfg_schema}" -ge 3 ]]; then
# containerd v2.x (schema v3+): base config (imports conf.d) plus drop-in
# fragments for sockets, debug, runtime and the linux shim.
local pluginid=\"io.containerd.cri.v1.runtime\"
local runtime_options_block=""
runtime_options_block="$(generate_runtime_options_block \
"${runtime}" "${pluginid}" "${runtime_config_path}" "${runtime_binary_path}")"
mkdir -p "${CONTAINERD_CONF_D}"
containerd_render_config_default_with_imports "${CONTAINERD_CONFIG_FILE}" "${CONTAINERD_CONF_D}"
containerd_emit_rootful_api_socket_overrides "${cfg_schema}" > "${CONTAINERD_CONF_D}/10-cri-test-api-sockets.toml"
cat <<'EOF' > "${CONTAINERD_CONF_D}/20-cri-test-debug.toml"
[debug]
level = "debug"
EOF
cat << EOF > "${CONTAINERD_CONF_D}/30-cri-test-runtime.toml"
[plugins]
[plugins.${pluginid}]
[plugins.${pluginid}.containerd]
default_runtime_name = "${runtime}"
[plugins.${pluginid}.containerd.runtimes.${runtime}]
runtime_type = "${runtime_type}"
sandboxer = "${SANDBOXER}"
$( [[ "${kata_annotations}" -eq 1 ]] && \
echo 'pod_annotations = ["io.katacontainers.*"]' && \
echo ' container_annotations = ["io.katacontainers.*"]'
)
${runtime_options_block}
EOF
if [[ -n "${containerd_shim_path}" ]]; then
cat << EOF > "${CONTAINERD_CONF_D}/40-cri-test-linux.toml"
[plugins.linux]
shim = "${containerd_shim_path}"
EOF
else
rm -f "${CONTAINERD_CONF_D}/40-cri-test-linux.toml"
fi
else
# containerd v1.x (schema v2): conf.d is not honoured the same way, so
# write a single complete, self-contained config file. The v1.x default
# API sockets are already root-owned, so no socket override is needed.
local pluginid=\"io.containerd.grpc.v1.cri\"
local runtime_options_block=""
runtime_options_block="$(generate_runtime_options_block \
"${runtime}" "${pluginid}" "${runtime_config_path}" "${runtime_binary_path}")"
mkdir -p "${CONTAINERD_CONF_D}"
cat << EOF > "${CONTAINERD_CONFIG_FILE}"
version = 2
[debug]
level = "debug"
[plugins]
[plugins.${pluginid}]
[plugins.${pluginid}.containerd]
default_runtime_name = "${runtime}"
[plugins.${pluginid}.containerd.runtimes.${runtime}]
runtime_type = "${runtime_type}"
$( [[ "${kata_annotations}" -eq 1 ]] && \
echo 'pod_annotations = ["io.katacontainers.*"]' && \
echo ' container_annotations = ["io.katacontainers.*"]'
)
${runtime_options_block}
EOF
fi
}
# Push the test containerd config to the host paths used by crictl.
function deploy_cri_integration_containerd_host_config() {
sudo cp "${default_containerd_config}" "${default_containerd_config_backup}"
local cfg_schema
cfg_schema="$(_containerd_blob_schema_version "$(PATH="${PATH}:/usr/local/bin:/usr/local/sbin" containerd config default 2>/dev/null || true)")"
if [[ "${cfg_schema}" =~ ^[0-9]+$ ]] && [[ "${cfg_schema}" -ge 3 ]]; then
# containerd v2.x (schema v3+): base config (imports conf.d) + drop-ins.
local host_main_fragment="${REPORT_DIR}/containerd-main-for-host.toml"
containerd_render_config_default_with_imports "${host_main_fragment}" "/etc/containerd/conf.d"
sudo mkdir -p /etc/containerd/conf.d
sudo cp "${host_main_fragment}" "${default_containerd_config}"
shopt -s nullglob
for f in "${CONTAINERD_CONF_D}"/*.toml; do
sudo cp "${f}" "/etc/containerd/conf.d/${CONTAINERD_SYSTEM_FRAGMENT_PREFIX}$(basename "${f}")"
done
shopt -u nullglob
else
# containerd v1.x (schema v2): deploy the complete, self-contained config.
sudo cp "${CONTAINERD_CONFIG_FILE}" "${default_containerd_config}"
fi
restart_containerd_service
}
function restore_cri_integration_containerd_host_config() {
sudo rm -f /etc/containerd/conf.d/"${CONTAINERD_SYSTEM_FRAGMENT_PREFIX}"*.toml
sudo cp "${default_containerd_config_backup}" "${default_containerd_config}"
restart_containerd_service
}
function cleanup() {
ci_cleanup
[[ -d "${tmp_dir}" ]] && rm -rf "${tmp_dir}"
}
trap cleanup EXIT
function err_report() {
local log_file="${REPORT_DIR}/containerd.log"
if [[ -f "${log_file}" ]]; then
echo "::group::ERROR: containerd log :"
echo "-------------------------------------"
cat "${log_file}"
echo "-------------------------------------"
echo "::endgroup::"
fi
echo "::group::ERROR: Kata Containers logs : "
echo "-------------------------------------"
sudo journalctl -xe -t kata
echo "-------------------------------------"
echo "::endgroup::"
}
function check_daemon_setup() {
info "containerd(cri): Check daemon works with runc"
# Use podsandbox for the runc sanity check: the shim sandboxer has a known
# containerd-side bug where the OCI spec is not populated before NewBundle is
# called, so config.json is never written and containerd-shim-runc-v2 fails.
# See https://github.com/containerd/containerd/issues/11640
# This check only verifies that containerd + runc are functional before the
# real kata tests run, so the sandboxer choice doesn't matter here.
local SANDBOXER="podsandbox"
create_containerd_config "runc"
# containerd cri-integration will modify the passed in config file. Let's
# give it a temp one.
cp "${CONTAINERD_CONFIG_FILE}" "${CONTAINERD_CONFIG_FILE_TEMP}"
# in some distros(AlibabaCloud), there is no btrfs-devel package available,
# so pass GO_BUILDTAGS="no_btrfs" to make to not use btrfs.
if ! sudo -E PATH="${PATH}:/usr/local/bin" \
REPORT_DIR="${REPORT_DIR}" \
FOCUS="TestImageLoad" \
RUNTIME="" \
CONTAINERD_CONFIG_FILE="${CONTAINERD_CONFIG_FILE_TEMP}" \
make GO_BUILDTAGS="no_btrfs" -e cri-integration
then
echo "::group::ERROR: cri-integration sanity-check config"
echo "-------------------------------------"
cat "${CONTAINERD_CONFIG_FILE_TEMP}" || true
echo "-------------------------------------"
echo "::endgroup::"
err_report
return 1
fi
}
function testContainerStart() {
# no_container_yaml set to 1 will not create container_yaml
# because caller has created its own container_yaml.
no_container_yaml=${1:-0}
local pod_yaml=${REPORT_DIR}/pod.yaml
local container_yaml=${REPORT_DIR}/container.yaml
local image="busybox:latest"
cat << EOF > "${pod_yaml}"
metadata:
name: busybox-sandbox1
namespace: default
uid: busybox-sandbox1-uid
EOF
#TestContainerSwap has created its own container_yaml.
if [[ "${no_container_yaml}" -ne 1 ]]; then
cat << EOF > "${container_yaml}"
metadata:
name: busybox-killed-vmm
namespace: default
uid: busybox-killed-vmm-uid
image:
image: "${image}"
command:
- top
EOF
fi
deploy_cri_integration_containerd_host_config
sudo crictl pull "${image}"
podid=$(sudo crictl --timeout=5s runp "${pod_yaml}")
cid=$(sudo crictl create "${podid}" "${container_yaml}" "${pod_yaml}")
sudo crictl start "${cid}"
}
function testContainerStop() {
info "show pod ${podid}"
sudo crictl --timeout=20s pods --id "${podid}"
info "stop pod ${podid}"
sudo crictl --timeout=20s stopp "${podid}"
info "remove pod ${podid}"
sudo crictl --timeout=20s rmp "${podid}"
restore_cri_integration_containerd_host_config
}
function TestKilledVmmCleanup() {
if [[ "${KATA_HYPERVISOR}" != "qemu" ]]; then
info "TestKilledVmmCleanup is skipped for ${KATA_HYPERVISOR}, only QEMU is currently tested"
return 0
fi
info "test killed vmm cleanup"
testContainerStart
qemu_pid=$(pgrep -f qemu || true)
info "kill qemu ${qemu_pid}"
sudo kill -SIGKILL "${qemu_pid}"
# sleep to let shimv2 exit
sleep 1
remained=$(pgrep -f shimv2 || true)
[[ -z "${remained}" ]] || die "found remaining shimv2 process ${remained}"
testContainerStop
info "stop containerd"
}
function TestContainerMemoryUpdate() {
# there's no need to set true for enable_virtio_mem in dragonball
# As it can support virtio-mem by default.
if [[ "${KATA_HYPERVISOR}" == "dragonball" ]]; then
# Currently, dragonball fails at decrease memory, just test increasing memory.
# We'll re-enable it as soon as we get it to work.
# Reference: https://github.com/kata-containers/kata-containers/issues/8804
# DoContainerMemoryUpdate 0
info "TestContainerMemoryUpdate skipped for dragonball"
fi
if [[ "${KATA_HYPERVISOR}" == "qemu-runtime-rs" ]]; then
# Remove TestContainerMemoryUpdate from passing_test
info "TestContainerMemoryUpdate skipped for qemu with runtime-rs"
info "Please check out https://github.com/kata-containers/kata-containers/issues/9375"
return
elif [[ "${KATA_HYPERVISOR}" != "qemu" ]] || [[ "${ARCH}" == "ppc64le" ]]; then
return
fi
for virtio_mem_enabled in 1 0; do
# On s390x, only run the test when virtio_mem is enabled
if [[ "${ARCH}" == "s390x" ]] && [[ ${virtio_mem_enabled} -eq 0 ]]; then
continue
fi
PrepareContainerMemoryUpdate "${virtio_mem_enabled}"
DoContainerMemoryUpdate "${virtio_mem_enabled}"
done
}
function PrepareContainerMemoryUpdate() {
test_virtio_mem=$1
if [[ "${test_virtio_mem}" -eq 1 ]]; then
if [[ "${ARCH}" != "x86_64" ]] && [[ "${ARCH}" != "aarch64" ]] && [[ "${ARCH}" != "s390x" ]]; then
return
fi
info "Test container memory update with virtio-mem"
# Handle both commented and uncommented enable_virtio_mem
sudo sed -i -e 's/^#\?enable_virtio_mem.*$/enable_virtio_mem = true/g' "${kata_config}"
else
info "Test container memory update without virtio-mem"
# Set to false instead of commenting out
sudo sed -i -e 's/^#\?enable_virtio_mem.*$/enable_virtio_mem = false/g' "${kata_config}"
fi
}
function DoContainerMemoryUpdate() {
descrease_memory=$1
# start a test container
testContainerStart
vm_size=$(($(sudo crictl exec "${cid}" cat /proc/meminfo | grep "MemTotal:" | awk '{print $2}')*1024))
if [[ "${vm_size}" -gt $((2*1024*1024*1024)) ]] || [[ "${vm_size}" -lt $((2*1024*1024*1024-128*1024*1024)) ]]; then
testContainerStop
die "The VM memory size ${vm_size} before update is not right"
fi
sudo crictl update --memory $((2*1024*1024*1024)) "${cid}"
sleep 1
vm_size=$(($(sudo crictl exec "${cid}" cat /proc/meminfo | grep "MemTotal:" | awk '{print $2}')*1024))
if [[ "${vm_size}" -gt $((4*1024*1024*1024)) ]] || [[ "${vm_size}" -lt $((4*1024*1024*1024-128*1024*1024)) ]]; then
testContainerStop
die "The VM memory size ${vm_size} after increase is not right"
fi
if [[ "${descrease_memory}" -eq 1 ]]; then
sudo crictl update --memory $((1*1024*1024*1024)) "${cid}"
sleep 1
vm_size=$(($(sudo crictl exec "${cid}" cat /proc/meminfo | grep "MemTotal:" | awk '{print $2}')*1024))
if [[ "${vm_size}" -gt $((3*1024*1024*1024)) ]] || [[ "${vm_size}" -lt $((3*1024*1024*1024-128*1024*1024)) ]]; then
testContainerStop
die "The VM memory size ${vm_size} after decrease is not right"
fi
fi
# stop the test container
testContainerStop
}
function getContainerSwapInfo() {
swap_size=$(($(sudo crictl exec "${cid}" cat /proc/meminfo | grep "SwapTotal:" | awk '{print $2}')*1024))
# NOTE: these below two checks only works on cgroup v1
swappiness=$(sudo crictl exec "${cid}" cat /sys/fs/cgroup/memory/memory.swappiness)
swap_in_bytes=$(sudo crictl exec "${cid}" cat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes)
}
function TestContainerSwap() {
if [[ "${KATA_HYPERVISOR}" != "qemu" ]] || [[ "${ARCH}" != "x86_64" ]]; then
return
fi
local container_yaml=${REPORT_DIR}/container.yaml
local image="busybox:latest"
info "Test container with guest swap"
create_containerd_config "kata-${KATA_HYPERVISOR}" 1
# Handle both commented and uncommented enable_guest_swap
sudo sed -i -e 's/^#\?enable_guest_swap.*$/enable_guest_swap = true/g' "${kata_config}"
# Test without swap device
testContainerStart
getContainerSwapInfo
# Current default swappiness is 60
if [[ "${swappiness}" -ne 60 ]]; then
testContainerStop
die "The VM swappiness ${swappiness} without swap device is not right"
fi
if [[ "${swap_in_bytes}" -lt 1125899906842624 ]]; then
testContainerStop
die "The VM swap_in_bytes ${swap_in_bytes} without swap device is not right"
fi
if [[ "${swap_size}" -ne 0 ]]; then
testContainerStop
die "The VM swap size ${swap_size} without swap device is not right"
fi
testContainerStop
# Test with swap device
cat << EOF > "${container_yaml}"
metadata:
name: busybox-swap
namespace: default
uid: busybox-swap-uid
annotations:
io.katacontainers.container.resource.swappiness: "100"
io.katacontainers.container.resource.swap_in_bytes: "1610612736"
linux:
resources:
memory_limit_in_bytes: 1073741824
image:
image: "${image}"
command:
- top
EOF
testContainerStart 1
getContainerSwapInfo
testContainerStop
if [[ "${swappiness}" -ne 100 ]]; then
die "The VM swappiness ${swappiness} with swap device is not right"
fi
if [[ "${swap_in_bytes}" -ne 1610612736 ]]; then
die "The VM swap_in_bytes ${swap_in_bytes} with swap device is not right"
fi
if [[ "${swap_size}" -ne 536870912 ]]; then
die "The VM swap size ${swap_size} with swap device is not right"
fi
# Test without swap_in_bytes
cat << EOF > "${container_yaml}"
metadata:
name: busybox-swap
namespace: default
uid: busybox-swap-uid
annotations:
io.katacontainers.container.resource.swappiness: "100"
linux:
resources:
memory_limit_in_bytes: 1073741824
image:
image: "${image}"
command:
- top
EOF
testContainerStart 1
getContainerSwapInfo
testContainerStop
if [[ "${swappiness}" -ne 100 ]]; then
die "The VM swappiness ${swappiness} without swap_in_bytes is not right"
fi
# swap_in_bytes is not set, it should be a value that bigger than 1125899906842624
if [[ "${swap_in_bytes}" -lt 1125899906842624 ]]; then
die "The VM swap_in_bytes ${swap_in_bytes} without swap_in_bytes is not right"
fi
if [[ "${swap_size}" -ne 1073741824 ]]; then
die "The VM swap size ${swap_size} without swap_in_bytes is not right"
fi
# Test without memory_limit_in_bytes
cat << EOF > "${container_yaml}"
metadata:
name: busybox-swap
namespace: default
uid: busybox-swap-uid
annotations:
io.katacontainers.container.resource.swappiness: "100"
image:
image: "${image}"
command:
- top
EOF
testContainerStart 1
getContainerSwapInfo
testContainerStop
if [[ "${swappiness}" -ne 100 ]]; then
die "The VM swappiness ${swappiness} without memory_limit_in_bytes is not right"
fi
# swap_in_bytes is not set, it should be a value that bigger than 1125899906842624
if [[ "${swap_in_bytes}" -lt 1125899906842624 ]]; then
die "The VM swap_in_bytes ${swap_in_bytes} without memory_limit_in_bytes is not right"
fi
if [[ "${swap_size}" -ne 2147483648 ]]; then
die "The VM swap size ${swap_size} without memory_limit_in_bytes is not right"
fi
create_containerd_config "kata-${KATA_HYPERVISOR}"
}
# k8s may restart docker which will impact on containerd stop
function stop_containerd() {
local tmp
tmp=$(pgrep kubelet || true)
[[ -n "${tmp}" ]] && sudo kubeadm reset -f
sudo systemctl stop containerd
}
function mountLoopDevice() {
local loop_file="$1"
if [[ -e "${loop_file}" ]]; then
sudo rm -f "${loop_file}"
info "${loop_file} was removed"
fi
sudo dd if=/dev/zero of="${loop_file}" bs=100M count=2
sudo mkfs.ext4 "${loop_file}"
sudo losetup -fP "${loop_file}"
local loinfo
loinfo=$(sudo losetup -a | grep "${loop_file}" || true)
local device
device=$(echo "${loinfo}" | awk -F'[: ]' '{print $1}')
echo "${device}"
}
function startDeviceCgroupContainers() {
local pod_yaml=${REPORT_DIR}/device-cgroup-pod.yaml
local container1_yaml=${REPORT_DIR}/device-cgroup-container1.yaml
local container2_yaml=${REPORT_DIR}/device-cgroup-container2.yaml
local image="busybox:latest"
cat > "${pod_yaml}" <<EOF
metadata:
name: busybox-device-cgroup-sandbox
namespace: default
uid: busybox-device-cgroup-sandbox-uid
EOF
cat > "${container1_yaml}" <<EOF
metadata:
name: busybox-device-cgroup-container1
namespace: default
uid: busybox-device-cgroup-container1-uid
image:
image: ${image}
command:
- top
linux: {}
devices:
- container_path: ${loop_dev1_container_path}
host_path: "${loop_dev1}"
permissions: rwm
EOF
cat > "${container2_yaml}" <<EOF
metadata:
name: busybox-device-cgroup-container2
namespace: default
uid: busybox-device-cgroup-container2-uid
image:
image: ${image}
command:
- top
linux: {}
devices:
- container_path: ${loop_dev2_container_path}
host_path: "${loop_dev2}"
permissions: rwm
EOF
deploy_cri_integration_containerd_host_config
sudo crictl pull "${image}"
podid=$(sudo crictl --timeout=5s runp "${pod_yaml}")
cid1=$(sudo crictl create "${podid}" "${container1_yaml}" "${pod_yaml}")
cid2=$(sudo crictl create "${podid}" "${container2_yaml}" "${pod_yaml}")
sudo crictl start "${cid1}"
sudo crictl start "${cid2}"
}
function stopDeviceCgroupContainers() {
info "show pod ${podid}"
sudo crictl --timeout=20s pods --id "${podid}"
info "stop pod ${podid}"
sudo crictl --timeout=20s stopp "${podid}"
info "remove pod ${podid}"
sudo crictl --timeout=20s rmp "${podid}"
restore_cri_integration_containerd_host_config
}
function TestDeviceCgroup() {
loop_dev1=$(mountLoopDevice "/tmp/device-cgroup-1.img" | tail -n 1)
loop_dev2=$(mountLoopDevice "/tmp/device-cgroup-2.img" | tail -n 1)
info "Two loop devices, ${loop_dev1} and ${loop_dev2}, are created."
loop_dev1_container_path="/dev/test-block-1"
loop_dev2_container_path="/dev/test-block-2"
startDeviceCgroupContainers
local dev1_ls
dev1_ls=$(sudo crictl exec "${cid1}" ls -l "${loop_dev1_container_path}")
local dev1_no
dev1_no=$(echo "${dev1_ls}" | awk '{print $5, $6}')
local dev1_major
dev1_major=$(echo "${dev1_no%%,*}" | tr -d ' ')
local dev1_minor
dev1_minor=$(echo "${dev1_no##*,}" | tr -d ' ')
local dev2_ls
dev2_ls=$(sudo crictl exec "${cid2}" ls -l "${loop_dev2_container_path}")
local dev2_no
dev2_no=$(echo "${dev2_ls}" | awk '{print $5, $6}')
local dev2_major
dev2_major=$(echo "${dev2_no%%,*}" | tr -d ' ')
local dev2_minor
dev2_minor=$(echo "${dev2_no##*,}" | tr -d ' ')
info "\"${dev1_major}:${dev1_minor}\" is for container1, and \"${dev2_major}:${dev2_minor}\" is for container2."
local cid1_device_cgroup
cid1_device_cgroup=$(sudo crictl exec "${cid1}" cat /sys/fs/cgroup/devices/devices.list)
local cid2_device_cgroup
cid2_device_cgroup=$(sudo crictl exec "${cid2}" cat /sys/fs/cgroup/devices/devices.list)
if [[ ${cid1_device_cgroup} != *"b ${dev1_major}:${dev1_minor} rwm"* ]]; then
die "The device cgroup of container1 is expected to have loop dev1"
fi
info "Container1 has \"b ${dev1_major}:${dev1_minor} rwm\"."
if [[ ${cid1_device_cgroup} == *"b ${dev2_major}:${dev2_minor} rwm"* ]]; then
die "The device cgroup of container1 isn't expected to have loop dev2"
fi
info "Container1 doesn't have \"b ${dev2_major}:${dev2_minor} rwm\"."
if [[ ${cid2_device_cgroup} == *"b ${dev1_major}:${dev1_minor} rwm"* ]]; then
die "The device cgroup of container2 isn't expected to have loop dev2"
fi
info "Container2 doesn't have \"b ${dev1_major}:${dev1_minor} rwm\"."
if [[ ${cid2_device_cgroup} != *"b ${dev2_major}:${dev2_minor} rwm"* ]]; then
die "The device cgroup of container2 is expected to have loop dev2"
fi
info "Container2 has \"b ${dev2_major}:${dev2_minor} rwm\"."
stopDeviceCgroupContainers
# Umount loop devices
sudo losetup -d "${loop_dev1}"
sudo losetup -d "${loop_dev2}"
info "Two loop devices, ${loop_dev1} and ${loop_dev2}, are umounted."
}
function main() {
info "Clean up containers and pods"
restart_containerd_service
mapfile -t containers < <(sudo crictl ps --all -o json | jq -r '.containers[].id')
for c in "${containers[@]}"; do
sudo crictl rm -f "${c}"
done
mapfile -t pods < <(sudo crictl pods -o json | jq -r '.items[].id')
for p in "${pods[@]}"; do
sudo crictl rmp -f "${p}"
done
info "Stop crio service"
systemctl is-active --quiet crio && sudo systemctl stop crio
info "Stop containerd service"
systemctl is-active --quiet containerd && stop_containerd
# Configure enviroment if running in CI
ci_config
pushd "containerd"
export_go_toolchain_for_containerd_source_builds
# Make sure the right artifacts are going to be built
sudo -E make clean
# the latest containerd had an issue for its e2e test, thus we should do the following
# fix to workaround this issue. For much info about this issue, please see:
# https://github.com/containerd/containerd/pull/11240
# Once this pr was merged and release new version, we can remove this workaround.
# shellcheck disable=SC2016
sed -i 's/cat "\${config_file}"/cat "\${CONTAINERD_CONFIG_FILE}"/' script/test/utils.sh
check_daemon_setup
info "containerd(cri): testing using runtime: ${containerd_runtime_type}"
create_containerd_config "kata-${KATA_HYPERVISOR}"
info "containerd(cri): Running cri-integration"
# TestContainerRestart is excluded: creating a new container in the same
# sandbox VM after the previous container has exited and been removed has
# never been supported by kata-containers (neither with the go-based nor
# the rust-based runtime). The kata VM shuts down when its last container
# is removed, so any attempt to start a new container in the same sandbox
# fails. This test exercises a use-case kata does not currently support.
passing_test="TestContainerStats|TestContainerListStatsWithIdFilter|TestContainerListStatsWithIdSandboxIdFilter|TestDuplicateName|TestImageLoad|TestImageFSInfo|TestSandboxCleanRemove"
if [[ "${KATA_HYPERVISOR}" == "clh-runtime-rs" || \
"${KATA_HYPERVISOR}" == "qemu" ]]; then
issue="https://github.com/kata-containers/tests/issues/2318"
info "${KATA_HYPERVISOR} fails with TestContainerListStatsWithSandboxIdFilter }"
info "see ${issue}"
else
passing_test="${passing_test}|TestContainerListStatsWithSandboxIdFilter"
fi
# in some distros(AlibabaCloud), there is no btrfs-devel package available,
# so pass GO_BUILDTAGS="no_btrfs" to make to not use btrfs.
# containerd cri-integration will modify the passed in config file. Let's
# give it a temp one.
cp "${CONTAINERD_CONFIG_FILE}" "${CONTAINERD_CONFIG_FILE_TEMP}"
sudo -E PATH="${PATH}:/usr/local/bin" \
REPORT_DIR="${REPORT_DIR}" \
FOCUS="^(${passing_test})$" \
RUNTIME="" \
CONTAINERD_CONFIG_FILE="${CONTAINERD_CONFIG_FILE_TEMP}" \
make GO_BUILDTAGS="no_btrfs" -e cri-integration
# trap error for print containerd log,
# containerd's `cri-integration` will print the log itself.
trap err_report ERR
# TestContainerSwap is currently failing with GHA.
# Let's re-enable it as soon as we get it to work.
# Reference: https://github.com/kata-containers/kata-containers/issues/7410
# TestContainerSwap
TestContainerMemoryUpdate
if [[ "${ARCH}" != "ppc64le" ]]; then
if [[ "${KATA_HYPERVISOR}" == "qemu-runtime-rs" ]]; then
info "TestKilledVmmCleanup and TestDeviceCgroup skipped for qemu with runtime-rs"
info "Please check out https://github.com/kata-containers/kata-containers/issues/9375"
return
else
TestKilledVmmCleanup
info "Skipping TestDeviceCgroup till the test is adapted to cgroupsv2"
#TestDeviceCgroup
fi
fi
popd
}
main