summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Tantsur <dtantsur@protonmail.com>2022-02-04 16:54:02 +0100
committerDmitry Tantsur <dtantsur@protonmail.com>2022-02-17 09:53:06 +0100
commitee76a3a05a24f1ca6ff28c7b60b0cee5e64e07b0 (patch)
tree4f615cc0f465a6ad4f202df54d3d4a4788017bcb
parent8a0b6384af815ae14f74f2851690e9cfffb46414 (diff)
downloadironic-ee76a3a05a24f1ca6ff28c7b60b0cee5e64e07b0.tar.gz
CI: use a custom cirros partition image instead of the default
Cirros partition images are not compatible with local boot since they don't ship grub (nor a normal root partition). This change adds a script that builds a partition image with UEFI artifacts present. It still cannot be booted in legacy mode, but it's a progress. Set the tempest plugin's partition_netboot option. We need it to inform the tempest plugin about the ability to do local boot. This option already exists but is never set. Also set the new default_boot_option parameter, which will be introduced and used in Iaba563a2ecbca029889bc6894b2a7f0754d27b88. Remove netboot from most of the UEFI jobs. Conflicts: devstack/files/bindep.txt zuul.d/ironic-jobs.yaml Change-Id: I15189e7f5928126c6b336b1416ce6408a4950062 (cherry picked from commit bbceca562e0b552cd2fc33b2833931ab3cbbfce5)
-rw-r--r--bindep.txt6
-rw-r--r--devstack/files/debs/ironic1
-rw-r--r--devstack/files/rpms/ironic1
-rw-r--r--devstack/lib/ironic49
-rwxr-xr-xdevstack/tools/ironic/scripts/cirros-partition.sh69
-rw-r--r--zuul.d/ironic-jobs.yaml5
6 files changed, 128 insertions, 3 deletions
diff --git a/bindep.txt b/bindep.txt
index 116fe5a2c..39a68265e 100644
--- a/bindep.txt
+++ b/bindep.txt
@@ -84,9 +84,13 @@ apparmor [platform:dpkg imagebuild]
gnupg [imagebuild]
squashfs-tools [platform:dpkg platform:redhat imagebuild]
squashfs [platform:suse imagebuild]
+# For custom partition images
+kpartx [devstack]
libguestfs0 [platform:dpkg imagebuild]
-libguestfs [platform:rpm imagebuild]
+libguestfs [platform:rpm imagebuild devstack]
+libguestfs-tools [platform:dpkg devstack]
python-guestfs [platform:dpkg imagebuild]
+qemu-img [platform:rpm devstack]
# for TinyIPA build
wget [imagebuild]
python-pip [imagebuild]
diff --git a/devstack/files/debs/ironic b/devstack/files/debs/ironic
index 49b0689d7..455bf0dfe 100644
--- a/devstack/files/debs/ironic
+++ b/devstack/files/debs/ironic
@@ -17,6 +17,7 @@ ipxe
ipxe-qemu
isolinux
jq
+kpartx
libguestfs-tools
libguestfs0
libvirt-bin # dist:bionic
diff --git a/devstack/files/rpms/ironic b/devstack/files/rpms/ironic
index 469f7fe6b..41847aade 100644
--- a/devstack/files/rpms/ironic
+++ b/devstack/files/rpms/ironic
@@ -3,6 +3,7 @@ ipmitool
iptables
ipxe-bootimgs
gnupg
+kpartx
libguestfs
libguestfs-tools
libvirt
diff --git a/devstack/lib/ironic b/devstack/lib/ironic
index 1f1c746bd..37aa39abc 100644
--- a/devstack/lib/ironic
+++ b/devstack/lib/ironic
@@ -2832,6 +2832,44 @@ function build_ipa_dib_ramdisk {
rm -rf $tempdir
}
+function upload_image_if_needed {
+ if [[ "$IRONIC_PARTITIONED_IMAGE_NAME" =~ cirros ]] \
+ && [[ "$IRONIC_DEFAULT_BOOT_OPTION" == local ]] \
+ && is_service_enabled glance; then
+ echo Building a Cirros image suitable for local boot
+
+ local dest
+ IRONIC_PARTITIONED_IMAGE_NAME=cirros-${CIRROS_VERSION}-x86_64-partition
+ dest="$IRONIC_DATA_DIR/$IRONIC_PARTITIONED_IMAGE_NAME.img"
+
+ # Export some variables that the script is using.
+ CIRROS_ARCH=$CIRROS_ARCH CIRROS_VERSION=$CIRROS_VERSION \
+ IRONIC_TTY_DEV=$IRONIC_TTY_DEV VERBOSE=$VERBOSE \
+ $IRONIC_SCRIPTS_DIR/cirros-partition.sh "$dest"
+
+ # TODO(dtantsur): stop uploading kernel/ramdisk when image_type support
+ # lands.
+ local kernel_id
+ kernel_id=$(openstack image list -f value -c ID -c Name \
+ | awk '/cirros.*kernel/ { print $1; exit 0; }')
+ die_if_not_set $LINENO kernel_id "Cannot find cirros kernel"
+
+ local ramdisk_id
+ ramdisk_id=$(openstack image list -f value -c ID -c Name \
+ | awk '/cirros.*ramdisk/ { print $1; exit 0; }')
+ die_if_not_set $LINENO ramdisk_id "Cannot find cirros ramdisk"
+
+ openstack image create $IRONIC_PARTITIONED_IMAGE_NAME \
+ --public --disk-format raw --container-format bare \
+ --property kernel_id=$kernel_id --property ramdisk_id=$ramdisk_id \
+ --file "$dest"
+
+ if [[ "$IRONIC_TEMPEST_WHOLE_DISK_IMAGE" != True ]]; then
+ IRONIC_IMAGE_NAME=$IRONIC_PARTITIONED_IMAGE_NAME
+ fi
+ fi
+}
+
# download EFI boot loader image and upload it to glance
# this function sets ``IRONIC_EFIBOOT_ID``
function upload_baremetal_ironic_efiboot {
@@ -3010,6 +3048,8 @@ function prepare_baremetal_basic_ops {
upload_baremetal_ironic_efiboot
fi
+ upload_image_if_needed
+
configure_tftpd
configure_iptables
}
@@ -3132,6 +3172,13 @@ function ironic_configure_tempest {
iniset $TEMPEST_CONFIG baremetal partition_image_ref $image_uuid
fi
+ # Our cirros images cannot do local boot in legacy mode.
+ if [[ "${IRONIC_PARTITIONED_IMAGE_NAME}" =~ cirros && "${IRONIC_BOOT_MODE}" == "bios" ]]; then
+ iniset $TEMPEST_CONFIG baremetal partition_netboot True
+ else
+ iniset $TEMPEST_CONFIG baremetal partition_netboot False
+ fi
+
if [[ "$IRONIC_IP_VERSION" == "6" ]]; then
iniset $TEMPEST_CONFIG baremetal whole_disk_image_url "http://$IRONIC_HOST_IPV6:$IRONIC_HTTP_PORT/${IRONIC_WHOLEDISK_IMAGE_NAME}.img"
else
@@ -3154,6 +3201,8 @@ function ironic_configure_tempest {
# Driver for API tests
iniset $TEMPEST_CONFIG baremetal driver fake-hardware
+ iniset $TEMPEST_CONFIG baremetal default_boot_option $IRONIC_DEFAULT_BOOT_OPTION
+
local adjusted_root_disk_size_gb
if [[ "$IRONIC_IS_HARDWARE" == "False" ]]; then
adjusted_root_disk_size_gb=$(( ${IRONIC_VM_SPECS_DISK} - ${IRONIC_VM_EPHEMERAL_DISK} ))
diff --git a/devstack/tools/ironic/scripts/cirros-partition.sh b/devstack/tools/ironic/scripts/cirros-partition.sh
new file mode 100755
index 000000000..40c87b19e
--- /dev/null
+++ b/devstack/tools/ironic/scripts/cirros-partition.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+set -eu -o pipefail
+
+VERBOSE=${VERBOSE:-True}
+if [[ "$VERBOSE" == True ]]; then
+ set -x
+ guestfish_args="--verbose"
+fi
+
+CIRROS_VERSION=${CIRROS_VERSION:-0.5.2}
+CIRROS_ARCH=${CIRROS_ARCH:-x86_64}
+# TODO(dtantsur): use the image cached on infra images in the CI
+DISK_URL=http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-disk.img
+OUT=$(realpath ${1:-rootfs.img})
+
+IRONIC_TTY_DEV=${IRONIC_TTY_DEV:-ttyS0,115200}
+# rdroot : boot from the ramdisk present on the root partition instead of
+# mounting the root partition.
+# dslist : disable Nova metadata support, it takes a long time on boot.
+KARGS=${KARGS:-nofb nomodeset vga=normal console=${IRONIC_TTY_DEV} rdroot dslist=configdrive}
+
+workdir=$(mktemp -d)
+root_mp=$workdir/root
+efi_mp=$workdir/efi
+dest=$workdir/dest
+
+cd $workdir
+
+curl -Lf -o disk.qcow2 $DISK_URL
+qemu-img convert -O raw disk.qcow2 disk.img
+rm disk.qcow2
+
+# kpartx automatically allocates loop devices for all partitions in the image
+device=$(sudo kpartx -av disk.img | grep -oE 'loop[0-9]+p' | head -1)
+
+function clean_up {
+ set +e
+ sudo umount $efi_mp
+ sudo umount $root_mp
+ sudo kpartx -d $workdir/disk.img
+ sudo rm -rf $workdir
+}
+trap clean_up EXIT
+
+# TODO(dtantsur): some logic instead of hardcoding numbers 1 and 15?
+rootdev=/dev/mapper/${device}1
+efidev=/dev/mapper/${device}15
+
+mkdir -p $root_mp $efi_mp $dest/boot/efi
+sudo mount $rootdev $root_mp
+sudo mount $efidev $efi_mp
+
+sudo cp -aR $root_mp/* $dest/
+sudo cp -aR $efi_mp/EFI $dest/boot/efi/
+
+# These locations are required by IPA even when it does not really run
+# grub-install.
+sudo mkdir -p $dest/{dev,proc,run,sys}
+
+# The default arguments don't work for us, update grub configuration.
+sudo sed -i "/^ *linux /s/\$/ $KARGS/" $dest/boot/efi/EFI/ubuntu/grub.cfg
+
+LIBGUESTFS_BACKEND=direct sudo -E \
+ virt-make-fs --size +50M --type ext3 --label cirros-rootfs \
+ ${guestfish_args:-} "$dest" "$OUT"
+
+sudo chown $USER "$OUT"
+qemu-img info "$OUT"
diff --git a/zuul.d/ironic-jobs.yaml b/zuul.d/ironic-jobs.yaml
index 7dd9320d2..01391ef96 100644
--- a/zuul.d/ironic-jobs.yaml
+++ b/zuul.d/ironic-jobs.yaml
@@ -236,6 +236,7 @@
vars:
devstack_localrc:
IRONIC_BOOT_MODE: uefi
+ IRONIC_DEFAULT_BOOT_OPTION: local
IRONIC_ENABLED_BOOT_INTERFACES: redfish-virtual-media
SWIFT_ENABLE_TEMPURLS: True
SWIFT_TEMPURL_KEY: secretkey
@@ -262,6 +263,7 @@
tempest_test_regex: test_baremetal_introspection
devstack_localrc:
IRONIC_BOOT_MODE: bios
+ IRONIC_DEFAULT_BOOT_OPTION: netboot
IRONIC_INSPECTOR_MANAGED_BOOT: True
IRONIC_INSPECTOR_NODE_NOT_FOUND_HOOK: ''
IRONIC_AUTOMATED_CLEAN_ENABLED: False
@@ -329,7 +331,6 @@
IRONIC_BOOT_MODE: uefi
IRONIC_VM_SPECS_RAM: 4096
IRONIC_AUTOMATED_CLEAN_ENABLED: False
- IRONIC_DEFAULT_BOOT_OPTION: netboot
- job:
name: ironic-tempest-ipa-partition-pxe_ipmitool
@@ -337,6 +338,7 @@
parent: ironic-base
vars:
devstack_localrc:
+ IRONIC_BOOT_MODE: bios
IRONIC_DEFAULT_BOOT_OPTION: netboot
IRONIC_AUTOMATED_CLEAN_ENABLED: True
@@ -662,7 +664,6 @@
IRONIC_BOOT_MODE: uefi
IRONIC_RAMDISK_TYPE: tinyipa
IRONIC_AUTOMATED_CLEAN_ENABLED: False
- IRONIC_DEFAULT_BOOT_OPTION: netboot
IRONIC_VM_SPECS_RAM: 4096
- job: