From ae9de17d8c1c720fe369a73bc6cd37703e99bc68 Mon Sep 17 00:00:00 2001 From: Adam Rozman Date: Tue, 4 Jul 2023 10:19:17 +0000 Subject: [PATCH] introduces custom iPXE firmware buiding support This commit: - Implements a function to initiate iPXE firmware bilding process based on the 'buildipxe' script of the 'ironic-image' - Implements logic to generate TLS certificates for the custom iPXE firmware - Adds a set of iPXE specific environment variables to help parameterizing the custom iPXE build process Signed-off-by: Adam Rozman --- 03_launch_mgmt_cluster.sh | 43 ++++++++++++++++++++++++++++++++++++++- lib/common.sh | 15 ++++++++++++-- lib/ironic_tls_setup.sh | 20 ++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/03_launch_mgmt_cluster.sh b/03_launch_mgmt_cluster.sh index 28631d1a1..6fd2105d5 100755 --- a/03_launch_mgmt_cluster.sh +++ b/03_launch_mgmt_cluster.sh @@ -42,7 +42,7 @@ source lib/ironic_basic_auth.sh # # Create the BMO deployment (not used for CAPM3 v1a4 since BMO is bundeled there) # -function launch_baremetal_operator() { +launch_baremetal_operator() { pushd "${BMOPATH}" # Deploy BMO using deploy.sh script @@ -462,6 +462,46 @@ function start_management_cluster () { fi } +build_ipxe_firmware () { +# Build iPXE firmware during deployment (only available on ubuntu) + # vars with CENV_ARG postfix are container environment variable arguments + # and only used to pass the env var to the containers + IPXE_BUILDER_IMAGE="${REGISTRY}/localimages/ipxe-builder:latest" + export IPXE_ENABLE_TLS_CENV_ARG="IPXE_ENABLE_TLS='false'" + export IPXE_ENABLE_IPV6_CENV_ARG="IPXE_ENABLE_IPV6='false'" + declare -a CERTS_MOUNTS=() + if [[ "${BUILD_IPXE}" != "true" ]]; then + return 0 + fi + if [[ ! -r "${IPXE_SOURCE_DIR}" ]]; then + git clone --depth 1 --branch "${IPXE_RELEASE_BRANCH}" \ + "https://github.com/ipxe/ipxe.git" "${IPXE_SOURCE_DIR}" + chmod -R 777 "${IPXE_SOURCE_DIR}" + elif [[ "${IPXE_SOURCE_FORCE_UPDATE}" = "true" ]]; then + rm -rf "/tmp/ipxe-source" + #shellcheck disable=SC2086 + git clone --depth 1 --branch "${IPXE_RELEASE_BRANCH}" \ + "https://github.com/ipxe/ipxe.git" "/tmp/ipxe-source" + rm -rf "${IPXE_SOURCE_DIR}" + mv "/tmp/ipxe-source" "${IPXE_SOURCE_DIR}" + rm -rf "/tmp/ipxe-source" + fi + if [[ "${IPXE_ENABLE_TLS}" = "true" ]]; then + export IPXE_ENABLE_TLS_CENV_ARG="IPXE_ENABLE_TLS=true" + CERTS_MOUNTS+=("-v ${IPXE_CACERT_FILE}:/certs/ca/ipxe/tls.crt") + CERTS_MOUNTS+=("-v ${IPXE_CERT_FILE}:/certs/ipxe/tls.crt") + CERTS_MOUNTS+=("-v ${IPXE_KEY_FILE}:/certs/ipxe/tls.key ") + fi + if [[ "${IPXE_ENABLE_IPV6}" = "true" ]]; then + export IPXE_ENABLE_IPV6_CENV_ARG="IPXE_ENABLE_IPV6=true" + fi + + #shellcheck disable=SC2086,SC2068 + sudo "${CONTAINER_RUNTIME}" run --net host --name ipxe-builder ${POD_NAME} \ + -e "${IPXE_ENABLE_TLS_CENV_ARG}" -e "${IPXE_ENABLE_IPV6_CENV_ARG}" \ + -e "IRONIC_IP=${IRONIC_HOST_IP}" ${CERTS_MOUNTS[@]} \ + -v "${IRONIC_DATA_DIR}":/shared "${IPXE_BUILDER_IMAGE}" +} # ----------------------------- # Deploy the management cluster # ----------------------------- @@ -471,6 +511,7 @@ function start_management_cluster () { create_clouds_yaml if [ "${EPHEMERAL_CLUSTER}" != "tilt" ]; then + build_ipxe_firmware start_management_cluster kubectl create namespace metal3 diff --git a/lib/common.sh b/lib/common.sh index 2e00b953e..606f9a249 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -254,7 +254,7 @@ export DOCKER_REGISTRY_IMAGE="${DOCKER_REGISTRY_IMAGE:-${DOCKER_HUB_PROXY}/libra # Registry to pull metal3 container images from export CONTAINER_REGISTRY="${CONTAINER_REGISTRY:-quay.io}" -# VBMC and Redfish images +# BMC emulator images export VBMC_IMAGE="${VBMC_IMAGE:-${CONTAINER_REGISTRY}/metal3-io/vbmc}" export SUSHY_TOOLS_IMAGE="${SUSHY_TOOLS_IMAGE:-${CONTAINER_REGISTRY}/metal3-io/sushy-tools}" @@ -293,6 +293,9 @@ else export BMOBRANCH="${BMORELEASEBRANCH:-main}" fi +# IPXE support image +export IPXE_BUILDER_IMAGE="${IPXE_BUILDER_IMAGE:-${CONTAINER_REGISTRY}/metal3-io/ipxe-builder}" + # Ironic vars export IRONIC_TLS_SETUP=${IRONIC_TLS_SETUP:-"true"} export IRONIC_BASIC_AUTH=${IRONIC_BASIC_AUTH:-"true"} @@ -304,6 +307,14 @@ export IRONIC_IMAGE_DIR="$IRONIC_DATA_DIR/html/images" export IRONIC_NAMESPACE="${IRONIC_NAMESPACE:-baremetal-operator-system}" export NAMEPREFIX="${NAMEPREFIX:-baremetal-operator}" +# iPXE vars of ironic-image +export BUILD_IPXE="${BUILD_IPXE:-false}" +export IPXE_ENABLE_TLS="${IPXE_ENABLE_TLS:-false}" +export IPXE_ENABLE_IPV6="${IPXE_ENABLE_IPV6:-false}" +export IPXE_RELEASE_BRANCH="${IPXE_RELEASE_BRANCH:-v1.21.1}" +export IPXE_SOURCE_FORCE_UPDATE="${IPXE_SOURCE_FORCE_UPDATE:-false}" +export IPXE_SOURCE_DIR="${IRONIC_DATA_DIR}/ipxe-source" + export IRONIC_KEEPALIVED_IMAGE="${IRONIC_KEEPALIVED_IMAGE:-${CONTAINER_REGISTRY}/metal3-io/keepalived:${KEEPALIVED_TAG}}" export MARIADB_IMAGE="${MARIADB_IMAGE:-${CONTAINER_REGISTRY}/metal3-io/mariadb:${MARIADB_TAG}}" @@ -567,7 +578,7 @@ differs(){ # remove_ironic_containers() { #shellcheck disable=SC2015 - for name in ipa-downloader vbmc sushy-tools httpd-infra; do + for name in ipa-downloader vbmc sushy-tools httpd-infra ipxe-builder; do if sudo "${CONTAINER_RUNTIME}" ps | grep -w -q "${name}$"; then sudo "${CONTAINER_RUNTIME}" kill "${name}" || true fi diff --git a/lib/ironic_tls_setup.sh b/lib/ironic_tls_setup.sh index fd3fcd614..eb2ba7a86 100644 --- a/lib/ironic_tls_setup.sh +++ b/lib/ironic_tls_setup.sh @@ -23,6 +23,10 @@ if [ "${IRONIC_TLS_SETUP}" == "true" ]; then export MARIADB_CERT_FILE="${MARIADB_CERT_FILE:-"${WORKING_DIR}/certs/mariadb.crt"}" export MARIADB_KEY_FILE="${MARIADB_KEY_FILE:-"${WORKING_DIR}/certs/mariadb.key"}" + export IPXE_CACERT_FILE="${IPXE_CACERT_FILE:-"${WORKING_DIR}/certs/ipxe-ca.pem"}" + export IPXE_CAKEY_FILE="${IPXE_CAKEY_FILE:-"${WORKING_DIR}/certs/ipxe-ca.key"}" + export IPXE_CERT_FILE="${IPXE_CERT_FILE:-"${WORKING_DIR}/certs/ipxe.crt"}" + export IPXE_KEY_FILE="${IPXE_KEY_FILE:-"${WORKING_DIR}/certs/ipxe.key"}" # Generate CA Key files if [ ! -f "${IRONIC_CAKEY_FILE}" ]; then @@ -34,6 +38,9 @@ if [ "${IRONIC_TLS_SETUP}" == "true" ]; then if [ ! -f "${MARIADB_CAKEY_FILE}" ]; then openssl genrsa -out "${MARIADB_CAKEY_FILE}" 2048 fi + if [ ! -f "${IPXE_CAKEY_FILE}" ]; then + openssl genrsa -out "${IPXE_CAKEY_FILE}" 2048 + fi # Generate CA cert files if [ ! -f "${IRONIC_CACERT_FILE}" ]; then @@ -45,6 +52,9 @@ if [ "${IRONIC_TLS_SETUP}" == "true" ]; then if [ ! -f "${MARIADB_CACERT_FILE}" ]; then openssl req -x509 -new -nodes -key "${MARIADB_CAKEY_FILE}" -sha256 -days 1825 -out "${MARIADB_CACERT_FILE}" -subj /CN="mariadb CA"/ fi + if [ ! -f "${IPXE_CACERT_FILE}" ]; then + openssl req -x509 -new -nodes -key "${IPXE_CAKEY_FILE}" -sha256 -days 1825 -out "${IPXE_CACERT_FILE}" -subj /CN="ipxe CA"/ + fi # Generate Key files if [ ! -f "${IRONIC_KEY_FILE}" ]; then @@ -56,6 +66,9 @@ if [ "${IRONIC_TLS_SETUP}" == "true" ]; then if [ ! -f "${MARIADB_KEY_FILE}" ]; then openssl genrsa -out "${MARIADB_KEY_FILE}" 2048 fi + if [ ! -f "${IPXE_KEY_FILE}" ]; then + openssl genrsa -out "${IPXE_KEY_FILE}" 2048 + fi # Generate CSR and certificate files if [ ! -f "${IRONIC_CERT_FILE}" ]; then @@ -71,6 +84,10 @@ if [ "${IRONIC_TLS_SETUP}" == "true" ]; then openssl req -new -key "${MARIADB_KEY_FILE}" -out /tmp/mariadb.csr -subj /CN="${MARIADB_HOST}"/ openssl x509 -req -in /tmp/mariadb.csr -CA "${MARIADB_CACERT_FILE}" -CAkey "${MARIADB_CAKEY_FILE}" -CAcreateserial -out "${MARIADB_CERT_FILE}" -days 825 -sha256 -extfile <(printf "subjectAltName=IP:%s" "${MARIADB_HOST_IP}") fi + if [ ! -f "${IPXE_CERT_FILE}" ]; then + openssl req -new -key "${IPXE_KEY_FILE}" -out /tmp/ipxe.csr -subj /CN="${IRONIC_HOST}"/ + openssl x509 -req -in /tmp/ipxe.csr -CA "${IPXE_CACERT_FILE}" -CAkey "${IPXE_CAKEY_FILE}" -CAcreateserial -out "${IPXE_CERT_FILE}" -days 825 -sha256 -extfile <(printf "subjectAltName=IP:%s" "${IRONIC_HOST_IP}") + fi #Populate the CA certificate B64 variable if [ "${IRONIC_CACERT_FILE}" == "${IRONIC_INSPECTOR_CACERT_FILE}" ]; then @@ -98,4 +115,7 @@ else unset MARIADB_CACERT_FILE unset MARIADB_CERT_FILE unset MARIADB_KEY_FILE + unset IPXE_CACERT_FILE + unset IPXE_CERT_FILE + unset IPXE_KEY_FILE fi