Skip to content

Commit

Permalink
Merge pull request #354 from dtantsur/sync
Browse files Browse the repository at this point in the history
Merge from upstream metal3-io/ironic-image
  • Loading branch information
openshift-merge-robot committed Apr 3, 2023
2 parents 41750f9 + 44a9337 commit e98d4c1
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 32 deletions.
6 changes: 5 additions & 1 deletion Dockerfile.fcos
Expand Up @@ -12,7 +12,7 @@ ENV PKGS_LIST=main-packages-list.ocp
ARG EXTRA_PKGS_LIST

COPY ${PKGS_LIST} ${EXTRA_PKGS_LIST:-$PKGS_LIST} /tmp/
COPY prepare-image.sh prepare-ipxe.sh /bin/
COPY prepare-image.sh prepare-ipxe.sh configure-nonroot.sh /bin/

# Configure OpenStack repos
RUN sed -i 's/ >=.*//g' /tmp/main-packages-list.ocp && \
Expand Down Expand Up @@ -49,4 +49,8 @@ RUN mkdir -p /var/lib/ironic /var/lib/ironic-inspector && \
COPY ironic-inspector-config/ironic-inspector.conf.j2 /etc/ironic-inspector/
COPY ironic-inspector-config/inspector-apache.conf.j2 /etc/httpd/conf.d/

# configure non-root user and set relevant permissions
RUN configure-nonroot.sh && \
rm -f /bin/configure-nonroot.sh

ENV IS_FCOS=true
6 changes: 5 additions & 1 deletion Dockerfile.ocp
Expand Up @@ -12,7 +12,7 @@ ENV PKGS_LIST=main-packages-list.ocp
ARG EXTRA_PKGS_LIST

COPY ${PKGS_LIST} ${EXTRA_PKGS_LIST:-$PKGS_LIST} /tmp/
COPY prepare-image.sh prepare-ipxe.sh /bin/
COPY prepare-image.sh prepare-ipxe.sh configure-nonroot.sh /bin/

RUN prepare-image.sh && \
rm -f /bin/prepare-image.sh && \
Expand Down Expand Up @@ -43,3 +43,7 @@ RUN mkdir -p /var/lib/ironic /var/lib/ironic-inspector && \
# IRONIC-INSPECTOR #
COPY ironic-inspector-config/ironic-inspector.conf.j2 /etc/ironic-inspector/
COPY ironic-inspector-config/inspector-apache.conf.j2 /etc/httpd/conf.d/

# configure non-root user and set relevant permissions
RUN configure-nonroot.sh && \
rm -f /bin/configure-nonroot.sh
6 changes: 5 additions & 1 deletion Dockerfile.scos
Expand Up @@ -12,7 +12,7 @@ ENV PKGS_LIST=main-packages-list.ocp
ARG EXTRA_PKGS_LIST

COPY ${PKGS_LIST} ${EXTRA_PKGS_LIST:-$PKGS_LIST} /tmp/
COPY prepare-image.sh prepare-ipxe.sh /bin/
COPY prepare-image.sh prepare-ipxe.sh configure-nonroot.sh /bin/

# Configure OpenStack repos
RUN sed -i 's/ >=.*//g' /tmp/main-packages-list.ocp && \
Expand Down Expand Up @@ -49,4 +49,8 @@ RUN mkdir -p /var/lib/ironic /var/lib/ironic-inspector && \
COPY ironic-inspector-config/ironic-inspector.conf.j2 /etc/ironic-inspector/
COPY ironic-inspector-config/inspector-apache.conf.j2 /etc/httpd/conf.d/

# configure non-root user and set relevant permissions
RUN configure-nonroot.sh && \
rm -f /bin/configure-nonroot.sh

ENV IS_SCOS=true
42 changes: 21 additions & 21 deletions README.md
Expand Up @@ -11,33 +11,33 @@ When updated, builds are automatically triggered on https://quay.io/repository/m
This repo supports the creation of multiple containers needed when provisioning baremetal nodes with Ironic. Eventually there will be separate images for each container, but currently separate containers can share this same image with specific entry points.

The following entry points are provided:
- runironic - Starts the ironic-conductor and ironic-api processes to manage the provisioning of baremetal nodes. Details on Ironic can be found at https://docs.openstack.org/ironic/latest/. This is the default entry point used by the Dockerfile.
- rundnsmasq - Runs the dnmasq dhcp server to provide addresses and initiate PXE boot of baremetal nodes. This includes a lightweight TFTP server. Details on dnsmasq can be found at http://www.thekelleys.org.uk/dnsmasq/doc.html.
- runhttpd - Starts the Apache web server to provide images via http for PXE boot and for deployment of the final images.
- runlogwatch - Waits for host provisioning ramdisk logs to appear, prints their contents and deletes files.
- `runironic` - Starts the ironic-conductor and ironic-api processes to manage the provisioning of baremetal nodes. Details on Ironic can be found at https://docs.openstack.org/ironic/latest/. This is the default entry point used by the Dockerfile.
- `rundnsmasq` - Runs the dnmasq dhcp server to provide addresses and initiate PXE boot of baremetal nodes. This includes a lightweight TFTP server. Details on dnsmasq can be found at http://www.thekelleys.org.uk/dnsmasq/doc.html.
- `runhttpd` - Starts the Apache web server to provide images via http for PXE boot and for deployment of the final images.
- `runlogwatch` - Waits for host provisioning ramdisk logs to appear, prints their contents and deletes files.

All of the containers must share a common mount point or data store. Ironic requires files for both the TFTP server and HTTP server to be stored in the same partition. This common store must include, in <shared store>/html/images, the following images:
- ironic-python-agent.kernel
- ironic-python-agent.initramfs
- final image to be deployed onto node in qcow2 format

The following environment variables can be passed in to customize run-time functionality:
- PROVISIONING_MACS - a comma seperated list of mac address of the master nodes (used to determine the PROVISIONING_INTERFACE)
- PROVISIONING_INTERFACE - interface to use for ironic, dnsmasq(dhcpd) and httpd (default provisioning, this is calculated if the above PROVISIONING_MACS is provided)
- DNSMASQ_EXCEPT_INTERFACE - interfaces to exclude when providing DHCP address (default "lo")
- HTTP_PORT - port used by http server (default 80)
- DHCP_RANGE - dhcp range to use for provisioning (default 172.22.0.10-172.22.0.100)
- DHCP_HOSTS - a `;` separated list of `dhcp-host` entries, e.g. known MAC addresses like `00:20:e0:3b:13:af;00:20:e0:3b:14:af` (empty by default). For more details on `dhcp-host` see [the man page](https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html).
- DHCP_IGNORE - a set of tags on hosts that should be ignored and not allocate DHCP leases for, e.g. `tag:!known` to ignore any unknown hosts (empty by default)
- MARIADB_PASSWORD - The database password
- OS_<section>_\_<name>=<value> - This format can be used to set arbitary ironic config options
- IRONIC_RAMDISK_SSH_KEY - A public key to allow ssh access to nodes running IPA, takes the format "ssh-rsa AAAAB3....."
- IRONIC_KERNEL_PARAMS - This parameter can be used to add additional kernel parameters to nodes running IPA
- GATEWAY_IP - gateway IP address to use for ironic dnsmasq(dhcpd)
- DNS_IP - DNS IP address to use for ironic dnsmasq(dhcpd)
- `PROVISIONING_MACS` - a comma seperated list of mac address of the master nodes (used to determine the `PROVISIONING_INTERFACE`)
- `PROVISIONING_INTERFACE` - interface to use for ironic, dnsmasq(dhcpd) and httpd (default provisioning, this is calculated if the above `PROVISIONING_MACS` is provided)
- `DNSMASQ_EXCEPT_INTERFACE` - interfaces to exclude when providing DHCP address (default "lo")
- `HTTP_PORT` - port used by http server (default 80)
- `DHCP_RANGE` - dhcp range to use for provisioning (default 172.22.0.10-172.22.0.100)
- `DHCP_HOSTS` - a `;` separated list of `dhcp-host` entries, e.g. known MAC addresses like `00:20:e0:3b:13:af;00:20:e0:3b:14:af` (empty by default). For more details on `dhcp-host` see [the man page](https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html).
- `DHCP_IGNORE` - a set of tags on hosts that should be ignored and not allocate DHCP leases for, e.g. `tag:!known` to ignore any unknown hosts (empty by default)
- `MARIADB_PASSWORD` - The database password
- `OS_<section>_\_<name>=<value>` - This format can be used to set arbitary ironic config options
- `IRONIC_RAMDISK_SSH_KEY` - A public key to allow ssh access to nodes running IPA, takes the format "ssh-rsa AAAAB3....."
- `IRONIC_KERNEL_PARAMS` - This parameter can be used to add additional kernel parameters to nodes running IPA
- `GATEWAY_IP` - gateway IP address to use for ironic dnsmasq(dhcpd)
- `DNS_IP` - DNS IP address to use for ironic dnsmasq(dhcpd)

The ironic configuration can be overridden by various environment variables. The following can serve as an example:
- OS_CONDUCTOR__DEPLOY_CALLBACK_TIMEOUT=4800 - timeout (seconds) to wait for a callback from a deploy ramdisk
- OS_CONDUCTOR__INSPECT_TIMEOUT=1800 - timeout (seconds) for waiting for node inspection
- OS_CONDUCTOR__CLEAN_CALLBACK_TIMEOUT=1800 - timeout (seconds) to wait for a callback from the ramdisk doing the cleaning
- OS_PXE__BOOT_RETRY_TIMEOUT=1200 - timeout (seconds) to enable boot retries.
- `OS_CONDUCTOR__DEPLOY_CALLBACK_TIMEOUT=4800` - timeout (seconds) to wait for a callback from a deploy ramdisk
- `OS_CONDUCTOR__INSPECT_TIMEOUT=1800` - timeout (seconds) for waiting for node inspection
- `OS_CONDUCTOR__CLEAN_CALLBACK_TIMEOUT=1800` - timeout (seconds) to wait for a callback from the ramdisk doing the cleaning
- `OS_PXE__BOOT_RETRY_TIMEOUT=1200` - timeout (seconds) to enable boot retries.
43 changes: 43 additions & 0 deletions configure-nonroot.sh
@@ -0,0 +1,43 @@
#!/usr/bin/bash

# This script changes permissions to allow Ironic container to run as non-root
# user. As the same image is used to run ironic, ironic-httpd, ironic-dsnmasq,
# ironic-inspector and ironic-log-watch via BMO's ironic k8s manifest, it has
# to be configured to work with multiple different users and groups, while they
# share files via bind mounts (/shared, /certs/*), which can only get one
# group id as "fsGroup". Additionally, dnsmasq needs three capabilities to run
# which we provide via "setcap", and "allowPrivilegeEscalation: true" in
# manifest.

set -eux

# user and group are from ironic rpms (uid 997, gid 994)
IRONIC_USER="ironic"
IRONIC_GROUP="ironic"
INSPECTOR_GROUP="ironic-inspector"

# we'll bind mount shared ca and ironic/inspector 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
chown "${IRONIC_USER}":"${INSPECTOR_GROUP}" /certs
chmod 2775 /certs

# ironic, inspector and httpd related changes
chown -R root:"${IRONIC_GROUP}" /etc/ironic /etc/httpd/conf /etc/httpd/conf.d
chown -R "${IRONIC_USER}":"${INSPECTOR_GROUP}" /etc/ironic-inspector
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/*

chown -R root:"${IRONIC_GROUP}" /var/lib/ironic
chown -R root:"${INSPECTOR_GROUP}" /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

# dnsmasq, and the capabilities required to run it as non-root user
chown -R root:"${IRONIC_GROUP}" /etc/dnsmasq.conf /var/lib/dnsmasq
chmod 2775 /var/lib/dnsmasq
touch /var/lib/dnsmasq/dnsmasq.leases
chmod 664 /etc/dnsmasq.conf /var/lib/dnsmasq/dnsmasq.leases

setcap "cap_net_raw,cap_net_admin,cap_net_bind_service=+eip" /usr/sbin/dnsmasq
6 changes: 5 additions & 1 deletion prepare-image.sh
Expand Up @@ -12,7 +12,7 @@ if [ $(uname -m) = "x86_64" ]; then
dnf install -y syslinux-nonlinux;
fi

if [[ ! -z ${EXTRA_PKGS_LIST:-} ]]; then
if [[ -n ${EXTRA_PKGS_LIST:-} ]]; then
if [[ -s /tmp/${EXTRA_PKGS_LIST} ]]; then
xargs -rtd'\n' dnf install -y < /tmp/${EXTRA_PKGS_LIST}
fi
Expand All @@ -25,5 +25,9 @@ rm -f /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/autoindex.conf /etc/httpd/con
# RDO-provided configuration forces creating log files
rm -f /usr/share/ironic/ironic-dist.conf /etc/ironic-inspector/inspector-dist.conf

# add ironic and ironic-inspector to apache group
usermod -aG ironic apache
usermod -aG ironic-inspector apache

dnf clean all
rm -rf /var/cache/{yum,dnf}/*
5 changes: 5 additions & 0 deletions scripts/ironic-common.sh
Expand Up @@ -2,6 +2,11 @@

set -euxo pipefail

IRONIC_IP="${IRONIC_IP:-}"
PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-}"
PROVISIONING_IP="${PROVISIONING_IP:-}"
PROVISIONING_MACS="${PROVISIONING_MACS:-}"

function get_provisioning_interface() {
if [ -n "${PROVISIONING_INTERFACE:-}" ]; then
# don't override the PROVISIONING_INTERFACE if one is provided
Expand Down
12 changes: 9 additions & 3 deletions scripts/rundnsmasq
@@ -1,5 +1,8 @@
#!/usr/bin/bash

set -eux

# shellcheck disable=SC1091
. /bin/ironic-common.sh

export HTTP_PORT=${HTTP_PORT:-"80"}
Expand All @@ -11,7 +14,6 @@ if [[ "${DNS_IP:-}" == "provisioning" ]]; then
export DNS_IP="$IRONIC_URL_HOST"
fi


mkdir -p /shared/tftpboot
mkdir -p /shared/tftpboot/arm64-efi
mkdir -p /shared/html/images
Expand All @@ -22,10 +24,14 @@ cp /tftpboot/undionly.kpxe /tftpboot/snponly.efi /shared/tftpboot
cp /tftpboot/arm64-efi/snponly.efi /shared/tftpboot/arm64-efi

# Template and write dnsmasq.conf
python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' </etc/dnsmasq.conf.j2 >/etc/dnsmasq.conf
# we template via /tmp as sed otherwise creates temp files in /etc directory
# 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

for iface in $( echo "$DNSMASQ_EXCEPT_INTERFACE" | tr ',' ' '); do
sed -i -e "/^interface=.*/ a\except-interface=${iface}" /etc/dnsmasq.conf
sed -i -e "/^interface=.*/ a\except-interface=${iface}" /tmp/dnsmasq.conf
done
cat /tmp/dnsmasq.conf > /etc/dnsmasq.conf
rm /tmp/dnsmasq.conf

exec /usr/sbin/dnsmasq -d -q -C /etc/dnsmasq.conf
9 changes: 5 additions & 4 deletions scripts/runhttpd
Expand Up @@ -38,8 +38,6 @@ if [ "$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
# Add user 'apache' to the group `ironic-inspector`, so httpd can access /etc/ironic-inspector and read the pasword file
usermod -aG ironic-inspector apache
else
export INSPECTOR_REVERSE_PROXY_SETUP="false" # If TLS is not used, we have no reason to use the reverse proxy
fi
Expand All @@ -48,8 +46,6 @@ if [ "$IRONIC_TLS_SETUP" = "true" ]; then
if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "true" ]]; then
render_j2_config /etc/httpd-ironic-api.conf.j2 /etc/httpd/conf.d/ironic.conf
fi
# Add user 'apache' to the group `ironic-inspector`, so httpd can access /etc/ironic-inspector and read the pasword file
usermod -aG ironic apache
else
export IRONIC_REVERSE_PROXY_SETUP="false" # If TLS is not used, we have no reason to use the reverse proxy
fi
Expand Down Expand Up @@ -78,6 +74,11 @@ sed -i -e 's|\(^[[:space:]]*\)\(DocumentRoot\)\(.*\)|\1\2 "/shared/html"|' \
sed -i -e 's%^ \+CustomLog.*% CustomLog /dev/stderr combined%g' /etc/httpd/conf/httpd.conf
sed -i -e 's%^ErrorLog.*%ErrorLog /dev/stderr%g' /etc/httpd/conf/httpd.conf

# put pidfile somewhere we can write as nonroot
cat <<'EOF' >>/etc/httpd/conf/httpd.conf
PidFile /var/tmp/httpd.pid
EOF

if [ "$IRONIC_VMEDIA_TLS_SETUP" = "true" ]; then
render_j2_config /etc/httpd-vmedia.conf.j2 /etc/httpd/conf.d/vmedia.conf
fi
Expand Down

0 comments on commit e98d4c1

Please sign in to comment.