Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ COPY --from=builder /tmp/esp.img /tmp/uefi_esp.img

COPY config/ironic.conf.j2 /etc/ironic/

# TODO(dtantsur): remove scripts/runironic script when we stop supporting
# running both API and conductor processes via one entry point.
COPY scripts/ /bin/
COPY config/dnsmasq.conf.j2 /etc/
COPY config/inspector.ipxe.j2 config/dualboot.ipxe /tmp/
Expand All @@ -57,5 +55,6 @@ COPY config/inspector.ipxe.j2 config/dualboot.ipxe /tmp/
RUN rm -f /etc/httpd/conf.d/autoindex.conf /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.modules.d/*.conf
COPY config/httpd.conf /etc/httpd/conf.d/
COPY config/httpd-modules.conf /etc/httpd/conf.modules.d/
COPY config/apache2-ironic-api.conf.j2 /etc/httpd-ironic-api.conf.j2

ENTRYPOINT ["/bin/runironic"]
52 changes: 52 additions & 0 deletions config/apache2-ironic-api.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

Listen 6385

{% if env.LISTEN_ALL_INTERFACES | lower == "true" %}
<VirtualHost *:6385>
{% else %}
<VirtualHost {{ env.IRONIC_URL_HOST }}:6385>
{% endif %}

WSGIDaemonProcess ironic user=ironic group=ironic threads=10 display-name=%{GROUP}
WSGIScriptAlias / /usr/bin/ironic-api-wsgi

SetEnv APACHE_RUN_USER ironic
SetEnv APACHE_RUN_GROUP ironic
WSGIProcessGroup ironic

ErrorLog /dev/stderr
LogLevel debug
CustomLog /dev/stdout combined

{% if env.IRONIC_TLS_SETUP == "true" %}
ServerName {{ env.IRONIC_IP }}
SSLEngine on
SSLCertificateFile {{ env.IRONIC_CERT_FILE }}
SSLCertificateKeyFile {{ env.IRONIC_KEY_FILE }}
{% endif %}

<Directory /usr/bin >
WSGIProcessGroup ironic
WSGIApplicationGroup %{GLOBAL}
AllowOverride All
Require all granted

{% if "HTTP_BASIC_HTPASSWD" in env and env.HTTP_BASIC_HTPASSWD | length %}
AuthType Basic
AuthName "Restricted WSGI area"
AuthUserFile "/etc/ironic/htpasswd"
Require valid-user
{% endif %}
</Directory>
</VirtualHost>
14 changes: 14 additions & 0 deletions config/httpd-modules.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,17 @@ LoadModule dir_module modules/mod_dir.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule wsgi_module modules/mod_wsgi_python3.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule env_module modules/mod_env.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
LoadModule headers_module modules/mod_headers.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authz_user_module modules/mod_authz_user.so
Comment thread
stbenjam marked this conversation as resolved.

10 changes: 2 additions & 8 deletions config/ironic.conf.j2
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
[DEFAULT]
{% if "HTTP_BASIC_HTPASSWD" in env and env.HTTP_BASIC_HTPASSWD | length %}
auth_strategy = http_basic
http_basic_auth_user_file = /etc/ironic/htpasswd
{% else %}
auth_strategy = noauth
{% endif %}
debug = true
default_boot_interface = ipxe
default_deploy_interface = direct
Expand All @@ -27,7 +22,7 @@ require_agent_token = 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 == "Combined" or (env.IRONIC_DEPLOYMENT == "Conductor" and env.JSON_RPC_AUTH_STRATEGY == "noauth") %}
{% 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
Expand Down Expand Up @@ -125,10 +120,9 @@ command_retry_timeout = 60
# containers are in host networking.
auth_strategy = {{ env.JSON_RPC_AUTH_STRATEGY }}
http_basic_auth_user_file = /etc/ironic/htpasswd-rpc
{% if env.IRONIC_DEPLOYMENT == "Combined" or (env.IRONIC_DEPLOYMENT == "Conductor" and env.JSON_RPC_AUTH_STRATEGY == "noauth" ) %}
{% 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 container, use localhost
host_ip = localhost
{% else %}
host_ip = {% if env.LISTEN_ALL_INTERFACES | lower == "true" %}::{% else %}{{ env.IRONIC_IP }}{% endif %}
Expand Down
2 changes: 2 additions & 0 deletions main-packages-list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ dnsmasq
gdisk
genisoimage
httpd
python3-mod_wsgi
mod_ssl
httpd-tools
ipmitool
iproute
Expand Down
7 changes: 7 additions & 0 deletions prepare-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ if [[ ! -z ${EXTRA_PKGS_LIST:-} ]]; then
xargs -rtd'\n' dnf --setopt=install_weak_deps=False install -y < /tmp/${EXTRA_PKGS_LIST}
fi
fi

# TODO: Delete the below line of code after the PR https://github.com/metal3-io/baremetal-operator/pull/728 go in
dnf install -y net-tools

dnf clean all
rm -rf /var/cache/{yum,dnf}/*
if [[ ! -z ${PATCH_LIST:-} ]]; then
Expand All @@ -19,3 +23,6 @@ if [[ ! -z ${PATCH_LIST:-} ]]; then
fi
fi
rm -f /bin/patch-image.sh

chown ironic:ironic /var/log/ironic
rm /etc/httpd/conf.d/ssl.conf # This file is generated after installing mod_ssl and it affects our configuration
42 changes: 42 additions & 0 deletions scripts/configure-httpd-ipa.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/bash

IRONIC_CERT_FILE=${IRONIC_CERT_FILE:-/certs/ironic/tls.crt}
HTTP_PORT=${HTTP_PORT:-"80"}

# Whether to enable fast_track provisioning or not
IRONIC_FAST_TRACK=${IRONIC_FAST_TRACK:-true}

wait_for_interface_or_ip

mkdir -pm 0777 /shared/html

if [ -f "$IRONIC_CERT_FILE" ]; then
IRONIC_BASE_URL="https://${IRONIC_URL_HOST}"
else
IRONIC_BASE_URL="http://${IRONIC_URL_HOST}"
fi

if [[ $IRONIC_FAST_TRACK == true ]]; then
INSPECTOR_EXTRA_ARGS=" ipa-api-url=${IRONIC_BASE_URL}:6385 ipa-inspection-callback-url=${IRONIC_BASE_URL}:5050/v1/continue"
else
INSPECTOR_EXTRA_ARGS=" ipa-inspection-callback-url=${IRONIC_BASE_URL}:5050/v1/continue"
fi

# Copy files to shared mount
render_j2_config /tmp/inspector.ipxe.j2 /shared/html/inspector.ipxe
cp /tmp/dualboot.ipxe /tmp/uefi_esp.img /shared/html/

# Use configured values
sed -i -e s/IRONIC_IP/${IRONIC_URL_HOST}/g \
-e s/HTTP_PORT/${HTTP_PORT}/g \
-e "s|EXTRA_ARGS|${INSPECTOR_EXTRA_ARGS}|g" \
/shared/html/inspector.ipxe

sed -i 's/^Listen .*$/Listen [::]:'"$HTTP_PORT"'/' /etc/httpd/conf/httpd.conf
sed -i -e 's|\(^[[:space:]]*\)\(DocumentRoot\)\(.*\)|\1\2 "/shared/html"|' \
-e 's|<Directory "/var/www/html">|<Directory "/shared/html">|' \
-e 's|<Directory "/var/www">|<Directory "/shared">|' /etc/httpd/conf/httpd.conf

# Log to std out/err
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
Comment on lines +35 to +42
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I like managing config files via sed, what if the config file changes just enough that the regex no longer matches?

Can we just ship a minimal /etc/httpd/conf/httpd.conf for this, possibly a jinja template?

Copy link
Copy Markdown
Member Author

@namnx228 namnx228 Feb 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I can do that, but should we do this in a separate PR? These sed commands already existed before, and I just move it from one place to another.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure that's fine, I didn't realize this was pre-existing.

49 changes: 3 additions & 46 deletions scripts/configure-ironic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@ fi

. /bin/ironic-common.sh

export HTTP_PORT=${HTTP_PORT:-"80"}
export MARIADB_PASSWORD=${MARIADB_PASSWORD:-"change_me"}
# TODO(dtantsur): remove the explicit default once we get
# https://review.opendev.org/761185 in the repositories
NUMPROC=$(cat /proc/cpuinfo | grep "^processor" | wc -l)
NUMPROC=$(( NUMPROC <= 4 ? NUMPROC : 4 ))
export NUMWORKERS=${NUMWORKERS:-$NUMPROC}
export LISTEN_ALL_INTERFACES="${LISTEN_ALL_INTERFACES:-"true"}"
export IRONIC_DEPLOYMENT="${IRONIC_DEPLOYMENT:-"Combined"}"

# Whether to enable fast_track provisioning or not
export IRONIC_FAST_TRACK=${IRONIC_FAST_TRACK:-true}
Expand Down Expand Up @@ -89,11 +87,6 @@ HTPASSWD_FILE=/etc/ironic/htpasswd
# The user can provide HTTP_BASIC_HTPASSWD and HTTP_BASIC_HTPASSWD_RPC. If
# - we are running conductor and HTTP_BASIC_HTPASSWD is set,
# use HTTP_BASIC_HTPASSWD for RPC.
# - we are running combined and HTTP_BASIC_HTPASSWD is set, i.e. API is
# authenticated. We want to authenticate RPC by default, but the user might
# override. Then try to infere the authentication strategy and credentials
# from /auth/ironic-rpc/auth-config. If not present, then generate a username
# and password, create the config file the htpasswd content
export JSON_RPC_AUTH_STRATEGY="noauth"
if [ -n "${HTTP_BASIC_HTPASSWD}" ]; then
if [ "${IRONIC_DEPLOYMENT}" == "Conductor" ]; then
Expand All @@ -104,52 +97,16 @@ if [ -n "${HTTP_BASIC_HTPASSWD}" ]; then
fi
fi


# When running both API and Conductor in the same container, we'll try to get the credentials
# from /auth/ironic-rpc/auth-config if present, or generate it
if [ "${IRONIC_DEPLOYMENT}" == "Combined" ]; then
# We try to read the credentials from the config file as it is probably mounted read-only,
# We cannot modify it. If it is not set to basic, then do not authenticate the RPC. This is
# to ensure that the setup will work if the user gives a specific config for rpc set to no_auth
if [ -f "/auth/ironic-rpc/auth-config" ]; then
IRONIC_RPC_TMP_TYPE="$(crudini --get /auth/ironic-rpc/auth-config json_rpc auth_type)" || exit 1
if [ "${IRONIC_RPC_TMP_TYPE}" == "http_basic" ]; then
IRONIC_RPC_TMP_USERNAME="$(crudini --get /auth/ironic-rpc/auth-config json_rpc username)" || exit 1
IRONIC_RPC_TMP_PASSWORD="$(crudini --get /auth/ironic-rpc/auth-config json_rpc password)" || exit 1
else
export JSON_RPC_AUTH_STRATEGY="noauth"
fi
# We do not have an auth config file, so we generate one
else
IRONIC_RPC_TMP_USERNAME="rpc-user"
IRONIC_RPC_TMP_PASSWORD="$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 12 | head -n 1)"
mkdir -p "/auth/ironic-rpc"
cat << EOF > "/auth/ironic-rpc/auth-config"
[json_rpc]
auth_type=http_basic
username=${IRONIC_RPC_TMP_USERNAME}
password=${IRONIC_RPC_TMP_PASSWORD}
http_basic_username=${IRONIC_RPC_TMP_USERNAME}
http_basic_password=${IRONIC_RPC_TMP_PASSWORD}
EOF
fi

# Populate HTTP_BASIC_HTPASSWD_RPC
if [ -n "${IRONIC_RPC_TMP_USERNAME:-}" ]; then
htpasswd -n -b -B "${IRONIC_RPC_TMP_USERNAME}" "${IRONIC_RPC_TMP_PASSWORD}" >"${HTPASSWD_FILE}-rpc"
fi
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

# Configure auth for clients
IRONIC_CONFIG_OPTIONS="--config-file /etc/ironic/ironic.conf"

configure_client_basic_auth() {
local auth_config_file="/auth/$1/auth-config"
if [ -f ${auth_config_file} ]; then
IRONIC_CONFIG_OPTIONS+=" --config-file ${auth_config_file}"
# Merge configurations in the "auth" directory into the default ironic configuration file because there is no way to choose the configuration file
# when running the api as a WSGI app.
crudini --merge "/etc/ironic/ironic.conf" < ${auth_config_file}
fi
}

Expand Down
Empty file modified scripts/ironic-common.sh
100755 → 100644
Empty file.
17 changes: 0 additions & 17 deletions scripts/runironic

This file was deleted.

11 changes: 10 additions & 1 deletion scripts/runironic-api
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,13 @@ while true ; do
sleep 5
done

exec /usr/bin/ironic-api --config-file /usr/share/ironic/ironic-dist.conf ${IRONIC_CONFIG_OPTIONS}

# TODO: Delete the line of code below and uncomment the next line after the PR https://github.com/metal3-io/baremetal-operator/pull/728 goes in
[ ! "$(netstat -l | grep ${HTTP_PORT})" ] && . /bin/configure-httpd-ipa.sh
# . /bin/configure-httpd-ipa.sh
# The code above avoids the httpd instance in this container to listen on port HTTP_PORT when it has been opened by BMO.

python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' < /etc/httpd-ironic-api.conf.j2 > /etc/httpd/conf.d/ironic.conf
sed -i "/Listen 80/c\#Listen 80" /etc/httpd/conf/httpd.conf
exec /usr/sbin/httpd -DFOREGROUND

3 changes: 1 addition & 2 deletions scripts/runironic-conductor
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ until ironic-dbsync --config-file /etc/ironic/ironic.conf upgrade; do
echo "WARNING: ironic-dbsync failed, retrying"
sleep 1
done

exec /usr/bin/ironic-conductor ${IRONIC_CONFIG_OPTIONS}
exec /usr/bin/ironic-conductor