From a003917622af175c8198cb2ddd001a0650b2daf1 Mon Sep 17 00:00:00 2001 From: Harika Nittala Date: Fri, 6 Dec 2024 00:24:29 +0000 Subject: [PATCH 1/8] Update snp docs to launch various SNP guest Updated snp docs to launch various unique guest using unique values of GUEST_NAME and HOST_SSH_PORT environment variables. Signed-off-by: Harika Nittala --- docs/snp.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/snp.md b/docs/snp.md index aac81d4..7d4c77c 100644 --- a/docs/snp.md +++ b/docs/snp.md @@ -132,6 +132,12 @@ Launch the guest: ./snp.sh launch-guest ``` +User can launch various unique SNP enabled guests at the same time using + different GUEST_NAME and HOST_SSH_PORT environment variables. Export the following environment variables to achieve this: +``` +export GUEST_NAME="guest-name" +export HOST_SSH_PORT="your-host-SSH-port" +``` ## Accessing the Guest via SSH Once launched, the guest can be accessed with the following SSH command: From 9178a503c91a48b42725c8b39870d4dd638f4460 Mon Sep 17 00:00:00 2001 From: Harika Nittala Date: Mon, 2 Dec 2024 23:28:06 +0000 Subject: [PATCH 2/8] snp.sh: Enhance the process of SNP guest creation speed Improve the speed of SNP guest creation through the download of the guest base os image once and re-use the same base image for SNP guest creation process for multiple guests. Signed-off-by: Harika Nittala --- tools/snp.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/snp.sh b/tools/snp.sh index 1c26829..687dbd3 100755 --- a/tools/snp.sh +++ b/tools/snp.sh @@ -87,6 +87,7 @@ GUEST_SSH_KEY_PATH="${GUEST_SSH_KEY_PATH:-${LAUNCH_WORKING_DIR}/${GUEST_NAME}-ke GUEST_ROOT_LABEL="${GUEST_ROOT_LABEL:-cloudimg-rootfs}" GUEST_KERNEL_APPEND="root=LABEL=${GUEST_ROOT_LABEL} ro console=ttyS0" QEMU_CMDLINE_FILE="${QEMU_CMDLINE:-${LAUNCH_WORKING_DIR}/qemu.cmdline}" +BASE_CLOUD_IMAGE="${BASE_CLOUD_IMAGE:-${WORKING_DIR}/base_cloud_image.img}" IMAGE="${IMAGE:-${LAUNCH_WORKING_DIR}/${GUEST_NAME}.img}" GENERATED_INITRD_BIN="${SETUP_WORKING_DIR}/initrd.img" @@ -540,7 +541,11 @@ EOF "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-metadata.yaml" # Download ubuntu 20.04 and change name - wget "${CLOUD_INIT_IMAGE_URL}" -O "${IMAGE}" + if [ ! -f "${BASE_CLOUD_IMAGE}" ]; then + wget "${CLOUD_INIT_IMAGE_URL}" -O "${BASE_CLOUD_IMAGE}" + fi + + cp -v "${BASE_CLOUD_IMAGE}" "${IMAGE}" } resize_guest() { From 6b182e2746f5712264dcffd76fe3c3960354ce76 Mon Sep 17 00:00:00 2001 From: Harika Nittala Date: Mon, 2 Dec 2024 23:58:49 +0000 Subject: [PATCH 3/8] snp.sh: snp-guest-key location and guest user name update Signed-off-by: Harika Nittala --- tools/snp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/snp.sh b/tools/snp.sh index 687dbd3..732dd2a 100755 --- a/tools/snp.sh +++ b/tools/snp.sh @@ -1401,7 +1401,7 @@ main() { echo -e "Guest SSH port forwarded to host port: ${HOST_SSH_PORT}" echo -e "The guest is running in the background. Use the following command to access via SSH:" - echo -e "ssh -p ${HOST_SSH_PORT} -i ${LAUNCH_WORKING_DIR}/snp-guest-key amd@localhost" + echo -e "ssh -p ${HOST_SSH_PORT} -i ${GUEST_SSH_KEY_PATH} ${GUEST_USER}@localhost" ;; attest-guest) From 0476cc5f5b6f5fea21d91e2302fb0e35bd05f5c2 Mon Sep 17 00:00:00 2001 From: Harika Nittala Date: Tue, 3 Dec 2024 00:02:58 +0000 Subject: [PATCH 4/8] snp.sh: Create and launch multiple SNP enabled guests Users can launch multiple SNP enabled guests at the same time via the export of the GUEST_NAME and HOST_SSH_PORT env. variables For the launch of multiple SNP guest at the same time, modified snp.sh to create a separate guest user directory and point the launch working directory to point the current specific guest user directory. Signed-off-by: Harika Nittala --- tools/snp.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tools/snp.sh b/tools/snp.sh index 732dd2a..d731c3d 100755 --- a/tools/snp.sh +++ b/tools/snp.sh @@ -68,7 +68,8 @@ trap cleanup EXIT # Working directory setup WORKING_DIR="${WORKING_DIR:-$HOME/snp}" SETUP_WORKING_DIR="${SETUP_WORKING_DIR:-${WORKING_DIR}/setup}" -LAUNCH_WORKING_DIR="${LAUNCH_WORKING_DIR:-${WORKING_DIR}/launch}" +GUEST_NAME="${GUEST_NAME:-snp-guest}" +LAUNCH_WORKING_DIR="${LAUNCH_WORKING_DIR:-${WORKING_DIR}/launch/${GUEST_NAME}}" ATTESTATION_WORKING_DIR="${ATTESTATION_WORKING_DIR:-${WORKING_DIR}/attest}" # Export environment variables @@ -76,7 +77,6 @@ COMMAND="help" UPM=true SKIP_IMAGE_CREATE=false HOST_SSH_PORT="${HOST_SSH_PORT:-10022}" -GUEST_NAME="${GUEST_NAME:-snp-guest}" GUEST_SIZE_GB="${GUEST_SIZE_GB:-20}" GUEST_MEM_SIZE_MB="${GUEST_MEM_SIZE_MB:-2048}" GUEST_SMP="${GUEST_SMP:-4}" @@ -503,8 +503,8 @@ generate_guest_ssh_keypair() { } cloud_init_create_data() { - if [[ -f "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-metadata.yaml" && \ - -f "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-user-data.yaml" && \ + if [[ -f "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/metadata.yaml" && \ + -f "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/user-data.yaml" && \ -f "${IMAGE}" ]]; then echo -e "cloud-init data already generated" return 0 @@ -513,13 +513,13 @@ cloud_init_create_data() { local pub_key=$(cat "${GUEST_SSH_KEY_PATH}.pub") # Seed image metadata -cat > "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-metadata.yaml" < "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/metadata.yaml" < "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-user-data.yaml" < "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/user-data.yaml" < Date: Tue, 3 Dec 2024 02:38:59 +0000 Subject: [PATCH 5/8] snp.sh: Update the guest seed image creation approach in the ubuntu OS Creates guest seed image containing user configured metadata and userdata via genisoimage utility in ubuntu as genisoimage utility is available across different OS distrubutions (cloud-localds utility is supported only in Ubuntu OS) Signed-off-by: Harika Nittala --- tools/snp.sh | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/tools/snp.sh b/tools/snp.sh index d731c3d..2ebbe89 100755 --- a/tools/snp.sh +++ b/tools/snp.sh @@ -244,6 +244,7 @@ install_ubuntu_dependencies() { # cloud-utils dependency sudo apt install -y cloud-image-utils + sudo apt install -y genisoimage # Virtualization tools for resizing image # virt-resize currently does not work with cloud-init images. It changes the partition @@ -502,6 +503,23 @@ generate_guest_ssh_keypair() { ssh-keygen -q -t ed25519 -N '' -f "${GUEST_SSH_KEY_PATH}" << Date: Fri, 6 Dec 2024 17:09:05 -0800 Subject: [PATCH 6/8] snp.sh: Rename guest cloud-init user data and metadata file Modified guest cloud-init userdata and metadata to apply the guest configuration details across different OS linux distros(Ubuntu, Fedora, etc) successfuly during SNP guest launch. Signed-off-by: Harika Nittala --- tools/snp.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/snp.sh b/tools/snp.sh index 2ebbe89..98707c7 100755 --- a/tools/snp.sh +++ b/tools/snp.sh @@ -521,8 +521,8 @@ download_guest_os_image(){ } cloud_init_create_data() { - if [[ -f "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/metadata.yaml" && \ - -f "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/user-data.yaml" && \ + if [[ -f "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/meta-data" && \ + -f "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/user-data" && \ -f "${IMAGE}" ]]; then echo -e "cloud-init data already generated" return 0 @@ -531,13 +531,13 @@ cloud_init_create_data() { local pub_key=$(cat "${GUEST_SSH_KEY_PATH}.pub") # Seed image metadata -cat > "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/metadata.yaml" < "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/meta-data" < "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/user-data.yaml" < "${LAUNCH_WORKING_DIR}/${GUEST_NAME}-data/user-data" < Date: Fri, 6 Dec 2024 14:26:00 -0800 Subject: [PATCH 7/8] snp.sh: Standardize SNP launch guest structure in Ubuntu Modified the structure of SNP guest launch process in ubuntu to standardize the SNP guest launch feature across various OS linux distros. Observed successful launch of SNP guest in ubuntu 22.04. Signed-off-by: Harika Nittala --- tools/snp.sh | 96 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 8 deletions(-) diff --git a/tools/snp.sh b/tools/snp.sh index 98707c7..b1e816d 100755 --- a/tools/snp.sh +++ b/tools/snp.sh @@ -84,7 +84,7 @@ CPU_MODEL="${CPU_MODEL:-EPYC-v4}" GUEST_USER="${GUEST_USER:-amd}" GUEST_PASS="${GUEST_PASS:-amd}" GUEST_SSH_KEY_PATH="${GUEST_SSH_KEY_PATH:-${LAUNCH_WORKING_DIR}/${GUEST_NAME}-key}" -GUEST_ROOT_LABEL="${GUEST_ROOT_LABEL:-cloudimg-rootfs}" +GUEST_ROOT_LABEL="${GUEST_ROOT_LABEL:-""}" GUEST_KERNEL_APPEND="root=LABEL=${GUEST_ROOT_LABEL} ro console=ttyS0" QEMU_CMDLINE_FILE="${QEMU_CMDLINE:-${LAUNCH_WORKING_DIR}/qemu.cmdline}" BASE_CLOUD_IMAGE="${BASE_CLOUD_IMAGE:-${WORKING_DIR}/base_cloud_image.img}" @@ -899,6 +899,53 @@ build_and_install_amdsev() { save_binary_paths } +get_package_install_command(){ + local linux_distro=$(get_linux_distro) + + case ${linux_distro} in + ubuntu) + echo "dpkg -i" + ;; + *) + >&2 echo -e "ERROR: ${linux_distro}" + return 1 + ;; + esac +} + +get_guest_kernel_package(){ + local linux_distro=$(get_linux_distro) + local guest_kernel_version=$(get_guest_kernel_version) + + pushd "${SETUP_WORKING_DIR}/AMDSEV/linux" >/dev/null + case ${linux_distro} in + ubuntu) + echo $(realpath linux-image*${guest_kernel_version}*.deb| grep -v dbg) + ;; + *) + >&2 echo -e "ERROR: ${linux_distro}" + return 1 + ;; + esac + popd>/dev/null +} + +set_default_guest_kernel_append() { + local linux_distro=$(get_linux_distro) + + # Sets default kernel append based on the linux distro + case ${linux_distro} in + ubuntu) + GUEST_ROOT_LABEL="cloudimg-rootfs" + GUEST_KERNEL_APPEND="root=LABEL=${GUEST_ROOT_LABEL} ro console=ttyS0" + ;; + *) + >&2 echo -e "ERROR: ${linux_distro}" + return 1 + ;; + esac +} + setup_and_launch_guest() { # Return error if user specified file that doesn't exist if [ ! -f "${IMAGE}" ] && ${SKIP_IMAGE_CREATE}; then @@ -938,16 +985,43 @@ setup_and_launch_guest() { # Install the guest kernel, retrieve the initrd and then reboot local guest_kernel_version=$(get_guest_kernel_version) - local guest_kernel_deb=$(echo "$(realpath ${SETUP_WORKING_DIR}/AMDSEV/linux/linux-image*snp-guest*.deb)" | grep -v dbg) - local guest_initrd_basename="initrd.img-${guest_kernel_version}" - wait_and_retry_command "scp_guest_command ${guest_kernel_deb} ${GUEST_USER}@localhost:/home/${GUEST_USER}" - ssh_guest_command "sudo dpkg -i /home/${GUEST_USER}/$(basename ${guest_kernel_deb})" - scp_guest_command "${GUEST_USER}@localhost:/boot/${guest_initrd_basename}" "${LAUNCH_WORKING_DIR}" + local guest_kernel_package=$(get_guest_kernel_package) + + local guest_initrd_basename="init*${guest_kernel_version}*" + local guest_kernel_basename="vmlinuz*${guest_kernel_version}*" + + # Uses package manager command based on the guest OS linux distro + local package_install_command=$(get_package_install_command) + + # Copy the built SNP guest kernel package into the guest + wait_and_retry_command "scp_guest_command ${guest_kernel_package} ${GUEST_USER}@localhost:/home/${GUEST_USER}" + + # Install the guest SNP kernel package inside the guest + ssh_guest_command "sudo ${package_install_command} /home/${GUEST_USER}/$(basename ${guest_kernel_package})" + + # Copy the installed guest initial ram disk into the host + local initrd_filepath=$(ssh_guest_command "ls /boot/${guest_initrd_basename} | grep -v kdump") + initrd_filepath=$(echo ${initrd_filepath}| tr -d '\r') + ssh_guest_command "sudo cp $(realpath ${initrd_filepath}) /home/${GUEST_USER}" + ssh_guest_command "sudo chmod 644 /home/${GUEST_USER}/$(basename $(realpath ${initrd_filepath}))" + scp_guest_command "${GUEST_USER}@localhost:/home/${GUEST_USER}/$(basename $(realpath ${initrd_filepath}))" "${LAUNCH_WORKING_DIR}" + + # Copy the installed SNP guest kernel from guest into the host + local vmlinuz_filepath=$(ssh_guest_command "ls /boot/${guest_kernel_basename}") + vmlinuz_filepath=$(echo ${vmlinuz_filepath}| tr -d '\r') + ssh_guest_command "sudo cp $(realpath ${vmlinuz_filepath}) /home/${GUEST_USER}" + ssh_guest_command "sudo chmod 644 /home/${GUEST_USER}/$(basename $(realpath ${vmlinuz_filepath}))" + scp_guest_command "${GUEST_USER}@localhost:/home/${GUEST_USER}/$(basename $(realpath ${vmlinuz_filepath}))" "${LAUNCH_WORKING_DIR}" ssh_guest_command "sudo shutdown now" || true echo "true" > "${guest_kernel_installed_file}" - # Update the initrd file path and name in the guest launch source-bins file - sed -i -e "s|^\(INITRD_BIN=\).*$|\1\"${LAUNCH_WORKING_DIR}/${guest_initrd_basename}\"|g" "${LAUNCH_WORKING_DIR}/source-bins" + # Update guest initrd, kernel binary file path in the host + GENERATED_INITRD_BIN=$(ls ${LAUNCH_WORKING_DIR}/${guest_initrd_basename} ) + GENERATED_KERNEL_BIN=$(ls ${LAUNCH_WORKING_DIR}/${guest_kernel_basename}* ) + + # Update the source bin file with the latest initrd & kernel file path + sed -i -e "s|^\(INITRD_BIN=\).*$|\1\"${GENERATED_INITRD_BIN}\"|g" "${LAUNCH_WORKING_DIR}/source-bins" + sed -i -e "s|^\(KERNEL_BIN=\).*$|\1\"${GENERATED_KERNEL_BIN}\"|g" "${LAUNCH_WORKING_DIR}/source-bins" # Wait for shutdown to complete wait_and_retry_command "! ps aux | grep \"${WORKING_DIR}.*qemu.*${IMAGE}\" | grep -v \"tail.*qemu.log\" | grep -v \"grep.*qemu\"" @@ -978,6 +1052,12 @@ setup_and_launch_guest() { # snp object and kernel-hashes on add_qemu_cmdline_opts "-object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,kernel-hashes=on" + # Update guest initrd, kernel to the updated guest SNP kernel version + source "${LAUNCH_WORKING_DIR}/source-bins" + + # Set the default guest kernel append parameter based on the linux distro + [ -z "${GUEST_ROOT_LABEL}" ] && set_default_guest_kernel_append + # ovmf, initrd, kernel and append options add_qemu_cmdline_opts "-bios ${OVMF_BIN}" add_qemu_cmdline_opts "-initrd ${INITRD_BIN}" From b0d7ca04197fc4ce392cf3edc5526b2b4f7f83b8 Mon Sep 17 00:00:00 2001 From: Harika Nittala Date: Tue, 10 Dec 2024 11:57:47 -0800 Subject: [PATCH 8/8] snp.sh: Add SNP launch guest support in Fedora Updated fedora dependencies for guest seed image creation to apply user configuration data on fedora image via genisoimage utility Added support for the SNP guest launch on Fedora 38 host Signed-off-by: Harika Nittala --- tools/snp.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/snp.sh b/tools/snp.sh index b1e816d..fae05f4 100755 --- a/tools/snp.sh +++ b/tools/snp.sh @@ -331,6 +331,8 @@ install_fedora_dependencies() { # cloud-utils dependency sudo dnf install -y cloud-init + sudo dnf install -y genisoimage + sudo dnf install -y qemu-img } get_linux_distro() { @@ -511,6 +513,9 @@ download_guest_os_image(){ ubuntu) CLOUD_INIT_IMAGE_URL="https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img" ;; + fedora) + CLOUD_INIT_IMAGE_URL="https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/38/Cloud/x86_64/images/Fedora-Cloud-Base-38-1.6.x86_64.qcow2" + ;; esac # Download the guest os-image and change name @@ -906,6 +911,9 @@ get_package_install_command(){ ubuntu) echo "dpkg -i" ;; + fedora) + echo "dnf install -y" + ;; *) >&2 echo -e "ERROR: ${linux_distro}" return 1 @@ -922,6 +930,10 @@ get_guest_kernel_package(){ ubuntu) echo $(realpath linux-image*${guest_kernel_version}*.deb| grep -v dbg) ;; + fedora) + guest_kernel_version="${guest_kernel_version//-/_}" # SNP kernel RPM package name contains _ in the version + echo $(realpath $(ls -t kernel-*${guest_kernel_version}*.rpm| grep -v header| head -1)) + ;; *) >&2 echo -e "ERROR: ${linux_distro}" return 1 @@ -939,6 +951,10 @@ set_default_guest_kernel_append() { GUEST_ROOT_LABEL="cloudimg-rootfs" GUEST_KERNEL_APPEND="root=LABEL=${GUEST_ROOT_LABEL} ro console=ttyS0" ;; + fedora) + GUEST_ROOT_LABEL="fedora" + GUEST_KERNEL_APPEND="console=ttys0 root=LABEL=${GUEST_ROOT_LABEL} ro rootflags=subvol=root" + ;; *) >&2 echo -e "ERROR: ${linux_distro}" return 1