From 1ce2beb084be84bb3ae2b0235aa34101bb09a001 Mon Sep 17 00:00:00 2001 From: Ryan Savino Date: Sat, 8 Apr 2023 03:05:29 -0500 Subject: [PATCH] snp: added snp unencrypted test Fixes: #5593 added makefile target as well Signed-Off-By: Ryan Savino --- .ci/ci_job_flags.sh | 29 ++++-- .ci/install_kata.sh | 6 +- .ci/install_kata_image.sh | 4 +- .ci/install_qemu.sh | 7 +- .ci/install_runtime.sh | 2 + Makefile | 6 ++ integration/kubernetes/confidential/snp.bats | 103 +++++++++++++++++++ 7 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 integration/kubernetes/confidential/snp.bats diff --git a/.ci/ci_job_flags.sh b/.ci/ci_job_flags.sh index 7df1b15af..136d44079 100755 --- a/.ci/ci_job_flags.sh +++ b/.ci/ci_job_flags.sh @@ -103,7 +103,7 @@ case "${CI_JOB}" in export CRI_RUNTIME="containerd" export KATA_HYPERVISOR="qemu" ;; -"CRI_CONTAINERD"|"CRI_CONTAINERD_K8S"|"CC_CRI_CONTAINERD"|"CC_CRI_CONTAINERD_K8S"|"CC_SEV_CRI_CONTAINERD_K8S") +"CRI_CONTAINERD"|"CRI_CONTAINERD_K8S"|"CC_CRI_CONTAINERD"|"CC_CRI_CONTAINERD_K8S") # This job only tests containerd + k8s init_ci_flags export CRI_CONTAINERD="yes" @@ -113,21 +113,36 @@ case "${CI_JOB}" in "CRI_CONTAINERD_K8S") export KUBERNETES="yes" ;; - "CC_CRI_CONTAINERD"|"CC_CRI_CONTAINERD_K8S"|"CC_SEV_CRI_CONTAINERD_K8S") + "CC_CRI_CONTAINERD"|"CC_CRI_CONTAINERD_K8S") # Export any CC specific environment variables export KATA_BUILD_CC="yes" export AA_KBC="offline_fs_kbc" if [[ "${CI_JOB}" =~ K8S ]]; then export KUBERNETES=yes fi - if [[ "${CI_JOB}" =~ SEV ]]; then - export TEE_TYPE="sev" - export AA_KBC="online_sev_kbc" - export TEST_INITRD="yes" - fi ;; esac ;; +"CC_SEV_CRI_CONTAINERD_K8S"|"CC_SNP_CRI_CONTAINERD_K8S") + init_ci_flags + export CRI_CONTAINERD="yes" + export CRI_RUNTIME="containerd" + export KATA_HYPERVISOR="qemu" + export KATA_BUILD_CC="yes" + export AA_KBC="offline_fs_kbc" + export TEST_INITRD="yes" + if [[ "${CI_JOB}" =~ K8S ]]; then + export KUBERNETES=yes + fi + if [[ "${CI_JOB}" =~ SEV ]]; then + export TEE_TYPE="sev" + export AA_KBC="online_sev_kbc" + fi + if [[ "${CI_JOB}" =~ SNP ]]; then + export TEE_TYPE="snp" + export KATA_BUILD_QEMU_TYPE="snp" + fi + ;; "CC_CRI_CONTAINERD_TDX_QEMU"|"CC_CRI_CONTAINERD_TDX_CLOUD_HYPERVISOR") init_ci_flags export CRI_CONTAINERD="yes" diff --git a/.ci/install_kata.sh b/.ci/install_kata.sh index 38a56b1ba..2af726757 100755 --- a/.ci/install_kata.sh +++ b/.ci/install_kata.sh @@ -33,6 +33,10 @@ if [ "${TEE_TYPE:-}" == "sev" ]; then KATA_BUILD_KERNEL_TYPE=sev fi +if [ "${TEE_TYPE:-}" == "snp" ]; then + KATA_BUILD_KERNEL_TYPE=snp +fi + if [ "${KATA_HYPERVISOR:-}" == "dragonball" ]; then KATA_BUILD_KERNEL_TYPE=dragonball fi @@ -87,7 +91,7 @@ case "${KATA_HYPERVISOR}" in "${cidir}/install_virtiofsd.sh" if [ "${TEE_TYPE}" == "tdx" ]; then "${cidir}/install_tdvf.sh" - elif [ "${TEE_TYPE:-}" == "sev" ]; then + elif [ "${TEE_TYPE:-}" == "sev" ] || [ "${TEE_TYPE:-}" == "snp" ]; then "${cidir}/install_ovmf_sev.sh" fi ;; diff --git a/.ci/install_kata_image.sh b/.ci/install_kata_image.sh index 67cff3cbc..4f8699845 100755 --- a/.ci/install_kata_image.sh +++ b/.ci/install_kata_image.sh @@ -74,7 +74,9 @@ build_rust_image() { build_image_for_cc () { if [ "${TEST_INITRD}" == "yes" ]; then - [ "${TEE_TYPE}" == "sev" ] || die "SEV is the only TEE type that supports initrd" + if [ "${TEE_TYPE}" != "sev" ] && [ "${TEE_TYPE}" != "snp" ]; then + die "SEV and SNP are the only TEE types that supports initrd" + fi build_static_artifact_and_install "sev-rootfs-initrd" else [ "${osbuilder_distro:-ubuntu}" == "ubuntu" ] || \ diff --git a/.ci/install_qemu.sh b/.ci/install_qemu.sh index 2d5c2bd61..88686d273 100755 --- a/.ci/install_qemu.sh +++ b/.ci/install_qemu.sh @@ -70,7 +70,7 @@ build_and_install_qemu_for_cc() { local artifact="qemu" case "${qemu_type}" in - tdx) + tdx|snp) artifact="${qemu_type}-${artifact}" ;; vanilla) ;; @@ -238,6 +238,11 @@ main() { QEMU_REPO_URL=$(get_version "assets.hypervisor.qemu.tdx.url") qemu_latest_build_url="${jenkins_url}/job/kata-containers-2.0-qemu-tdx-$(uname -m)/${cached_artifacts_path}" ;; + snp) + CURRENT_QEMU_VERSION=$(get_version "assets.hypervisor.qemu.snp.tag") + QEMU_REPO_URL=$(get_version "assets.hypervisor.qemu.snp.url") + qemu_latest_build_url="${jenkins_url}/job/kata-containers-2.0-qemu-snp-$(uname -m)/${cached_artifacts_path}" + ;; vanilla) CURRENT_QEMU_VERSION=$(get_version "assets.hypervisor.qemu.version") QEMU_REPO_URL=$(get_version "assets.hypervisor.qemu.url") diff --git a/.ci/install_runtime.sh b/.ci/install_runtime.sh index 32fa43653..621312f1d 100755 --- a/.ci/install_runtime.sh +++ b/.ci/install_runtime.sh @@ -137,6 +137,8 @@ case "${KATA_HYPERVISOR}" in enable_hypervisor_config "${PKGDEFAULTSDIR}/configuration-qemu-tdx.toml" elif [ "$TEE_TYPE" == "sev" ]; then enable_hypervisor_config "${PKGDEFAULTSDIR}/configuration-qemu-sev.toml" + elif [ "$TEE_TYPE" == "snp" ]; then + enable_hypervisor_config "${PKGDEFAULTSDIR}/configuration-qemu-snp.toml" elif [ "$TEE_TYPE" == "se" ]; then enable_hypervisor_config "${PKGDEFAULTSDIR}/configuration-qemu-se.toml" else diff --git a/Makefile b/Makefile index 1875a5ad6..0f32eb0b2 100644 --- a/Makefile +++ b/Makefile @@ -110,6 +110,12 @@ cc-sev-kubernetes: K8S_TEST_UNION="confidential/sev.bats" \ bash integration/kubernetes/run_kubernetes_tests.sh +# Run the Confidential Containers AMD SNP specific tests. +cc-snp-kubernetes: + bash -f .ci/install_bats.sh + K8S_TEST_UNION="confidential/snp.bats" \ + bash integration/kubernetes/run_kubernetes_tests.sh + log-parser: make -C cmd/log-parser diff --git a/integration/kubernetes/confidential/snp.bats b/integration/kubernetes/confidential/snp.bats new file mode 100644 index 000000000..7180bbe87 --- /dev/null +++ b/integration/kubernetes/confidential/snp.bats @@ -0,0 +1,103 @@ +#!/usr/bin/env bats +# Copyright 2023 Advanced Micro Devices, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Environment variables +TEST_TAG="[cc][kubernetes][containerd][snp]" +TESTS_REPO_DIR=$(realpath "${BATS_TEST_DIRNAME}/../../..") +RUNTIMECLASS="${RUNTIMECLASS:-"kata"}" +IMAGE_REPO="ghcr.io/confidential-containers/test-container" +UNENCRYPTED_IMAGE_URL="${IMAGE_REPO}:unencrypted" + +# Text to grep for active feature in guest dmesg output +SNP_DMESG_GREP_TEXT="Memory Encryption Features active:.*SEV-SNP" + +export TEST_DIR +export ENCRYPTION_KEY +export SSH_KEY_FILE + +load "${BATS_TEST_DIRNAME}/../../confidential/lib.sh" +load "${TESTS_REPO_DIR}/lib/common.bash" + + +# Delete all test services +k8s_delete_all() { + k8s_delete_by_yaml "snp-unencrypted" "${TEST_DIR}/snp-unencrypted.yaml" +} + +setup_file() { + TEST_DIR="$(mktemp -d /tmp/test-kata-snp.XXXXXXXX)" + SSH_KEY_FILE="${TEST_DIR}/container-ssh-key" + + # Install package dependencies + echo "Installing required packages..." + esudo apt install -y \ + python-is-python3 \ + python3-pip \ + jq \ + mysql-client \ + docker-compose \ + cpuid + pip install sev-snp-measure + "${TESTS_REPO_DIR}/.ci/install_yq.sh" >&2 + + # Configure CoCo settings in containerd config + local saved_containerd_conf_file="/etc/containerd/config.toml.$$" + configure_cc_containerd "${saved_containerd_conf_file}" + + # Pull unencrypted image and retrieve ssh keys + echo "Pulling unencrypted image and retrieve ssh key..." + docker_image_label_save_ssh_key "${UNENCRYPTED_IMAGE_URL}" "${SSH_KEY_FILE}" + + # SEV service yaml generation + k8s_generate_service_yaml "${TEST_DIR}/snp-unencrypted.yaml" "${IMAGE_REPO}:unencrypted" +} + +teardown_file() { + # Allow to not destroy the environment if you are developing/debugging tests + if [[ "${CI:-false}" == "false" && "${DEBUG:-}" == true ]]; then + echo "Leaving changes and created resources untouched" + return + fi + + # Remove all k8s test services + k8s_delete_all + + # Cleanup directories + esudo rm -rf "${TEST_DIR}" +} + +setup() { + # Remove any previous k8s test services + echo "Deleting previous test services..." + k8s_delete_all +} + + +@test "${TEST_TAG} Test SNP unencrypted container launch success" { + # Start the service/deployment/pod + esudo kubectl apply -f "${TEST_DIR}/snp-unencrypted.yaml" + + # Retrieve pod name, wait for it to come up, retrieve pod ip + local pod_name=$(esudo kubectl get pod -o wide | grep snp-unencrypted | awk '{print $1;}') + k8s_wait_for_pod_ready_state "$pod_name" 20 + local pod_ip=$(esudo kubectl get pod -o wide | grep snp-unencrypted | awk '{print $6;}') + + k8s_print_info "snp-unencrypted" + + # Look for SEV enabled in container dmesg output + local snp_enabled=$(ssh_dmesg_grep \ + "${SSH_KEY_FILE}" \ + "${pod_ip}" \ + "${SNP_DMESG_GREP_TEXT}") + + if [ -z "${snp_enabled}" ]; then + >&2 echo -e "KATA SNP TEST - FAIL: SNP is NOT Enabled" + return 1 + else + echo "DMESG REPORT: ${snp_enabled}" + echo -e "KATA SNP TEST - PASS: SNP is Enabled" + fi +}