diff --git a/src/cloud-api-adaptor/Makefile b/src/cloud-api-adaptor/Makefile index 651f401f5..f123fd839 100644 --- a/src/cloud-api-adaptor/Makefile +++ b/src/cloud-api-adaptor/Makefile @@ -207,5 +207,6 @@ endif --build-arg CLOUD_PROVIDER=$(or $(CLOUD_PROVIDER),generic) \ --build-arg IMAGE_URL=$(IMAGE_URL) \ --build-arg IMAGE_CHECKSUM=$(IMAGE_CHECKSUM) \ + --build-arg SE_BOOT=$(SE_BOOT) \ $(DOCKER_OPTS) . rm -rf .git diff --git a/src/cloud-api-adaptor/podvm/Dockerfile.podvm.rhel b/src/cloud-api-adaptor/podvm/Dockerfile.podvm.rhel index 024a70e86..451e74b5a 100644 --- a/src/cloud-api-adaptor/podvm/Dockerfile.podvm.rhel +++ b/src/cloud-api-adaptor/podvm/Dockerfile.podvm.rhel @@ -24,6 +24,7 @@ ENV PODVM_DISTRO=${PODVM_DISTRO} ENV ARCH=${ARCH} ENV UEFI=${UEFI} +ARG SE_BOOT ARG IMAGE_URL ARG IMAGE_CHECKSUM @@ -31,6 +32,7 @@ ADD ${IMAGE_URL} /tmp/rhel.img ENV IMAGE_URL=/tmp/rhel.img ENV IMAGE_CHECKSUM=${IMAGE_CHECKSUM} +ENV SE_BOOT=${SE_BOOT} # workaround to ensure hashicorp packer is called instead # of cracklib packer which is installed by default ENV PATH="/usr/bin:${PATH}" diff --git a/src/cloud-api-adaptor/podvm/Makefile b/src/cloud-api-adaptor/podvm/Makefile index ff647a8f0..877185d69 100644 --- a/src/cloud-api-adaptor/podvm/Makefile +++ b/src/cloud-api-adaptor/podvm/Makefile @@ -53,8 +53,10 @@ else ifeq ($(PODVM_DISTRO),rhel) @echo defined $(eval OPTS := -var disk_size=11144) ifeq ($(ARCH),s390x) + $(eval OPTS += -var se_boot=${SE_BOOT}) $(eval OPTS += -var machine_type=${QEMU_MACHINE_TYPE_${ARCH}}) $(eval OPTS += -var cpu_type=max) + $(eval OPTS += -var os_arch=s390x) ifndef QEMU_BINARY $(eval OPTS += -var qemu_binary=qemu-system-${ARCH}) endif diff --git a/src/cloud-api-adaptor/podvm/qcow2/build-s390x-se-image.sh b/src/cloud-api-adaptor/podvm/qcow2/build-s390x-se-image.sh index 0746a2c05..9ffaeb36a 100755 --- a/src/cloud-api-adaptor/podvm/qcow2/build-s390x-se-image.sh +++ b/src/cloud-api-adaptor/podvm/qcow2/build-s390x-se-image.sh @@ -16,14 +16,40 @@ for i in /tmp/files/*.crt; do host_keys+="-k ${i} " done [[ -z $host_keys ]] && echo "Didn't find host key files, please download host key files to 'files' folder " && exit 1 -echo "Installing jq" -export DEBIAN_FRONTEND=noninteractive -sudo apt-get update > /dev/null 2>&1 -sudo apt-get install jq -y > /dev/null 2>&1 -sudo apt-get remove unattended-upgrades -y -sudo apt-get autoremove -sudo apt-get clean -sudo rm -rf /var/lib/apt/lists/* + +if [ "${PODVM_DISTRO}" = "rhel" ]; then + export LANG=C.UTF-8 + if ! command -v jq &> /dev/null || ! command -v cryptsetup &> /dev/null; then + if ! command -v jq &> /dev/null; then + echo >&2 "jq is required but it's not installed. Installing now..." + sudo yum install jq -y >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo >&2 "Failed to install jq. Aborting." + exit 1 + fi + fi + + if ! command -v cryptsetup &> /dev/null; then + echo >&2 "cryptsetup is required but it's not installed. Installing now..." + sudo yum install cryptsetup -y >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo >&2 "Failed to install cryptsetup. Aborting." + exit 1 + fi + fi + fi + sudo yum clean all + echo "jq and cryptsetup are installed. Proceeding with the script..." +else + echo "Installing jq" + export DEBIAN_FRONTEND=noninteractive + sudo apt-get update > /dev/null 2>&1 + sudo apt-get install jq -y > /dev/null 2>&1 + sudo apt-get remove unattended-upgrades -y + sudo apt-get autoremove + sudo apt-get clean + sudo rm -rf /var/lib/apt/lists/* +fi workdir=$(pwd) disksize=100G @@ -112,16 +138,27 @@ END' sudo -E bash -c 'echo s390_trng >> ${dst_mnt}/etc/modules' -echo "Preparing files needed for mkinitrd" +echo "Preparing files needed for mkinitrd / initramfs" + +if [ "${PODVM_DISTRO}" = "rhel" ]; then + sudo -E bash -c 'echo "UMASK=0077" >> ${dst_mnt}/etc/dracut.conf.d/crypt.conf' + sudo -E bash -c 'echo "add_drivers+=\" dm_crypt \"" >> ${dst_mnt}/etc/dracut.conf.d/crypt.conf' + sudo -E bash -c 'echo "add_dracutmodules+=\" crypt \"" >> ${dst_mnt}/etc/dracut.conf.d/crypt.conf' + sudo -E bash -c 'echo "KEYFILE_PATTERN=\" /etc/keys/*.key \"" >> ${dst_mnt}/etc/dracut.conf.d/crypt.conf' + sudo -E bash -c 'echo "install_items+=\" /etc/keys/*.key \"" >> ${dst_mnt}/etc/dracut.conf.d/crypt.conf' + echo 'install_items+=" /etc/fstab "' >> ${dst_mnt}/etc/dracut.conf.d/crypt.conf + echo 'install_items+=" /etc/crypttab "' >> ${dst_mnt}/etc/dracut.conf.d/crypt.conf +else + sudo -E bash -c 'echo "KEYFILE_PATTERN=\"/etc/keys/*.key\"" >> ${dst_mnt}/etc/cryptsetup-initramfs/conf-hook' + sudo -E bash -c 'echo "UMASK=0077" >> ${dst_mnt}/etc/initramfs-tools/initramfs.conf' +fi -sudo -E bash -c 'echo "KEYFILE_PATTERN=\"/etc/keys/*.key\"" >> ${dst_mnt}/etc/cryptsetup-initramfs/conf-hook' -sudo -E bash -c 'echo "UMASK=0077" >> ${dst_mnt}/etc/initramfs-tools/initramfs.conf' sudo -E bash -c 'cat < ${dst_mnt}/etc/zipl.conf [defaultboot] default=linux target=/boot-se -targetbase=/dev/vda +targetbase=${tmp_nbd} targettype=scsi targetblocksize=512 targetoffset=2048 @@ -131,15 +168,23 @@ image = /boot-se/se.img END' echo "Updating initial ram disk" -sudo chroot "${dst_mnt}" update-initramfs -u || true +if [ "${PODVM_DISTRO}" = "rhel" ]; then + sudo cp "/boot/vmlinuz-$(uname -r)" "${dst_mnt}/boot/vmlinuz-$(uname -r)" + sudo cp "/boot/initramfs-$(uname -r).img" "${dst_mnt}/boot/initramfs-$(uname -r).img" + sleep 10 + sudo chroot ${dst_mnt} dracut -f -v + KERNEL_FILE="vmlinuz-$(uname -r)" + INITRD_FILE="initramfs-$(uname -r).img" +else + sudo chroot "${dst_mnt}" update-initramfs -u || true + # Clean up kernel names and make sure they are where we expect them + KERNEL_FILE=$(readlink ${dst_mnt}/boot/vmlinuz) + INITRD_FILE=$(readlink ${dst_mnt}/boot/initrd.img) +fi echo "!!! Bootloader install errors prior to this line are intentional !!!!!" 1>&2 echo "Generating an IBM Secure Execution image" - -# Clean up kernel names and make sure they are where we expect them -KERNEL_FILE=$(readlink ${dst_mnt}/boot/vmlinuz) -INITRD_FILE=$(readlink ${dst_mnt}/boot/initrd.img) echo "Creating SE boot image" -export SE_PARMLINE="root=/dev/mapper/$LUKS_NAME console=ttysclp0 quiet panic=0 rd.shell=0 blacklist=virtio_rng swiotlb=262144" +export SE_PARMLINE="root=/dev/mapper/$LUKS_NAME rd.auto=1 rd.retry=30 console=ttysclp0 quiet panic=0 rd.shell=0 blacklist=virtio_rng swiotlb=262144" sudo -E bash -c 'echo "${SE_PARMLINE}" > ${dst_mnt}/boot/parmfile' sudo -E /usr/bin/genprotimg \ -i ${dst_mnt}/boot/${KERNEL_FILE} \ @@ -175,3 +220,4 @@ sudo rm -rf ${src_mnt} ${dst_mnt} echo "Closing encrypted root partition" sudo cryptsetup close $LUKS_NAME sleep 10 +echo "SE podvm qcow2 image build completed successfully" diff --git a/src/cloud-api-adaptor/podvm/qcow2/rhel/qemu-rhel.pkr.hcl b/src/cloud-api-adaptor/podvm/qcow2/rhel/qemu-rhel.pkr.hcl index 381f03046..19cdb3e97 100644 --- a/src/cloud-api-adaptor/podvm/qcow2/rhel/qemu-rhel.pkr.hcl +++ b/src/cloud-api-adaptor/podvm/qcow2/rhel/qemu-rhel.pkr.hcl @@ -1,8 +1,29 @@ - locals { machine_type = "${var.os_arch}" == "x86_64" && "${var.is_uefi}" ? "q35" : "${var.machine_type}" use_pflash = "${var.os_arch}" == "x86_64" && "${var.is_uefi}" ? "true" : "false" firmware = "${var.os_arch}" == "x86_64" && "${var.is_uefi}" ? "${var.uefi_firmware}" : "" + se_qemuargs = [ + ["-drive", "file=se-${var.qemu_image_name},if=none,cache=writeback,discard=ignore,format=qcow2,id=se-virtio-drive"], + ["-device", "virtio-blk,drive=se-virtio-drive,id=virtio-disk1"] + ] + qemuargs = "${var.se_boot}" == "1" ? ( + [ + ["-device", "virtio-blk,drive=virtio-drive,id=virtio-disk0,bootindex=1"], + ["-drive", "file=${var.output_directory}/${var.qemu_image_name},if=none,cache=writeback,discard=ignore,format=qcow2,id=virtio-drive"], + ["-cdrom", "${var.cloud_init_image}"], + ["-m", "${var.memory}"], + ["-smp", "cpus=${var.cpus}"], + ["-serial", "mon:stdio"] + ] + ) : ( + [ + ["-m", "${var.memory}"], + ["-smp", "cpus=${var.cpus}"], + ["-cdrom", "${var.cloud_init_image}"], + ["-serial", "mon:stdio"] + ] + ) + final_qemuargs = "${var.se_boot}" == "1" ? concat(local.qemuargs, local.se_qemuargs) : local.qemuargs } source "qemu" "rhel" { @@ -14,8 +35,8 @@ source "qemu" "rhel" { headless = true iso_checksum = "${var.cloud_image_checksum}" iso_url = "${var.cloud_image_url}" - output_directory = "output" - qemuargs = [["-m", "${var.memory}"], ["-smp", "cpus=${var.cpus}"], ["-cdrom", "${var.cloud_init_image}"], ["-serial", "mon:stdio"], ["-cpu", "${var.cpu_type}"]] + output_directory = "${var.output_directory}" + qemuargs = "${local.final_qemuargs}" ssh_password = "${var.ssh_password}" ssh_port = 22 ssh_username = "${var.ssh_username}" @@ -90,4 +111,32 @@ build { "sudo -E bash ~/misc-settings.sh" ] } + + provisioner "file" { + source = "qcow2/build-s390x-se-image.sh" + destination = "~/build-s390x-se-image.sh" + } + + provisioner "shell" { + remote_folder = "~" + environment_vars = [ + "SE_BOOT=${var.se_boot}", + "PODVM_DISTRO=${var.podvm_distro}", + "ARCH=${var.os_arch}" + ] + inline = [ + "sudo -E bash ~/build-s390x-se-image.sh" + ] + } + + post-processor "shell-local" { + name = "post-build-se-image" + script = "qcow2/build-s390x-se-image-post.sh" + environment_vars = [ + "SE_BOOT=${var.se_boot}", + "ARCH=${var.os_arch}", + "OUTPUT_DIRECTORY=${var.output_directory}", + "IMAGE_NAME=${var.qemu_image_name}" + ] + } } diff --git a/src/cloud-api-adaptor/podvm/qcow2/rhel/variables.pkr.hcl b/src/cloud-api-adaptor/podvm/qcow2/rhel/variables.pkr.hcl index 6f0ccde1d..0016fc493 100644 --- a/src/cloud-api-adaptor/podvm/qcow2/rhel/variables.pkr.hcl +++ b/src/cloud-api-adaptor/podvm/qcow2/rhel/variables.pkr.hcl @@ -101,4 +101,14 @@ variable "boot_wait" { variable "disable_cloud_config" { type = string default = env("DISABLE_CLOUD_CONFIG") -} \ No newline at end of file +} + +variable "se_boot" { + type = string + default = env("SE_BOOT") +} + +variable "output_directory" { + type = string + default = "output" +}