diff --git a/devstack/common_settings b/devstack/common_settings index 8d5660c4df..82eaf6968f 100644 --- a/devstack/common_settings +++ b/devstack/common_settings @@ -35,8 +35,13 @@ function add_image_link { # Do not restrict downloading image only for specific case. Download both disk and uec images. # NOTE (vdrok): Here the images are actually pre-cached by devstack, in # the files folder, so they won't be downloaded again. -add_image_link http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz -add_image_link http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-disk.img +if [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + add_image_link http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-aarch64-uec.tar.gz + add_image_link http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-aarch64-disk.img +else + add_image_link http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz + add_image_link http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-disk.img +fi export IRONIC_WHOLEDISK_IMAGE_NAME=${IRONIC_WHOLEDISK_IMAGE_NAME:-${IRONIC_IMAGE_NAME/-uec/-disk}} export IRONIC_PARTITIONED_IMAGE_NAME=${IRONIC_PARTITIONED_IMAGE_NAME:-${IRONIC_IMAGE_NAME/-disk/-uec}} diff --git a/devstack/lib/ironic b/devstack/lib/ironic index 65ea02621d..520a11c61c 100644 --- a/devstack/lib/ironic +++ b/devstack/lib/ironic @@ -74,6 +74,7 @@ IRONIC_STATE_PATH=/var/lib/ironic IRONIC_AUTH_CACHE_DIR=${IRONIC_AUTH_CACHE_DIR:-/var/cache/ironic} IRONIC_CONF_DIR=${IRONIC_CONF_DIR:-/etc/ironic} IRONIC_CONF_FILE=$IRONIC_CONF_DIR/ironic.conf +IRONIC_MACHINE_TYPE=${IRONIC_MACHINE_TYPE:-q35} # Deploy Ironic API under uwsgi (NOT mod_wsgi) server. # Devstack aims to remove mod_wsgi support, so ironic shouldn't use it too. # If set to False that will fall back to use the eventlet server that @@ -109,8 +110,22 @@ IRONIC_HW_NODE_CPU=${IRONIC_HW_NODE_CPU:-1} IRONIC_HW_NODE_RAM=${IRONIC_HW_NODE_RAM:-512} IRONIC_HW_NODE_DISK=${IRONIC_HW_NODE_DISK:-10} IRONIC_HW_EPHEMERAL_DISK=${IRONIC_HW_EPHEMERAL_DISK:-0} + +# Ironic hardware architecture type, supported types are: +IRONIC_SUPPORTED_HW_ARCH_TYPES_RE="^(x86_64|aarch64)$" IRONIC_HW_ARCH=${IRONIC_HW_ARCH:-x86_64} +if [[ ! "$IRONIC_HW_ARCH" =~ $IRONIC_SUPPORTED_HW_ARCH_TYPES_RE ]]; then + die $LINENO "Unsupported IRONIC_HW_ARCH: $IRONIC_HW_ARCH. Expected either of 'x86_64' or 'aarch64'." +fi + +IRONIC_VM_EMULATOR="/usr/bin/qemu-system-${IRONIC_HW_ARCH}" + +GRUB_ARCH=x64 +if [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + GRUB_ARCH=aa64 +fi + # Deploy Ironic Nodes & configure n-cpu for sharding # Currently only supports 0 (old behavior) or 1 (adds all nodes # to the same shard). You can still use this with multinode to @@ -151,11 +166,9 @@ IRONIC_TFTP_BLOCKSIZE=${IRONIC_TFTP_BLOCKSIZE:-$((PUBLIC_BRIDGE_MTU-50))} IRONIC_VM_COUNT=${IRONIC_VM_COUNT:-1} IRONIC_VM_SPECS_CPU=${IRONIC_VM_SPECS_CPU:-1} IRONIC_VM_SPECS_RAM=${IRONIC_VM_SPECS_RAM:-3072} -IRONIC_VM_SPECS_CPU_ARCH=${IRONIC_VM_SPECS_CPU_ARCH:-'x86_64'} IRONIC_VM_SPECS_DISK=${IRONIC_VM_SPECS_DISK:-10} IRONIC_VM_SPECS_DISK_FORMAT=${IRONIC_VM_SPECS_DISK_FORMAT:-qcow2} IRONIC_VM_EPHEMERAL_DISK=${IRONIC_VM_EPHEMERAL_DISK:-0} -IRONIC_VM_EMULATOR=${IRONIC_VM_EMULATOR:-'/usr/bin/qemu-system-x86_64'} IRONIC_VM_ENGINE=${IRONIC_VM_ENGINE:-qemu} IRONIC_VM_NETWORK_BRIDGE=${IRONIC_VM_NETWORK_BRIDGE:-brbm} IRONIC_VM_INTERFACE_COUNT=${IRONIC_VM_INTERFACE_COUNT:-2} @@ -259,9 +272,6 @@ if [[ "$IRONIC_VM_ENGINE" == "auto" ]]; then if [ ! -e /dev/kvm ]; then echo "WARNING: Switching to QEMU" IRONIC_VM_ENGINE=qemu - if [[ -z "$IRONIC_VM_EMULATOR" ]]; then - IRONIC_VM_EMULATOR='/usr/bin/qemu-system-x86_64' - fi else IRONIC_VM_ENGINE=kvm fi @@ -299,10 +309,12 @@ fi # NOTE(TheJulia): If we ever run any arm64, we will need to consider doing # the same. Nested virt is not a thing there. # Prevent a case that will likely result in a failure. -if [[ "$hostdomain" =~ "rax" ]] || [[ "$hostdomain" =~ "iweb" ]] || ! $(grep -q vmx /proc/cpuinfo) ; then - if [[ "$IRONIC_RAMDISK_TYPE" == "dib" ]]; then - echo "** WARNING ** - DIB based IPA images have been defined, however we are running devstack on an environment which does not support nested VMs. Due to virtualization constraints, we are automatically falling back to TinyIPA to ensure CI job passage." - IRONIC_RAMDISK_TYPE="tinyipa" +if [[ $IRONIC_HW_ARCH != "aarch64" ]]; then + if [[ "$hostdomain" =~ "rax" ]] || [[ "$hostdomain" =~ "iweb" ]] || ! $(grep -q vmx /proc/cpuinfo) ; then + if [[ "$IRONIC_RAMDISK_TYPE" == "dib" ]]; then + echo "** WARNING ** - DIB based IPA images have been defined, however we are running devstack on an environment which does not support nested VMs. Due to virtualization constraints, we are automatically falling back to TinyIPA to ensure CI job passage." + IRONIC_RAMDISK_TYPE="tinyipa" + fi fi fi @@ -327,6 +339,11 @@ IRONIC_EFIBOOT=${IRONIC_EFIBOOT:-$TOP_DIR/files/ir-deploy-$IRONIC_DEPLOY_DRIVER. IPA_DOWNLOAD_BRANCH=${IPA_DOWNLOAD_BRANCH:-${TARGET_BRANCH:-master}} IPA_DOWNLOAD_BRANCH=$(echo $IPA_DOWNLOAD_BRANCH | tr / -) +IPA_DOWNLOAD_SOURCE=ironic-python-agent +if [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + IPA_DOWNLOAD_SOURCE=ironic-python-agent-builder +fi + # OS for using with DIB images IRONIC_DIB_RAMDISK_OS=${IRONIC_DIB_RAMDISK_OS:-centos9} IRONIC_DIB_RAMDISK_RELEASE=${IRONIC_DIB_RAMDISK_RELEASE:-} @@ -347,8 +364,8 @@ if [[ "$IRONIC_BUILD_DEPLOY_RAMDISK" == "False" && \ IRONIC_AGENT_RAMDISK_FILE=ipa-${IRONIC_DIB_RAMDISK_OS}-${IPA_DOWNLOAD_BRANCH}.initramfs ;; esac - IRONIC_AGENT_KERNEL_URL=https://tarballs.openstack.org/ironic-python-agent/${IRONIC_RAMDISK_TYPE}/files/${IRONIC_AGENT_KERNEL_FILE} - IRONIC_AGENT_RAMDISK_URL=https://tarballs.openstack.org/ironic-python-agent/${IRONIC_RAMDISK_TYPE}/files/${IRONIC_AGENT_RAMDISK_FILE} + IRONIC_AGENT_KERNEL_URL=https://tarballs.openstack.org/${IPA_DOWNLOAD_SOURCE}/${IRONIC_RAMDISK_TYPE}/files/${IRONIC_AGENT_KERNEL_FILE} + IRONIC_AGENT_RAMDISK_URL=https://tarballs.openstack.org/${IPA_DOWNLOAD_SOURCE}/${IRONIC_RAMDISK_TYPE}/files/${IRONIC_AGENT_RAMDISK_FILE} fi # This refers the options for disk-image-create and the platform on which @@ -661,14 +678,25 @@ IRONIC_UEFI_FILES_DIR=${IRONIC_UEFI_FILES_DIR:-/var/lib/libvirt/images} UEFI_LOADER_PATH=$IRONIC_UEFI_FILES_DIR/OVMF_CODE.fd UEFI_NVRAM_PATH=$IRONIC_UEFI_FILES_DIR/OVMF_VARS.fd +if [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + UEFI_LOADER_PATH=$IRONIC_UEFI_FILES_DIR/AAVMF_CODE.fd + UEFI_NVRAM_PATH=$IRONIC_UEFI_FILES_DIR/AAVMF_VARS.fd +fi + # Handle architecture specific package installs +install_package shim shim-signed if [[ $IRONIC_HW_ARCH == "x86_64" ]]; then - install_package shim if is_ubuntu; then - install_package grub-efi-amd64-signed shim-signed + install_package grub-efi-amd64-signed elif is_fedora; then install_package grub2 grub2-efi fi +elif [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + if is_ubuntu; then + install_package qemu-system-arm qemu-efi qemu-efi-aarch64 + elif is_fedora; then + install_package grub2-arm64-efi + fi fi # Sanity checks @@ -681,14 +709,34 @@ if [[ "$IRONIC_BOOT_MODE" == "uefi" ]]; then die $LINENO "Boot mode UEFI only works in Ubuntu or Fedora for now." fi - if is_ubuntu && [[ -z $IRONIC_GRUB2_FILE ]]; then - IRONIC_GRUB2_SHIM_FILE=/usr/lib/shim/shimx64.efi.signed - IRONIC_GRUB2_FILE=/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed - IRONIC_GRUB2_NETWORK_FILE=/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed - elif is_fedora && [[ -z $IRONIC_GRUB2_FILE ]]; then - IRONIC_GRUB2_SHIM_FILE=/boot/efi/EFI/fedora/shimx64.efi - IRONIC_GRUB2_FILE=/boot/efi/EFI/fedora/grubx64.efi - IRONIC_GRUB2_NETWORK_FILE=/boot/efi/EFI/fedora/grubx64.efi + if is_ubuntu; then + if [[ $IRONIC_HW_ARCH == "x86_64" ]]; then + if [[ -z $IRONIC_GRUB2_FILE ]]; then + IRONIC_GRUB2_SHIM_FILE=/usr/lib/shim/shimx64.efi.signed + IRONIC_GRUB2_FILE=/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed + IRONIC_GRUB2_NETWORK_FILE=/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed + fi + elif [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + if [[ -z $IRONIC_GRUB2_FILE ]]; then + IRONIC_GRUB2_SHIM_FILE=/usr/lib/shim/shimaa64.efi.signed + IRONIC_GRUB2_FILE=/usr/lib/grub/arm64-efi-signed/grubaa64.efi.signed + IRONIC_GRUB2_NETWORK_FILE=/usr/lib/grub/arm64-efi-signed/grubnetaa64.efi.signed + fi + fi + elif is_fedora; then + if [[ $IRONIC_HW_ARCH == "x86_64" ]]; then + if [[ -z $IRONIC_GRUB2_FILE ]]; then + IRONIC_GRUB2_SHIM_FILE=/boot/efi/EFI/fedora/shimx64.efi + IRONIC_GRUB2_FILE=/boot/efi/EFI/fedora/grubx64.efi + IRONIC_GRUB2_NETWORK_FILE=/boot/efi/EFI/fedora/grubx64.efi + fi + elif [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + if [[ -z $IRONIC_GRUB2_FILE ]]; then + IRONIC_GRUB2_SHIM_FILE=/boot/efi/EFI/fedora/shimaa64.efi + IRONIC_GRUB2_FILE=/boot/efi/EFI/fedora/grubaa64.efi + IRONIC_GRUB2_NETWORK_FILE=/boot/efi/EFI/fedora/grubaa64.efi + fi + fi fi if [[ "$IRONIC_IPXE_ENABLED" == "False" ]]; then @@ -774,18 +822,34 @@ IRONIC_AGENT_IMAGE_DOWNLOAD_SOURCE=${IRONIC_AGENT_IMAGE_DOWNLOAD_SOURCE:-$IRONIC # UEFI related functions function get_uefi_loader { - if is_ubuntu; then - echo /usr/share/OVMF/OVMF_CODE.fd - elif is_fedora; then - echo /usr/share/edk2/ovmf/OVMF_CODE.fd + if [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + if is_ubuntu; then + echo /usr/share/AAVMF/AAVMF_CODE.fd + elif is_fedora; then + echo /usr/share/edk2/aarch64/QEMU_EFI.fd + fi + else + if is_ubuntu; then + echo /usr/share/OVMF/OVMF_CODE.fd + elif is_fedora; then + echo /usr/share/edk2/ovmf/OVMF_CODE.fd + fi fi } function get_uefi_nvram { - if is_ubuntu; then - echo /usr/share/OVMF/OVMF_VARS.fd - elif is_fedora; then - echo /usr/share/edk2/ovmf/OVMF_VARS.fd + if [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + if is_ubuntu; then + echo /usr/share/AAVMF/AAVMF_VARS.fd + elif is_fedora; then + echo /usr/share/edk2/aarch64/QEMU_VARS.fd + fi + else + if is_ubuntu; then + echo /usr/share/OVMF/OVMF_VARS.fd + elif is_fedora; then + echo /usr/share/edk2/ovmf/OVMF_VARS.fd + fi fi } @@ -1097,13 +1161,15 @@ function configure_redfish { mkdir -p $(dirname $IRONIC_REDFISH_EMULATOR_CONFIG) fi + local ironic_node_arch=$IRONIC_HW_ARCH + cat - < $IRONIC_REDFISH_EMULATOR_CONFIG SUSHY_EMULATOR_BOOT_LOADER_MAP = { 'UEFI': { - 'x86_64': '$UEFI_LOADER_PATH' + '$ironic_node_arch': '$UEFI_LOADER_PATH' }, 'Legacy': { - 'x86_64': None + '$ironic_node_arch': None } } SUSHY_EMULATOR_FEATURE_SET = "$IRONIC_REDFISH_EMULATOR_FEATURE_SET" @@ -1271,26 +1337,54 @@ function configure_ironic_dirs { # pre-package such loader files. if [[ "$IRONIC_BOOT_MODE" == "uefi" ]]; then if is_ubuntu; then - # NOTE(TheJulia): This is done separately here as this allows - # the script to have hirtuse/bionic compatibility. - if [[ -f /usr/lib/ipxe/snponly.efi ]]; then - update_loader_copy_paths snponly.efi:/usr/lib/ipxe/snponly.efi - elif [[ -f /usr/lib/ipxe/ipxe.efi ]]; then - update_loader_copy_paths snponly.efi:/usr/lib/ipxe/ipxe.efi + if [[ $IRONIC_HW_ARCH == "x86_64" ]]; then + # NOTE(TheJulia): This is done separately here as this allows + # the script to have hirtuse/bionic compatibility. + if [[ -f /usr/lib/ipxe/snponly.efi ]]; then + update_loader_copy_paths snponly.efi:/usr/lib/ipxe/snponly.efi + elif [[ -f /usr/lib/ipxe/ipxe.efi ]]; then + update_loader_copy_paths snponly.efi:/usr/lib/ipxe/ipxe.efi + fi + elif [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + # NOTE(cid): Ensure ARM-specific binaries are prepared if they don't already exist + if [[ ! -f /usr/lib/ipxe/arm/snponly.efi ]]; then + sudo mkdir -p /usr/lib/ipxe/arm + sudo wget -O /usr/lib/ipxe/arm/snponly.efi http://boot.ipxe.org/arm64-efi/snponly.efi + fi + if [[ -f /usr/lib/ipxe/arm/snponly.efi ]]; then + update_loader_copy_paths snponly.efi:/usr/lib/ipxe/arm/snponly.efi + elif [[ -f /usr/lib/ipxe/arm/ipxe.efi ]]; then + update_loader_copy_paths snponly.efi:/usr/lib/ipxe/arm/ipxe.efi + fi fi fi + if is_fedora; then - if [ -f /usr/share/ipxe/ipxe-snponly-x86_64.efi ]; then - # NOTE(TheJulia): I think this file got renamed at some - # point during it's centos8 run, but this is current. - update_loader_copy_paths snponly.efi:/usr/share/ipxe/ipxe-snponly-x86_64.efi + if [[ $IRONIC_HW_ARCH == "x86_64" ]]; then + if [[ -f /usr/share/ipxe/ipxe-snponly-x86_64.efi ]]; then + # NOTE(TheJulia): I think this file got renamed at some + # point during its centos8 run, but this is current. + update_loader_copy_paths snponly.efi:/usr/share/ipxe/ipxe-snponly-x86_64.efi + fi + elif [[ $IRONIC_HW_ARCH == "aarch64" ]]; then + if [[ -f /usr/share/ipxe/arm/ipxe-snponly-aarch64.efi ]]; then + update_loader_copy_paths snponly.efi:/usr/share/ipxe/arm/ipxe-snponly-aarch64.efi + fi fi fi - if [ -f $IRONIC_GRUB2_SHIM_FILE ]; then - update_loader_copy_paths "bootx64.efi:$IRONIC_GRUB2_SHIM_FILE" - fi - if [ -f $IRONIC_GRUB2_SHIM_FILE ]; then - update_loader_copy_paths "grubx64.efi:$IRONIC_GRUB2_NETWORK_FILE" + + if [[ "$IRONIC_HW_ARCH" == "aarch64" ]]; then + if [ -f $IRONIC_GRUB2_SHIM_FILE ]; then + update_loader_copy_paths "bootaa64.efi:$IRONIC_GRUB2_SHIM_FILE" + update_loader_copy_paths "grubaa64.efi:$IRONIC_GRUB2_FILE" + fi + else + if [ -f $IRONIC_GRUB2_SHIM_FILE ]; then + update_loader_copy_paths "bootx64.efi:$IRONIC_GRUB2_SHIM_FILE" + fi + if [ -f $IRONIC_GRUB2_SHIM_FILE ]; then + update_loader_copy_paths "grubx64.efi:$IRONIC_GRUB2_NETWORK_FILE" + fi fi else if [[ -f /usr/lib/ipxe/undionly.kpxe ]]; then @@ -2176,9 +2270,10 @@ function create_bridge_and_vms { newgrp $LIBVIRT_GROUP <> $IRONIC_VM_MACS_CSV_FILE + -v $IRONIC_VM_VOLUME_COUNT -P $LIBVIRT_STORAGE_POOL \ + -t $IRONIC_MACHINE_TYPE >> $IRONIC_VM_MACS_CSV_FILE SUBSHELL if is_deployed_by_ipmi; then @@ -2438,7 +2533,7 @@ function enroll_nodes { local ironic_node_ram=$IRONIC_VM_SPECS_RAM local ironic_node_disk=$IRONIC_VM_SPECS_DISK local ironic_ephemeral_disk=$IRONIC_VM_EPHEMERAL_DISK - local ironic_node_arch=x86_64 + local ironic_node_arch=$IRONIC_HW_ARCH if [[ ! -f $IRONIC_VM_MACS_CSV_FILE ]]; then touch $IRONIC_VM_MACS_CSV_FILE fi @@ -2947,7 +3042,8 @@ function upload_image_if_needed { echo Building a Cirros image suitable for local boot local dest - IRONIC_PARTITIONED_IMAGE_NAME=cirros-${CIRROS_VERSION}-x86_64-partition + IRONIC_PARTITIONED_IMAGE_NAME=cirros-${CIRROS_VERSION}-${IRONIC_HW_ARCH}-partition + dest="$IRONIC_DATA_DIR/$IRONIC_PARTITIONED_IMAGE_NAME.img" # Export some variables that the script is using. @@ -3012,14 +3108,14 @@ function upload_baremetal_ironic_efiboot { sudo mkdir -p $efiboot_mount/efi/boot if [[ "$IRONIC_GRUB2_SHIM_FILE" =~ "http".* ]]; then - sudo wget "$IRONIC_GRUB2_SHIM_FILE" -O $efiboot_mount/efi/boot/bootx64.efi + sudo wget "$IRONIC_GRUB2_SHIM_FILE" -O $efiboot_mount/efi/boot/boot${GRUB_ARCH}.efi else - sudo cp "$IRONIC_GRUB2_SHIM_FILE" $efiboot_mount/efi/boot/bootx64.efi + sudo cp "$IRONIC_GRUB2_SHIM_FILE" $efiboot_mount/efi/boot/boot${GRUB_ARCH}.efi fi if [[ "$IRONIC_GRUB2_FILE" =~ "http".* ]]; then - sudo wget "$IRONIC_GRUB2_FILE" -O $efiboot_mount/efi/boot/grubx64.efi + sudo wget "$IRONIC_GRUB2_FILE" -O $efiboot_mount/efi/boot/grub${GRUB_ARCH}.efi else - sudo cp "$IRONIC_GRUB2_FILE" $efiboot_mount/efi/boot/grubx64.efi + sudo cp "$IRONIC_GRUB2_FILE" $efiboot_mount/efi/boot/grub${GRUB_ARCH}.efi fi sudo umount $efiboot_mount diff --git a/devstack/tools/ironic/scripts/configure-vm.py b/devstack/tools/ironic/scripts/configure-vm.py index d9a426f15c..dee17b886f 100755 --- a/devstack/tools/ironic/scripts/configure-vm.py +++ b/devstack/tools/ironic/scripts/configure-vm.py @@ -49,7 +49,7 @@ CONSOLE_PTY = """ - + """ @@ -136,6 +136,7 @@ def main(): params['console'] = CONSOLE_LOG % {'console_log': args.console_log} else: params['console'] = CONSOLE_PTY + libvirt_template = template.render(**params) conn = libvirt.open("qemu:///system") diff --git a/devstack/tools/ironic/scripts/create-node.sh b/devstack/tools/ironic/scripts/create-node.sh index 15f1110f73..8530b846ff 100755 --- a/devstack/tools/ironic/scripts/create-node.sh +++ b/devstack/tools/ironic/scripts/create-node.sh @@ -12,7 +12,7 @@ export PS4='+ ${BASH_SOURCE:-}:${FUNCNAME[0]:-}:L${LINENO:-}: ' # Keep track of the DevStack directory TOP_DIR=$(cd $(dirname "$0")/.. && pwd) -while getopts "n:c:i:m:M:d:a:b:e:E:p:o:f:l:L:N:A:D:v:P:" arg; do +while getopts "n:c:i:m:M:d:a:b:e:E:p:o:f:l:L:N:A:D:v:P:t:" arg; do case $arg in n) NAME=$OPTARG;; c) CPU=$OPTARG;; @@ -36,6 +36,7 @@ while getopts "n:c:i:m:M:d:a:b:e:E:p:o:f:l:L:N:A:D:v:P:" arg; do D) NIC_DRIVER=$OPTARG;; v) VOLUME_COUNT=$OPTARG;; P) STORAGE_POOL=$OPTARG;; + t) MACHINE_TYPE=$OPTARG;; esac done @@ -123,11 +124,12 @@ if ! virsh list --all | grep -q $NAME; then if [[ -n "$EMULATOR" ]]; then vm_opts+="--emulator $EMULATOR " fi + $PYTHON $TOP_DIR/scripts/configure-vm.py \ --bootdev network --name $NAME \ --arch $ARCH --cpus $CPU --memory $MEM --libvirt-nic-driver $LIBVIRT_NIC_DRIVER \ --disk-format $DISK_FORMAT $VM_LOGGING --engine $ENGINE $UEFI_OPTS $vm_opts \ - --interface-count $INTERFACE_COUNT $MAC_ADDRESS >&2 + --interface-count $INTERFACE_COUNT $MAC_ADDRESS --machine_type $MACHINE_TYPE >&2 fi # echo mac in format mac1,ovs-node-0i1;mac2,ovs-node-0i2;...;macN,ovs-node0iN diff --git a/devstack/tools/ironic/templates/vm.xml b/devstack/tools/ironic/templates/vm.xml index feec6174c0..bd36e9f360 100644 --- a/devstack/tools/ironic/templates/vm.xml +++ b/devstack/tools/ironic/templates/vm.xml @@ -14,10 +14,19 @@ {% endif %} {% endif %} + {% if arch != 'aarch64' %} + {% endif %} - {% if engine == 'kvm' %} - + {% if engine == 'kvm' or arch == 'aarch64' %} + {% if engine == 'kvm' %} + + {% endif %} + {% if arch == 'aarch64' %} + + cortex-a53 + + {% endif %} {% else %} {% endif %} diff --git a/doc/source/contributor/arm-devstack-guide.rst b/doc/source/contributor/arm-devstack-guide.rst new file mode 100644 index 0000000000..de7d75a6cb --- /dev/null +++ b/doc/source/contributor/arm-devstack-guide.rst @@ -0,0 +1,105 @@ +===================================================== +Deploying Ironic on ARM64 with DevStack +===================================================== + +The instructions here are specifically on how to configure for +`Deploying Ironic with DevStack `_ +on an ARM64 architecture. + +.. _ARM64configurations: + +Configurations +============== + +Create devstack/local.conf with the following content:: + + cat >local.conf < + + # Credentials + ADMIN_PASSWORD=password + DATABASE_PASSWORD=password + RABBIT_PASSWORD=password + SERVICE_PASSWORD=password + SERVICE_TOKEN=password + + # Set glance's default limit to be baremetal image friendly + GLANCE_LIMIT_IMAGE_SIZE_TOTAL=5000 + + # Enable Ironic plugin + enable_plugin ironic https://opendev.org/openstack/ironic + + # Create a virtual machine to pose as Ironic's baremetal node. + IRONIC_VM_COUNT=1 + + # The parameters below represent the minimum possible values to create + # functional aarch64-based nodes. + IRONIC_VM_SPECS_RAM=4096 + IRONIC_VM_SPECS_DISK=3 + + IRONIC_VM_SPECS_CPU=1 + IRONIC_VM_VOLUME_COUNT=2 + + IRONIC_RPC_TRANSPORT=json-rpc + IRONIC_RAMDISK_TYPE=dib + + # Enable hardware types and interfaces. + IRONIC_ENABLED_HARDWARE_TYPES=redfish + IRONIC_ENABLED_MANAGEMENT_INTERFACES=redfish + IRONIC_DEFAULT_RESCUE_INTERFACE=agent + IRONIC_ENABLED_BOOT_INTERFACES="ipxe,redfish-virtual-media,http-ipxe,pxe,http" + IRONIC_ENABLED_DEPLOY_INTERFACES="direct,ramdisk" + IRONIC_ENABLED_RESCUE_INTERFACES="agent,no-rescue" + + # Specify deploy driver. This driver should be in the enabled list above. + IRONIC_DEPLOY_DRIVER=redfish + + CIRROS_VERSION=0.6.1 + CIRROS_ARCH=aarch64 + DEFAULT_IMAGE_NAME=cirros-0.6.1-aarch64-uec + + FORCE_CONFIG_DRIVE=False + + # aarch64 + IRONIC_BUILD_DEPLOY_RAMDISK will be a bad mix + IRONIC_BUILD_DEPLOY_RAMDISK=False + + IRONIC_AGENT_IMAGE_DOWNLOAD_SOURCE=http + IRONIC_AUTOMATED_CLEAN_ENABLED=False + IRONIC_BOOT_MODE=uefi + IRONIC_CALLBACK_TIMEOUT=800 + IRONIC_GRUB2_SHIM_FILE=https://mirror.stream.centos.org/9-stream/BaseOS/aarch64/os/EFI/BOOT/BOOTAA64.EFI + IRONIC_GRUB2_FILE=https://mirror.stream.centos.org/9-stream/BaseOS/aarch64/os/EFI/BOOT/grubaa64.efi + IRONIC_HW_ARCH=aarch64 + IRONIC_MACHINE_TYPE=virt-6.2 + IRONIC_JSON_RPC_AUTH_STRATEGY='http_basic' + IRONIC_DIB_RAMDISK_OS=debian-arm64 + + INSTALL_TEMPEST=False + VIRT_DRIVER=ironic + + # By default, DevStack creates a 10.0.0.0/24 network for instances. + # If this overlaps with the hosts network, you may adjust with the + # following. + IP_VERSION=4 + FIXED_RANGE=10.1.0.0/20 + IPV4_ADDRS_SAFE_TO_USE=10.1.0.0/20 + NETWORK_GATEWAY=10.1.0.1 + + Q_AGENT=openvswitch + Q_ML2_PLUGIN_MECHANISM_DRIVERS=openvswitch + Q_ML2_TENANT_NETWORK_TYPE=vxlan + + # Log all output to files + LOGFILE=/opt/stack/devstack.log + LOGDIR=/opt/stack/logs + IRONIC_VM_LOG_DIR=/opt/stack/ironic-bm-logs + + END + +This configuration sets up DevStack to work with ARM architecture hardware, +using aarch64 images and appropriate hardware types, interfaces, and settings. + +Refer to the `Ironic on Devstack setup guide `_ for more information on deploying Ironic with DevStack. diff --git a/doc/source/contributor/devstack-guide.rst b/doc/source/contributor/devstack-guide.rst index 9b6251224c..7e01fe8744 100644 --- a/doc/source/contributor/devstack-guide.rst +++ b/doc/source/contributor/devstack-guide.rst @@ -270,7 +270,7 @@ documentation: Ironic Boot from Volume Ironic w/Multitenant Networking - + Deploying Ironic on ARM64 architecture with DevStack Deploying to Ironic node using Nova =================================== diff --git a/zuul.d/ironic-jobs.yaml b/zuul.d/ironic-jobs.yaml index 692b7b9108..3c159d7995 100644 --- a/zuul.d/ironic-jobs.yaml +++ b/zuul.d/ironic-jobs.yaml @@ -101,6 +101,74 @@ s-object: False s-proxy: False +- job: + name: ironic-standalone-aarch64 + description: + Test ironic standalone configured with ipmi hardware type, ramdisk and + direct deploy interfaces, rescue enabled. + parent: ironic-base + irrelevant-files: + - ^.*\.rst$ + - ^api-ref/.*$ + - ^doc/.*$ + - ^install-guide/.*$ + - ^ironic/locale/.*$ + - ^ironic/tests/.*$ + - ^releasenotes/.*$ + - ^setup.cfg$ + - ^test-requirements.txt$ + - ^tools/.*$ + - ^tox.ini$ + vars: + tempest_test_regex: BaremetalDriverDirectWholedisk + tempest_concurrency: 2 + devstack_localrc: + CIRROS_VERSION: 0.6.1 + CIRROS_ARCH: aarch64 + DEFAULT_IMAGE_NAME: cirros-0.6.1-aarch64-uec + FORCE_CONFIG_DRIVE: False + IRONIC_AGENT_IMAGE_DOWNLOAD_SOURCE: http + IRONIC_AUTOMATED_CLEAN_ENABLED: False + IRONIC_BUILD_DEPLOY_RAMDISK: False + IRONIC_DEPLOY_DRIVER: redfish + IRONIC_DEFAULT_RESCUE_INTERFACE: agent + IRONIC_ENABLED_BOOT_INTERFACES: "ipxe,redfish-virtual-media,http-ipxe,pxe,http" + IRONIC_ENABLED_HARDWARE_TYPES: redfish + IRONIC_ENABLED_MANAGEMENT_INTERFACES: redfish + IRONIC_ENABLED_DEPLOY_INTERFACES: "direct,ramdisk" + IRONIC_ENABLED_RESCUE_INTERFACES: "agent,no-rescue" + IRONIC_BOOT_MODE: uefi + IRONIC_CALLBACK_TIMEOUT: 800 + IRONIC_GRUB2_SHIM_FILE: https://mirror.stream.centos.org/9-stream/BaseOS/aarch64/os/EFI/BOOT/BOOTAA64.EFI + IRONIC_GRUB2_FILE: https://mirror.stream.centos.org/9-stream/BaseOS/aarch64/os/EFI/BOOT/grubaa64.efi + IRONIC_HW_ARCH: aarch64 + IRONIC_MACHINE_TYPE: virt-6.2 + IRONIC_JSON_RPC_AUTH_STRATEGY: 'http_basic' + IRONIC_DIB_RAMDISK_OS: debian-arm64 + IRONIC_RAMDISK_TYPE: dib + IRONIC_RPC_TRANSPORT: json-rpc + IRONIC_VM_SPECS_RAM: 4096 + IRONIC_VM_SPECS_CPU: 1 + IRONIC_VM_COUNT: 1 + IRONIC_VM_VOLUME_COUNT: 2 + # We're using a lot of disk space in this job. Some testing nodes have + # a small root partition, so use /opt which is mounted from a bigger + # ephemeral partition on such nodes + LIBVIRT_STORAGE_POOL_PATH: /opt/libvirt/images + devstack_services: + n-api: False + n-api-meta: False + n-cond: False + n-cpu: False + n-novnc: False + n-sch: False + nova: False + placement-api: False + s-account: False + s-container: False + s-object: False + s-proxy: False + # NOTE(TheJulia): This job is being phased out as it ends up executing # the wholedisk standalone deploy, the partition standalone deploy, # software raid tests, and ramdisk iso boot tests. All of this while in diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index e6952770af..d8e281c22a 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -55,6 +55,8 @@ voting: false - ironic-inspector-tempest-uefi-redfish-vmedia: voting: false + - ironic-standalone-aarch64: + voting: false - ironic-tempest-ipa-wholedisk-bios-ipmi-direct-dib: voting: false - ironic-tempest-ipxe-ipv6: