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