forked from suse-edge/Factory
Compare commits
14 Commits
main
...
alignment-
Author | SHA256 | Date | |
---|---|---|---|
0efa970293
|
|||
98af6481c6
|
|||
7a377d7d90
|
|||
411dddbedf
|
|||
49b8245bf8
|
|||
d68fa72bc4
|
|||
2377717803
|
|||
28c3565d52
|
|||
dccfe7863b
|
|||
da9f8f9c2c
|
|||
ecdb953890
|
|||
c7e6740ac2
|
|||
7f24019049
|
|||
aa9aa54149
|
@@ -32,7 +32,9 @@ RUN mkdir -p /installroot/var/lib/ironic && \
|
|||||||
/installroot/usr/bin/sqlite3 /installroot/var/lib/ironic/ironic.sqlite "pragma journal_mode=wal" && \
|
/installroot/usr/bin/sqlite3 /installroot/var/lib/ironic/ironic.sqlite "pragma journal_mode=wal" && \
|
||||||
zypper --installroot /installroot --non-interactive remove sqlite3
|
zypper --installroot /installroot --non-interactive remove sqlite3
|
||||||
|
|
||||||
|
# build actual image
|
||||||
FROM micro AS final
|
FROM micro AS final
|
||||||
|
|
||||||
MAINTAINER SUSE LLC (https://www.suse.com/)
|
MAINTAINER SUSE LLC (https://www.suse.com/)
|
||||||
# Define labels according to https://en.opensuse.org/Building_derived_containers
|
# Define labels according to https://en.opensuse.org/Building_derived_containers
|
||||||
LABEL org.opencontainers.image.title="SLE Openstack Ironic Container Image"
|
LABEL org.opencontainers.image.title="SLE Openstack Ironic Container Image"
|
||||||
@@ -62,14 +64,16 @@ RUN echo 'alias mkisofs="xorriso -as mkisofs"' >> ~/.bashrc
|
|||||||
COPY mkisofs_wrapper /usr/bin/mkisofs
|
COPY mkisofs_wrapper /usr/bin/mkisofs
|
||||||
RUN set -euo pipefail; chmod +x /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 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 /tftpboot
|
||||||
RUN mkdir -p $GRUB_DIR
|
RUN mkdir -p $GRUB_DIR
|
||||||
|
|
||||||
# No need to support the Legacy BIOS boot
|
COPY scripts/ /bin/
|
||||||
#RUN cp /usr/share/syslinux/pxelinux.0 /tftpboot
|
COPY configure-nonroot.sh /bin/
|
||||||
#RUN cp /usr/share/syslinux/chain.c32 /tftpboot/
|
RUN set -euo pipefail; chmod +x /bin/configure-ironic.sh /bin/rundnsmasq /bin/runhttpd /bin/runironic /bin/runironic-exporter /bin/runlogwatch.sh /bin/configure-nonroot.sh
|
||||||
|
|
||||||
|
COPY ironic-config/inspector.ipxe.j2 ironic-config/httpd-ironic-api.conf.j2 \
|
||||||
|
ironic-config/ipxe_config.template ironic-config/dnsmasq.conf.j2 \
|
||||||
|
/templates/
|
||||||
|
|
||||||
# IRONIC #
|
# IRONIC #
|
||||||
RUN cp /usr/share/ipxe/undionly.kpxe /tftpboot/undionly.kpxe
|
RUN cp /usr/share/ipxe/undionly.kpxe /tftpboot/undionly.kpxe
|
||||||
@@ -85,23 +89,17 @@ RUN if [ "$(uname -m)" = "aarch64" ]; then\
|
|||||||
COPY --from=base /tmp/esp-x86_64.img /tmp/uefi_esp-x86_64.img
|
COPY --from=base /tmp/esp-x86_64.img /tmp/uefi_esp-x86_64.img
|
||||||
COPY --from=base /tmp/esp-aarch64.img /tmp/uefi_esp-arm64.img
|
COPY --from=base /tmp/esp-aarch64.img /tmp/uefi_esp-arm64.img
|
||||||
|
|
||||||
COPY ironic.conf.j2 /etc/ironic/
|
COPY ironic-config/ironic.conf.j2 ironic-config/network-data-schema-empty.json /etc/ironic/
|
||||||
COPY inspector.ipxe.j2 httpd-ironic-api.conf.j2 ipxe_config.template /tmp/
|
|
||||||
COPY network-data-schema-empty.json /etc/ironic/
|
|
||||||
|
|
||||||
# DNSMASQ
|
|
||||||
COPY dnsmasq.conf.j2 /etc/
|
|
||||||
|
|
||||||
# Custom httpd config, removes all but the bare minimum needed modules
|
|
||||||
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
|
|
||||||
COPY apache2-ipxe.conf.j2 /etc/httpd-ipxe.conf.j2
|
|
||||||
|
|
||||||
# Workaround
|
# Workaround
|
||||||
# Removing the 010-ironic.conf file that comes with the package
|
# Removing the 010-ironic.conf file that comes with the package
|
||||||
RUN rm /etc/ironic/ironic.conf.d/010-ironic.conf
|
RUN rm /etc/ironic/ironic.conf.d/010-ironic.conf
|
||||||
|
|
||||||
|
# Custom httpd config, removes all but the bare minimum needed modules
|
||||||
|
COPY ironic-config/httpd.conf.j2 /etc/httpd/conf/
|
||||||
|
COPY ironic-config/httpd-modules.conf /etc/httpd/conf.modules.d/
|
||||||
|
COPY ironic-config/apache2-vmedia.conf.j2 /templates/httpd-vmedia.conf.j2
|
||||||
|
COPY ironic-config/apache2-ipxe.conf.j2 /templates/httpd-ipxe.conf.j2
|
||||||
|
|
||||||
# configure non-root user and set relevant permissions
|
# configure non-root user and set relevant permissions
|
||||||
RUN configure-nonroot.sh && \
|
RUN configure-nonroot.sh && rm -f /bin/configure-nonroot.sh
|
||||||
rm -f /bin/configure-nonroot.sh
|
|
||||||
|
@@ -1,59 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
|
|
||||||
set -euxo pipefail
|
|
||||||
|
|
||||||
export IRONIC_REVERSE_PROXY_SETUP=${IRONIC_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
|
|
||||||
if [[ -f "/auth/ironic/htpasswd" ]]; then
|
|
||||||
IRONIC_HTPASSWD=$(</auth/ironic/htpasswd)
|
|
||||||
fi
|
|
||||||
export IRONIC_HTPASSWD=${IRONIC_HTPASSWD:-${HTTP_BASIC_HTPASSWD:-}}
|
|
||||||
|
|
||||||
configure_client_basic_auth()
|
|
||||||
{
|
|
||||||
local auth_config_file="/auth/$1/auth-config"
|
|
||||||
local dest="${2:-/etc/ironic/ironic.conf}"
|
|
||||||
if [[ -f "${auth_config_file}" ]]; then
|
|
||||||
# Merge configurations in the "auth" directory into the default ironic configuration file
|
|
||||||
crudini --merge "${dest}" < "${auth_config_file}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
configure_json_rpc_auth()
|
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
configure_ironic_auth()
|
|
||||||
{
|
|
||||||
local config=/etc/ironic/ironic.conf
|
|
||||||
# Configure HTTP basic auth for API server
|
|
||||||
if [[ -n "${IRONIC_HTPASSWD}" ]]; then
|
|
||||||
printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}"
|
|
||||||
if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "false" ]]; then
|
|
||||||
crudini --set "${config}" DEFAULT auth_strategy http_basic
|
|
||||||
crudini --set "${config}" DEFAULT http_basic_auth_user_file "${IRONIC_HTPASSWD_FILE}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
write_htpasswd_files()
|
|
||||||
{
|
|
||||||
if [[ -n "${IRONIC_HTPASSWD:-}" ]]; then
|
|
||||||
printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}"
|
|
||||||
fi
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
#!ipxe
|
|
||||||
|
|
||||||
:retry_boot
|
|
||||||
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_URL_HOST }}:{{ env.HTTP_PORT }}/images/ironic-python-agent-${buildarch}.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-${buildarch}.initramfs || goto retry_boot
|
|
||||||
boot
|
|
@@ -10,15 +10,13 @@ Listen {{ env.VMEDIA_TLS_PORT }}
|
|||||||
SSLCertificateFile {{ env.IRONIC_VMEDIA_CERT_FILE }}
|
SSLCertificateFile {{ env.IRONIC_VMEDIA_CERT_FILE }}
|
||||||
SSLCertificateKeyFile {{ env.IRONIC_VMEDIA_KEY_FILE }}
|
SSLCertificateKeyFile {{ env.IRONIC_VMEDIA_KEY_FILE }}
|
||||||
|
|
||||||
<Directory "/shared">
|
<Directory ~ "/shared/html">
|
||||||
AllowOverride None
|
Order deny,allow
|
||||||
Require all granted
|
deny from all
|
||||||
</Directory>
|
</Directory>
|
||||||
|
<Directory ~ "/shared/html/(redfish|ilo)/">
|
||||||
<Directory "/shared/html">
|
Order allow,deny
|
||||||
Options Indexes FollowSymLinks
|
allow from all
|
||||||
AllowOverride None
|
|
||||||
Require all granted
|
|
||||||
</Directory>
|
</Directory>
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
|
|
@@ -3,6 +3,7 @@ bind-dynamic
|
|||||||
enable-tftp
|
enable-tftp
|
||||||
tftp-root=/shared/tftpboot
|
tftp-root=/shared/tftpboot
|
||||||
log-queries
|
log-queries
|
||||||
|
dhcp-leasefile=/data/dnsmasq/dnsmasq.leases
|
||||||
|
|
||||||
# Configure listening for DNS (0 disables DNS)
|
# Configure listening for DNS (0 disables DNS)
|
||||||
port={{ env.DNS_PORT }}
|
port={{ env.DNS_PORT }}
|
||||||
@@ -31,11 +32,11 @@ dhcp-match=ipxe,175
|
|||||||
# Client is already running iPXE; move to next stage of chainloading
|
# Client is already running iPXE; move to next stage of chainloading
|
||||||
{%- if env.IPXE_TLS_SETUP == "true" %}
|
{%- if env.IPXE_TLS_SETUP == "true" %}
|
||||||
# iPXE with (U)EFI
|
# iPXE with (U)EFI
|
||||||
dhcp-boot=tag:efi,tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/custom-ipxe/snponly.efi
|
dhcp-boot=tag:efi,tag:ipxe,{{ env.IRONIC_HTTP_URL }}/custom-ipxe/snponly.efi
|
||||||
# iPXE with BIOS
|
# iPXE with BIOS
|
||||||
dhcp-boot=tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/custom-ipxe/undionly.kpxe
|
dhcp-boot=tag:ipxe,{{ env.IRONIC_HTTP_URL }}/custom-ipxe/undionly.kpxe
|
||||||
{% else %}
|
{% else %}
|
||||||
dhcp-boot=tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/boot.ipxe
|
dhcp-boot=tag:ipxe,{{ env.IRONIC_HTTP_URL }}/boot.ipxe
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# Note: Need to test EFI booting
|
# Note: Need to test EFI booting
|
||||||
@@ -59,8 +60,8 @@ ra-param={{ env.PROVISIONING_INTERFACE }},0,0
|
|||||||
|
|
||||||
dhcp-vendorclass=set:pxe6,enterprise:343,PXEClient
|
dhcp-vendorclass=set:pxe6,enterprise:343,PXEClient
|
||||||
dhcp-userclass=set:ipxe6,iPXE
|
dhcp-userclass=set:ipxe6,iPXE
|
||||||
dhcp-option=tag:pxe6,option6:bootfile-url,tftp://{{ env.IRONIC_URL_HOST }}/snponly.efi
|
dhcp-option=tag:pxe6,option6:bootfile-url,{{ env.IRONIC_TFTP_URL }}/snponly.efi
|
||||||
dhcp-option=tag:ipxe6,option6:bootfile-url,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/boot.ipxe
|
dhcp-option=tag:ipxe6,option6:bootfile-url,{{ env.IRONIC_HTTP_URL }}/boot.ipxe
|
||||||
|
|
||||||
# It can be used when setting DNS or GW variables.
|
# It can be used when setting DNS or GW variables.
|
||||||
{%- if env["GATEWAY_IP"] is undefined %}
|
{%- if env["GATEWAY_IP"] is undefined %}
|
@@ -45,7 +45,7 @@ Listen {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_LISTEN_PORT }}
|
|||||||
{% if "IRONIC_HTPASSWD" in env and env.IRONIC_HTPASSWD | length %}
|
{% if "IRONIC_HTPASSWD" in env and env.IRONIC_HTPASSWD | length %}
|
||||||
AuthType Basic
|
AuthType Basic
|
||||||
AuthName "Restricted area"
|
AuthName "Restricted area"
|
||||||
AuthUserFile "/etc/ironic/htpasswd"
|
AuthUserFile {{ env.HTPASSWD_FILE }}
|
||||||
Require valid-user
|
Require valid-user
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</Location>
|
</Location>
|
@@ -1,10 +1,10 @@
|
|||||||
ServerRoot "/etc/httpd"
|
ServerRoot {{ env.HTTPD_DIR }}
|
||||||
{%- if env.LISTEN_ALL_INTERFACES | lower == "true" %}
|
{%- if env.LISTEN_ALL_INTERFACES | lower == "true" %}
|
||||||
Listen {{ env.HTTP_PORT }}
|
Listen {{ env.HTTP_PORT }}
|
||||||
{% else %}
|
{% else %}
|
||||||
Listen {{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}
|
Listen {{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
Include conf.modules.d/*.conf
|
Include /etc/httpd/conf.modules.d/*.conf
|
||||||
User ironic-suse
|
User ironic-suse
|
||||||
Group ironic-suse
|
Group ironic-suse
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ AddDefaultCharset UTF-8
|
|||||||
MIMEMagicFile conf/magic
|
MIMEMagicFile conf/magic
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|
||||||
PidFile /var/tmp/httpd.pid
|
PidFile {{ env.IRONIC_TMP_DATA_DIR }}/httpd.pid
|
||||||
|
|
||||||
# EnableSendfile directive could speed up deployments but it could also cause
|
# EnableSendfile directive could speed up deployments but it could also cause
|
||||||
# issues depending on the underlying file system, to learn more:
|
# issues depending on the underlying file system, to learn more:
|
10
ironic-image/ironic-config/inspector.ipxe.j2
Normal file
10
ironic-image/ironic-config/inspector.ipxe.j2
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!ipxe
|
||||||
|
|
||||||
|
:retry_boot
|
||||||
|
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 {{ env.IRONIC_HTTP_URL }}/images/ironic-python-agent-${buildarch}.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 {{ env.IRONIC_HTTP_URL }}/images/ironic-python-agent.initramfs || goto retry_boot
|
||||||
|
boot
|
@@ -49,6 +49,7 @@ deploy_logs_local_path = /shared/log/ironic/deploy
|
|||||||
# retries here works around such problems without affecting the normal path.
|
# retries here works around such problems without affecting the normal path.
|
||||||
# See https://bugzilla.redhat.com/show_bug.cgi?id=1822763
|
# See https://bugzilla.redhat.com/show_bug.cgi?id=1822763
|
||||||
max_command_attempts = 30
|
max_command_attempts = 30
|
||||||
|
certificates_path = {{ env.IRONIC_GEN_CERT_DIR }}
|
||||||
|
|
||||||
[api]
|
[api]
|
||||||
{% if env.IRONIC_REVERSE_PROXY_SETUP == "true" %}
|
{% if env.IRONIC_REVERSE_PROXY_SETUP == "true" %}
|
||||||
@@ -83,7 +84,7 @@ send_sensor_data = {{ env.SEND_SENSOR_DATA }}
|
|||||||
# Power state is checked every 60 seconds and BMC activity should
|
# Power state is checked every 60 seconds and BMC activity should
|
||||||
# be avoided more often than once every sixty seconds.
|
# be avoided more often than once every sixty seconds.
|
||||||
send_sensor_data_interval = 160
|
send_sensor_data_interval = 160
|
||||||
bootloader = {{ env.IRONIC_BOOT_BASE_URL }}/uefi_esp-{{ env.DEPLOY_ARCHITECTURE }}.img
|
bootloader = file:///templates/uefi_esp.img
|
||||||
verify_step_priority_override = management.clear_job_queue:90
|
verify_step_priority_override = management.clear_job_queue:90
|
||||||
# We don't use this feature, and it creates an additional load on the database
|
# We don't use this feature, and it creates an additional load on the database
|
||||||
node_history = False
|
node_history = False
|
||||||
@@ -95,16 +96,22 @@ deploy_kernel = file://{{ env.IRONIC_DEFAULT_KERNEL }}
|
|||||||
{% if env.IRONIC_DEFAULT_RAMDISK is defined %}
|
{% if env.IRONIC_DEFAULT_RAMDISK is defined %}
|
||||||
deploy_ramdisk = file://{{ env.IRONIC_DEFAULT_RAMDISK }}
|
deploy_ramdisk = file://{{ env.IRONIC_DEFAULT_RAMDISK }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if env.DISABLE_DEEP_IMAGE_INSPECTION | lower == "true" %}
|
||||||
|
disable_deep_image_inspection = True
|
||||||
|
{% endif %}
|
||||||
|
# Allowed path for file:// links: ipa-downloader uses /shared/html/images,
|
||||||
|
# while the bootloader configuration above refers to /templates.
|
||||||
|
file_url_allowed_paths = /shared/html/images,/templates
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
{% if env.IRONIC_USE_MARIADB | lower == "false" %}
|
{% if env.IRONIC_USE_MARIADB | lower == "true" %}
|
||||||
connection = sqlite:////var/lib/ironic/ironic.sqlite
|
connection = {{ env.MARIADB_CONNECTION }}
|
||||||
|
{% else %}
|
||||||
|
connection = {{ env.LOCAL_DB_URI }}
|
||||||
# Synchronous mode is required for data integrity in case of operating system
|
# Synchronous mode is required for data integrity in case of operating system
|
||||||
# crash. In our case we restart the container from scratch, so we can save some
|
# crash. In our case we restart the container from scratch, so we can save some
|
||||||
# IO by not doing syncs all the time.
|
# IO by not doing syncs all the time.
|
||||||
sqlite_synchronous = False
|
sqlite_synchronous = False
|
||||||
{% else %}
|
|
||||||
connection = {{ env.MARIADB_CONNECTION }}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
[deploy]
|
[deploy]
|
||||||
@@ -112,7 +119,7 @@ default_boot_option = local
|
|||||||
erase_devices_metadata_priority = 10
|
erase_devices_metadata_priority = 10
|
||||||
erase_devices_priority = 0
|
erase_devices_priority = 0
|
||||||
http_root = /shared/html/
|
http_root = /shared/html/
|
||||||
http_url = {{ env.IRONIC_BOOT_BASE_URL }}
|
http_url = {{ env.IRONIC_HTTP_URL }}
|
||||||
fast_track = {{ env.IRONIC_FAST_TRACK }}
|
fast_track = {{ env.IRONIC_FAST_TRACK }}
|
||||||
{% if env.IRONIC_BOOT_ISO_SOURCE %}
|
{% if env.IRONIC_BOOT_ISO_SOURCE %}
|
||||||
ramdisk_image_download_source = {{ env.IRONIC_BOOT_ISO_SOURCE }}
|
ramdisk_image_download_source = {{ env.IRONIC_BOOT_ISO_SOURCE }}
|
||||||
@@ -175,7 +182,7 @@ cipher_suite_versions = 3,17
|
|||||||
# unauthenticated connections from other processes in the same host since the
|
# unauthenticated connections from other processes in the same host since the
|
||||||
# containers are in host networking.
|
# containers are in host networking.
|
||||||
auth_strategy = http_basic
|
auth_strategy = http_basic
|
||||||
http_basic_auth_user_file = /etc/ironic/htpasswd-rpc
|
http_basic_auth_user_file = {{ env.IRONIC_RPC_HTPASSWD_FILE }}
|
||||||
host_ip = {% if env.LISTEN_ALL_INTERFACES | lower == "true" %}::{% else %}{{ env.IRONIC_IP }}{% endif %}
|
host_ip = {% if env.LISTEN_ALL_INTERFACES | lower == "true" %}::{% else %}{{ env.IRONIC_IP }}{% endif %}
|
||||||
{% if env.IRONIC_TLS_SETUP == "true" %}
|
{% if env.IRONIC_TLS_SETUP == "true" %}
|
||||||
use_ssl = true
|
use_ssl = true
|
||||||
@@ -201,7 +208,7 @@ images_path = /shared/html/tmp
|
|||||||
instance_master_path = /shared/html/master_images
|
instance_master_path = /shared/html/master_images
|
||||||
tftp_master_path = /shared/tftpboot/master_images
|
tftp_master_path = /shared/tftpboot/master_images
|
||||||
tftp_root = /shared/tftpboot
|
tftp_root = /shared/tftpboot
|
||||||
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' }}
|
kernel_append_params = nofb nomodeset vga=normal ipa-insecure=1 {% 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
|
||||||
# This makes networking boot templates generated even for nodes using local
|
# This makes networking boot templates generated even for nodes using local
|
||||||
# boot (the default), ensuring that they boot correctly even if they start
|
# boot (the default), ensuring that they boot correctly even if they start
|
||||||
# netbooting for some reason (e.g. with the noop management interface).
|
# netbooting for some reason (e.g. with the noop management interface).
|
||||||
@@ -209,19 +216,19 @@ enable_netboot_fallback = true
|
|||||||
# Enable the fallback path to in-band inspection
|
# Enable the fallback path to in-band inspection
|
||||||
ipxe_fallback_script = inspector.ipxe
|
ipxe_fallback_script = inspector.ipxe
|
||||||
{% if env.IPXE_TLS_SETUP | lower == "true" %}
|
{% if env.IPXE_TLS_SETUP | lower == "true" %}
|
||||||
ipxe_config_template = /tmp/ipxe_config.template
|
ipxe_config_template = /templates/ipxe_config.template
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
[redfish]
|
[redfish]
|
||||||
use_swift = false
|
use_swift = false
|
||||||
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' }}
|
kernel_append_params = nofb nomodeset vga=normal ipa-insecure=1 {% 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
|
||||||
|
|
||||||
[ilo]
|
[ilo]
|
||||||
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' }}
|
kernel_append_params = nofb nomodeset vga=normal ipa-insecure=1 {% 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
|
||||||
use_web_server_for_images = true
|
use_web_server_for_images = true
|
||||||
|
|
||||||
[irmc]
|
[irmc]
|
||||||
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' }}
|
kernel_append_params = nofb nomodeset vga=normal ipa-insecure=1 {% 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
|
||||||
|
|
||||||
[service_catalog]
|
[service_catalog]
|
||||||
endpoint_override = {{ env.IRONIC_BASE_URL }}
|
endpoint_override = {{ env.IRONIC_BASE_URL }}
|
@@ -1,9 +0,0 @@
|
|||||||
#!/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.
|
|
@@ -1,23 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
|
|
||||||
# This setting must go before configure-ironic since it has different defaults.
|
|
||||||
export IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-false}
|
|
||||||
|
|
||||||
# shellcheck disable=SC1091
|
|
||||||
. /bin/configure-ironic.sh
|
|
||||||
|
|
||||||
# Ramdisk logs
|
|
||||||
mkdir -p /shared/log/ironic/deploy
|
|
||||||
|
|
||||||
run_ironic_dbsync
|
|
||||||
|
|
||||||
if [[ "$IRONIC_TLS_SETUP" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
python3.11 -m pyinotify --raw-format -e IN_DELETE_SELF -v "${IRONIC_CERT_FILE}" | while read -r file event; do
|
|
||||||
kill $(pgrep ironic)
|
|
||||||
done &
|
|
||||||
fi
|
|
||||||
|
|
||||||
configure_ironic_auth
|
|
||||||
|
|
||||||
exec /usr/bin/ironic
|
|
@@ -1,19 +0,0 @@
|
|||||||
#!/usr/bin/bash
|
|
||||||
|
|
||||||
# Ramdisk logs path
|
|
||||||
LOG_DIR="/shared/log/ironic/deploy"
|
|
||||||
|
|
||||||
# The ironic container creates the directory, wait for
|
|
||||||
# it to exist before running inotifywait or it can fail causing
|
|
||||||
# a spurious restart
|
|
||||||
while [ ! -d "${LOG_DIR}" ]; do
|
|
||||||
echo "Waiting for ${LOG_DIR}"
|
|
||||||
sleep 5
|
|
||||||
done
|
|
||||||
|
|
||||||
python3.11 -m pyinotify --raw-format -e IN_CLOSE_WRITE -v "${LOG_DIR}" |
|
|
||||||
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
|
|
97
ironic-image/scripts/auth-common.sh
Normal file
97
ironic-image/scripts/auth-common.sh
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
export IRONIC_REVERSE_PROXY_SETUP=${IRONIC_REVERSE_PROXY_SETUP:-false}
|
||||||
|
|
||||||
|
# CUSTOM_CONFIG_DIR is also managed in the ironic-common.sh, in order to
|
||||||
|
# keep auth-common and ironic-common separate (to stay consistent with the
|
||||||
|
# architecture) part of the ironic-common logic had to be duplicated
|
||||||
|
CUSTOM_CONFIG_DIR="${CUSTOM_CONFIG_DIR:-/conf}"
|
||||||
|
IRONIC_CONF_DIR="${CUSTOM_CONFIG_DIR}/ironic"
|
||||||
|
|
||||||
|
# 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="${IRONIC_CONF_DIR}/htpasswd"
|
||||||
|
export IRONIC_RPC_HTPASSWD_FILE="${IRONIC_HTPASSWD_FILE}-rpc"
|
||||||
|
if [[ -f "/auth/ironic/htpasswd" ]]; then
|
||||||
|
IRONIC_HTPASSWD=$(</auth/ironic/htpasswd)
|
||||||
|
fi
|
||||||
|
if [[ -f "/auth/ironic-rpc/htpasswd" ]]; then
|
||||||
|
IRONIC_RPC_HTPASSWD=$(</auth/ironic-rpc/htpasswd)
|
||||||
|
fi
|
||||||
|
export IRONIC_HTPASSWD=${IRONIC_HTPASSWD:-${HTTP_BASIC_HTPASSWD:-}}
|
||||||
|
export IRONIC_RPC_HTPASSWD=${IRONIC_RPC_HTPASSWD:-${IRONIC_HTPASSWD}}
|
||||||
|
|
||||||
|
if [[ -n "${MARIADB_PASSWORD:-}" ]]; then
|
||||||
|
echo "WARNING: passing MARIADB_PASSWORD is deprecated, mount a secret under /auth/mariadb instead"
|
||||||
|
elif [[ -f /auth/mariadb/password ]]; then
|
||||||
|
MARIADB_PASSWORD=$(</auth/mariadb/password)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${MARIADB_USER:-}" ]] && [[ -f /auth/mariadb/username ]]; then
|
||||||
|
MARIADB_USER=$(</auth/mariadb/username)
|
||||||
|
fi
|
||||||
|
|
||||||
|
IRONIC_CONFIG="${IRONIC_CONF_DIR}/ironic.conf"
|
||||||
|
|
||||||
|
configure_json_rpc_auth()
|
||||||
|
{
|
||||||
|
if [[ "${IRONIC_EXPOSE_JSON_RPC}" != "true" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local auth_config_file="/auth/ironic-rpc/auth-config"
|
||||||
|
local username_file="/auth/ironic-rpc/username"
|
||||||
|
local password_file="/auth/ironic-rpc/password"
|
||||||
|
if [[ -f "${username_file}" ]] && [[ -f "${password_file}" ]]; then
|
||||||
|
crudini --set "${IRONIC_CONFIG}" json_rpc username "$(<${username_file})"
|
||||||
|
set +x
|
||||||
|
crudini --set "${IRONIC_CONFIG}" json_rpc password "$(<${password_file})"
|
||||||
|
set -x
|
||||||
|
elif [[ -f "${auth_config_file}" ]]; then
|
||||||
|
echo "WARNING: using auth-config is deprecated, mount a secret directly"
|
||||||
|
# Merge configurations in the "auth" directory into the default ironic configuration file
|
||||||
|
crudini --merge "${IRONIC_CONFIG}" < "${auth_config_file}"
|
||||||
|
else
|
||||||
|
echo "FATAL: no client-side credentials provided for JSON RPC"
|
||||||
|
echo "HINT: mount a secret with username and password fields under /auth/ironic-rpc"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${IRONIC_RPC_HTPASSWD}" ]]; then
|
||||||
|
if [[ -f "${username_file}" ]] && [[ -f "${password_file}" ]]; then
|
||||||
|
htpasswd -c -i -B "${IRONIC_RPC_HTPASSWD_FILE}" "$(<${username_file})" <"${password_file}"
|
||||||
|
else
|
||||||
|
echo "FATAL: enabling JSON RPC requires authentication"
|
||||||
|
echo "HINT: mount a secret with either username and password or htpasswd under /auth/ironic-rpc"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
printf "%s\n" "${IRONIC_RPC_HTPASSWD}" > "${IRONIC_RPC_HTPASSWD_FILE}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_ironic_auth()
|
||||||
|
{
|
||||||
|
# Configure HTTP basic auth for API server
|
||||||
|
if [[ -n "${IRONIC_HTPASSWD}" ]]; then
|
||||||
|
printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}"
|
||||||
|
if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "false" ]]; then
|
||||||
|
crudini --set "${IRONIC_CONFIG}" DEFAULT auth_strategy http_basic
|
||||||
|
crudini --set "${IRONIC_CONFIG}" DEFAULT http_basic_auth_user_file "${IRONIC_HTPASSWD_FILE}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
write_htpasswd_files()
|
||||||
|
{
|
||||||
|
if [[ -n "${IRONIC_HTPASSWD:-}" ]]; then
|
||||||
|
printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}"
|
||||||
|
fi
|
||||||
|
}
|
@@ -19,10 +19,11 @@ export IRONIC_ENABLE_VLAN_INTERFACES=${IRONIC_ENABLE_VLAN_INTERFACES:-${IRONIC_I
|
|||||||
|
|
||||||
export HTTP_PORT=${HTTP_PORT:-80}
|
export HTTP_PORT=${HTTP_PORT:-80}
|
||||||
|
|
||||||
export IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-true}
|
if [[ "${IRONIC_USE_MARIADB}" == true ]]; then
|
||||||
|
if [[ -z "${MARIADB_PASSWORD:-}" ]]; then
|
||||||
if [[ "$IRONIC_USE_MARIADB" == "true" ]]; then
|
echo "FATAL: IRONIC_USE_MARIADB requires password, mount a secret under /auth/mariadb"
|
||||||
MARIADB_PASSWORD=${MARIADB_PASSWORD}
|
exit 1
|
||||||
|
fi
|
||||||
MARIADB_DATABASE=${MARIADB_DATABASE:-ironic}
|
MARIADB_DATABASE=${MARIADB_DATABASE:-ironic}
|
||||||
MARIADB_USER=${MARIADB_USER:-ironic}
|
MARIADB_USER=${MARIADB_USER:-ironic}
|
||||||
MARIADB_HOST=${MARIADB_HOST:-127.0.0.1}
|
MARIADB_HOST=${MARIADB_HOST:-127.0.0.1}
|
||||||
@@ -32,13 +33,9 @@ if [[ "$IRONIC_USE_MARIADB" == "true" ]]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# TODO(dtantsur): remove the explicit default once we get
|
# zero makes it do cpu number detection on Ironic side
|
||||||
# https://review.opendev.org/761185 in the repositories
|
export NUMWORKERS=${NUMWORKERS:-0}
|
||||||
NUMPROC="$(grep -c "^processor" /proc/cpuinfo)"
|
|
||||||
if [[ "$NUMPROC" -lt 4 ]]; then
|
|
||||||
NUMPROC=4
|
|
||||||
fi
|
|
||||||
export NUMWORKERS=${NUMWORKERS:-$NUMPROC}
|
|
||||||
|
|
||||||
# Whether to enable fast_track provisioning or not
|
# Whether to enable fast_track provisioning or not
|
||||||
export IRONIC_FAST_TRACK=${IRONIC_FAST_TRACK:-true}
|
export IRONIC_FAST_TRACK=${IRONIC_FAST_TRACK:-true}
|
||||||
@@ -57,8 +54,6 @@ wait_for_interface_or_ip
|
|||||||
# Hostname to use for the current conductor instance.
|
# Hostname to use for the current conductor instance.
|
||||||
export IRONIC_CONDUCTOR_HOST=${IRONIC_CONDUCTOR_HOST:-${IRONIC_URL_HOST}}
|
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}"}
|
|
||||||
|
|
||||||
if [[ -n "$IRONIC_EXTERNAL_IP" ]]; then
|
if [[ -n "$IRONIC_EXTERNAL_IP" ]]; then
|
||||||
export IRONIC_EXTERNAL_CALLBACK_URL=${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
|
if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]]; then
|
||||||
@@ -74,9 +69,9 @@ if [[ -f "${IMAGE_CACHE_PREFIX}.kernel" ]] && [[ -f "${IMAGE_CACHE_PREFIX}.initr
|
|||||||
export IRONIC_DEFAULT_RAMDISK="${IMAGE_CACHE_PREFIX}.initramfs"
|
export IRONIC_DEFAULT_RAMDISK="${IMAGE_CACHE_PREFIX}.initramfs"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f /etc/ironic/ironic.conf ]]; then
|
if [[ -f "${IRONIC_CONF_DIR}/ironic.conf" ]]; then
|
||||||
# Make a copy of the original supposed empty configuration file
|
# Make a copy of the original supposed empty configuration file
|
||||||
cp /etc/ironic/ironic.conf /etc/ironic/ironic.conf_orig
|
cp "${IRONIC_CONF_DIR}/ironic.conf" "${IRONIC_CONF_DIR}/ironic.conf.orig"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# oslo.config also supports Config Opts From Environment, log them to stdout
|
# oslo.config also supports Config Opts From Environment, log them to stdout
|
||||||
@@ -86,34 +81,16 @@ env | grep "^OS_" || true
|
|||||||
mkdir -p /shared/html
|
mkdir -p /shared/html
|
||||||
mkdir -p /shared/ironic_prometheus_exporter
|
mkdir -p /shared/ironic_prometheus_exporter
|
||||||
|
|
||||||
configure_json_rpc_auth
|
|
||||||
|
|
||||||
if [[ -f /proc/sys/crypto/fips_enabled ]]; then
|
if [[ -f /proc/sys/crypto/fips_enabled ]]; then
|
||||||
ENABLE_FIPS_IPA=$(cat /proc/sys/crypto/fips_enabled)
|
ENABLE_FIPS_IPA=$(cat /proc/sys/crypto/fips_enabled)
|
||||||
export ENABLE_FIPS_IPA
|
export ENABLE_FIPS_IPA
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The original ironic.conf is empty, and can be found in ironic.conf_orig
|
# 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
|
render_j2_config "/etc/ironic/ironic.conf.j2" \
|
||||||
|
"${IRONIC_CONF_DIR}/ironic.conf"
|
||||||
|
|
||||||
configure_client_basic_auth ironic-rpc
|
configure_json_rpc_auth
|
||||||
|
|
||||||
# Make sure ironic traffic bypasses any proxies
|
# Make sure ironic traffic bypasses any proxies
|
||||||
export NO_PROXY="${NO_PROXY:-},$IRONIC_IP"
|
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
|
|
@@ -2,11 +2,36 @@
|
|||||||
|
|
||||||
set -euxo pipefail
|
set -euxo pipefail
|
||||||
|
|
||||||
IRONIC_IP="${IRONIC_IP:-}"
|
# Export IRONIC_IP to avoid needing to lean on IRONIC_URL_HOST for consumption in
|
||||||
|
# e.g. dnsmasq configuration
|
||||||
|
export IRONIC_IP="${IRONIC_IP:-}"
|
||||||
PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-}"
|
PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-}"
|
||||||
PROVISIONING_IP="${PROVISIONING_IP:-}"
|
PROVISIONING_IP="${PROVISIONING_IP:-}"
|
||||||
PROVISIONING_MACS="${PROVISIONING_MACS:-}"
|
PROVISIONING_MACS="${PROVISIONING_MACS:-}"
|
||||||
IPXE_CUSTOM_FIRMWARE_DIR="${IPXE_CUSTOM_FIRMWARE_DIR:-/shared/custom_ipxe_firmware}"
|
IPXE_CUSTOM_FIRMWARE_DIR="${IPXE_CUSTOM_FIRMWARE_DIR:-/shared/custom_ipxe_firmware}"
|
||||||
|
CUSTOM_CONFIG_DIR="${CUSTOM_CONFIG_DIR:-/conf}"
|
||||||
|
CUSTOM_DATA_DIR="${CUSTOM_DATA_DIR:-/data}"
|
||||||
|
export DNSMASQ_CONF_DIR="${CUSTOM_CONFIG_DIR}/dnsmasq"
|
||||||
|
export DNSMASQ_DATA_DIR="${CUSTOM_DATA_DIR}/dnsmasq"
|
||||||
|
export DNSMASQ_TEMP_DIR="${CUSTOM_CONFIG_DIR}/dnsmasq"
|
||||||
|
export HTTPD_DIR="${CUSTOM_CONFIG_DIR}/httpd"
|
||||||
|
export HTTPD_CONF_DIR="${HTTPD_DIR}/conf"
|
||||||
|
export HTTPD_CONF_DIR_D="${HTTPD_DIR}/conf.d"
|
||||||
|
export IRONIC_CONF_DIR="${CUSTOM_CONFIG_DIR}/ironic"
|
||||||
|
export IRONIC_DB_DIR="${CUSTOM_DATA_DIR}/db"
|
||||||
|
export IRONIC_GEN_CERT_DIR="${CUSTOM_DATA_DIR}/auto_gen_certs"
|
||||||
|
export IRONIC_TMP_DATA_DIR="${CUSTOM_DATA_DIR}/tmp"
|
||||||
|
export PROBE_CONF_DIR="${CUSTOM_CONFIG_DIR}/probes"
|
||||||
|
|
||||||
|
mkdir -p "${IRONIC_CONF_DIR}" "${PROBE_CONF_DIR}" "${HTTPD_CONF_DIR}" \
|
||||||
|
"${HTTPD_CONF_DIR_D}" "${DNSMASQ_CONF_DIR}" "${DNSMASQ_TEMP_DIR}" \
|
||||||
|
"${IRONIC_DB_DIR}" "${IRONIC_GEN_CERT_DIR}" "${DNSMASQ_DATA_DIR}" \
|
||||||
|
"${IRONIC_TMP_DATA_DIR}"
|
||||||
|
|
||||||
|
export HTPASSWD_FILE="${IRONIC_CONF_DIR}/htpasswd"
|
||||||
|
export LOCAL_DB_URI="sqlite:///${IRONIC_DB_DIR}/ironic.sqlite"
|
||||||
|
|
||||||
|
export IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-false}
|
||||||
|
|
||||||
get_provisioning_interface()
|
get_provisioning_interface()
|
||||||
{
|
{
|
||||||
@@ -19,13 +44,13 @@ get_provisioning_interface()
|
|||||||
local interface="provisioning"
|
local interface="provisioning"
|
||||||
|
|
||||||
if [[ -n "${PROVISIONING_IP}" ]]; then
|
if [[ -n "${PROVISIONING_IP}" ]]; then
|
||||||
if ip -br addr show | grep -qi " ${PROVISIONING_IP}/"; then
|
if ip -br addr show | grep -i " ${PROVISIONING_IP}/" &>/dev/null; then
|
||||||
interface="$(ip -br addr show | grep -i " ${PROVISIONING_IP}/" | cut -f 1 -d ' ' | cut -f 1 -d '@')"
|
interface="$(ip -br addr show | grep -i " ${PROVISIONING_IP}/" | cut -f 1 -d ' ' | cut -f 1 -d '@')"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for mac in ${PROVISIONING_MACS//,/ }; do
|
for mac in ${PROVISIONING_MACS//,/ }; do
|
||||||
if ip -br link show up | grep -qi "$mac"; then
|
if ip -br link show up | grep -i "$mac" &>/dev/null; then
|
||||||
interface="$(ip -br link show up | grep -i "$mac" | cut -f 1 -d ' ' | cut -f 1 -d '@')"
|
interface="$(ip -br link show up | grep -i "$mac" | cut -f 1 -d ' ' | cut -f 1 -d '@')"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
@@ -42,9 +67,12 @@ export LISTEN_ALL_INTERFACES="${LISTEN_ALL_INTERFACES:-true}"
|
|||||||
# Wait for the interface or IP to be up, sets $IRONIC_IP
|
# Wait for the interface or IP to be up, sets $IRONIC_IP
|
||||||
wait_for_interface_or_ip()
|
wait_for_interface_or_ip()
|
||||||
{
|
{
|
||||||
# If $PROVISIONING_IP is specified, then we wait for that to become available on an interface, otherwise we look at $PROVISIONING_INTERFACE for an IP
|
# If $PROVISIONING_IP is specified, then we wait for that to become
|
||||||
if [[ -n "$PROVISIONING_IP" ]]; then
|
# available on an interface, otherwise we look at $PROVISIONING_INTERFACE
|
||||||
# Convert the address using ipcalc which strips out the subnet. For IPv6 addresses, this will give the short-form address
|
# for an IP
|
||||||
|
if [[ -n "${PROVISIONING_IP}" ]]; then
|
||||||
|
# Convert the address using ipcalc which strips out the subnet.
|
||||||
|
# For IPv6 addresses, this will give the short-form address
|
||||||
IRONIC_IP="$(ipcalc "${PROVISIONING_IP}" | grep "^Address:" | awk '{print $2}')"
|
IRONIC_IP="$(ipcalc "${PROVISIONING_IP}" | grep "^Address:" | awk '{print $2}')"
|
||||||
export IRONIC_IP
|
export IRONIC_IP
|
||||||
until grep -F " ${IRONIC_IP}/" <(ip -br addr show); do
|
until grep -F " ${IRONIC_IP}/" <(ip -br addr show); do
|
||||||
@@ -69,31 +97,37 @@ wait_for_interface_or_ip()
|
|||||||
export IPV=4
|
export IPV=4
|
||||||
export IRONIC_URL_HOST="$IRONIC_IP"
|
export IRONIC_URL_HOST="$IRONIC_IP"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Avoid having to construct full URL multiple times while allowing
|
||||||
|
# the override of IRONIC_HTTP_URL for environments in which IRONIC_IP
|
||||||
|
# is unreachable from hosts being provisioned.
|
||||||
|
export IRONIC_HTTP_URL="${IRONIC_HTTP_URL:-http://${IRONIC_URL_HOST}:${HTTP_PORT}}"
|
||||||
|
export IRONIC_TFTP_URL="${IRONIC_TFTP_URL:-tftp://${IRONIC_URL_HOST}}"
|
||||||
|
export IRONIC_BASE_URL=${IRONIC_BASE_URL:-"${IRONIC_SCHEME}://${IRONIC_URL_HOST}:${IRONIC_ACCESS_PORT}"}
|
||||||
}
|
}
|
||||||
|
|
||||||
render_j2_config()
|
render_j2_config()
|
||||||
{
|
{
|
||||||
ls $1 # DEBUG
|
python3.11 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' < "$1" > "$2"
|
||||||
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()
|
run_ironic_dbsync()
|
||||||
{
|
{
|
||||||
if [[ "${IRONIC_USE_MARIADB:-true}" == "true" ]]; then
|
if [[ "${IRONIC_USE_MARIADB}" == "true" ]]; then
|
||||||
# It's possible for the dbsync to fail if mariadb is not up yet, so
|
# It's possible for the dbsync to fail if mariadb is not up yet, so
|
||||||
# retry until success
|
# retry until success
|
||||||
until ironic-dbsync --config-file /etc/ironic/ironic.conf upgrade; do
|
until ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" upgrade; do
|
||||||
echo "WARNING: ironic-dbsync failed, retrying"
|
echo "WARNING: ironic-dbsync failed, retrying"
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
# SQLite does not support some statements. Fortunately, we can just create
|
# SQLite does not support some statements. Fortunately, we can just
|
||||||
# the schema in one go if not already created, instead of going through an upgrade
|
# create the schema in one go if not already created, instead of going
|
||||||
DB_VERSION="$(ironic-dbsync --config-file /etc/ironic/ironic.conf version)"
|
# through an upgrade
|
||||||
|
cp "/var/lib/ironic/ironic.sqlite" "${IRONIC_DB_DIR}/ironic.sqlite"
|
||||||
|
DB_VERSION="$(ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" version)"
|
||||||
if [[ "${DB_VERSION}" == "None" ]]; then
|
if [[ "${DB_VERSION}" == "None" ]]; then
|
||||||
ironic-dbsync --config-file /etc/ironic/ironic.conf create_schema
|
ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" create_schema
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
23
ironic-image/scripts/ironic-probe.sh
Executable file
23
ironic-image/scripts/ironic-probe.sh
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eu -o pipefail
|
||||||
|
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. /bin/ironic-common.sh
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. /bin/auth-common.sh
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
curl -sSf ${PROBE_CURL_ARGS} "${PROBE_URL}"
|
10
ironic-image/scripts/rundatabase-upgrade
Executable file
10
ironic-image/scripts/rundatabase-upgrade
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. /bin/configure-ironic.sh
|
||||||
|
|
||||||
|
# NOTE(dtantsur): no retries here: this script is supposed to be run as a Job
|
||||||
|
# that is retried on failure.
|
||||||
|
exec ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" upgrade
|
@@ -13,7 +13,11 @@ export DNS_PORT=${DNS_PORT:-0}
|
|||||||
|
|
||||||
wait_for_interface_or_ip
|
wait_for_interface_or_ip
|
||||||
if [[ "${DNS_IP:-}" == "provisioning" ]]; then
|
if [[ "${DNS_IP:-}" == "provisioning" ]]; then
|
||||||
export DNS_IP="$IRONIC_URL_HOST"
|
if [[ "${IPV}" == "4" ]]; then
|
||||||
|
export DNS_IP="${IRONIC_IP}"
|
||||||
|
else
|
||||||
|
export DNS_IP="[${IRONIC_IP}]"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p /shared/tftpboot
|
mkdir -p /shared/tftpboot
|
||||||
@@ -32,12 +36,12 @@ fi
|
|||||||
# Template and write dnsmasq.conf
|
# Template and write dnsmasq.conf
|
||||||
# we template via /tmp as sed otherwise creates temp files in /etc directory
|
# we template via /tmp as sed otherwise creates temp files in /etc directory
|
||||||
# where we can't write
|
# where we can't write
|
||||||
python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' </etc/dnsmasq.conf.j2 >/tmp/dnsmasq.conf
|
python3.11 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' <"/templates/dnsmasq.conf.j2" >"${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf"
|
||||||
|
|
||||||
for iface in $(echo "$DNSMASQ_EXCEPT_INTERFACE" | tr ',' ' '); do
|
for iface in $(echo "$DNSMASQ_EXCEPT_INTERFACE" | tr ',' ' '); do
|
||||||
sed -i -e "/^interface=.*/ a\except-interface=${iface}" /tmp/dnsmasq.conf
|
sed -i -e "/^interface=.*/ a\except-interface=${iface}" "${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf"
|
||||||
done
|
done
|
||||||
cat /tmp/dnsmasq.conf > /etc/dnsmasq.conf
|
cat "${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf" > "${DNSMASQ_CONF_DIR}/dnsmasq.conf"
|
||||||
rm /tmp/dnsmasq.conf
|
rm "${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf"
|
||||||
|
|
||||||
exec /usr/sbin/dnsmasq -d -q -C /etc/dnsmasq.conf
|
exec /usr/sbin/dnsmasq -d -q -C "${DNSMASQ_CONF_DIR}/dnsmasq.conf"
|
@@ -28,25 +28,28 @@ wait_for_interface_or_ip
|
|||||||
mkdir -p /shared/html
|
mkdir -p /shared/html
|
||||||
chmod 0777 /shared/html
|
chmod 0777 /shared/html
|
||||||
|
|
||||||
IRONIC_BASE_URL="${IRONIC_SCHEME}://${IRONIC_URL_HOST}"
|
INSPECTOR_EXTRA_ARGS=" ipa-inspection-callback-url=${IRONIC_BASE_URL}/v1/continue_inspection"
|
||||||
|
|
||||||
INSPECTOR_EXTRA_ARGS=" ipa-inspection-callback-url=${IRONIC_BASE_URL}:${IRONIC_ACCESS_PORT}/v1/continue_inspection"
|
|
||||||
|
|
||||||
if [[ "$IRONIC_FAST_TRACK" == "true" ]]; then
|
if [[ "$IRONIC_FAST_TRACK" == "true" ]]; then
|
||||||
INSPECTOR_EXTRA_ARGS+=" ipa-api-url=${IRONIC_BASE_URL}:${IRONIC_ACCESS_PORT}"
|
INSPECTOR_EXTRA_ARGS+=" ipa-api-url=${IRONIC_BASE_URL}"
|
||||||
fi
|
fi
|
||||||
export INSPECTOR_EXTRA_ARGS
|
export INSPECTOR_EXTRA_ARGS
|
||||||
|
|
||||||
# Copy files to shared mount
|
# Copy files to shared mount
|
||||||
render_j2_config /tmp/inspector.ipxe.j2 /shared/html/inspector.ipxe
|
render_j2_config /templates/inspector.ipxe.j2 /shared/html/inspector.ipxe
|
||||||
cp /tmp/uefi_esp*.img /shared/html/
|
# cp -r /etc/httpd/* "${HTTPD_DIR}"
|
||||||
|
if [[ -f "${HTTPD_CONF_DIR}/httpd.conf" ]]; then
|
||||||
|
mv "${HTTPD_CONF_DIR}/httpd.conf" "${HTTPD_CONF_DIR}/httpd.conf.example"
|
||||||
|
fi
|
||||||
|
|
||||||
# Render the core httpd config
|
# Render the core httpd config
|
||||||
render_j2_config /etc/httpd/conf/httpd.conf.j2 /etc/httpd/conf/httpd.conf
|
render_j2_config "/etc/httpd/conf/httpd.conf.j2" \
|
||||||
|
"${HTTPD_CONF_DIR}/httpd.conf"
|
||||||
|
|
||||||
if [[ "$IRONIC_TLS_SETUP" == "true" ]]; then
|
if [[ "$IRONIC_TLS_SETUP" == "true" ]]; then
|
||||||
if [[ "${IRONIC_REVERSE_PROXY_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
|
render_j2_config "/templates/httpd-ironic-api.conf.j2" \
|
||||||
|
"${HTTPD_CONF_DIR_D}/ironic.conf"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
export IRONIC_REVERSE_PROXY_SETUP="false" # If TLS is not used, we have no reason to use the reverse proxy
|
export IRONIC_REVERSE_PROXY_SETUP="false" # If TLS is not used, we have no reason to use the reverse proxy
|
||||||
@@ -56,33 +59,24 @@ write_htpasswd_files
|
|||||||
|
|
||||||
# Render httpd TLS configuration for /shared/html/<redifsh;ilo>
|
# Render httpd TLS configuration for /shared/html/<redifsh;ilo>
|
||||||
if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]]; then
|
if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]]; then
|
||||||
render_j2_config /etc/httpd-vmedia.conf.j2 /etc/httpd/conf.d/vmedia.conf
|
render_j2_config "/templates/httpd-vmedia.conf.j2" \
|
||||||
|
"${HTTPD_CONF_DIR_D}/vmedia.conf"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Render httpd TLS configuration for /shared/html
|
# Render httpd TLS configuration for /shared/html
|
||||||
if [[ "$IPXE_TLS_SETUP" == "true" ]]; then
|
if [[ "$IPXE_TLS_SETUP" == "true" ]]; then
|
||||||
mkdir -p /shared/html/custom-ipxe
|
mkdir -p /shared/html/custom-ipxe
|
||||||
chmod 0777 /shared/html/custom-ipxe
|
chmod 0777 /shared/html/custom-ipxe
|
||||||
render_j2_config "/etc/httpd-ipxe.conf.j2" "/etc/httpd/conf.d/ipxe.conf"
|
render_j2_config "/templates/httpd-ipxe.conf.j2" "${HTTPD_CONF_DIR_D}/ipxe.conf"
|
||||||
cp "${IPXE_CUSTOM_FIRMWARE_DIR}/undionly.kpxe" \
|
cp "${IPXE_CUSTOM_FIRMWARE_DIR}/undionly.kpxe" \
|
||||||
"${IPXE_CUSTOM_FIRMWARE_DIR}/snponly.efi" \
|
"${IPXE_CUSTOM_FIRMWARE_DIR}/snponly.efi" \
|
||||||
"/shared/html/custom-ipxe"
|
"/shared/html/custom-ipxe"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Set up inotify to kill the container (restart) whenever cert files for ironic api change
|
# Set up inotify to kill the container (restart) whenever cert files for ironic api change
|
||||||
if [[ "$IRONIC_TLS_SETUP" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then
|
configure_restart_on_certificate_update "${IRONIC_TLS_SETUP}" httpd "${IRONIC_CERT_FILE}"
|
||||||
# shellcheck disable=SC2034
|
|
||||||
python3.11 -m pyinotify --raw-format -e IN_DELETE_SELF -v "${IRONIC_CERT_FILE}" | while read -r file event; do
|
|
||||||
kill -WINCH $(pgrep httpd)
|
|
||||||
done &
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set up inotify to kill the container (restart) whenever cert of httpd for /shared/html/<redifsh;ilo> path change
|
# Set up inotify to kill the container (restart) whenever cert of httpd for /shared/html/<redifsh;ilo> path change
|
||||||
if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then
|
configure_restart_on_certificate_update "${IRONIC_VMEDIA_TLS_SETUP}" httpd "${IRONIC_VMEDIA_CERT_FILE}"
|
||||||
# shellcheck disable=SC2034
|
|
||||||
python3.11 -m pyinotify --raw-format -e IN_DELETE_SELF -v "${IRONIC_VMEDIA_CERT_FILE}" | while read -r file event; do
|
|
||||||
kill -WINCH $(pgrep httpd)
|
|
||||||
done &
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec /usr/sbin/httpd -DFOREGROUND -f /etc/httpd/conf/httpd.conf
|
exec /usr/sbin/httpd -DFOREGROUND -f "${HTTPD_CONF_DIR}/httpd.conf"
|
18
ironic-image/scripts/runironic
Normal file
18
ironic-image/scripts/runironic
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. /bin/configure-ironic.sh
|
||||||
|
|
||||||
|
# Ramdisk logs
|
||||||
|
mkdir -p /shared/log/ironic/deploy
|
||||||
|
|
||||||
|
# Allows skipping dbsync if it's done by an external job
|
||||||
|
if [[ "${IRONIC_SKIP_DBSYNC:-false}" != true ]]; then
|
||||||
|
run_ironic_dbsync
|
||||||
|
fi
|
||||||
|
|
||||||
|
configure_restart_on_certificate_update "${IRONIC_TLS_SETUP}" ironic "${IRONIC_CERT_FILE}"
|
||||||
|
|
||||||
|
configure_ironic_auth
|
||||||
|
|
||||||
|
exec /usr/bin/ironic --config-dir "${IRONIC_CONF_DIR}"
|
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
. /bin/configure-ironic.sh
|
. /bin/configure-ironic.sh
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. /bin/ironic-common.sh
|
||||||
|
|
||||||
FLASK_RUN_HOST=${FLASK_RUN_HOST:-0.0.0.0}
|
FLASK_RUN_HOST=${FLASK_RUN_HOST:-0.0.0.0}
|
||||||
FLASK_RUN_PORT=${FLASK_RUN_PORT:-9608}
|
FLASK_RUN_PORT=${FLASK_RUN_PORT:-9608}
|
||||||
|
|
||||||
export IRONIC_CONFIG="/etc/ironic/ironic.conf"
|
export IRONIC_CONFIG="${IRONIC_CONF_DIR}/ironic.conf"
|
||||||
|
|
||||||
exec gunicorn -b "${FLASK_RUN_HOST}:${FLASK_RUN_PORT}" -w 4 \
|
exec gunicorn -b "${FLASK_RUN_HOST}:${FLASK_RUN_PORT}" -w 4 \
|
||||||
ironic_prometheus_exporter.app.wsgi:application
|
ironic_prometheus_exporter.app.wsgi:application
|
21
ironic-image/scripts/runlogwatch.sh
Normal file
21
ironic-image/scripts/runlogwatch.sh
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# Ramdisk logs path
|
||||||
|
LOG_DIR="/shared/log/ironic/deploy"
|
||||||
|
|
||||||
|
mkdir -p "${LOG_DIR}"
|
||||||
|
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
python3.11 -m pyinotify --raw-format -e IN_CLOSE_WRITE -v "${LOG_DIR}" |
|
||||||
|
while read -r event dir mask maskname filename filepath pathname wd; do
|
||||||
|
#NOTE(elfosardo): a pyinotify event looks like this:
|
||||||
|
# <Event dir=False mask=0x8 maskname=IN_CLOSE_WRITE name=mylogs.gzip path=/shared/log/ironic/deploy pathname=/shared/log/ironic/deploy/mylogs.gzip wd=1 >
|
||||||
|
FILENAME=$(echo "${filename}" | cut -d'=' -f2-)
|
||||||
|
echo "************ Contents of ${LOG_DIR}/${FILENAME} ramdisk log file bundle **************"
|
||||||
|
tar -tzf "${LOG_DIR}/${FILENAME}" | while read -r entry; do
|
||||||
|
echo "${FILENAME}: **** Entry: ${entry} ****"
|
||||||
|
tar -xOzf "${LOG_DIR}/${FILENAME}" "${entry}" | sed -e "s/^/${FILENAME}: /"
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
rm -f "${LOG_DIR}/${FILENAME}"
|
||||||
|
done
|
10
ironic-image/scripts/runonline-data-migrations
Executable file
10
ironic-image/scripts/runonline-data-migrations
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
. /bin/configure-ironic.sh
|
||||||
|
|
||||||
|
# NOTE(dtantsur): no retries here: this script is supposed to be run as a Job
|
||||||
|
# that is retried on failure.
|
||||||
|
exec ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" online_data_migrations
|
@@ -20,11 +20,6 @@ export MARIADB_CACERT_FILE=/certs/ca/mariadb/tls.crt
|
|||||||
|
|
||||||
export IPXE_TLS_PORT="${IPXE_TLS_PORT:-8084}"
|
export IPXE_TLS_PORT="${IPXE_TLS_PORT:-8084}"
|
||||||
|
|
||||||
mkdir -p /certs/ironic
|
|
||||||
mkdir -p /certs/ca/ironic
|
|
||||||
mkdir -p /certs/ipxe
|
|
||||||
mkdir -p /certs/vmedia
|
|
||||||
|
|
||||||
if [[ -f "$IRONIC_CERT_FILE" ]] && [[ ! -f "$IRONIC_KEY_FILE" ]]; then
|
if [[ -f "$IRONIC_CERT_FILE" ]] && [[ ! -f "$IRONIC_KEY_FILE" ]]; then
|
||||||
echo "Missing TLS Certificate key file $IRONIC_KEY_FILE"
|
echo "Missing TLS Certificate key file $IRONIC_KEY_FILE"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -69,6 +64,7 @@ if [[ -f "$IRONIC_CERT_FILE" ]] || [[ -f "$IRONIC_CACERT_FILE" ]]; then
|
|||||||
export IRONIC_TLS_SETUP="true"
|
export IRONIC_TLS_SETUP="true"
|
||||||
export IRONIC_SCHEME="https"
|
export IRONIC_SCHEME="https"
|
||||||
if [[ ! -f "$IRONIC_CACERT_FILE" ]]; then
|
if [[ ! -f "$IRONIC_CACERT_FILE" ]]; then
|
||||||
|
mkdir -p "$(dirname "${IRONIC_CACERT_FILE}")"
|
||||||
copy_atomic "$IRONIC_CERT_FILE" "$IRONIC_CACERT_FILE"
|
copy_atomic "$IRONIC_CERT_FILE" "$IRONIC_CACERT_FILE"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
@@ -95,3 +91,21 @@ if [[ -f "$MARIADB_CACERT_FILE" ]]; then
|
|||||||
else
|
else
|
||||||
export MARIADB_TLS_ENABLED="false"
|
export MARIADB_TLS_ENABLED="false"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
configure_restart_on_certificate_update()
|
||||||
|
{
|
||||||
|
local enabled="$1"
|
||||||
|
local service="$2"
|
||||||
|
local cert_file="$3"
|
||||||
|
local signal="TERM"
|
||||||
|
|
||||||
|
if [[ "${enabled}" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then
|
||||||
|
if [[ "${service}" == httpd ]]; then
|
||||||
|
signal="WINCH"
|
||||||
|
fi
|
||||||
|
python3.12 -m pyinotify --raw-format -e IN_DELETE_SELF -v "${cert_file}" |
|
||||||
|
while read -r; do
|
||||||
|
pkill "-${signal}" "${service}"
|
||||||
|
done &
|
||||||
|
fi
|
||||||
|
}
|
Reference in New Issue
Block a user