From 8de574cd5867e6223f84cee2db65265ddf2f9bd891f6d0ef04c97c1fdc27c2ba Mon Sep 17 00:00:00 2001 From: Steven Hardy Date: Tue, 12 Nov 2024 18:31:53 +0000 Subject: [PATCH 1/4] baremetal-operator: update to 0.8.0 --- baremetal-operator/_service | 2 +- baremetal-operator/baremetal-operator.spec | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/baremetal-operator/_service b/baremetal-operator/_service index d9b32bb..2628004 100644 --- a/baremetal-operator/_service +++ b/baremetal-operator/_service @@ -2,7 +2,7 @@ https://github.com/metal3-io/baremetal-operator git - v0.6.1 + v0.8.0 _auto_ @PARENT_TAG@ enable diff --git a/baremetal-operator/baremetal-operator.spec b/baremetal-operator/baremetal-operator.spec index 58bb8bd..66c6108 100644 --- a/baremetal-operator/baremetal-operator.spec +++ b/baremetal-operator/baremetal-operator.spec @@ -17,14 +17,14 @@ Name: baremetal-operator -Version: 0.6.1 -Release: 0.6.1 +Version: 0.8.0 +Release: 0.8.0 Summary: Implements a Kubernetes API for managing bare metal hosts License: Apache-2.0 URL: https://github.com/metal3-io/baremetal-operator Source: baremetal-operator-%{version}.tar.gz Source1: vendor.tar.gz -BuildRequires: golang(API) = 1.21 +BuildRequires: golang(API) = 1.22 ExcludeArch: s390 ExcludeArch: %{ix86} -- 2.45.2 From 58c61b7a8a795c151fbb22660f03a58124a24a7da17442804da5bd702644ba23 Mon Sep 17 00:00:00 2001 From: Steven Hardy Date: Tue, 12 Nov 2024 18:34:16 +0000 Subject: [PATCH 2/4] ironic-ipa-ramdisk: add new/renamed package To align with isv:SUSE:Edge:Metal3:Ironic:2024.2 --- .obs/workflows.yml | 4 + ironic-ipa-ramdisk/_constraints | 8 + ironic-ipa-ramdisk/config.sh | 105 +++++++++++++ ironic-ipa-ramdisk/ironic-ipa-ramdisk.kiwi | 173 +++++++++++++++++++++ ironic-ipa-ramdisk/ironic-ipa-ramdisk.spec | 167 ++++++++++++++++++++ ironic-ipa-ramdisk/root.tar.bz2 | Bin 0 -> 3866 bytes 6 files changed, 457 insertions(+) create mode 100644 ironic-ipa-ramdisk/_constraints create mode 100644 ironic-ipa-ramdisk/config.sh create mode 100644 ironic-ipa-ramdisk/ironic-ipa-ramdisk.kiwi create mode 100644 ironic-ipa-ramdisk/ironic-ipa-ramdisk.spec create mode 100644 ironic-ipa-ramdisk/root.tar.bz2 diff --git a/.obs/workflows.yml b/.obs/workflows.yml index af2407f..8c923ad 100644 --- a/.obs/workflows.yml +++ b/.obs/workflows.yml @@ -230,3 +230,7 @@ staging_build: source_package: kube-rbac-proxy-image source_project: isv:SUSE:Edge:Factory target_project: isv:SUSE:Edge:Factory:Staging + - branch_package: + source_package: ironic-ipa-ramdisk + source_project: isv:SUSE:Edge:Factory + target_project: isv:SUSE:Edge:Factory:Staging diff --git a/ironic-ipa-ramdisk/_constraints b/ironic-ipa-ramdisk/_constraints new file mode 100644 index 0000000..19d0995 --- /dev/null +++ b/ironic-ipa-ramdisk/_constraints @@ -0,0 +1,8 @@ + + + 4 + + 12 + + + diff --git a/ironic-ipa-ramdisk/config.sh b/ironic-ipa-ramdisk/config.sh new file mode 100644 index 0000000..8285ba4 --- /dev/null +++ b/ironic-ipa-ramdisk/config.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +test -f /.kconfig && . /.kconfig +test -f /.profile && . /.profile + +#====================================== +# Greeting... +#-------------------------------------- +echo "Configure image: [$kiwi_iname]..." + +#========================================== +# setup build day +#------------------------------------------ +baseSetupBuildDay + +#====================================== +# Mount system filesystems +#-------------------------------------- +#baseMount + +#========================================== +# remove unneded kernel files +#------------------------------------------ +suseStripKernel +baseStripLocales en_US.utf-8 C.utf8 + +#====================================== +# Setup baseproduct link +#-------------------------------------- +suseSetupProduct + +#====================================== +# Add missing gpg keys to rpm +#-------------------------------------- +suseImportBuildKey + +#====================================== +# Activate services +#-------------------------------------- +baseInsertService openstack-ironic-python-agent +baseInsertService suse-ironic-image-setup +baseInsertService suse-network-setup +baseInsertService sshd +baseInsertService NetworkManager +#suseInsertService sshd +#suseInsertService openstack-ironic-python-agent +#suseInsertService suse-ironic-image-setup + +echo 'DEFAULT_TIMEZONE="UTC"' >> /etc/sysconfig/clock +baseUpdateSysConfig /etc/sysconfig/clock HWCLOCK "-u" +baseUpdateSysConfig /etc/sysconfig/clock TIMEZONE UTC +baseUpdateSysConfig /etc/sysconfig/network/dhcp DHCLIENT_SET_HOSTNAME no +baseUpdateSysConfig /etc/sysconfig/network/dhcp WRITE_HOSTNAME_TO_HOSTS no + +#========================================== +# generate autologin@ service +# based on getty@ service +#------------------------------------------ +#sed 's/^ExecStart=.*/\0 --autologin root/' /usr/lib/systemd/system/getty@.service > /etc/systemd/system/autologin\@.service +sed -E 's/^(ExecStart=.*\/agetty).*(--noclear.*)/\1 \2 --autologin root/' /usr/lib/systemd/system/getty@.service > /etc/systemd/system/autologin\@.service + +#========================================== +# add fstab entry for tmpfs based /tmp +#------------------------------------------ +echo 'tmpfs /tmp tmpfs size=3G 0 0' >> /etc/fstab + +#========================================== +# remove package docs and manuals +#------------------------------------------ +#baseStripDocs +#baseStripMans +#baseStripInfos + +#====================================== +# only basic version of vim is +# installed; no syntax highlighting +#-------------------------------------- +sed -i -e's/^syntax on/" syntax on/' /etc/vimrc + +#====================================== +# Remove yast if not in use +#-------------------------------------- +#suseRemoveYaST + +#====================================== +# Remove package manager +#-------------------------------------- +#suseStripPackager + +#rm -f usr/lib/perl5/*/*/auto/Encode/??/??.so # 9MB + +#====================================== +# Umount kernel filesystems +#-------------------------------------- +#baseCleanMount + +ln -s /sbin/init /init + +#========================================== +# umount +#------------------------------------------ +umount /proc >/dev/null 2>&1 + +exit 0 + diff --git a/ironic-ipa-ramdisk/ironic-ipa-ramdisk.kiwi b/ironic-ipa-ramdisk/ironic-ipa-ramdisk.kiwi new file mode 100644 index 0000000..315d4d0 --- /dev/null +++ b/ironic-ipa-ramdisk/ironic-ipa-ramdisk.kiwi @@ -0,0 +1,173 @@ + + + + Cloud developers + cloud-devel@suse.de + kernel and ramdisk image for metal3 + + + + + + en_US + zypper + false + UTC + 1.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ironic-ipa-ramdisk/ironic-ipa-ramdisk.spec b/ironic-ipa-ramdisk/ironic-ipa-ramdisk.spec new file mode 100644 index 0000000..2e4232a --- /dev/null +++ b/ironic-ipa-ramdisk/ironic-ipa-ramdisk.spec @@ -0,0 +1,167 @@ +# +# spec file for package openstack-ironic-image +# +# Copyright (c) 2023 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# +# needsrootforbuild +# needsbinariesforbuild + + +Name: ironic-ipa-ramdisk +Version: 3.0.0 +Release: 0 +Summary: Kernel and ramdisk image for OpenStack Ironic +License: SUSE-EULA +Group: System/Management +URL: https://github.com/SUSE-Cloud/ +Source0: config.sh +Source10: ironic-ipa-ramdisk.kiwi +Source20: root.tar.bz2 + +BuildRequires: -post-build-checks +BuildRequires: bash +BuildRequires: kiwi +BuildRequires: kiwi-tools +BuildRequires: zypper +BuildArch: noarch + +BuildRequires: checkmedia +BuildRequires: acl +BuildRequires: ca-certificates +BuildRequires: cracklib-dict-full +BuildRequires: cron +BuildRequires: dbus-1 +BuildRequires: elfutils +BuildRequires: filesystem +BuildRequires: fipscheck +BuildRequires: fontconfig +BuildRequires: fonts-config +BuildRequires: gptfdisk +BuildRequires: grub2 +BuildRequires: grub2-x86_64-efi +BuildRequires: haveged +BuildRequires: hdparm +BuildRequires: hwinfo +BuildRequires: ipmitool +BuildRequires: iproute2 +BuildRequires: iputils +BuildRequires: kernel-default +BuildRequires: kernel-firmware +BuildRequires: lvm2 +BuildRequires: net-tools +BuildRequires: ntp +BuildRequires: open-iscsi +BuildRequires: openssh +BuildRequires: openstack-ironic-python-agent +BuildRequires: pam-config +BuildRequires: parted +BuildRequires: patterns-base-minimal_base +BuildRequires: pinentry +BuildRequires: pkgconfig +BuildRequires: Mesa-gallium +BuildRequires: plymouth +BuildRequires: plymouth-scripts +BuildRequires: python311-proliantutils +BuildRequires: psmisc +BuildRequires: qemu-tools +BuildRequires: sg3_utils +BuildRequires: sles-release +BuildRequires: sudo +BuildRequires: suse-build-key +BuildRequires: systemd-presets-branding-SLE +BuildRequires: timezone +BuildRequires: udev +BuildRequires: vim +BuildRequires: wpa_supplicant +BuildRequires: dhcp-client +BuildRequires: which +BuildRequires: NetworkManager +BuildRequires: nm-configurator-030 +BuildRequires: logrotate +BuildRequires: plymouth-dracut +BuildRequires: plymouth-theme-bgrt +BuildRequires: dracut-kiwi-oem-dump +BuildRequires: dracut-kiwi-oem-repart +BuildRequires: gfxboot-branding-SLE +BuildRequires: grub2-branding-SLE +BuildRequires: open-iscsi +BuildRequires: plymouth-branding-SLE +BuildRequires: lshw +BuildRequires: kbd +%ifarch aarch64 +BuildRequires: dmidecode +BuildRequires: efibootmgr +%endif +%ifarch x86_64 +BuildRequires: dmidecode +BuildRequires: efibootmgr +BuildRequires: syslinux +%endif + +%description +Kernel and ramdisk image for use with Metal3 + +%package %{_arch} +Summary: Kernel and ramdisk image for Metal3 +Group: System/Management +Provides: openstack-ironic-python-agent = %{version} +Obsoletes: openstack-ironic-python-agent < %{version} + +%description %{_arch} +Kernel and ramdisk image for use with Metal3 +For %{_arch} + +%prep +mkdir -p /tmp/openstack-ironic-image/build /tmp/openstack-ironic-image/root /tmp/openstack-ironic-image/img + +cp -a %{SOURCE0} /tmp/openstack-ironic-image/config.sh + +cp -a %{SOURCE10} /tmp/openstack-ironic-image/config.kiwi + +tar -xC /tmp/openstack-ironic-image/root -f %{SOURCE20} + +%build +if ! which kiwi; then + cat <&2 +kiwi not found in \$PATH; most likely this build was missing +the --userootforbuild option. If you are invoking osc build +manually, please use 'make buildlocal' instead. +EOF + exit 1 +fi + +kiwi-ng --debug --profile default system build --description /tmp/openstack-ironic-image --target-dir /tmp/openstack-ironic-image/img + +%install +TDIR=`mktemp -d /tmp/openstack-ironic-image.XXXXX` +cd /tmp/openstack-ironic-image/img/build/image-root +find . | cpio --create --format=newc --quiet > $TDIR/initrdtmp +cd $TDIR +gzip -9 -f initrdtmp +INITRDGZ=`ls *.gz | head -1` +gzip -cd $INITRDGZ | xz --check=crc32 -c9 > initrd.xz +INITRD=`ls *.xz | head -1` + +ls /tmp/openstack-ironic-image/img/openstack-ironic-image* +KERNEL=`ls /tmp/openstack-ironic-image/img/openstack-ironic-image*default*kernel | head -1` + +mkdir -p %{buildroot}/srv/tftpboot/openstack-ironic-image +install -p -m 644 $KERNEL $INITRD %{buildroot}/srv/tftpboot/openstack-ironic-image/ + +%files %{_arch} +%defattr(644,root,root) +%dir %attr(755, root, root) /srv/tftpboot/openstack-ironic-image +%attr(644, root, root) /srv/tftpboot/openstack-ironic-image/* + +%changelog diff --git a/ironic-ipa-ramdisk/root.tar.bz2 b/ironic-ipa-ramdisk/root.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000000000000000000000000000..b7be89a56cef5e1a5db424f5919a5260afcfcdd1f963159fa6d1fc6067566dcd GIT binary patch literal 3866 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 c00RFPaz!{$koc*UBqHVjXaE2J literal 0 HcmV?d00001 -- 2.45.2 From 6a4b3388bd1f98ed7ee941f0fe4f1c859aae1ab707f42d1eb7633432b1948dcf Mon Sep 17 00:00:00 2001 From: Steven Hardy Date: Tue, 12 Nov 2024 18:38:59 +0000 Subject: [PATCH 3/4] ironic-ipa-downloader-image: Update to 3.0.0 Align with isv:SUSE:Edge:Metal3:Ironic:2024.2 --- ironic-ipa-downloader-image/Dockerfile | 10 +++++----- ironic-ipa-downloader-image/_service | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ironic-ipa-downloader-image/Dockerfile b/ironic-ipa-downloader-image/Dockerfile index 905d1d9..5470626 100644 --- a/ironic-ipa-downloader-image/Dockerfile +++ b/ironic-ipa-downloader-image/Dockerfile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:2.0.0 -#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:2.0.0-%RELEASE% +#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.0 +#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.0-%RELEASE% #!BuildVersion: 15.6 ARG SLE_VERSION FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro @@ -8,7 +8,7 @@ FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro FROM registry.suse.com/bci/bci-base:$SLE_VERSION AS base COPY --from=micro / /installroot/ RUN sed -i -e 's%^# rpm.install.excludedocs = no.*%rpm.install.excludedocs = yes%g' /etc/zypp/zypp.conf -RUN zypper --installroot /installroot --non-interactive install --no-recommends openstack-ironic-image-x86_64 python311-devel python311 python311-pip tar gawk git curl xz fakeroot shadow sed cpio; zypper -n clean; rm -rf /var/log/* +RUN zypper --installroot /installroot --non-interactive install --no-recommends ironic-ipa-ramdisk-x86_64 python311-devel python311 python311-pip tar gawk git curl xz fakeroot shadow sed cpio; zypper -n clean; rm -rf /var/log/* #RUN zypper --installroot /installroot --non-interactive install --no-recommends sles-release; RUN cp /usr/bin/getopt /installroot/ @@ -19,11 +19,11 @@ FROM micro AS final LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)" LABEL org.opencontainers.image.title="SLE Based Ironic IPA Downloader Container Image" LABEL org.opencontainers.image.description="ironic-ipa-downloader based on the SLE Base Container Image." -LABEL org.opencontainers.image.version="2.0.0" +LABEL org.opencontainers.image.version="3.0.0" LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/" LABEL org.opencontainers.image.created="%BUILDTIME%" LABEL org.opencontainers.image.vendor="SUSE LLC" -LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:2.0.0-%RELEASE%" +LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.0-%RELEASE%" LABEL org.openbuildservice.disturl="%DISTURL%" LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" LABEL com.suse.eula="SUSE Combined EULA February 2024" diff --git a/ironic-ipa-downloader-image/_service b/ironic-ipa-downloader-image/_service index ccbaa8e..c8d3f38 100644 --- a/ironic-ipa-downloader-image/_service +++ b/ironic-ipa-downloader-image/_service @@ -3,8 +3,8 @@ Dockerfile - %%openstack-ironic-image-x86_64_version%% - openstack-ironic-image-x86_64 + %%ironic-ipa-ramdisk-x86_64_version%% + ironic-ipa-ramdisk-x86_64 patch -- 2.45.2 From 024494ac1285ec4b498f6edec8422081616ff0bf501821a9169c2fb9f460a9b7 Mon Sep 17 00:00:00 2001 From: Steven Hardy Date: Tue, 12 Nov 2024 18:44:52 +0000 Subject: [PATCH 4/4] ironic-image: Update to 26.1.2.0 To align with isv:SUSE:Edge:Metal3:Ironic:2024.2 --- ironic-image/Dockerfile | 30 +++++----- ironic-image/apache2-ipxe.conf.j2 | 35 ++++++++++++ ironic-image/apache2-vmedia.conf.j2 | 20 ++++--- ironic-image/auth-common.sh | 46 ++++++--------- ironic-image/configure-ironic.sh | 57 ++++++++++++------- ironic-image/configure-nonroot.sh | 21 ++++--- ironic-image/dnsmasq.conf.j2 | 12 +++- ironic-image/httpd-ironic-api.conf.j2 | 25 --------- ironic-image/httpd-modules.conf | 1 - ironic-image/httpd.conf.j2 | 2 +- ironic-image/inspector.ipxe.j2 | 4 +- ironic-image/ipxe_config.template | 81 +++++++++++++++++++++++++++ ironic-image/ironic-common.sh | 25 ++++----- ironic-image/ironic-probe.j2 | 9 +++ ironic-image/ironic.conf.j2 | 78 ++++++++++---------------- ironic-image/rundnsmasq | 10 +++- ironic-image/runhttpd | 31 +++------- ironic-image/runironic | 4 +- ironic-image/runlogwatch.sh | 21 ++----- ironic-image/tls-common.sh | 54 +++++++++--------- 20 files changed, 320 insertions(+), 246 deletions(-) create mode 100644 ironic-image/apache2-ipxe.conf.j2 create mode 100644 ironic-image/ipxe_config.template create mode 100644 ironic-image/ironic-probe.j2 diff --git a/ironic-image/Dockerfile b/ironic-image/Dockerfile index d57ae3f..1a7f66c 100644 --- a/ironic-image/Dockerfile +++ b/ironic-image/Dockerfile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -#!BuildTag: %%IMG_PREFIX%%ironic:24.1.2.0 -#!BuildTag: %%IMG_PREFIX%%ironic:24.1.2.0-%RELEASE% +#!BuildTag: %%IMG_PREFIX%%ironic:26.1.2.0 +#!BuildTag: %%IMG_PREFIX%%ironic:26.1.2.0-%RELEASE% #!BuildVersion: 15.6 ARG SLE_VERSION @@ -16,7 +16,12 @@ RUN /bin/prepare-efi.sh COPY --from=micro / /installroot/ RUN sed -i -e 's%^# rpm.install.excludedocs = no.*%rpm.install.excludedocs = yes%g' /etc/zypp/zypp.conf -RUN zypper --installroot /installroot --non-interactive install --no-recommends python311-devel python311 python311-pip python-dracclient python311-sushy-oem-idrac python311-proliantutils python311-sushy python3-ironicclient git curl sles-release tar gzip vim gawk dnsmasq dosfstools apache2 apache2-mod_wsgi inotify-tools ipcalc ipmitool iproute2 procps qemu-tools sqlite3 util-linux xorriso tftp syslinux ipxe-bootimgs python311-sushy-tools crudini openstack-ironic openstack-ironic-inspector-api +RUN zypper --installroot /installroot --non-interactive install --no-recommends python311-devel python311 python311-pip python-dracclient python311-sushy-oem-idrac python311-proliantutils python311-sushy python3-ironicclient git curl sles-release tar gzip vim gawk dnsmasq dosfstools apache2 inotify-tools ipcalc ipmitool iproute2 procps qemu-tools sqlite3 util-linux xorriso tftp syslinux ipxe-bootimgs crudini openstack-ironic + +# DATABASE +RUN mkdir -p /installroot/var/lib/ironic && \ + /installroot/usr/bin/sqlite3 /installroot/var/lib/ironic/ironic.sqlite "pragma journal_mode=wal" && \ + zypper --installroot /installroot --non-interactive remove sqlite3 FROM micro AS final MAINTAINER SUSE LLC (https://www.suse.com/) @@ -26,8 +31,8 @@ LABEL org.opencontainers.image.description="Openstack Ironic based on the SLE Ba LABEL org.opencontainers.image.url="https://www.suse.com/products/server/" LABEL org.opencontainers.image.created="%BUILDTIME%" LABEL org.opencontainers.image.vendor="SUSE LLC" -LABEL org.opencontainers.image.version="24.1.2.0" -LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic:24.1.2.0-%RELEASE%" +LABEL org.opencontainers.image.version="26.1.2.0" +LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic:26.1.2.0-%RELEASE%" LABEL org.openbuildservice.disturl="%DISTURL%" LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" LABEL com.suse.eula="SUSE Combined EULA February 2024" @@ -48,8 +53,8 @@ RUN echo 'alias mkisofs="xorriso -as mkisofs"' >> ~/.bashrc COPY mkisofs_wrapper /usr/bin/mkisofs RUN set -euo pipefail; chmod +x /usr/bin/mkisofs -COPY auth-common.sh configure-ironic.sh ironic-common.sh rundnsmasq runhttpd runironic runironic-api runironic-conductor runironic-exporter runironic-inspector runlogwatch.sh tls-common.sh configure-nonroot.sh /bin/ -RUN set -euo pipefail; chmod +x /bin/auth-common.sh; chmod +x /bin/configure-ironic.sh; chmod +x /bin/ironic-common.sh; chmod +x /bin/rundnsmasq; chmod +x /bin/runhttpd; chmod +x /bin/runironic; chmod +x /bin/runironic-api; chmod +x /bin/runironic-conductor; chmod +x /bin/runironic-exporter; chmod +x /bin/runironic-inspector; chmod +x /bin/runlogwatch.sh; chmod +x /bin/tls-common.sh; chmod +x /bin/configure-nonroot.sh; +COPY auth-common.sh configure-ironic.sh ironic-common.sh rundnsmasq runhttpd runironic runlogwatch.sh tls-common.sh configure-nonroot.sh ironic-probe.j2 /bin/ +RUN set -euo pipefail; chmod +x /bin/auth-common.sh; chmod +x /bin/configure-ironic.sh; chmod +x /bin/ironic-common.sh; chmod +x /bin/rundnsmasq; chmod +x /bin/runhttpd; chmod +x /bin/runironic; chmod +x /bin/runlogwatch.sh; chmod +x /bin/tls-common.sh; chmod +x /bin/configure-nonroot.sh; RUN mkdir -p /tftpboot RUN mkdir -p $GRUB_DIR @@ -63,7 +68,7 @@ RUN cp /usr/share/ipxe/ipxe-x86_64.efi /tftpboot/ipxe.efi COPY --from=base /tmp/esp.img /tmp/uefi_esp.img COPY ironic.conf.j2 /etc/ironic/ -COPY inspector.ipxe.j2 httpd-ironic-api.conf.j2 /tmp/ +COPY inspector.ipxe.j2 httpd-ironic-api.conf.j2 ipxe_config.template /tmp/ COPY network-data-schema-empty.json /etc/ironic/ # DNSMASQ @@ -73,14 +78,7 @@ COPY dnsmasq.conf.j2 /etc/ COPY httpd.conf.j2 /etc/httpd/conf/ COPY httpd-modules.conf /etc/httpd/conf.modules.d/ COPY apache2-vmedia.conf.j2 /etc/httpd-vmedia.conf.j2 - -# IRONIC-INSPECTOR # -RUN mkdir -p /var/lib/ironic /var/lib/ironic-inspector && \ - sqlite3 /var/lib/ironic/ironic.db "pragma journal_mode=wal" && \ - sqlite3 /var/lib/ironic-inspector/ironic-inspector.db "pragma journal_mode=wal" - -COPY ironic-inspector.conf.j2 /etc/ironic-inspector/ -COPY inspector-apache.conf.j2 /etc/httpd/conf.d/ +COPY apache2-ipxe.conf.j2 /etc/httpd-ipxe.conf.j2 # Workaround # Removing the 010-ironic.conf file that comes with the package diff --git a/ironic-image/apache2-ipxe.conf.j2 b/ironic-image/apache2-ipxe.conf.j2 new file mode 100644 index 0000000..88959ff --- /dev/null +++ b/ironic-image/apache2-ipxe.conf.j2 @@ -0,0 +1,35 @@ +Listen {{ env.IPXE_TLS_PORT }} + + + ErrorLog /dev/stderr + LogLevel debug + CustomLog /dev/stdout combined + + SSLEngine on + SSLProtocol {{ env.IPXE_SSL_PROTOCOL }} + SSLCertificateFile {{ env.IPXE_CERT_FILE }} + SSLCertificateKeyFile {{ env.IPXE_KEY_FILE }} + + + Order Allow,Deny + Allow from all + + + Order Deny,Allow + Deny from all + + + + + SSLRequireSSL + + + SSLRequireSSL + + + SSLRequireSSL + + + SSLRequireSSL + + diff --git a/ironic-image/apache2-vmedia.conf.j2 b/ironic-image/apache2-vmedia.conf.j2 index 1d7ad21..aa1132e 100644 --- a/ironic-image/apache2-vmedia.conf.j2 +++ b/ironic-image/apache2-vmedia.conf.j2 @@ -9,16 +9,18 @@ Listen {{ env.VMEDIA_TLS_PORT }} SSLProtocol {{ env.IRONIC_VMEDIA_SSL_PROTOCOL }} SSLCertificateFile {{ env.IRONIC_VMEDIA_CERT_FILE }} SSLCertificateKeyFile {{ env.IRONIC_VMEDIA_KEY_FILE }} - - - AllowOverride None - Require all granted - - - Options Indexes FollowSymLinks - AllowOverride None - Require all granted + + Order deny,allow + deny from all + + + Order allow,deny + allow from all + + + Order allow,deny + allow from all diff --git a/ironic-image/auth-common.sh b/ironic-image/auth-common.sh index 9906776..cb6a548 100644 --- a/ironic-image/auth-common.sh +++ b/ironic-image/auth-common.sh @@ -2,36 +2,39 @@ set -euxo pipefail -export IRONIC_HTPASSWD=${IRONIC_HTPASSWD:-${HTTP_BASIC_HTPASSWD:-}} -export INSPECTOR_HTPASSWD=${INSPECTOR_HTPASSWD:-${HTTP_BASIC_HTPASSWD:-}} -export IRONIC_DEPLOYMENT="${IRONIC_DEPLOYMENT:-}" export IRONIC_REVERSE_PROXY_SETUP=${IRONIC_REVERSE_PROXY_SETUP:-false} -export INSPECTOR_REVERSE_PROXY_SETUP=${INSPECTOR_REVERSE_PROXY_SETUP:-false} + +# Backward compatibility +if [[ "${IRONIC_DEPLOYMENT:-}" == "Conductor" ]]; then + export IRONIC_EXPOSE_JSON_RPC=true +else + export IRONIC_EXPOSE_JSON_RPC="${IRONIC_EXPOSE_JSON_RPC:-false}" +fi IRONIC_HTPASSWD_FILE=/etc/ironic/htpasswd -INSPECTOR_HTPASSWD_FILE=/etc/ironic-inspector/htpasswd +if [[ -f "/auth/ironic/htpasswd" ]]; then + IRONIC_HTPASSWD=$( "${IRONIC_HTPASSWD_FILE}-rpc" - else - printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}" + if [[ "${IRONIC_EXPOSE_JSON_RPC}" == "true" ]]; then + if [[ -z "${IRONIC_HTPASSWD}" ]]; then + echo "FATAL: enabling JSON RPC requires authentication" + exit 1 fi + printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}-rpc" fi } @@ -48,24 +51,9 @@ configure_ironic_auth() fi } -configure_inspector_auth() -{ - local config=/etc/ironic-inspector/ironic-inspector.conf - if [[ -n "${INSPECTOR_HTPASSWD}" ]]; then - printf "%s\n" "${INSPECTOR_HTPASSWD}" > "${INSPECTOR_HTPASSWD_FILE}" - if [[ "${INSPECTOR_REVERSE_PROXY_SETUP}" == "false" ]]; then - crudini --set "${config}" DEFAULT auth_strategy http_basic - crudini --set "${config}" DEFAULT http_basic_auth_user_file "${INSPECTOR_HTPASSWD_FILE}" - fi - fi -} - write_htpasswd_files() { if [[ -n "${IRONIC_HTPASSWD:-}" ]]; then printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}" fi - if [[ -n "${INSPECTOR_HTPASSWD:-}" ]]; then - printf "%s\n" "${INSPECTOR_HTPASSWD}" > "${INSPECTOR_HTPASSWD_FILE}" - fi } diff --git a/ironic-image/configure-ironic.sh b/ironic-image/configure-ironic.sh index fa07f43..dbf8a67 100644 --- a/ironic-image/configure-ironic.sh +++ b/ironic-image/configure-ironic.sh @@ -2,14 +2,13 @@ set -euxo pipefail -IRONIC_DEPLOYMENT="${IRONIC_DEPLOYMENT:-}" IRONIC_EXTERNAL_IP="${IRONIC_EXTERNAL_IP:-}" # Define the VLAN interfaces to be included in introspection report, e.g. # all - all VLANs on all interfaces using LLDP information # - all VLANs on a particular interface using LLDP information # - a particular VLAN on an interface, not relying on LLDP -export IRONIC_INSPECTOR_VLAN_INTERFACES=${IRONIC_INSPECTOR_VLAN_INTERFACES:-all} +export IRONIC_ENABLE_VLAN_INTERFACES=${IRONIC_ENABLE_VLAN_INTERFACES:-${IRONIC_INSPECTOR_VLAN_INTERFACES:-all}} # shellcheck disable=SC1091 . /bin/tls-common.sh @@ -20,13 +19,17 @@ export IRONIC_INSPECTOR_VLAN_INTERFACES=${IRONIC_INSPECTOR_VLAN_INTERFACES:-all} export HTTP_PORT=${HTTP_PORT:-80} -MARIADB_PASSWORD=${MARIADB_PASSWORD} -MARIADB_DATABASE=${MARIADB_DATABASE:-ironic} -MARIADB_USER=${MARIADB_USER:-ironic} -MARIADB_HOST=${MARIADB_HOST:-127.0.0.1} -export MARIADB_CONNECTION="mysql+pymysql://${MARIADB_USER}:${MARIADB_PASSWORD}@${MARIADB_HOST}/${MARIADB_DATABASE}?charset=utf8" -if [[ "$MARIADB_TLS_ENABLED" == "true" ]]; then - export MARIADB_CONNECTION="${MARIADB_CONNECTION}&ssl=on&ssl_ca=${MARIADB_CACERT_FILE}" +export IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-true} + +if [[ "$IRONIC_USE_MARIADB" == "true" ]]; then + MARIADB_PASSWORD=${MARIADB_PASSWORD} + MARIADB_DATABASE=${MARIADB_DATABASE:-ironic} + MARIADB_USER=${MARIADB_USER:-ironic} + MARIADB_HOST=${MARIADB_HOST:-127.0.0.1} + export MARIADB_CONNECTION="mysql+pymysql://${MARIADB_USER}:${MARIADB_PASSWORD}@${MARIADB_HOST}/${MARIADB_DATABASE}?charset=utf8" + if [[ "$MARIADB_TLS_ENABLED" == "true" ]]; then + export MARIADB_CONNECTION="${MARIADB_CONNECTION}&ssl=on&ssl_ca=${MARIADB_CACERT_FILE}" + fi fi # TODO(dtantsur): remove the explicit default once we get @@ -37,9 +40,6 @@ if [[ "$NUMPROC" -lt 4 ]]; then fi export NUMWORKERS=${NUMWORKERS:-$NUMPROC} -export IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-true} -export IRONIC_EXPOSE_JSON_RPC=${IRONIC_EXPOSE_JSON_RPC:-true} - # Whether to enable fast_track provisioning or not export IRONIC_FAST_TRACK=${IRONIC_FAST_TRACK:-true} @@ -58,16 +58,14 @@ wait_for_interface_or_ip export IRONIC_CONDUCTOR_HOST=${IRONIC_CONDUCTOR_HOST:-${IRONIC_URL_HOST}} export IRONIC_BASE_URL=${IRONIC_BASE_URL:-"${IRONIC_SCHEME}://${IRONIC_URL_HOST}:${IRONIC_ACCESS_PORT}"} -export IRONIC_INSPECTOR_BASE_URL=${IRONIC_INSPECTOR_BASE_URL:-"${IRONIC_INSPECTOR_SCHEME}://${IRONIC_URL_HOST}:${IRONIC_INSPECTOR_ACCESS_PORT}"} if [[ -n "$IRONIC_EXTERNAL_IP" ]]; then - export IRONIC_EXTERNAL_CALLBACK_URL="${IRONIC_SCHEME}://${IRONIC_EXTERNAL_IP}:${IRONIC_ACCESS_PORT}" + export IRONIC_EXTERNAL_CALLBACK_URL=${IRONIC_EXTERNAL_CALLBACK_URL:-"${IRONIC_SCHEME}://${IRONIC_EXTERNAL_IP}:${IRONIC_ACCESS_PORT}"} if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]]; then - export IRONIC_EXTERNAL_HTTP_URL="https://${IRONIC_EXTERNAL_IP}:${VMEDIA_TLS_PORT}" + export IRONIC_EXTERNAL_HTTP_URL=${IRONIC_EXTERNAL_HTTP_URL:-"https://${IRONIC_EXTERNAL_IP}:${VMEDIA_TLS_PORT}"} else - export IRONIC_EXTERNAL_HTTP_URL="http://${IRONIC_EXTERNAL_IP}:${HTTP_PORT}" + export IRONIC_EXTERNAL_HTTP_URL=${IRONIC_EXTERNAL_HTTP_URL:-"http://${IRONIC_EXTERNAL_IP}:${HTTP_PORT}"} fi - export IRONIC_INSPECTOR_CALLBACK_ENDPOINT_OVERRIDE="https://${IRONIC_EXTERNAL_IP}:${IRONIC_INSPECTOR_ACCESS_PORT}" fi IMAGE_CACHE_PREFIX=/shared/html/images/ironic-python-agent @@ -90,13 +88,32 @@ mkdir -p /shared/ironic_prometheus_exporter configure_json_rpc_auth +if [[ -f /proc/sys/crypto/fips_enabled ]]; then + ENABLE_FIPS_IPA=$(cat /proc/sys/crypto/fips_enabled) + export ENABLE_FIPS_IPA +fi + # The original ironic.conf is empty, and can be found in ironic.conf_orig render_j2_config /etc/ironic/ironic.conf.j2 /etc/ironic/ironic.conf -if [[ "${USE_IRONIC_INSPECTOR}" == "true" ]]; then - configure_client_basic_auth ironic-inspector -fi configure_client_basic_auth ironic-rpc # Make sure ironic traffic bypasses any proxies export NO_PROXY="${NO_PROXY:-},$IRONIC_IP" + +PROBE_CURL_ARGS= +if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "true" ]]; then + if [[ "${IRONIC_PRIVATE_PORT}" == "unix" ]]; then + PROBE_URL="http://127.0.0.1:6385" + PROBE_CURL_ARGS="--unix-socket /shared/ironic.sock" + else + PROBE_URL="http://127.0.0.1:${IRONIC_PRIVATE_PORT}" + fi +else + PROBE_URL="${IRONIC_BASE_URL}" +fi +export PROBE_CURL_ARGS +export PROBE_URL + +PROBE_KIND=readiness render_j2_config /bin/ironic-probe.j2 /bin/ironic-readiness +PROBE_KIND=liveness render_j2_config /bin/ironic-probe.j2 /bin/ironic-liveness diff --git a/ironic-image/configure-nonroot.sh b/ironic-image/configure-nonroot.sh index caeec02..6f07cba 100644 --- a/ironic-image/configure-nonroot.sh +++ b/ironic-image/configure-nonroot.sh @@ -10,12 +10,12 @@ useradd -r -g ${NONROOT_GID} \ -d /var/lib/ironic \ -s /sbin/nologin \ ${USER} - + # create ironic's http_root directory mkdir -p /shared/html chown "${NONROOT_UID}":"${NONROOT_GID}" /shared/html -# we'll bind mount shared ca and ironic/inspector certificate dirs here +# we'll bind mount shared ca and ironic certificate dirs here # that need to have correct ownership as the entire ironic in BMO # deployment shares a single fsGroup in manifest's securityContext mkdir -p /certs/ca @@ -26,17 +26,15 @@ chmod 2775 /certs{,/ca} chown -R "${NONROOT_UID}":"${NONROOT_GID}" /etc/apache2 chown -R "${NONROOT_UID}":"${NONROOT_GID}" /run -# ironic, inspector and httpd related changes +# ironic and httpd related changes +mkdir -p /etc/httpd/conf.d chown -R "${NONROOT_UID}":"${NONROOT_GID}" /etc/ironic /etc/httpd /etc/httpd -chown -R "${NONROOT_UID}":"${NONROOT_GID}" /etc/ironic-inspector chown -R "${NONROOT_UID}":"${NONROOT_GID}" /var/log -chmod 2775 /etc/ironic /etc/ironic-inspector /etc/httpd/conf /etc/httpd/conf.d -chmod 664 /etc/ironic/* /etc/ironic-inspector/* /etc/httpd/conf/* /etc/httpd/conf.d/* +chmod 2775 /etc/ironic /etc/httpd/conf /etc/httpd/conf.d +chmod 664 /etc/ironic/* /etc/httpd/conf/* /etc/httpd/conf.d/* chown -R "${NONROOT_UID}":"${NONROOT_GID}" /var/lib/ironic -chown -R "${NONROOT_UID}":"${NONROOT_GID}" /var/lib/ironic-inspector -chmod 2775 /var/lib/ironic /var/lib/ironic-inspector -chmod 664 /var/lib/ironic/ironic.db /var/lib/ironic-inspector/ironic-inspector.db +chmod 664 /var/lib/ironic/ironic.sqlite # dnsmasq, and the capabilities required to run it as non-root user chown -R "${NONROOT_UID}":"${NONROOT_GID}" /etc/dnsmasq.conf /var/lib/dnsmasq @@ -48,3 +46,8 @@ chmod 664 /etc/dnsmasq.conf /var/lib/dnsmasq/dnsmasq.leases touch /var/lib/ca-certificates/ca-bundle.pem.new chown -R "${NONROOT_UID}":"${NONROOT_GID}" /var/lib/ca-certificates/ chmod -R +w /var/lib/ca-certificates/ + +# probes that are created before start +touch /bin/ironic-{readi,live}ness +chown root:"${NONROOT_GID}" /bin/ironic-{readi,live}ness +chmod 775 /bin/ironic-{readi,live}ness diff --git a/ironic-image/dnsmasq.conf.j2 b/ironic-image/dnsmasq.conf.j2 index 502de9a..ad58078 100644 --- a/ironic-image/dnsmasq.conf.j2 +++ b/ironic-image/dnsmasq.conf.j2 @@ -29,13 +29,23 @@ dhcp-option=option{% if ":" in env["DNS_IP"] %}6{% endif %}:dns-server,{{ env["D # IPv4 Configuration: dhcp-match=ipxe,175 # Client is already running iPXE; move to next stage of chainloading +{%- if env.IPXE_TLS_SETUP == "true" %} +# iPXE with (U)EFI +dhcp-boot=tag:efi,tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/custom-ipxe/snponly.efi +# iPXE with BIOS +dhcp-boot=tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/custom-ipxe/undionly.kpxe +{% else %} dhcp-boot=tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/boot.ipxe +{% endif %} # Note: Need to test EFI booting dhcp-match=set:efi,option:client-arch,7 dhcp-match=set:efi,option:client-arch,9 dhcp-match=set:efi,option:client-arch,11 -# Client is PXE booting over EFI without iPXE ROM; send EFI version of iPXE chainloader +# Client is PXE booting over EFI without iPXE ROM; send EFI version of iPXE chainloader do the same also if iPXE ROM boots but TLS is enabled +{%- if env.IPXE_TLS_SETUP == "true" %} +dhcp-boot=tag:efi,tag:ipxe,snponly.efi +{% endif %} dhcp-boot=tag:efi,tag:!ipxe,snponly.efi # Client is running PXE over BIOS; send BIOS version of iPXE chainloader diff --git a/ironic-image/httpd-ironic-api.conf.j2 b/ironic-image/httpd-ironic-api.conf.j2 index 2132c9f..15c73b6 100644 --- a/ironic-image/httpd-ironic-api.conf.j2 +++ b/ironic-image/httpd-ironic-api.conf.j2 @@ -19,8 +19,6 @@ Listen {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_LISTEN_PORT }} {% endif %} - {% if env.IRONIC_REVERSE_PROXY_SETUP | lower == "true" %} - {% if env.IRONIC_PRIVATE_PORT == "unix" %} ProxyPass "/" "unix:/shared/ironic.sock|http://127.0.0.1/" ProxyPassReverse "/" "unix:/shared/ironic.sock|http://127.0.0.1/" @@ -29,14 +27,8 @@ Listen {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_LISTEN_PORT }} ProxyPassReverse "/" "http://127.0.0.1:{{ env.IRONIC_PRIVATE_PORT }}/" {% endif %} - {% else %} - WSGIDaemonProcess ironic user=ironic group=ironic threads=10 display-name=%{GROUP} - WSGIScriptAlias / /usr/bin/ironic-api-wsgi - {% endif %} - SetEnv APACHE_RUN_USER ironic-suse SetEnv APACHE_RUN_GROUP ironic-suse - WSGIProcessGroup ironic-suse ErrorLog /dev/stderr LogLevel debug @@ -49,7 +41,6 @@ Listen {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_LISTEN_PORT }} SSLCertificateKeyFile {{ env.IRONIC_KEY_FILE }} {% endif %} - {% if env.IRONIC_REVERSE_PROXY_SETUP | lower == "true" %} {% if "IRONIC_HTPASSWD" in env and env.IRONIC_HTPASSWD | length %} AuthType Basic @@ -58,22 +49,6 @@ Listen {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_LISTEN_PORT }} Require valid-user {% endif %} - {% else %} - - WSGIProcessGroup ironic - WSGIApplicationGroup %{GLOBAL} - AllowOverride None - - {% if "IRONIC_HTPASSWD" in env and env.IRONIC_HTPASSWD | length %} - AuthType Basic - AuthName "Restricted WSGI area" - AuthUserFile "/etc/ironic/htpasswd" - Require valid-user - {% else %} - Require all granted - {% endif %} - - {% endif %} Require all granted diff --git a/ironic-image/httpd-modules.conf b/ironic-image/httpd-modules.conf index c1c5aaa..fd2bc99 100644 --- a/ironic-image/httpd-modules.conf +++ b/ironic-image/httpd-modules.conf @@ -5,7 +5,6 @@ LoadModule dir_module /usr/lib64/apache2/mod_dir.so LoadModule authz_core_module /usr/lib64/apache2/mod_authz_core.so #LoadModule unixd_module modules/mod_unixd.so #LoadModule mpm_event_module modules/mod_mpm_event.so -LoadModule wsgi_module /usr/lib64/apache2/mod_wsgi.so LoadModule ssl_module /usr/lib64/apache2/mod_ssl.so LoadModule env_module /usr/lib64/apache2/mod_env.so LoadModule proxy_module /usr/lib64/apache2/mod_proxy.so diff --git a/ironic-image/httpd.conf.j2 b/ironic-image/httpd.conf.j2 index 16f5470..28e5308 100644 --- a/ironic-image/httpd.conf.j2 +++ b/ironic-image/httpd.conf.j2 @@ -1,6 +1,6 @@ ServerRoot "/etc/httpd" {%- if env.LISTEN_ALL_INTERFACES | lower == "true" %} -Listen [::]:{{ env.HTTP_PORT }} +Listen {{ env.HTTP_PORT }} {% else %} Listen {{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }} {% endif %} diff --git a/ironic-image/inspector.ipxe.j2 b/ironic-image/inspector.ipxe.j2 index 93f8c75..7616b12 100644 --- a/ironic-image/inspector.ipxe.j2 +++ b/ironic-image/inspector.ipxe.j2 @@ -5,6 +5,6 @@ echo In inspector.ipxe imgfree # NOTE(dtantsur): keep inspection kernel params in [mdns]params in # ironic-inspector-image and configuration in configure-ironic.sh -kernel --timeout 60000 http://{{ env.IRONIC_IP }}:{{ env.HTTP_PORT }}/images/ironic-python-agent.kernel ipa-insecure=1 ipa-inspection-collectors={{ env.IRONIC_IPA_COLLECTORS }} systemd.journald.forward_to_console=yes BOOTIF=${mac} ipa-debug=1 ipa-enable-vlan-interfaces={{ env.IRONIC_INSPECTOR_VLAN_INTERFACES }} ipa-inspection-dhcp-all-interfaces=1 ipa-collect-lldp=1 {{ env.INSPECTOR_EXTRA_ARGS }} initrd=ironic-python-agent.initramfs {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} || goto retry_boot -initrd --timeout 60000 http://{{ env.IRONIC_IP }}:{{ env.HTTP_PORT }}/images/ironic-python-agent.initramfs || goto retry_boot +kernel --timeout 60000 http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/images/ironic-python-agent.kernel ipa-insecure=1 ipa-inspection-collectors={{ env.IRONIC_IPA_COLLECTORS }} systemd.journald.forward_to_console=yes BOOTIF=${mac} ipa-debug=1 ipa-enable-vlan-interfaces={{ env.IRONIC_ENABLE_VLAN_INTERFACES }} ipa-inspection-dhcp-all-interfaces=1 ipa-collect-lldp=1 {{ env.INSPECTOR_EXTRA_ARGS }} initrd=ironic-python-agent.initramfs {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} || goto retry_boot +initrd --timeout 60000 http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/images/ironic-python-agent.initramfs || goto retry_boot boot diff --git a/ironic-image/ipxe_config.template b/ironic-image/ipxe_config.template new file mode 100644 index 0000000..8f27dd1 --- /dev/null +++ b/ironic-image/ipxe_config.template @@ -0,0 +1,81 @@ +#!ipxe + +set attempts:int32 10 +set i:int32 0 + +goto deploy + +:deploy +imgfree +{%- if pxe_options.deployment_aki_path %} +{%- set aki_path_https_elements = pxe_options.deployment_aki_path.split(':') %} +{%- set aki_port_and_path = aki_path_https_elements[2].split('/') %} +{%- set aki_afterport = aki_port_and_path[1:]|join('/') %} +{%- set aki_path_https = ['https:', aki_path_https_elements[1], ':8084/', aki_afterport]|join %} +{%- endif %} +{%- if pxe_options.deployment_ari_path %} +{%- set ari_path_https_elements = pxe_options.deployment_ari_path.split(':') %} +{%- set ari_port_and_path = ari_path_https_elements[2].split('/') %} +{%- set ari_afterport = ari_port_and_path[1:]|join('/') %} +{%- set ari_path_https = ['https:', ari_path_https_elements[1], ':8084/', ari_afterport]|join %} +{%- endif %} +kernel {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ aki_path_https }} selinux=0 troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }} BOOTIF=${mac} initrd={{ pxe_options.initrd_filename|default("deploy_ramdisk", true) }} || goto retry + +initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ ari_path_https }} || goto retry +boot + +:retry +iseq ${i} ${attempts} && goto fail || +inc i +echo No response, retrying in ${i} seconds. +sleep ${i} +goto deploy + +:fail +echo Failed to get a response after ${attempts} attempts +echo Powering off in 30 seconds. +sleep 30 +poweroff + +:boot_anaconda +imgfree +kernel {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ aki_path_https }} text {{ pxe_options.pxe_append_params|default("", true) }} inst.ks={{ pxe_options.ks_cfg_url }} {% if pxe_options.repo_url %}inst.repo={{ pxe_options.repo_url }}{% else %}inst.stage2={{ pxe_options.stage2_url }}{% endif %} initrd=ramdisk || goto boot_anaconda +initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ ari_path_https }} || goto boot_anaconda +boot + +:boot_ramdisk +imgfree +{%- if pxe_options.boot_iso_url %} +sanboot {{ pxe_options.boot_iso_url }} +{%- else %} +kernel {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ aki_path_https }} root=/dev/ram0 text {{ pxe_options.pxe_append_params|default("", true) }} {{ pxe_options.ramdisk_opts|default('', true) }} initrd=ramdisk || goto boot_ramdisk +initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ ari_path_https }} || goto boot_ramdisk +boot +{%- endif %} + +{%- if pxe_options.boot_from_volume %} + +:boot_iscsi +imgfree +{% if pxe_options.username %}set username {{ pxe_options.username }}{% endif %} +{% if pxe_options.password %}set password {{ pxe_options.password }}{% endif %} +{% if pxe_options.iscsi_initiator_iqn %}set initiator-iqn {{ pxe_options.iscsi_initiator_iqn }}{% endif %} +sanhook --drive 0x80 {{ pxe_options.iscsi_boot_url }} || goto fail_iscsi_retry +{%- if pxe_options.iscsi_volumes %}{% for i, volume in enumerate(pxe_options.iscsi_volumes) %} +set username {{ volume.username }} +set password {{ volume.password }} +{%- set drive_id = 129 + i %} +sanhook --drive {{ '0x%x' % drive_id }} {{ volume.url }} || goto fail_iscsi_retry +{%- endfor %}{% endif %} +{% if pxe_options.iscsi_volumes %}set username {{ pxe_options.username }}{% endif %} +{% if pxe_options.iscsi_volumes %}set password {{ pxe_options.password }}{% endif %} +sanboot --no-describe || goto fail_iscsi_retry + +:fail_iscsi_retry +echo Failed to attach iSCSI volume(s), retrying in 10 seconds. +sleep 10 +goto boot_iscsi +{%- endif %} + +:boot_whole_disk +sanboot --no-describe || exit 0 diff --git a/ironic-image/ironic-common.sh b/ironic-image/ironic-common.sh index f388c6b..fd740f3 100644 --- a/ironic-image/ironic-common.sh +++ b/ironic-image/ironic-common.sh @@ -6,6 +6,7 @@ IRONIC_IP="${IRONIC_IP:-}" PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-}" PROVISIONING_IP="${PROVISIONING_IP:-}" PROVISIONING_MACS="${PROVISIONING_MACS:-}" +IPXE_CUSTOM_FIRMWARE_DIR="${IPXE_CUSTOM_FIRMWARE_DIR:-/shared/custom_ipxe_firmware}" get_provisioning_interface() { @@ -72,7 +73,10 @@ wait_for_interface_or_ip() render_j2_config() { + ls $1 # DEBUG + python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' < "$1" python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' < "$1" > "$2" + ls $2 # DEBUG } run_ironic_dbsync() @@ -86,25 +90,18 @@ run_ironic_dbsync() done else # SQLite does not support some statements. Fortunately, we can just create - # the schema in one go instead of going through an upgrade. - ironic-dbsync --config-file /etc/ironic/ironic.conf create_schema + # the schema in one go if not already created, instead of going through an upgrade + DB_VERSION="$(ironic-dbsync --config-file /etc/ironic/ironic.conf version)" + if [[ "${DB_VERSION}" == "None" ]]; then + ironic-dbsync --config-file /etc/ironic/ironic.conf create_schema + fi fi } # Use the special value "unix" for unix sockets -export IRONIC_PRIVATE_PORT=${IRONIC_PRIVATE_PORT:-6388} -export IRONIC_INSPECTOR_PRIVATE_PORT=${IRONIC_INSPECTOR_PRIVATE_PORT:-5049} +export IRONIC_PRIVATE_PORT=${IRONIC_PRIVATE_PORT:-unix} export IRONIC_ACCESS_PORT=${IRONIC_ACCESS_PORT:-6385} export IRONIC_LISTEN_PORT=${IRONIC_LISTEN_PORT:-$IRONIC_ACCESS_PORT} -export IRONIC_INSPECTOR_ACCESS_PORT=${IRONIC_INSPECTOR_ACCESS_PORT:-5050} -export IRONIC_INSPECTOR_LISTEN_PORT=${IRONIC_INSPECTOR_LISTEN_PORT:-$IRONIC_INSPECTOR_ACCESS_PORT} - -# If this is false, built-in inspection is used. -export USE_IRONIC_INSPECTOR=${USE_IRONIC_INSPECTOR:-true} -export IRONIC_INSPECTOR_ENABLE_DISCOVERY=${IRONIC_INSPECTOR_ENABLE_DISCOVERY:-false} -if [[ "${USE_IRONIC_INSPECTOR}" != "true" ]] && [[ "${IRONIC_INSPECTOR_ENABLE_DISCOVERY}" == "true" ]]; then - echo "Discovery is only supported with ironic-inspector at this point" - exit 1 -fi +export IRONIC_ENABLE_DISCOVERY=${IRONIC_ENABLE_DISCOVERY:-${IRONIC_INSPECTOR_ENABLE_DISCOVERY:-false}} diff --git a/ironic-image/ironic-probe.j2 b/ironic-image/ironic-probe.j2 new file mode 100644 index 0000000..85a5ca7 --- /dev/null +++ b/ironic-image/ironic-probe.j2 @@ -0,0 +1,9 @@ +#!/bin/bash + +set -eu -o pipefail + +curl -sSf {{ env.PROBE_CURL_ARGS }} "{{ env.PROBE_URL }}" + +# TODO(dtantsur): when PROBE_KIND==readiness, try the conductor and driver API +# to make sure the conductor is ready. This requires having access to secrets +# since these endpoints are authenticated. diff --git a/ironic-image/ironic.conf.j2 b/ironic-image/ironic.conf.j2 index 5bce6d2..e2cb681 100644 --- a/ironic-image/ironic.conf.j2 +++ b/ironic-image/ironic.conf.j2 @@ -1,28 +1,22 @@ [DEFAULT] -{% if env.AUTH_STRATEGY is defined %} -auth_strategy = {{ env.AUTH_STRATEGY }} -{% if env.AUTH_STRATEGY == "http_basic" %} -http_basic_auth_user_file=/etc/ironic/htpasswd -{% endif %} -{% else %} auth_strategy = noauth -{% endif %} debug = true default_deploy_interface = direct -default_inspect_interface = {% if env.USE_IRONIC_INSPECTOR == "true" %}inspector{% else %}agent{% endif %} +default_inspect_interface = agent default_network_interface = noop -enabled_bios_interfaces = idrac-wsman,no-bios,redfish,idrac-redfish,irmc,ilo -enabled_boot_interfaces = ipxe,ilo-ipxe,pxe,ilo-pxe,fake,redfish-virtual-media,idrac-redfish-virtual-media,ilo-virtual-media +enabled_bios_interfaces = no-bios,redfish,idrac-redfish,irmc,ilo +enabled_boot_interfaces = ipxe,ilo-ipxe,pxe,ilo-pxe,fake,redfish-virtual-media,idrac-redfish-virtual-media,ilo-virtual-media,redfish-https enabled_deploy_interfaces = direct,fake,ramdisk,custom-agent +enabled_firmware_interfaces = no-firmware,fake,redfish # NOTE(dtantsur): when changing this, make sure to update the driver # dependencies in Dockerfile. enabled_hardware_types = ipmi,idrac,irmc,fake-hardware,redfish,manual-management,ilo,ilo5 -enabled_inspect_interfaces = {% if env.USE_IRONIC_INSPECTOR == "true" %}inspector{% else %}agent{% endif %},idrac-wsman,irmc,fake,redfish,ilo -enabled_management_interfaces = ipmitool,idrac-wsman,irmc,fake,redfish,idrac-redfish,ilo,ilo5,noop -enabled_power_interfaces = ipmitool,idrac-wsman,irmc,fake,redfish,idrac-redfish,ilo -enabled_raid_interfaces = no-raid,irmc,agent,fake,idrac-wsman,redfish,idrac-redfish,ilo5 -enabled_vendor_interfaces = no-vendor,ipmitool,idrac-wsman,idrac-redfish,redfish,ilo,fake -enabled_firmware_interfaces = no-firmware,fake,redfish +enabled_inspect_interfaces = agent,irmc,fake,redfish,ilo +enabled_management_interfaces = ipmitool,irmc,fake,redfish,idrac-redfish,ilo,ilo5,noop +enabled_network_interfaces = noop +enabled_power_interfaces = ipmitool,irmc,fake,redfish,idrac-redfish,ilo +enabled_raid_interfaces = no-raid,irmc,agent,fake,redfish,idrac-redfish,ilo5 +enabled_vendor_interfaces = no-vendor,ipmitool,idrac-redfish,redfish,ilo,fake {% if env.IRONIC_EXPOSE_JSON_RPC | lower == "true" %} rpc_transport = json-rpc {% else %} @@ -32,14 +26,7 @@ use_stderr = true # NOTE(dtantsur): the default md5 is not compatible with FIPS mode hash_ring_algorithm = sha256 my_ip = {{ env.IRONIC_IP }} -{% if env.IRONIC_DEPLOYMENT == "Conductor" and env.JSON_RPC_AUTH_STRATEGY == "noauth" %} -# if access is unauthenticated, we bind only to localhost - use that as the -# host name also, so that the client can find the server -# If we run both API and conductor in the same pod, use localhost -host = localhost -{% else %} host = {{ env.IRONIC_CONDUCTOR_HOST }} -{% endif %} # If a path to a certificate is defined, use that first for webserver {% if env.WEBSERVER_CACERT_FILE %} @@ -96,7 +83,7 @@ send_sensor_data = {{ env.SEND_SENSOR_DATA }} # Power state is checked every 60 seconds and BMC activity should # be avoided more often than once every sixty seconds. send_sensor_data_interval = 160 -bootloader = {{ env.IRONIC_BOOT_BASE_URL }}/uefi_esp.img +bootloader = http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/uefi_esp.img verify_step_priority_override = management.clear_job_queue:90 # We don't use this feature, and it creates an additional load on the database node_history = False @@ -125,7 +112,7 @@ default_boot_option = local erase_devices_metadata_priority = 10 erase_devices_priority = 0 http_root = /shared/html/ -http_url = {{ env.IRONIC_BOOT_BASE_URL }} +http_url = http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }} fast_track = {{ env.IRONIC_FAST_TRACK }} {% if env.IRONIC_BOOT_ISO_SOURCE %} ramdisk_image_download_source = {{ env.IRONIC_BOOT_ISO_SOURCE }} @@ -143,26 +130,22 @@ external_callback_url = {{ env.IRONIC_EXTERNAL_CALLBACK_URL }} dhcp_provider = none [inspector] +# NOTE(dtantsur): we properly configure the "unmanaged" inspection boot (i.e. +# booting IPA through a separate inspector.ipxe rather than the driver's boot +# interface), so managed boot is not required. +require_managed_boot = False power_off = {{ false if env.IRONIC_FAST_TRACK == "true" else true }} # NOTE(dtantsur): keep inspection arguments synchronized with inspector.ipxe # Also keep in mind that only parameters unique for inspection go here. # No need to duplicate pxe_append_params/kernel_append_params. -extra_kernel_params = ipa-inspection-collectors={{ env.IRONIC_IPA_COLLECTORS }} ipa-enable-vlan-interfaces={{ env.IRONIC_INSPECTOR_VLAN_INTERFACES }} ipa-inspection-dhcp-all-interfaces=1 ipa-collect-lldp=1 net.ifnames={{ '0' if env.PREDICTABLE_NIC_NAMES == 'false' else '1' }} - -{% if env.USE_IRONIC_INSPECTOR == "true" %} -endpoint_override = {{ env.IRONIC_INSPECTOR_BASE_URL }} -{% if env.IRONIC_INSPECTOR_TLS_SETUP == "true" %} -cafile = {{ env.IRONIC_INSPECTOR_CACERT_FILE }} -insecure = {{ env.IRONIC_INSPECTOR_INSECURE }} -{% endif %} -{% if env.IRONIC_INSPECTOR_CALLBACK_ENDPOINT_OVERRIDE %} -callback_endpoint_override = {{ env.IRONIC_INSPECTOR_CALLBACK_ENDPOINT_OVERRIDE }} -{% endif %} -{% else %} +extra_kernel_params = ipa-inspection-collectors={{ env.IRONIC_IPA_COLLECTORS }} ipa-enable-vlan-interfaces={{ env.IRONIC_ENABLE_VLAN_INTERFACES }} ipa-inspection-dhcp-all-interfaces=1 ipa-collect-lldp=1 hooks = $default_hooks,parse-lldp add_ports = all keep_ports = present -{% endif %} + +[auto_discovery] +enabled = {{ env.IRONIC_ENABLE_DISCOVERY }} +driver = ipmi [ipmi] # use_ipmitool_retries transfers the responsibility of retrying to ipmitool @@ -191,15 +174,9 @@ cipher_suite_versions = 3,17 # authentication over localhost, using the same credentials as API, to prevent # unauthenticated connections from other processes in the same host since the # containers are in host networking. -auth_strategy = {{ env.JSON_RPC_AUTH_STRATEGY }} +auth_strategy = http_basic http_basic_auth_user_file = /etc/ironic/htpasswd-rpc -{% if env.IRONIC_DEPLOYMENT == "Conductor" and env.JSON_RPC_AUTH_STRATEGY == "noauth" %} -# if access is unauthenticated, we bind only to localhost - use that as the -# host name also, so that the client can find the server -host_ip = localhost -{% else %} host_ip = {% if env.LISTEN_ALL_INTERFACES | lower == "true" %}::{% else %}{{ env.IRONIC_IP }}{% endif %} -{% endif %} {% if env.IRONIC_TLS_SETUP == "true" %} use_ssl = true cafile = {{ env.IRONIC_CACERT_FILE }} @@ -224,24 +201,27 @@ images_path = /shared/html/tmp instance_master_path = /shared/html/master_images tftp_master_path = /shared/tftpboot/master_images tftp_root = /shared/tftpboot -kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes +kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.ENABLE_FIPS_IPA %}fips={{ env.ENABLE_FIPS_IPA|trim }}{% endif %} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes net.ifnames={{ '0' if env.PREDICTABLE_NIC_NAMES == 'false' else '1' }} # This makes networking boot templates generated even for nodes using local # boot (the default), ensuring that they boot correctly even if they start # netbooting for some reason (e.g. with the noop management interface). enable_netboot_fallback = true # Enable the fallback path to in-band inspection ipxe_fallback_script = inspector.ipxe +{% if env.IPXE_TLS_SETUP | lower == "true" %} +ipxe_config_template = /tmp/ipxe_config.template +{% endif %} [redfish] use_swift = false -kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes +kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.ENABLE_FIPS_IPA %}fips={{ env.ENABLE_FIPS_IPA|trim }}{% endif %} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes net.ifnames={{ '0' if env.PREDICTABLE_NIC_NAMES == 'false' else '1' }} [ilo] -kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes +kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.ENABLE_FIPS_IPA %}fips={{ env.ENABLE_FIPS_IPA|trim }}{% endif %} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes net.ifnames={{ '0' if env.PREDICTABLE_NIC_NAMES == 'false' else '1' }} use_web_server_for_images = true [irmc] -kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes +kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.ENABLE_FIPS_IPA %}fips={{ env.ENABLE_FIPS_IPA|trim }}{% endif %} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes net.ifnames={{ '0' if env.PREDICTABLE_NIC_NAMES == 'false' else '1' }} [service_catalog] endpoint_override = {{ env.IRONIC_BASE_URL }} diff --git a/ironic-image/rundnsmasq b/ironic-image/rundnsmasq index 92af2eb..16f4c76 100644 --- a/ironic-image/rundnsmasq +++ b/ironic-image/rundnsmasq @@ -4,6 +4,8 @@ set -eux # shellcheck disable=SC1091 . /bin/ironic-common.sh +# shellcheck disable=SC1091 +. /bin/tls-common.sh export HTTP_PORT=${HTTP_PORT:-80} DNSMASQ_EXCEPT_INTERFACE=${DNSMASQ_EXCEPT_INTERFACE:-lo} @@ -19,7 +21,13 @@ mkdir -p /shared/html/images mkdir -p /shared/html/pxelinux.cfg # Copy files to shared mount -cp /tftpboot/undionly.kpxe /tftpboot/snponly.efi /shared/tftpboot +if [[ -r "${IPXE_CUSTOM_FIRMWARE_DIR}" ]]; then + cp "${IPXE_CUSTOM_FIRMWARE_DIR}/undionly.kpxe" \ + "${IPXE_CUSTOM_FIRMWARE_DIR}/snponly.efi" \ + "/shared/tftpboot" +else + cp /tftpboot/undionly.kpxe /tftpboot/snponly.efi /shared/tftpboot +fi # Template and write dnsmasq.conf # we template via /tmp as sed otherwise creates temp files in /etc directory diff --git a/ironic-image/runhttpd b/ironic-image/runhttpd index 57e7c97..4622f26 100644 --- a/ironic-image/runhttpd +++ b/ironic-image/runhttpd @@ -8,10 +8,7 @@ export HTTP_PORT=${HTTP_PORT:-80} export VMEDIA_TLS_PORT=${VMEDIA_TLS_PORT:-8083} -INSPECTOR_ORIG_HTTPD_CONFIG=/etc/httpd/conf.d/inspector-apache.conf.j2 -INSPECTOR_RESULT_HTTPD_CONFIG=/etc/httpd/conf.d/ironic-inspector.conf export IRONIC_REVERSE_PROXY_SETUP=${IRONIC_REVERSE_PROXY_SETUP:-false} -export INSPECTOR_REVERSE_PROXY_SETUP=${INSPECTOR_REVERSE_PROXY_SETUP:-false} # In Metal3 context they are called node images in Ironic context they are # called user images. @@ -33,11 +30,7 @@ chmod 0777 /shared/html IRONIC_BASE_URL="${IRONIC_SCHEME}://${IRONIC_URL_HOST}" -if [[ "${USE_IRONIC_INSPECTOR}" == "true" ]]; then - INSPECTOR_EXTRA_ARGS=" ipa-inspection-callback-url=${IRONIC_BASE_URL}:${IRONIC_INSPECTOR_ACCESS_PORT}/v1/continue" -else - INSPECTOR_EXTRA_ARGS=" ipa-inspection-callback-url=${IRONIC_BASE_URL}:${IRONIC_ACCESS_PORT}/v1/continue_inspection" -fi +INSPECTOR_EXTRA_ARGS=" ipa-inspection-callback-url=${IRONIC_BASE_URL}:${IRONIC_ACCESS_PORT}/v1/continue_inspection" if [[ "$IRONIC_FAST_TRACK" == "true" ]]; then INSPECTOR_EXTRA_ARGS+=" ipa-api-url=${IRONIC_BASE_URL}:${IRONIC_ACCESS_PORT}" @@ -51,14 +44,6 @@ cp /tmp/uefi_esp.img /shared/html/uefi_esp.img # Render the core httpd config render_j2_config /etc/httpd/conf/httpd.conf.j2 /etc/httpd/conf/httpd.conf -if [[ "$USE_IRONIC_INSPECTOR" == "true" ]] && [[ "$IRONIC_INSPECTOR_TLS_SETUP" == "true" ]]; then - if [[ "${INSPECTOR_REVERSE_PROXY_SETUP}" == "true" ]]; then - render_j2_config "$INSPECTOR_ORIG_HTTPD_CONFIG" "$INSPECTOR_RESULT_HTTPD_CONFIG" - fi -else - export INSPECTOR_REVERSE_PROXY_SETUP="false" # If TLS is not used, we have no reason to use the reverse proxy -fi - if [[ "$IRONIC_TLS_SETUP" == "true" ]]; then if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "true" ]]; then render_j2_config /tmp/httpd-ironic-api.conf.j2 /etc/httpd/conf.d/ironic.conf @@ -74,12 +59,14 @@ if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]]; then render_j2_config /etc/httpd-vmedia.conf.j2 /etc/httpd/conf.d/vmedia.conf fi -# Set up inotify to kill the container (restart) whenever cert files for ironic inspector change -if [[ "$IRONIC_INSPECTOR_TLS_SETUP" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then - # shellcheck disable=SC2034 - inotifywait -m -e delete_self "${IRONIC_INSPECTOR_CERT_FILE}" | while read -r file event; do - kill -WINCH $(pgrep httpd) - done & +# Render httpd TLS configuration for /shared/html +if [[ "$IPXE_TLS_SETUP" == "true" ]]; then + mkdir -p /shared/html/custom-ipxe + chmod 0777 /shared/html/custom-ipxe + render_j2_config "/etc/httpd-ipxe.conf.j2" "/etc/httpd/conf.d/ipxe.conf" + cp "${IPXE_CUSTOM_FIRMWARE_DIR}/undionly.kpxe" \ + "${IPXE_CUSTOM_FIRMWARE_DIR}/snponly.efi" \ + "/shared/html/custom-ipxe" fi # Set up inotify to kill the container (restart) whenever cert files for ironic api change diff --git a/ironic-image/runironic b/ironic-image/runironic index 5dd6ef2..067a065 100644 --- a/ironic-image/runironic +++ b/ironic-image/runironic @@ -1,9 +1,7 @@ #!/usr/bin/bash -# These settings must go before configure-ironic since it has different -# defaults. +# This setting must go before configure-ironic since it has different defaults. export IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-false} -export IRONIC_EXPOSE_JSON_RPC=${IRONIC_EXPOSE_JSON_RPC:-false} # shellcheck disable=SC1091 . /bin/configure-ironic.sh diff --git a/ironic-image/runlogwatch.sh b/ironic-image/runlogwatch.sh index 8b2124e..525cd7d 100644 --- a/ironic-image/runlogwatch.sh +++ b/ironic-image/runlogwatch.sh @@ -1,20 +1,11 @@ #!/usr/bin/bash # Ramdisk logs path -LOG_DIRS=("/shared/log/ironic/deploy" "/shared/log/ironic-inspector/ramdisk") +LOG_DIR="/shared/log/ironic/deploy" -while :; do - for LOG_DIR in "${LOG_DIRS[@]}"; do - if ! ls "${LOG_DIR}"/*.tar.gz 1> /dev/null 2>&1; then - continue - fi - - for fn in "${LOG_DIR}"/*.tar.gz; do - echo "************ Contents of $fn ramdisk log file bundle **************" - tar -xOzvvf "$fn" | sed -e "s/^/$(basename "$fn"): /" - rm -f "$fn" - done +inotifywait -m "${LOG_DIR}" -e close_write | + while read -r path _action file; do + echo "************ Contents of ${path}/${file} ramdisk log file bundle **************" + tar -xOzvvf "${path}/${file}" | sed -e "s/^/${file}: /" + rm -f "${path}/${file}" done - - sleep 5 -done diff --git a/ironic-image/tls-common.sh b/ironic-image/tls-common.sh index 992f475..6805885 100644 --- a/ironic-image/tls-common.sh +++ b/ironic-image/tls-common.sh @@ -5,24 +5,25 @@ export IRONIC_KEY_FILE=/certs/ironic/tls.key export IRONIC_CACERT_FILE=/certs/ca/ironic/tls.crt export IRONIC_INSECURE=${IRONIC_INSECURE:-false} export IRONIC_SSL_PROTOCOL=${IRONIC_SSL_PROTOCOL:-"-ALL +TLSv1.2 +TLSv1.3"} +export IPXE_SSL_PROTOCOL=${IPXE_SSL_PROTOCOL:-"-ALL +TLSv1.2 +TLSv1.3"} export IRONIC_VMEDIA_SSL_PROTOCOL=${IRONIC_VMEDIA_SSL_PROTOCOL:-"ALL"} -export IRONIC_INSPECTOR_CERT_FILE=/certs/ironic-inspector/tls.crt -export IRONIC_INSPECTOR_KEY_FILE=/certs/ironic-inspector/tls.key -export IRONIC_INSPECTOR_CACERT_FILE=/certs/ca/ironic-inspector/tls.crt -export IRONIC_INSPECTOR_INSECURE=${IRONIC_INSPECTOR_INSECURE:-$IRONIC_INSECURE} - export IRONIC_VMEDIA_CERT_FILE=/certs/vmedia/tls.crt export IRONIC_VMEDIA_KEY_FILE=/certs/vmedia/tls.key +export IPXE_CERT_FILE=/certs/ipxe/tls.crt +export IPXE_KEY_FILE=/certs/ipxe/tls.key + export RESTART_CONTAINER_CERTIFICATE_UPDATED=${RESTART_CONTAINER_CERTIFICATE_UPDATED:-"false"} export MARIADB_CACERT_FILE=/certs/ca/mariadb/tls.crt +export IPXE_TLS_PORT="${IPXE_TLS_PORT:-8084}" + mkdir -p /certs/ironic -mkdir -p /certs/ironic-inspector mkdir -p /certs/ca/ironic -mkdir -p /certs/ca/ironic-inspector +mkdir -p /certs/ipxe +mkdir -p /certs/vmedia if [[ -f "$IRONIC_CERT_FILE" ]] && [[ ! -f "$IRONIC_KEY_FILE" ]]; then echo "Missing TLS Certificate key file $IRONIC_KEY_FILE" @@ -33,15 +34,6 @@ if [[ ! -f "$IRONIC_CERT_FILE" ]] && [[ -f "$IRONIC_KEY_FILE" ]]; then exit 1 fi -if [[ -f "$IRONIC_INSPECTOR_CERT_FILE" ]] && [[ ! -f "$IRONIC_INSPECTOR_KEY_FILE" ]]; then - echo "Missing TLS Certificate key file $IRONIC_INSPECTOR_KEY_FILE" - exit 1 -fi -if [[ ! -f "$IRONIC_INSPECTOR_CERT_FILE" ]] && [[ -f "$IRONIC_INSPECTOR_KEY_FILE" ]]; then - echo "Missing TLS Certificate file $IRONIC_INSPECTOR_CERT_FILE" - exit 1 -fi - if [[ -f "$IRONIC_VMEDIA_CERT_FILE" ]] && [[ ! -f "$IRONIC_VMEDIA_KEY_FILE" ]]; then echo "Missing TLS Certificate key file $IRONIC_VMEDIA_KEY_FILE" exit 1 @@ -51,6 +43,15 @@ if [[ ! -f "$IRONIC_VMEDIA_CERT_FILE" ]] && [[ -f "$IRONIC_VMEDIA_KEY_FILE" ]]; exit 1 fi +if [[ -f "$IPXE_CERT_FILE" ]] && [[ ! -f "$IPXE_KEY_FILE" ]]; then + echo "Missing TLS Certificate key file $IPXE_KEY_FILE" + exit 1 +fi +if [[ ! -f "$IPXE_CERT_FILE" ]] && [[ -f "$IPXE_KEY_FILE" ]]; then + echo "Missing TLS Certificate file $IPXE_CERT_FILE" + exit 1 +fi + copy_atomic() { local src="$1" @@ -75,25 +76,20 @@ else export IRONIC_SCHEME="http" fi -if [[ -f "$IRONIC_INSPECTOR_CERT_FILE" ]] || [[ -f "$IRONIC_INSPECTOR_CACERT_FILE" ]]; then - export IRONIC_INSPECTOR_TLS_SETUP="true" - export IRONIC_INSPECTOR_SCHEME="https" - if [[ ! -f "$IRONIC_INSPECTOR_CACERT_FILE" ]]; then - copy_atomic "$IRONIC_INSPECTOR_CERT_FILE" "$IRONIC_INSPECTOR_CACERT_FILE" - fi -else - export IRONIC_INSPECTOR_TLS_SETUP="false" - export IRONIC_INSPECTOR_SCHEME="http" -fi - if [[ -f "$IRONIC_VMEDIA_CERT_FILE" ]]; then - export IRONIC_VMEDIA_SCHEME="https" export IRONIC_VMEDIA_TLS_SETUP="true" else - export IRONIC_VMEDIA_SCHEME="http" export IRONIC_VMEDIA_TLS_SETUP="false" fi +if [[ -f "$IPXE_CERT_FILE" ]]; then + export IPXE_SCHEME="https" + export IPXE_TLS_SETUP="true" +else + export IPXE_SCHEME="http" + export IPXE_TLS_SETUP="false" +fi + if [[ -f "$MARIADB_CACERT_FILE" ]]; then export MARIADB_TLS_ENABLED="true" else -- 2.45.2