From dc3c0d9725acea76e53c306a4ffd06f17e02fa46 Mon Sep 17 00:00:00 2001 From: Sarita Mahajan Date: Tue, 15 Nov 2022 11:22:24 +0000 Subject: [PATCH] simplified-installer: do not mandate FDO section in simplified provisioning - build simplified installer iso without mentioning FDO section. - change done for rhel8 and rhel9 - add test case for this use case in test/case/ostree-simplified-installer.shovisioning - fixed review comments Signed-off-by: Sarita Mahajan --- internal/blueprint/customizations.go | 4 + internal/distro/rhel8/distro.go | 36 +++--- internal/distro/rhel8/pipelines.go | 2 +- internal/distro/rhel8/stage_options.go | 21 ++-- internal/distro/rhel9/distro.go | 36 +++--- internal/distro/rhel9/pipelines.go | 2 +- internal/distro/rhel9/stage_options.go | 21 ++-- test/cases/ostree-simplified-installer.sh | 129 +++++++++++++++++++++- 8 files changed, 187 insertions(+), 64 deletions(-) diff --git a/internal/blueprint/customizations.go b/internal/blueprint/customizations.go index 69b0db2e2..299ccc6df 100644 --- a/internal/blueprint/customizations.go +++ b/internal/blueprint/customizations.go @@ -380,3 +380,7 @@ func (c *Customizations) GetOpenSCAP() *OpenSCAPCustomization { } return c.OpenSCAP } + +func (f *FDOCustomization) HasFDO() bool { + return f != nil +} diff --git a/internal/distro/rhel8/distro.go b/internal/distro/rhel8/distro.go index 5c6ef191c..f7b8a4bb5 100644 --- a/internal/distro/rhel8/distro.go +++ b/internal/distro/rhel8/distro.go @@ -606,24 +606,24 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio if customizations.GetInstallationDevice() == "" { return fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.name) } - if customizations.GetFDO() == nil { - return fmt.Errorf("boot ISO image type %q requires specifying FDO configuration to install to", t.name) - } - if customizations.GetFDO().ManufacturingServerURL == "" { - return fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to", t.name) - } - var diunSet int - if customizations.GetFDO().DiunPubKeyHash != "" { - diunSet++ - } - if customizations.GetFDO().DiunPubKeyInsecure != "" { - diunSet++ - } - if customizations.GetFDO().DiunPubKeyRootCerts != "" { - diunSet++ - } - if diunSet != 1 { - return fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to", t.name) + //making fdo optional so that simplified installer can be composed w/o the FDO section in the blueprint + if customizations.GetFDO() != nil { + if customizations.GetFDO().ManufacturingServerURL == "" { + return fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to", t.name) + } + var diunSet int + if customizations.GetFDO().DiunPubKeyHash != "" { + diunSet++ + } + if customizations.GetFDO().DiunPubKeyInsecure != "" { + diunSet++ + } + if customizations.GetFDO().DiunPubKeyRootCerts != "" { + diunSet++ + } + if diunSet != 1 { + return fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to", t.name) + } } } else if t.name == "edge-installer" { allowed := []string{"User", "Group"} diff --git a/internal/distro/rhel8/pipelines.go b/internal/distro/rhel8/pipelines.go index f531e247e..124d5684c 100644 --- a/internal/distro/rhel8/pipelines.go +++ b/internal/distro/rhel8/pipelines.go @@ -899,7 +899,7 @@ func simplifiedInstallerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd. "coreos-installer", "fdo", }) - if fdo.DiunPubKeyRootCerts != "" { + if fdo.HasFDO() && fdo.DiunPubKeyRootCerts != "" { p.AddStage(osbuild.NewFDOStageForRootCerts(fdo.DiunPubKeyRootCerts)) dracutStageOptions.Install = []string{"/fdo_diun_pub_key_root_certs.pem"} } diff --git a/internal/distro/rhel8/stage_options.go b/internal/distro/rhel8/stage_options.go index e9e57c2a6..873b2d469 100644 --- a/internal/distro/rhel8/stage_options.go +++ b/internal/distro/rhel8/stage_options.go @@ -236,17 +236,18 @@ func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVers Vendor: vendor, } - grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.manufacturing_server_url="+fdo.ManufacturingServerURL) - if fdo.DiunPubKeyInsecure != "" { - grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_insecure="+fdo.DiunPubKeyInsecure) + if fdo.HasFDO() { + grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.manufacturing_server_url="+fdo.ManufacturingServerURL) + if fdo.DiunPubKeyInsecure != "" { + grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_insecure="+fdo.DiunPubKeyInsecure) + } + if fdo.DiunPubKeyHash != "" { + grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_hash="+fdo.DiunPubKeyHash) + } + if fdo.DiunPubKeyRootCerts != "" { + grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_root_certs=/fdo_diun_pub_key_root_certs.pem") + } } - if fdo.DiunPubKeyHash != "" { - grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_hash="+fdo.DiunPubKeyHash) - } - if fdo.DiunPubKeyRootCerts != "" { - grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_root_certs=/fdo_diun_pub_key_root_certs.pem") - } - return grubISOStageOptions } diff --git a/internal/distro/rhel9/distro.go b/internal/distro/rhel9/distro.go index 95f033e0d..c9e4952db 100644 --- a/internal/distro/rhel9/distro.go +++ b/internal/distro/rhel9/distro.go @@ -572,24 +572,24 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio if customizations.GetInstallationDevice() == "" { return fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.name) } - if customizations.GetFDO() == nil { - return fmt.Errorf("boot ISO image type %q requires specifying FDO configuration to install to", t.name) - } - if customizations.GetFDO().ManufacturingServerURL == "" { - return fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to", t.name) - } - var diunSet int - if customizations.GetFDO().DiunPubKeyHash != "" { - diunSet++ - } - if customizations.GetFDO().DiunPubKeyInsecure != "" { - diunSet++ - } - if customizations.GetFDO().DiunPubKeyRootCerts != "" { - diunSet++ - } - if diunSet != 1 { - return fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to", t.name) + //making fdo optional so that simplified installer can be composed w/o the FDO section in the blueprint + if customizations.GetFDO() != nil { + if customizations.GetFDO().ManufacturingServerURL == "" { + return fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to", t.name) + } + var diunSet int + if customizations.GetFDO().DiunPubKeyHash != "" { + diunSet++ + } + if customizations.GetFDO().DiunPubKeyInsecure != "" { + diunSet++ + } + if customizations.GetFDO().DiunPubKeyRootCerts != "" { + diunSet++ + } + if diunSet != 1 { + return fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to", t.name) + } } } else if t.name == "edge-installer" { allowed := []string{"User", "Group"} diff --git a/internal/distro/rhel9/pipelines.go b/internal/distro/rhel9/pipelines.go index bee95b699..76fefd783 100644 --- a/internal/distro/rhel9/pipelines.go +++ b/internal/distro/rhel9/pipelines.go @@ -898,7 +898,7 @@ func simplifiedInstallerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd. "coreos-installer", "fdo", }) - if fdo.DiunPubKeyRootCerts != "" { + if fdo.HasFDO() && fdo.DiunPubKeyRootCerts != "" { p.AddStage(osbuild.NewFDOStageForRootCerts(fdo.DiunPubKeyRootCerts)) dracutStageOptions.Install = []string{"/fdo_diun_pub_key_root_certs.pem"} } diff --git a/internal/distro/rhel9/stage_options.go b/internal/distro/rhel9/stage_options.go index 7b0a932b0..38343e790 100644 --- a/internal/distro/rhel9/stage_options.go +++ b/internal/distro/rhel9/stage_options.go @@ -235,16 +235,17 @@ func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVers Architectures: architectures, Vendor: vendor, } - - grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.manufacturing_server_url="+fdo.ManufacturingServerURL) - if fdo.DiunPubKeyInsecure != "" { - grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_insecure="+fdo.DiunPubKeyInsecure) - } - if fdo.DiunPubKeyHash != "" { - grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_hash="+fdo.DiunPubKeyHash) - } - if fdo.DiunPubKeyRootCerts != "" { - grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_root_certs=/fdo_diun_pub_key_root_certs.pem") + if fdo.HasFDO() { + grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.manufacturing_server_url="+fdo.ManufacturingServerURL) + if fdo.DiunPubKeyInsecure != "" { + grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_insecure="+fdo.DiunPubKeyInsecure) + } + if fdo.DiunPubKeyHash != "" { + grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_hash="+fdo.DiunPubKeyHash) + } + if fdo.DiunPubKeyRootCerts != "" { + grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_root_certs=/fdo_diun_pub_key_root_certs.pem") + } } return grubISOStageOptions diff --git a/test/cases/ostree-simplified-installer.sh b/test/cases/ostree-simplified-installer.sh index f883c063f..9781fe394 100755 --- a/test/cases/ostree-simplified-installer.sh +++ b/test/cases/ostree-simplified-installer.sh @@ -210,12 +210,12 @@ wait_for_ssh_up () { clean_up () { greenprint "๐Ÿงผ Cleaning up" - # Clear vm - if [[ $(sudo virsh domstate "${IMAGE_KEY}-fdorootcert") == "running" ]]; then - sudo virsh destroy "${IMAGE_KEY}-fdorootcert" + # Clean up BIOS VM + greenprint "๐Ÿงน Clean up BIOS VM" + if [[ $(sudo virsh domstate "${IMAGE_KEY}-simplified_iso_without_fdo") == "running" ]]; then + sudo virsh destroy "${IMAGE_KEY}-simplified_iso_without_fdo" fi - sudo virsh undefine "${IMAGE_KEY}-fdorootcert" --nvram - # Remove qcow2 file. + sudo virsh undefine "${IMAGE_KEY}-simplified_iso_without_fdo" --nvram sudo virsh vol-delete --pool images "$LIBVIRT_IMAGE_PATH" # Remove any status containers if exist @@ -759,6 +759,123 @@ EOF sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e fdo_credential="true" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result +greenprint "๐Ÿงน Clean up VM" +if [[ $(sudo virsh domstate "${IMAGE_KEY}-fdorootcert") == "running" ]]; then + sudo virsh destroy "${IMAGE_KEY}-fdorootcert" +fi +sudo virsh undefine "${IMAGE_KEY}-fdorootcert" --nvram +sudo virsh vol-delete --pool images "$LIBVIRT_IMAGE_PATH" + +################################################################## +## +## Build edge-simplified-installer without FDO +## +################################################################## + +tee "$BLUEPRINT_FILE" > /dev/null << EOF +name = "simplified_iso_without_fdo" +description = "A rhel-edge simplified-installer image without FDO" +version = "0.0.1" +modules = [] +groups = [] + +[customizations] +installation_device = "/dev/vda" + +EOF + +greenprint "๐Ÿ“„ simplified_iso_without_fdo blueprint" +cat "$BLUEPRINT_FILE" + +# Prepare the blueprint for the compose. +greenprint "๐Ÿ“‹ Preparing installer blueprint" +sudo composer-cli blueprints push "$BLUEPRINT_FILE" +sudo composer-cli blueprints depsolve simplified_iso_without_fdo + +# Build simplified installer iso image. +build_image simplified_iso_without_fdo "${INSTALLER_TYPE}" "${PROD_REPO_URL}/" + +# Download the image +greenprint "๐Ÿ“ฅ Downloading the simplified_iso_without_fdo image" +sudo composer-cli compose image "${COMPOSE_ID}" > /dev/null +ISO_FILENAME="${COMPOSE_ID}-${INSTALLER_FILENAME}" +sudo cp "${ISO_FILENAME}" /var/lib/libvirt/images + +# Clean compose and blueprints. +greenprint "๐Ÿงน Clean up simplified_iso_without_fdo blueprint and compose" +sudo composer-cli compose delete "${COMPOSE_ID}" > /dev/null +sudo composer-cli blueprints delete simplified_iso_without_fdo > /dev/null + +# Ensure SELinux is happy with our new images. +greenprint "๐Ÿ‘ฟ Running restorecon on image directory" +sudo restorecon -Rv /var/lib/libvirt/images/ + +# Create qcow2 file for virt install. +greenprint "๐Ÿ–ฅ Create qcow2 file for virt install" +sudo qemu-img create -f qcow2 "${LIBVIRT_IMAGE_PATH}" 20G + +greenprint "๐Ÿ’ฟ Install ostree image via installer(ISO) on UEFI VM" +sudo virt-install --name="${IMAGE_KEY}-simplified_iso_without_fdo"\ + --disk path="${LIBVIRT_IMAGE_PATH}",format=qcow2 \ + --ram 3072 \ + --vcpus 2 \ + --network network=integration,mac=34:49:22:B0:83:32 \ + --os-type linux \ + --os-variant ${OS_VARIANT} \ + --cdrom "/var/lib/libvirt/images/${ISO_FILENAME}" \ + --boot uefi,loader_ro=yes,loader_type=pflash,nvram_template=/usr/share/edk2/ovmf/OVMF_VARS.fd,loader_secure=no \ + --tpm backend.type=emulator,backend.version=2.0,model=tpm-crb \ + --nographics \ + --noautoconsole \ + --wait=15 \ + --noreboot + +# Installation can get stuck, destroying VM helps +# See https://github.com/osbuild/osbuild-composer/issues/2413 +if [[ $(sudo virsh domstate "${IMAGE_KEY}-simplified_iso_without_fdo") == "running" ]]; then + sudo virsh destroy "${IMAGE_KEY}-simplified_iso_without_fdo" +fi + +# Start VM. +greenprint "๐Ÿ’ป Start UEFI VM" +sudo virsh start "${IMAGE_KEY}-simplified_iso_without_fdo" + +# Check for ssh ready to go. +greenprint "๐Ÿ›ƒ Checking for SSH is ready to go" +for LOOP_COUNTER in $(seq 0 30); do + RESULTS="$(wait_for_ssh_up $ROOT_CERT_GUEST_ADDRESS)" + if [[ $RESULTS == 1 ]]; then + echo "SSH is ready now! ๐Ÿฅณ" + break + fi + sleep 10 +done + +# Check image installation result +check_result + +greenprint "๐Ÿ•น Get ostree install commit value" +INSTALL_HASH=$(curl "${PROD_REPO_URL}/refs/heads/${OSTREE_REF}") + +# Add instance IP address into /etc/ansible/hosts +sudo tee "${TEMPDIR}"/inventory > /dev/null << EOF +[ostree_guest] +${ROOT_CERT_GUEST_ADDRESS} + +[ostree_guest:vars] +ansible_python_interpreter=/usr/bin/python3 +ansible_user=admin +ansible_private_key_file=${SSH_KEY} +ansible_ssh_common_args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" +ansible_become=yes +ansible_become_method=sudo +ansible_become_pass=${EDGE_USER_PASSWORD} +EOF + +# Test IoT/Edge OS +sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${INSTALL_HASH}" -e fdo_credential="false" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 +check_result + ######################## ## ## Build upgrade image @@ -890,7 +1007,7 @@ ansible_become_pass=${EDGE_USER_PASSWORD} EOF # Test IoT/Edge OS -sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${UPGRADE_HASH}" -e fdo_credential="true" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 +sudo ansible-playbook -v -i "${TEMPDIR}"/inventory -e image_type=redhat -e ostree_commit="${UPGRADE_HASH}" -e fdo_credential="false" /usr/share/tests/osbuild-composer/ansible/check_ostree.yaml || RESULTS=0 check_result # Final success clean up