Skip to content

Commit

Permalink
ci: Add test cases for CoCo image pulling without forked containerd
Browse files Browse the repository at this point in the history
Additional tests are necessary to verify new feature that pulling image without forked containerd in CoCo.
1)image sharing on the host without dm-verity.
2)image sharing on the host with dm-verity.
3)image pulling in the guest with nydus-snapshotter.

Fixes kata-containers#5763

Depends-on: github.com/kata-containers/kata-containers#7676

Signed-off-by: ChengyuZhu6 <[email protected]>
  • Loading branch information
ChengyuZhu6 committed Sep 20, 2023
1 parent 6cf4306 commit ee3ce77
Show file tree
Hide file tree
Showing 13 changed files with 326 additions and 33 deletions.
90 changes: 90 additions & 0 deletions .ci/install_nydus_snapshotter.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/bash
#
# Copyright (c) 2023 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

set -o errexit
set -o nounset
set -o pipefail
set -o errtrace

cidir=$(dirname "$0")
source "${cidir}/lib.sh"

target_dir="/opt/confidential-containers"

nydus_snapshotter_repo=${nydus_snapshotter_repo:-"github.com/containerd/nydus-snapshotter"}
nydus_snapshotter_repo_git="https://${nydus_snapshotter_repo}.git"
nydus_snapshotter_version=${nydus_snapshotter_version:-"v0.12.0"}
nydus_snapshotter_repo_dir="${GOPATH}/src/${nydus_snapshotter_repo}"
nydus_snapshotter_binary_target_dir="$target_dir/bin"
nydus_snapshotter_config_target_dir="$target_dir/share/nydus-snapshotter"

nydus_repo=${nydus_repo:-"https://github.com/dragonflyoss/image-service"}
nydus_version=${nydus_version:-"v2.2.3"}

arch="$(uname -m)"

clone_nydus_snapshotter_repo() {
add_repo_to_git_safe_directory "${nydus_snapshotter_repo_dir}"

if [ ! -d "${nydus_snapshotter_repo_dir}" ]; then
sudo mkdir -p "${nydus_snapshotter_repo_dir}"
git clone ${nydus_snapshotter_repo_git} "${nydus_snapshotter_repo_dir}" || true
pushd "${nydus_snapshotter_repo_dir}"
git checkout "${nydus_snapshotter_version}"
popd
fi
}

build_nydus_snapshotter() {
pushd "${nydus_snapshotter_repo_dir}"
if [ "$arch" = "s390x" ]; then
export GOARCH=$arch
fi
sudo -E PATH=$PATH make

if [ ! -d "$nydus_snapshotter_binary_target_dir" ]; then
sudo mkdir -p $nydus_snapshotter_binary_target_dir
fi
sudo install -D -m 755 "bin/containerd-nydus-grpc" "$nydus_snapshotter_binary_target_dir/containerd-nydus-grpc"
sudo install -D -m 755 "bin/nydus-overlayfs" "$nydus_snapshotter_binary_target_dir/nydus-overlayfs"
if [ ! -f "/usr/local/bin/nydus-overlayfs" ]; then
echo " /usr/local/bin/nydus-overlayfs exists, now we will replace it."
sudo cp -f "$nydus_snapshotter_binary_target_dir/nydus-overlayfs" "/usr/local/bin/nydus-overlayfs"
fi
sudo rm -rf "$nydus_snapshotter_repo_dir/bin"
popd >/dev/null
}

download_nydus_snapshotter_config() {
if [ ! -d "$nydus_snapshotter_config_target_dir" ]; then
mkdir -p "$nydus_snapshotter_config_target_dir"
fi
sudo curl -L https://raw.githubusercontent.com/containerd/nydus-snapshotter/main/misc/snapshotter/config-coco-guest-pulling.toml -o "$nydus_snapshotter_config_target_dir/config-coco-guest-pulling.toml"
sudo curl -L https://raw.githubusercontent.com/containerd/nydus-snapshotter/main/misc/snapshotter/config-coco-host-sharing.toml -o "$nydus_snapshotter_config_target_dir/config-coco-host-sharing.toml"
sudo chmod 644 "$nydus_snapshotter_config_target_dir/config-coco-guest-pulling.toml"
sudo chmod 644 "$nydus_snapshotter_config_target_dir/config-coco-host-sharing.toml"

}

download_nydus_from_tarball() {
if [ "$arch" = "s390x" ]; then
echo "Skip to download nydus for $arch, it doesn't work for $arch now."
return
fi
local goarch="$(${cidir}/kata-arch.sh --golang)"
local tarball_url="${nydus_repo}/releases/download/${nydus_version}/nydus-static-${nydus_version}-linux-$goarch.tgz"
echo "Download tarball from ${tarball_url}"
tmp_dir=$(mktemp -d -t install-nydus-tmp.XXXXXXXXXX)
curl -Ls "$tarball_url" | sudo tar xfz - -C $tmp_dir --strip-components=1
sudo install -D -m 755 "$tmp_dir/nydus-image" "/usr/local/bin/"
}

download_nydus_from_tarball
clone_nydus_snapshotter_repo
build_nydus_snapshotter
download_nydus_snapshotter_config
echo "install nydus-snapshotter successful"
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ cc-containerd:
# Run the Confidential Containers tests for kubernetes.
cc-kubernetes:
bash -f .ci/install_bats.sh
K8S_TEST_UNION="confidential/agent_image.bats confidential/agent_image_encrypted.bats confidential/sealed_secret.bats" \
K8S_TEST_UNION="confidential/agent_image.bats confidential/agent_image_encrypted.bats confidential/sealed_secret.bats confidential/image_pulling_with_snapshotter.bats" \
bash integration/kubernetes/run_kubernetes_tests.sh

# Run the Confidential Containers AMD SEV specific tests.
Expand Down
108 changes: 101 additions & 7 deletions integration/confidential/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ source "${BATS_TEST_DIRNAME}/../../../lib/common.bash"
source "${BATS_TEST_DIRNAME}/../../../.ci/lib.sh"
FIXTURES_DIR="${BATS_TEST_DIRNAME}/fixtures"
SHARED_FIXTURES_DIR="${BATS_TEST_DIRNAME}/../../confidential/fixtures"
NYDUS_SNAPSHOTTER_BINARY="/opt/kata/bin/containerd-nydus-grpc"
NYDUS_SNAPSHOTTER_TARFS_CONFIG="/opt/kata/share/nydus-snapshotter/config-coco-host-sharing.toml"
NYDUS_SNAPSHOTTER_GUEST_CONFIG="/opt/kata/share/nydus-snapshotter/config-coco-guest-pulling.toml"
NYDUS_SNAPSHOTTER_CONFIG="$NYDUS_SNAPSHOTTER_TARFS_CONFIG"

# Toggle between true and false the service_offload configuration of
# the Kata agent.
Expand Down Expand Up @@ -180,6 +184,13 @@ disable_full_debug() {
sudo sed -i -e 's/^# *\(enable_debug\).*=.*$/\1 = false/g' "$RUNTIME_CONFIG_PATH"
}

restart_containerd() {
sudo systemctl restart containerd
if ! waitForProcess 30 5 "sudo crictl info >/dev/null"; then
die "containerd seems not operational after restarted"
fi
}

# Configure containerd for confidential containers. Among other things, it ensures
# the CRI handler is configured to deal with confidential container.
#
Expand All @@ -198,15 +209,15 @@ configure_cc_containerd() {
# installed via operator it will assume containerd is in right state
# already.
[ "${TESTS_CONFIGURE_CC_CONTAINERD:-yes}" == "yes" ] || return 0
sudo iptables -w -P FORWARD ACCEPT

# Even if we are not saving the original file it is a good idea to
# restart containerd because it might be in an inconsistent state here.
sudo systemctl stop containerd
sleep 5
[ -n "$saved_containerd_conf_file" ] && \
sudo cp -f "$containerd_conf_file" "$saved_containerd_conf_file"
sudo systemctl start containerd
waitForProcess 30 5 "sudo crictl info >/dev/null"
restart_containerd

# Ensure the cc CRI handler is set.
local cri_handler=$(sudo crictl info | \
Expand All @@ -223,11 +234,6 @@ configure_cc_containerd() {
sudo tee -a "$containerd_conf_file"
fi

sudo systemctl restart containerd
if ! waitForProcess 30 5 "sudo crictl info >/dev/null"; then
die "containerd seems not operational after reconfigured"
fi
sudo iptables -w -P FORWARD ACCEPT
}

#
Expand Down Expand Up @@ -445,3 +451,91 @@ EOF
EOF
fi
}

###############################################################################

# remote-snapshotter

configure_remote_snapshotter() {
case "${SNAPSHOTTER:-}" in
"nydus")
configure_nydus_snapshotter
;;
*) ;;

esac
}

is_containerd_support_per_runtime_snapshotter() {
containerd_version=$(containerd --version | awk '{print $3}')
required_version="v1.7.0"
printf '%s\n' ${required_version} ${containerd_version} | sort --check=quiet -V
}

set_vanilla_containerd() {
sudo systemctl stop containerd
sleep 5
sudo mv /usr/local/bin/containerd /usr/local/bin/containerd-coco
sudo cp /usr/local/bin/containerd-vanilla /usr/local/bin/containerd
echo "vanilla containerd version: $(containerd --version | awk '{print $3}')"
}

unset_vanilla_containerd() {
sudo systemctl stop containerd
sleep 5
sudo rm -f /usr/local/bin/containerd
sudo mv /usr/local/bin/containerd-coco /usr/local/bin/containerd
echo "coco containerd version: $(containerd --version | awk '{print $3}')"
}

configure_containerd_for_nydus_snapshotter() {
set_vanilla_containerd
if [ "${SNAPSHOTTER:-}" = "nydus" ]; then
local containerd_config="$1"
snapshotter_socket="/run/containerd-nydus/containerd-nydus-grpc.sock"
proxy_config=" [proxy_plugins.$SNAPSHOTTER]\n type = \"snapshot\"\n address = \"${snapshotter_socket}\""

if grep -q "\[proxy_plugins\]" "$containerd_config"; then
sudo sed -i '/\[proxy_plugins\]/a\'"$proxy_config" "$containerd_config"
else
sudo echo -e "[proxy_plugins]" >>"$containerd_config"
sudo echo -e "$proxy_config" >>"$containerd_config"
fi

sudo sed -i 's/disable_snapshot_annotations = .*/disable_snapshot_annotations = false/g' "$containerd_config"
sudo sed -i 's/snapshotter = .*/snapshotter = "nydus"/g' "$containerd_config"
fi
}

kill_nydus_snapshotter_process() {
echo "Kill nydus snapshotter"
bin="containerd-nydus-grpc"
sudo kill -9 $(pidof $bin) || true
sudo rm -rf "/var/lib/containerd-nydus" || true
}

remove_test_image() {
local test_image="$1"
crictl rmi "$1"
pause_name=$(crictl images -o json | jq -r '.images[].repoTags[] | select(. | contains("pause"))')
crictl rmi "$pause_name"
}

restart_nydus_snapshotter() {
kill_nydus_snapshotter_process || true
echo "Restart nydus snapshotter"
sudo "$NYDUS_SNAPSHOTTER_BINARY" --config "$NYDUS_SNAPSHOTTER_CONFIG" >/dev/stdout 2>&1 &
}

configure_nydus_snapshotter() {
if [ "${SNAPSHOTTER:-}" = "nydus" ]; then
echo "Configure nydus snapshotter"
if [ "$EXPORT_MODE" == "image_guest_pull" ]; then
NYDUS_SNAPSHOTTER_CONFIG="$NYDUS_SNAPSHOTTER_GUEST_CONFIG"
else
NYDUS_SNAPSHOTTER_CONFIG="$NYDUS_SNAPSHOTTER_TARFS_CONFIG"
sudo sed -i "s/export_mode = .*/export_mode = \"$EXPORT_MODE\"/" "$NYDUS_SNAPSHOTTER_CONFIG"
fi
restart_nydus_snapshotter
fi
}
2 changes: 1 addition & 1 deletion integration/containerd/confidential/tests_common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ setup_common() {
echo "Prepare containerd for Confidential Container"
SAVED_CONTAINERD_CONF_FILE="/etc/containerd/config.toml.$$"
configure_cc_containerd "$SAVED_CONTAINERD_CONF_FILE"

restart_containerd
# Note: ensure that intructions changing the kernel parameters are
# executed *after* saving the original list.
saved_kernel_params=$(get_kernel_params)
Expand Down
4 changes: 3 additions & 1 deletion integration/kubernetes/confidential/agent_image.bats
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ RUNTIMECLASS="${RUNTIMECLASS:-kata}"
test_tag="[cc][agent][kubernetes][containerd]"

setup() {
setup_common
setup_containerd
restart_containerd
reconfigure_kata
}

@test "$test_tag Test can launch pod with measured boot enabled" {
Expand Down
12 changes: 3 additions & 9 deletions integration/kubernetes/confidential/agent_image_encrypted.bats
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
# SPDX-License-Identifier: Apache-2.0
#

load "${BATS_TEST_DIRNAME}/lib.sh"
load "${BATS_TEST_DIRNAME}/../../confidential/lib.sh"
load "${BATS_TEST_DIRNAME}/../../../lib/common.bash"
load "${BATS_TEST_DIRNAME}/tests_common.sh"

# Allow to configure the runtimeClassName on pod configuration.
RUNTIMECLASS="${RUNTIMECLASS:-kata}"
Expand All @@ -25,13 +24,8 @@ setup() {
SAVED_CONTAINERD_CONF_FILE="/etc/containerd/config.toml.$$"
configure_cc_containerd "$SAVED_CONTAINERD_CONF_FILE"

echo "Reconfigure Kata Containers"
switch_image_service_offload on
clear_kernel_params
add_kernel_params "${original_kernel_params}"

setup_proxy
switch_measured_rootfs_verity_scheme none
restart_containerd
reconfigure_kata
}

@test "$test_tag Test can pull an encrypted image inside the guest with decryption key" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
apiVersion: v1
kind: Pod
metadata:
name: busybox-cc
name: busybox-cc$INDEX
spec:
runtimeClassName: $RUNTIMECLASS
containers:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env bats
# Copyright (c) 2023 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

load "${BATS_TEST_DIRNAME}/tests_common.sh"

tag_suffix=""
if [ "$(uname -m)" != "x86_64" ]; then
tag_suffix="-$(uname -m)"
fi

# Images used on the tests.

image_unsigned_protected="quay.io/kata-containers/confidential-containers:unsigned${tag_suffix}"

original_kernel_params=$(get_kernel_params)
# Allow to configure the runtimeClassName on pod configuration.
RUNTIMECLASS="${RUNTIMECLASS:-kata}"
test_tag="[cc][agent][kubernetes][containerd]"

setup() {
remove_test_image "$image_unsigned_protected" || true
setup_containerd
configure_containerd_for_nydus_snapshotter "/etc/containerd/config.toml"
restart_containerd
reconfigure_kata
switch_image_service_offload off
}

@test "$test_tag Test can pull an image as a raw block disk image to guest with dm-verity enabled" {
if [ "$(uname -m)" = "s390x" ]; then
skip "test for s390x as nydus-image doesn't currently support this platform"
fi
if [ "$SNAPSHOTTER" = "nydus" ]; then
EXPORT_MODE="image_block_with_verity" RUNTIMECLASS="$RUNTIMECLASS" SNAPSHOTTER="nydus" configure_remote_snapshotter
pod_config="$(new_pod_config "$image_unsigned_protected")"
echo $pod_config
create_test_pod
fi
}

@test "$test_tag Test can pull an image as a raw block disk image to guest without dm-verity" {
if [ "$(uname -m)" = "s390x" ]; then
skip "test for s390x as nydus-image doesn't currently support this platform"
fi
if [ "$SNAPSHOTTER" = "nydus" ]; then
EXPORT_MODE="image_block" RUNTIMECLASS="$RUNTIMECLASS" SNAPSHOTTER="nydus" configure_remote_snapshotter
pod_config="$(new_pod_config "$image_unsigned_protected")"
echo $pod_config
create_test_pod
fi
}

@test "$test_tag Test can create two pods with pulling the image only once with dm-verity enabled" {
if [ "$(uname -m)" = "s390x" ]; then
skip "test for s390x as nydus-image doesn't currently support this platform"
fi
if [ ! is_containerd_support_per_runtime_snapshotter ]; then
skip "test only for containerd 1.7.x or above. See https://github.com/kata-containers/tests/issues/5772"
fi
if [ "$SNAPSHOTTER" = "nydus" ]; then
EXPORT_MODE="image_block_with_verity" RUNTIMECLASS="$RUNTIMECLASS" SNAPSHOTTER="nydus" configure_remote_snapshotter

pod_config="$(new_pod_config "$image_unsigned_protected" "1")"
echo $pod_config
create_test_pod
pod_config="$(new_pod_config "$image_unsigned_protected" "2")"
echo $pod_config
create_test_pod

pull_times=$(journalctl -t containerd --since "$test_start_date" -g "PullImage \"$image_unsigned_protected\" with snapshotter nydus" | wc -l)
[ ${pull_times} -eq 1 ]
fi
}

@test "$test_tag Test can pull an image inside the guest with remote-snapshotter" {
switch_image_service_offload on
if [ "$SNAPSHOTTER" = "nydus" ]; then
EXPORT_MODE="image_guest_pull" RUNTIMECLASS="$RUNTIMECLASS" SNAPSHOTTER="nydus" configure_remote_snapshotter
pod_config="$(new_pod_config "$image_unsigned_protected")"
echo $pod_config
create_test_pod
fi
}

teardown() {
teardown_common
remove_test_image "$image_unsigned_protected" || true
kill_nydus_snapshotter_process
unset_vanilla_containerd
restart_containerd
}
Loading

0 comments on commit ee3ce77

Please sign in to comment.