WIP: Have the IPA 'ramdisk' as a separate OCI Image #379
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic:32.0.0.1
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic:32.0.0.1-%RELEASE%
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic:32.0.0.2
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic:32.0.0.2-%RELEASE%
|
||||
|
||||
ARG SLE_VERSION
|
||||
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
|
||||
@@ -47,8 +47,8 @@ LABEL org.opencontainers.image.description="Openstack Ironic based on the SLE Ba
|
||||
LABEL org.opencontainers.image.url="https://www.suse.com/products/server/"
|
||||
LABEL org.opencontainers.image.created="%BUILDTIME%"
|
||||
LABEL org.opencontainers.image.vendor="SUSE LLC"
|
||||
LABEL org.opencontainers.image.version="32.0.0.1"
|
||||
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic:32.0.0.1-%RELEASE%"
|
||||
LABEL org.opencontainers.image.version="32.0.0.2"
|
||||
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic:32.0.0.2-%RELEASE%"
|
||||
LABEL org.openbuildservice.disturl="%DISTURL%"
|
||||
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
|
||||
LABEL com.suse.eula="SUSE Combined EULA February 2024"
|
||||
|
||||
@@ -7,4 +7,5 @@ imgfree
|
||||
# ironic-inspector-image and configuration in configure-ironic.sh
|
||||
kernel --timeout 60000 {{ env.IRONIC_HTTP_URL }}/images/ironic-python-agent-${buildarch}.kernel ipa-insecure={{ env.IPA_INSECURE }} 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-${buildarch}.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-${buildarch}.initramfs || goto retry_boot
|
||||
initrd --timeout 60000 {{ env.IRONIC_HTTP_URL }}/ipa-cacert-bundle || goto retry_boot
|
||||
boot
|
||||
|
||||
@@ -22,6 +22,8 @@ imgfree
|
||||
kernel {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ aki_path_https }} selinux=0 troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }} BOOTIF=${mac} initrd={{ pxe_options.initrd_filename|default("deploy_ramdisk", true) }} || goto retry
|
||||
|
||||
initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ ari_path_https }} || goto retry
|
||||
# Load ipa-cacert-bundle, path is relative to the ipxe script that will be located in /shared/html/{node_id}/
|
||||
initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %} ../ipa-cacert-bundle || goto retry
|
||||
boot
|
||||
|
||||
:retry
|
||||
@@ -41,6 +43,7 @@ poweroff
|
||||
imgfree
|
||||
kernel {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ aki_path_https }} text {{ pxe_options.pxe_append_params|default("", true) }} inst.ks={{ pxe_options.ks_cfg_url }} {% if pxe_options.repo_url %}inst.repo={{ pxe_options.repo_url }}{% else %}inst.stage2={{ pxe_options.stage2_url }}{% endif %} initrd=ramdisk || goto boot_anaconda
|
||||
initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ ari_path_https }} || goto boot_anaconda
|
||||
initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %} ../ipa-cacert-bundle || goto boot_anaconda
|
||||
boot
|
||||
|
||||
:boot_ramdisk
|
||||
@@ -50,6 +53,7 @@ sanboot {{ pxe_options.boot_iso_url }}
|
||||
{%- else %}
|
||||
kernel {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ aki_path_https }} root=/dev/ram0 text {{ pxe_options.pxe_append_params|default("", true) }} {{ pxe_options.ramdisk_opts|default('', true) }} initrd=ramdisk || goto boot_ramdisk
|
||||
initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %}{{ ari_path_https }} || goto boot_ramdisk
|
||||
initrd {% if pxe_options.ipxe_timeout > 0 %}--timeout {{ pxe_options.ipxe_timeout }} {% endif %} ../ipa-cacert-bundle || goto boot_ramdisk
|
||||
boot
|
||||
{%- endif %}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ deploy_logs_local_path = /shared/log/ironic/deploy
|
||||
# See https://bugzilla.redhat.com/show_bug.cgi?id=1822763
|
||||
max_command_attempts = 30
|
||||
certificates_path = {{ env.IRONIC_GEN_CERT_DIR }}
|
||||
api_ca_file = {{ env.IPA_CACERT_FILE }}
|
||||
|
||||
[api]
|
||||
{% if env.IRONIC_REVERSE_PROXY_SETUP == "true" %}
|
||||
@@ -236,7 +237,7 @@ images_path = /shared/html/tmp
|
||||
instance_master_path = /shared/html/master_images
|
||||
tftp_master_path = /shared/tftpboot/master_images
|
||||
tftp_root = /shared/tftpboot
|
||||
kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.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 initrd=ipa-cacert-bundle ipa-insecure={{ env.IPA_INSECURE }} {% if env.ENABLE_FIPS_IPA %}fips={{ env.ENABLE_FIPS_IPA|trim }}{% endif %} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes net.ifnames={{ '0' if env.PREDICTABLE_NIC_NAMES == 'false' else '1' }}
|
||||
# This makes networking boot templates generated even for nodes using local
|
||||
# boot (the default), ensuring that they boot correctly even if they start
|
||||
# netbooting for some reason (e.g. with the noop management interface).
|
||||
|
||||
@@ -32,6 +32,12 @@ else
|
||||
cp /tftpboot/undionly.kpxe /tftpboot/snponly.efi /shared/tftpboot
|
||||
fi
|
||||
|
||||
generate_cacert_bundle_initrd /shared/tftpboot/ipa-cacert-bundle
|
||||
generate_cacert_bundle_initrd /shared/html/ipa-cacert-bundle
|
||||
|
||||
# this will get dnsmasq killed on certificate update triggering a pod restart
|
||||
configure_restart_on_certificate_update "true" dnsmasq "${IPA_CACERTS_PATH}/*"
|
||||
|
||||
# Template and write dnsmasq.conf
|
||||
# we template via /tmp as sed otherwise creates temp files in /etc directory
|
||||
# where we can't write
|
||||
|
||||
@@ -24,4 +24,14 @@ if [[ -d "${BMC_CACERTS_PATH}" ]]; then
|
||||
"${BMC_CACERTS_PATH}" &
|
||||
fi
|
||||
|
||||
if ls "${IPA_CACERTS_PATH}"/* > /dev/null 2>&1; then
|
||||
# Ignore error if IRONIC_CACERT_FILE doesn't exist as it will still work as intended
|
||||
# shellcheck disable=SC2034
|
||||
watchmedo shell-command \
|
||||
--patterns="*" \
|
||||
--ignore-directories \
|
||||
--command='cat "${IPA_CACERTS_PATH}"/* "${IRONIC_CACERT_FILE}" 2>/dev/null > "${IPA_CACERT_FILE}"' \
|
||||
"${IPA_CACERTS_PATH}" &
|
||||
fi
|
||||
|
||||
exec /usr/bin/ironic --config-dir "${IRONIC_CONF_DIR}"
|
||||
|
||||
@@ -5,6 +5,8 @@ export IRONIC_SSL_PROTOCOL=${IRONIC_SSL_PROTOCOL:-"-ALL +TLSv1.2 +TLSv1.3"}
|
||||
export IPXE_SSL_PROTOCOL=${IPXE_SSL_PROTOCOL:-"-ALL +TLSv1.2 +TLSv1.3"}
|
||||
export IRONIC_VMEDIA_SSL_PROTOCOL=${IRONIC_VMEDIA_SSL_PROTOCOL:-"ALL"}
|
||||
|
||||
export DEFAULT_CACERT_BUNDLE=${DEFAULT_CACERT_BUNDLE:-"/etc/ssl/cert.pem"}
|
||||
|
||||
# Node image storage is using the same cert and port as the API
|
||||
export IRONIC_CERT_FILE=/certs/ironic/tls.crt
|
||||
export IRONIC_KEY_FILE=/certs/ironic/tls.key
|
||||
@@ -23,6 +25,8 @@ export MARIADB_CACERT_FILE=/certs/ca/mariadb/tls.crt
|
||||
export BMC_CACERTS_PATH=/certs/ca/bmc
|
||||
export BMC_CACERT_FILE=/conf/bmc-tls.pem
|
||||
export IRONIC_CACERT_FILE=/certs/ca/ironic/tls.crt
|
||||
export IPA_CACERT_FILE=/conf/ipa-tls.pem
|
||||
export IPA_CACERTS_PATH=/certs/ca/ipa
|
||||
|
||||
export IPXE_TLS_PORT="${IPXE_TLS_PORT:-8084}"
|
||||
|
||||
@@ -127,3 +131,37 @@ if [ -d "${BMC_CACERTS_PATH}" ]; then
|
||||
else
|
||||
export BMC_TLS_ENABLED="false"
|
||||
fi
|
||||
|
||||
if ls "${IPA_CACERTS_PATH}"/* > /dev/null 2>&1; then
|
||||
cat "${IPA_CACERTS_PATH}"/* > "${IPA_CACERT_FILE}"
|
||||
else
|
||||
if [ -f "${DEFAULT_CACERT_BUNDLE}" ]; then
|
||||
copy_atomic "${DEFAULT_CACERT_BUNDLE}" "${IPA_CACERT_FILE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f "${IRONIC_CACERT_FILE}" ]; then
|
||||
cat "${IRONIC_CACERT_FILE}" >> "${IPA_CACERT_FILE}"
|
||||
fi
|
||||
|
||||
generate_cacert_bundle_initrd()
|
||||
(
|
||||
local output_path="$1"
|
||||
local temp_dir
|
||||
|
||||
temp_dir="$(mktemp -d)"
|
||||
|
||||
cd "${temp_dir}" || return
|
||||
|
||||
mkdir -p etc/ironic-python-agent.d etc/ironic-python-agent
|
||||
cp "${IPA_CACERT_FILE}" etc/ironic-python-agent/ironic.crt
|
||||
cat > etc/ironic-python-agent.d/ironic-tls.conf <<EOF
|
||||
[DEFAULT]
|
||||
cafile = /etc/ironic-python-agent/ironic.crt
|
||||
EOF
|
||||
|
||||
find . | cpio -o -H newc --reproducible >> "${output_path}"
|
||||
|
||||
# Remove temp directory
|
||||
cd && rm -rf "${temp_dir}"
|
||||
)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.11
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.11-%RELEASE%
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.1.0
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.1.0-%RELEASE%
|
||||
ARG SLE_VERSION
|
||||
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
|
||||
|
||||
FROM registry.suse.com/bci/bci-base:$SLE_VERSION AS base
|
||||
COPY --from=micro / /installroot/
|
||||
RUN sed -i -e 's%^# rpm.install.excludedocs = no.*%rpm.install.excludedocs = yes%g' /etc/zypp/zypp.conf
|
||||
RUN zypper --installroot /installroot --non-interactive install --no-recommends ironic-ipa-ramdisk-x86_64 ironic-ipa-ramdisk-aarch64 tar gawk curl xz zstd shadow cpio findutils
|
||||
RUN zypper --installroot /installroot --non-interactive install --no-recommends bsdtar gawk curl xz zstd shadow cpio findutils jq
|
||||
|
||||
FROM micro AS final
|
||||
|
||||
@@ -16,11 +16,11 @@ FROM micro AS final
|
||||
LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)"
|
||||
LABEL org.opencontainers.image.title="SLE Based Ironic IPA Downloader Container Image"
|
||||
LABEL org.opencontainers.image.description="ironic-ipa-downloader based on the SLE Base Container Image."
|
||||
LABEL org.opencontainers.image.version="3.0.11"
|
||||
LABEL org.opencontainers.image.version="3.1.0"
|
||||
LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/"
|
||||
LABEL org.opencontainers.image.created="%BUILDTIME%"
|
||||
LABEL org.opencontainers.image.vendor="SUSE LLC"
|
||||
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.11-%RELEASE%"
|
||||
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.1.0-%RELEASE%"
|
||||
LABEL org.openbuildservice.disturl="%DISTURL%"
|
||||
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
|
||||
LABEL com.suse.eula="SUSE Combined EULA February 2024"
|
||||
@@ -30,7 +30,6 @@ LABEL com.suse.release-stage="released"
|
||||
# endlabelprefix
|
||||
|
||||
COPY --from=base /installroot /
|
||||
RUN sha256sum /srv/tftpboot/openstack-ironic-image/initrd*.zst /srv/tftpboot/openstack-ironic-image/openstack-ironic-image*.kernel > /tmp/images.sha256
|
||||
# configure non-root user
|
||||
COPY configure-nonroot.sh /bin/
|
||||
RUN set -euo pipefail; chmod +x /bin/configure-nonroot.sh
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.10
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.10-%RELEASE%
|
||||
ARG SLE_VERSION
|
||||
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
|
||||
|
||||
FROM registry.suse.com/bci/bci-base:$SLE_VERSION AS base
|
||||
COPY --from=micro / /installroot/
|
||||
RUN sed -i -e 's%^# rpm.install.excludedocs = no.*%rpm.install.excludedocs = yes%g' /etc/zypp/zypp.conf
|
||||
RUN zypper --installroot /installroot --non-interactive install --no-recommends ironic-ipa-ramdisk-aarch64 tar gawk curl xz zstd shadow cpio findutils
|
||||
|
||||
FROM micro AS final
|
||||
|
||||
# Define labels according to https://en.opensuse.org/Building_derived_containers
|
||||
# labelprefix=com.suse.application.ironic
|
||||
LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)"
|
||||
LABEL org.opencontainers.image.title="SLE Based Ironic IPA Downloader Container Image"
|
||||
LABEL org.opencontainers.image.description="ironic-ipa-downloader based on the SLE Base Container Image."
|
||||
LABEL org.opencontainers.image.version="3.0.10"
|
||||
LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/"
|
||||
LABEL org.opencontainers.image.created="%BUILDTIME%"
|
||||
LABEL org.opencontainers.image.vendor="SUSE LLC"
|
||||
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%RELEASE%"
|
||||
LABEL org.openbuildservice.disturl="%DISTURL%"
|
||||
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
|
||||
LABEL com.suse.eula="SUSE Combined EULA February 2024"
|
||||
LABEL com.suse.lifecycle-url="https://www.suse.com/lifecycle"
|
||||
LABEL com.suse.image-type="application"
|
||||
LABEL com.suse.release-stage="released"
|
||||
# endlabelprefix
|
||||
|
||||
COPY --from=base /installroot /
|
||||
RUN sha256sum /srv/tftpboot/openstack-ironic-image/initrd*.zst /srv/tftpboot/openstack-ironic-image/openstack-ironic-image*.kernel > /tmp/images.sha256
|
||||
# configure non-root user
|
||||
COPY configure-nonroot.sh /bin/
|
||||
RUN set -euo pipefail; chmod +x /bin/configure-nonroot.sh
|
||||
RUN set -euo pipefail; /bin/configure-nonroot.sh && rm -f /bin/configure-nonroot.sh
|
||||
COPY get-resource.sh /usr/local/bin/get-resource.sh
|
||||
|
||||
RUN set -euo pipefail; chmod +x /usr/local/bin/get-resource.sh
|
||||
@@ -1,40 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.10
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.10-%RELEASE%
|
||||
ARG SLE_VERSION
|
||||
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
|
||||
|
||||
FROM registry.suse.com/bci/bci-base:$SLE_VERSION AS base
|
||||
COPY --from=micro / /installroot/
|
||||
RUN sed -i -e 's%^# rpm.install.excludedocs = no.*%rpm.install.excludedocs = yes%g' /etc/zypp/zypp.conf
|
||||
RUN zypper --installroot /installroot --non-interactive install --no-recommends ironic-ipa-ramdisk-x86_64 tar gawk curl xz zstd shadow cpio findutils
|
||||
|
||||
FROM micro AS final
|
||||
|
||||
# Define labels according to https://en.opensuse.org/Building_derived_containers
|
||||
# labelprefix=com.suse.application.ironic
|
||||
LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)"
|
||||
LABEL org.opencontainers.image.title="SLE Based Ironic IPA Downloader Container Image"
|
||||
LABEL org.opencontainers.image.description="ironic-ipa-downloader based on the SLE Base Container Image."
|
||||
LABEL org.opencontainers.image.version="3.0.10"
|
||||
LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/"
|
||||
LABEL org.opencontainers.image.created="%BUILDTIME%"
|
||||
LABEL org.opencontainers.image.vendor="SUSE LLC"
|
||||
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%RELEASE%"
|
||||
LABEL org.openbuildservice.disturl="%DISTURL%"
|
||||
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
|
||||
LABEL com.suse.eula="SUSE Combined EULA February 2024"
|
||||
LABEL com.suse.lifecycle-url="https://www.suse.com/lifecycle"
|
||||
LABEL com.suse.image-type="application"
|
||||
LABEL com.suse.release-stage="released"
|
||||
# endlabelprefix
|
||||
|
||||
COPY --from=base /installroot /
|
||||
RUN sha256sum /srv/tftpboot/openstack-ironic-image/initrd*.zst /srv/tftpboot/openstack-ironic-image/openstack-ironic-image*.kernel > /tmp/images.sha256
|
||||
# configure non-root user
|
||||
COPY configure-nonroot.sh /bin/
|
||||
RUN set -euo pipefail; chmod +x /bin/configure-nonroot.sh
|
||||
RUN set -euo pipefail; /bin/configure-nonroot.sh && rm -f /bin/configure-nonroot.sh
|
||||
COPY get-resource.sh /usr/local/bin/get-resource.sh
|
||||
|
||||
RUN set -euo pipefail; chmod +x /usr/local/bin/get-resource.sh
|
||||
@@ -1,4 +0,0 @@
|
||||
<multibuild>
|
||||
<flavor>x86_64</flavor>
|
||||
<flavor>aarch64</flavor>
|
||||
</multibuild>
|
||||
@@ -2,8 +2,6 @@
|
||||
<service mode="buildtime" name="kiwi_metainfo_helper"/>
|
||||
<service mode="buildtime" name="docker_label_helper"/>
|
||||
<service name="replace_using_env" mode="buildtime">
|
||||
<param name="file">Dockerfile.aarch64</param>
|
||||
<param name="file">Dockerfile.x86_64</param>
|
||||
<param name="file">Dockerfile</param>
|
||||
<param name="eval">IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})</param>
|
||||
<param name="var">IMG_PREFIX</param>
|
||||
|
||||
@@ -6,45 +6,237 @@ export http_proxy=${http_proxy:-$HTTP_PROXY}
|
||||
export https_proxy=${https_proxy:-$HTTPS_PROXY}
|
||||
export no_proxy=${no_proxy:-$NO_PROXY}
|
||||
|
||||
IMAGES_BASE_PATH="/srv/tftpboot/openstack-ironic-image"
|
||||
# Fetches an OCI manifest and determines if it is an Image Manifest or an Image Index.
|
||||
#
|
||||
# It uses the 'mediaType' field from the manifest content to make the determination.
|
||||
# It supports both OCI v1 and Docker v2 manifest formats.
|
||||
#
|
||||
# As a fallback, if the mediaType is not recognized, it inspects the JSON structure
|
||||
# for the presence of 'manifests' (Image Index) or 'layers' (Image Manifest) keys.
|
||||
#
|
||||
# Usage:
|
||||
# get_manifest_type <manifest_url> [curl_options...]
|
||||
#
|
||||
# Arguments:
|
||||
# manifest_url: The full URL to the image manifest.
|
||||
# curl_options: (Optional) Extra options to pass to the curl command,
|
||||
# e.g., for authentication headers like -H "Authorization: Bearer <token>".
|
||||
#
|
||||
# Example for a public image on Google Container Registry:
|
||||
# get_manifest_type "https://gcr.io/v2/google-containers/pause/manifests/3.9"
|
||||
#
|
||||
# Example for an image requiring authentication on Docker Hub:
|
||||
# TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/ubuntu:pull" | jq -r .token)
|
||||
# get_manifest_type "https://registry-1.docker.io/v2/library/ubuntu/manifests/latest" -H "Authorization: Bearer "
|
||||
#
|
||||
|
|
||||
get_oci_tarball() {
|
||||
local image_ref="$1"
|
||||
shift
|
||||
local curl_opts=("$@")
|
||||
|
||||
if [ -d "/tmp/ironic-certificates" ]; then
|
||||
sha256sum /tmp/ironic-certificates/* > /tmp/certificates.sha256
|
||||
if cmp "/shared/certificates.sha256" "/tmp/certificates.sha256"; then
|
||||
CERTS_CHANGED=0
|
||||
else
|
||||
CERTS_CHANGED=1
|
||||
fi
|
||||
fi
|
||||
local registry="docker.io"
|
||||
local repo
|
||||
local ref="latest"
|
||||
local registry_url
|
||||
|
||||
# Which image should we use
|
||||
if [ -z "${IPA_BASEURI}" ]; then
|
||||
if cmp "/shared/images.sha256" "/tmp/images.sha256"; then
|
||||
if [ "${CERTS_CHANGED:-0}" = "0" ]; then
|
||||
# everything is the same exit early
|
||||
exit 0
|
||||
# 1. Parse Registry
|
||||
# Heuristic: if the first segment (before /) contains '.' or ':' or is 'localhost',
|
||||
# it is treated as a registry domain. Otherwise, it defaults to docker.io.
|
||||
if [[ "$image_ref" =~ ^([^/]+)/ ]]; then
|
||||
local first_segment="${BASH_REMATCH[1]}"
|
||||
if [[ "$first_segment" =~ [.:] ]] || [[ "$first_segment" == "localhost" ]]; then
|
||||
registry="$first_segment"
|
||||
image_ref="${image_ref#$registry/}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
IMAGE_CHANGED=1
|
||||
# SLES BASED IPA - ironic-ipa-ramdisk-x86_64 and ironic-ipa-ramdisk-aarch64 packages
|
||||
mkdir -p /shared/html/images
|
||||
if [ -f ${IMAGES_BASE_PATH}/initrd-x86_64.zst ]; then
|
||||
cp ${IMAGES_BASE_PATH}/initrd-x86_64.zst /shared/html/images/ironic-python-agent_x86_64.initramfs
|
||||
cp ${IMAGES_BASE_PATH}/openstack-ironic-image.x86_64*.kernel /shared/html/images/ironic-python-agent_x86_64.kernel
|
||||
fi
|
||||
if [ -f ${IMAGES_BASE_PATH}/initrd-aarch64.zst ]; then
|
||||
cp ${IMAGES_BASE_PATH}/initrd-aarch64.zst /shared/html/images/ironic-python-agent_aarch64.initramfs
|
||||
cp ${IMAGES_BASE_PATH}/openstack-ironic-image.aarch64*.kernel /shared/html/images/ironic-python-agent_aarch64.kernel
|
||||
|
||||
# 2. Parse Tag or Digest
|
||||
# Check for digest (@sha256:...) first, then tag (:tag), otherwise default to 'latest'.
|
||||
if [[ "$image_ref" =~ @(sha256:[a-f0-9]+) ]]; then
|
||||
ref="${BASH_REMATCH[1]}"
|
||||
repo="${image_ref%@*}"
|
||||
elif [[ "$image_ref" =~ :([^/]+)$ ]]; then
|
||||
ref="${BASH_REMATCH[1]}"
|
||||
repo="${image_ref%:*}"
|
||||
else
|
||||
repo="$image_ref"
|
||||
fi
|
||||
|
||||
# 3. Handle Docker Hub specifics
|
||||
if [[ "$registry" == "docker.io" || "$registry" == "index.docker.io" ]]; then
|
||||
registry_url="https://registry-1.docker.io"
|
||||
|
||||
# Expand official images (e.g., 'ubuntu' -> 'library/ubuntu')
|
||||
if [[ "$repo" != */* ]]; then
|
||||
repo="library/$repo"
|
||||
fi
|
||||
|
||||
# 4. Auto-fetch token for Docker Hub (anonymous access)
|
||||
# Docker Hub requires a bearer token even for public images.
|
||||
local token_url="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull"
|
||||
local token
|
||||
# We use curl and jq here as requested
|
||||
token=$(curl -s "$token_url" | jq -r .token)
|
||||
|
||||
if [[ -n "$token" && "$token" != "null" ]]; then
|
||||
curl_opts+=("-H" "Authorization: Bearer $token")
|
||||
fi
|
||||
else
|
||||
# Default to HTTPS for other registries
|
||||
registry_url="https://$registry"
|
||||
fi
|
||||
|
||||
# 5. Construct the OCI/Docker V2 Manifest URL
|
||||
local repo_url="${registry_url}/v2/$repo"
|
||||
|
||||
local manifest_url="${repo_url}/manifests/$ref"
|
||||
|
||||
local manifest_json
|
||||
manifest_json=$(curl -s -L \
|
||||
-H "Accept: application/vnd.oci.image.manifest.v1+json" \
|
||||
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
|
||||
-H "Accept: application/vnd.oci.image.index.v1+json" \
|
||||
-H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" \
|
||||
"${curl_opts[@]}" \
|
||||
"$manifest_url")
|
||||
|
||||
local exit_code=$?
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
echo "Error: curl failed with exit code for URL " >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "$manifest_json" ] || [ "$(echo "$manifest_json" | jq -r '.errors | length > 0')" == "true" ]; then
|
||||
echo "Error: Failed to fetch a valid manifest from " >&2
|
||||
echo "Response: " >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local media_type
|
||||
media_type=$(echo "$manifest_json" | jq -r '.mediaType')
|
||||
|
||||
case "$media_type" in
|
||||
"application/vnd.oci.image.manifest.v1+json" | "application/vnd.docker.distribution.manifest.v2+json")
|
||||
parse_image_manifest "$manifest_json" "$repo_url" "${curl_opts[@]}"
|
||||
;;
|
||||
"application/vnd.oci.image.index.v1+json" | "application/vnd.docker.distribution.manifest.list.v2+json")
|
||||
parse_image_index "$manifest_json" "$repo_url" "${curl_opts[@]}"
|
||||
;;
|
||||
*)
|
||||
# Fallback: check for key fields if mediaType is not present or different
|
||||
if echo "$manifest_json" | jq -e '.manifests' > /dev/null; then
|
||||
parse_image_index "$manifest_json" "$repo_url" "${curl_opts[@]}"
|
||||
elif echo "$manifest_json" | jq -e '.layers' > /dev/null; then
|
||||
parse_image_manifest "$manifest_json" "$repo_url" "${curl_opts[@]}"
|
||||
else
|
||||
echo "Unknown manifest type" >&2
|
||||
echo "MediaType: $media_type" >&2
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
parse_image_index() {
|
||||
local manifest_json="$1"
|
||||
shift
|
||||
local repo_url="$1"
|
||||
shift
|
||||
local curl_opts=("$@")
|
||||
|
||||
for digest in $(echo "$manifest_json" | jq -r '.manifests[].digest'); do
|
||||
local manifest_url="${repo_url}/manifests/${digest}"
|
||||
local sub_manifest_json
|
||||
sub_manifest_json=$(curl -s -L \
|
||||
-H "Accept: application/vnd.oci.image.manifest.v1+json" \
|
||||
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
|
||||
"${curl_opts[@]}" \
|
||||
"$manifest_url")
|
||||
|
||||
parse_image_manifest "$sub_manifest_json" "$repo_url" "${curl_opts[@]}"
|
||||
done
|
||||
}
|
||||
|
||||
parse_image_manifest() {
|
||||
local manifest_json="$1"
|
||||
shift
|
||||
local repo_url="$1"
|
||||
shift
|
||||
local curl_opts=("$@")
|
||||
|
||||
local digest
|
||||
digest="sha256:$(echo -n "${manifest_json}" | sha256sum | awk '{print $1}')"
|
||||
|
||||
if [ -d "/shared/html/images/${digest}" ]; then
|
||||
echo "Image already downloaded, skipping" >&2
|
||||
return 0
|
||||
fi
|
||||
|
||||
cp /tmp/images.sha256 /shared/images.sha256
|
||||
local layers_count
|
||||
layers_count=$(echo "${manifest_json}" | jq '.layers | length')
|
||||
if [ "${layers_count}" -ne 1 ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local layer_digest
|
||||
layer_digest=$(echo "${manifest_json}" | jq -r '.layers[0].digest')
|
||||
local tmp_dir
|
||||
tmp_dir=$(mktemp -d -p /shared/tmp)
|
||||
|
||||
local config_manifest_url
|
||||
config_manifest_url="${repo_url}/blobs/$(echo "${manifest_json}" | jq -r '.config.digest')"
|
||||
local config_manifest_json
|
||||
config_manifest_json=$(curl -s -L "${curl_opts[@]}" "$config_manifest_url")
|
||||
|
||||
|
||||
local architecture
|
||||
architecture=$(echo "${config_manifest_json}" | jq -r '.architecture')
|
||||
# normalize architecture
|
||||
case "$architecture" in
|
||||
"amd64")
|
||||
architecture="x86_64"
|
||||
;;
|
||||
"arm64")
|
||||
architecture="aarch64"
|
||||
;;
|
||||
esac
|
||||
cd "$tmp_dir"
|
||||
|
||||
curl -s -L "${curl_opts[@]}" -o "./layer.tar" "${repo_url}/blobs/${layer_digest}"
|
||||
mkdir "${digest}"
|
||||
(
|
||||
bsdtar xaf layer.tar --strip-components 4 'usr/lib/modules/*/vmlinuz' && \
|
||||
mv vmlinuz "${digest}/$FILENAME.kernel"
|
||||
) || (
|
||||
bsdtar xaf layer.tar --strip-components 4 'usr/lib/modules/*/Image' && \
|
||||
mv Image "${digest}/$FILENAME.kernel"
|
||||
) || (
|
||||
bsdtar xaf layer.tar --strip-components 4 'usr/lib/modules/*/zImage' && \
|
||||
mv zImage "${digest}/$FILENAME.kernel"
|
||||
)
|
||||
bsdtar --format=newc -cf - "@layer.tar" | zstd -c > "${digest}/$FILENAME.initramfs"
|
||||
mv "$digest" "/shared/html/images/${digest}"
|
||||
cd /shared/html/images
|
||||
|
||||
ln -sf "$digest/$FILENAME.kernel" "${FILENAME}_${architecture,,}.kernel"
|
||||
ln -sf "$digest/$FILENAME.initramfs" "${FILENAME}_${architecture,,}.initramfs"
|
||||
|
||||
rm -rf "$tmp_dir"
|
||||
}
|
||||
|
||||
FILENAME=ironic-python-agent
|
||||
|
||||
mkdir -p /shared/html/images /shared/tmp
|
||||
cd /shared/html/images
|
||||
|
||||
if [[ "${IPA_BASEURI}" == oci://* ]]; then
|
||||
get_oci_tarball "${IPA_BASEURI#oci://}"
|
||||
else
|
||||
FILENAME=ironic-python-agent
|
||||
FILENAME_EXT=.tar
|
||||
FFILENAME=$FILENAME$FILENAME_EXT
|
||||
|
||||
mkdir -p /shared/html/images /shared/tmp
|
||||
cd /shared/html/images
|
||||
|
||||
|
||||
TMPDIR=$(mktemp -d -p /shared/tmp)
|
||||
|
||||
@@ -88,19 +280,7 @@ else
|
||||
ln -sf "$FILENAME-$ETAG/$FFILENAME.headers" "$FFILENAME.headers"
|
||||
ln -sf "$FILENAME-$ETAG/$FILENAME.initramfs" "${FILENAME}_${ARCH,,}.initramfs"
|
||||
ln -sf "$FILENAME-$ETAG/$FILENAME.kernel" "${FILENAME}_${ARCH,,}.kernel"
|
||||
|
||||
IMAGE_CHANGED=1
|
||||
else
|
||||
rm -rf "$TMPDIR"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${CERTS_CHANGED:-0}" = "1" ] || [ "${IMAGE_CHANGED:-0}" = "1" ]; then
|
||||
mkdir -p /tmp/ca/tmp-initrd && cd /tmp/ca/tmp-initrd
|
||||
mkdir -p etc/ironic-python-agent.d/ca-certs
|
||||
cp /tmp/ironic-certificates/* etc/ironic-python-agent.d/ca-certs/
|
||||
for initramfs in /shared/html/images/ironic-python-agent_*.initramfs; do
|
||||
find . | cpio -o -H newc --reproducible | zstd -c >> "${initramfs}"
|
||||
done
|
||||
cp /tmp/certificates.sha256 /shared/certificates.sha256
|
||||
fi
|
||||
fi
|
||||
@@ -1,8 +0,0 @@
|
||||
<constraints>
|
||||
<hardware>
|
||||
<processors>4</processors>
|
||||
<disk>
|
||||
<size unit="G">12</size>
|
||||
</disk>
|
||||
</hardware>
|
||||
</constraints>
|
||||
@@ -1,61 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
test -f /.kconfig && . /.kconfig
|
||||
test -f /.profile && . /.profile
|
||||
|
||||
#======================================
|
||||
# Greeting...
|
||||
#--------------------------------------
|
||||
echo "Configure image: [$kiwi_iname]..."
|
||||
|
||||
#==========================================
|
||||
# setup build day
|
||||
#------------------------------------------
|
||||
baseSetupBuildDay
|
||||
|
||||
#==========================================
|
||||
# remove unneded kernel files
|
||||
#------------------------------------------
|
||||
#suseStripKernel
|
||||
baseStripLocales en_US.utf-8 C.utf8
|
||||
|
||||
#======================================
|
||||
# Setup baseproduct link
|
||||
#--------------------------------------
|
||||
suseSetupProduct
|
||||
|
||||
#======================================
|
||||
# Add missing gpg keys to rpm
|
||||
#--------------------------------------
|
||||
suseImportBuildKey
|
||||
|
||||
#======================================
|
||||
# Activate services
|
||||
#--------------------------------------
|
||||
baseInsertService openstack-ironic-python-agent
|
||||
baseInsertService suse-ironic-image-setup
|
||||
baseInsertService sshd
|
||||
baseInsertService NetworkManager
|
||||
|
||||
echo 'DEFAULT_TIMEZONE="UTC"' >> /etc/sysconfig/clock
|
||||
baseUpdateSysConfig /etc/sysconfig/clock HWCLOCK "-u"
|
||||
baseUpdateSysConfig /etc/sysconfig/clock TIMEZONE UTC
|
||||
baseUpdateSysConfig /etc/sysconfig/network/dhcp DHCLIENT_SET_HOSTNAME no
|
||||
baseUpdateSysConfig /etc/sysconfig/network/dhcp WRITE_HOSTNAME_TO_HOSTS no
|
||||
|
||||
#==========================================
|
||||
# generate autologin@ service
|
||||
# based on getty@ service
|
||||
#------------------------------------------
|
||||
#sed 's/^ExecStart=.*/\0 --autologin root/' /usr/lib/systemd/system/getty@.service > /etc/systemd/system/autologin\@.service
|
||||
sed -E 's/^(ExecStart=.*\/agetty).*(--noclear.*)/\1 \2 --autologin root/' /usr/lib/systemd/system/getty@.service > /etc/systemd/system/autologin\@.service
|
||||
|
||||
#==========================================
|
||||
# add fstab entry for tmpfs based /tmp
|
||||
#------------------------------------------
|
||||
echo 'tmpfs /tmp tmpfs size=3G 0 0' >> /etc/fstab
|
||||
|
||||
ln -s /sbin/init /init
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<image schemaversion="7.4" name="openstack-ironic-image">
|
||||
<description type="system">
|
||||
<author>Cloud developers</author>
|
||||
<contact>cloud-devel@suse.de</contact>
|
||||
<specification>kernel and ramdisk image for metal3</specification>
|
||||
</description>
|
||||
<profiles>
|
||||
<profile name="default" description="Booting default profile" import="true"/>
|
||||
</profiles>
|
||||
<preferences>
|
||||
<locale>en_US</locale>
|
||||
<packagemanager>zypper</packagemanager>
|
||||
<rpm-check-signatures>false</rpm-check-signatures>
|
||||
<rpm-excludedocs>true</rpm-excludedocs>
|
||||
<timezone>UTC</timezone>
|
||||
<version>1.0.0</version>
|
||||
</preferences>
|
||||
<preferences profiles="default">
|
||||
<type image="kis" initrd_system="none" compressed="false"/>
|
||||
</preferences>
|
||||
|
||||
<users>
|
||||
<user password="*" home="/root" name="root" groups="root"/>
|
||||
</users>
|
||||
|
||||
<repository alias="build-binaries" type="rpm-md" priority="99">
|
||||
<source path="dir:///.build.binaries"/>
|
||||
</repository>
|
||||
|
||||
<packages type="delete">
|
||||
<package name="gpg2"/>
|
||||
<package name="libcairo2"/>
|
||||
<package name="libpango-1_0-0"/>
|
||||
<package name="libX11-6"/>
|
||||
<package name="libXext6"/>
|
||||
<package name="libXft2"/>
|
||||
<package name="libXrender1"/>
|
||||
<package name="libX11-data"/>
|
||||
<package name="libXau6"/>
|
||||
<package name="libxcb-render0"/>
|
||||
<package name="libxcb-shm0"/>
|
||||
<package name="libxcb1"/>
|
||||
<package name="kernel-firmware-amdgpu"/>
|
||||
<package name="kernel-firmware-ath10k"/>
|
||||
<package name="kernel-firmware-ath11k"/>
|
||||
<package name="kernel-firmware-ath12k"/>
|
||||
<package name="kernel-firmware-atheros"/>
|
||||
<package name="kernel-firmware-bluetooth"/>
|
||||
<package name="kernel-firmware-brcm"/>
|
||||
<package name="kernel-firmware-i915"/>
|
||||
<package name="kernel-firmware-iwlwifi"/>
|
||||
<package name="kernel-firmware-media"/>
|
||||
<package name="kernel-firmware-nvidia"/>
|
||||
<package name="kernel-firmware-qcom"/>
|
||||
<package name="kernel-firmware-radeon"/>
|
||||
<package name="kernel-firmware-realtek"/>
|
||||
<package name="kernel-firmware-sound"/>
|
||||
<package name="kernel-firmware-ti"/>
|
||||
<package name="kernel-firmware-ueagle"/>
|
||||
</packages>
|
||||
|
||||
<packages type="bootstrap">
|
||||
<package name="glibc-locale"/>
|
||||
<package name="udev"/>
|
||||
<package name="filesystem"/>
|
||||
<package name="cracklib-dict-full"/>
|
||||
<package name="ca-certificates"/>
|
||||
<package name="sles-release"/>
|
||||
|
||||
<package name="checkmedia"/>
|
||||
<package name="fontconfig"/>
|
||||
<package name="fonts-config"/>
|
||||
<package name="grub2-arm64-efi" arch="aarch64"/>
|
||||
<package name="grub2-branding-SLE"/>
|
||||
<package name="grub2-i386-pc" arch="x86_64"/>
|
||||
<package name="grub2-x86_64-efi" arch="x86_64"/>
|
||||
<package name="grub2"/>
|
||||
<package name="gettext-runtime"/>
|
||||
<package name="iproute2"/>
|
||||
<package name="iputils"/>
|
||||
<package name="kernel-default"/>
|
||||
<package name="kernel-firmware-all"/>
|
||||
<package name="lvm2"/>
|
||||
<package name="NetworkManager"/>
|
||||
<package name="nm-configurator"/>
|
||||
<package name="openssh"/>
|
||||
<package name="timezone"/>
|
||||
<package name="which"/>
|
||||
<!-- ironic-python-agent specific -->
|
||||
<package name="chrony"/>
|
||||
<package name="dmidecode"/>
|
||||
<package name="efibootmgr"/>
|
||||
<package name="gptfdisk"/>
|
||||
<package name="hdparm"/>
|
||||
<package name="hwinfo"/>
|
||||
<package name="ipmitool"/>
|
||||
<package name="iputils"/>
|
||||
<package name="kbd"/>
|
||||
<package name="krb5"/>
|
||||
<package name="lshw"/>
|
||||
<package name="lvm2"/>
|
||||
<package name="net-tools"/>
|
||||
<package name="open-iscsi"/>
|
||||
<package name="openstack-ironic-python-agent"/>
|
||||
<package name="parted"/>
|
||||
<package name="psmisc"/>
|
||||
<package name="qemu-tools"/>
|
||||
<package name="timezone"/>
|
||||
<package name="which"/>
|
||||
</packages>
|
||||
|
||||
<packages type="kis">
|
||||
<package name="dracut-kiwi-oem-repart"/>
|
||||
<package name="dracut-kiwi-oem-dump"/>
|
||||
</packages>
|
||||
</image>
|
||||
@@ -1,165 +0,0 @@
|
||||
#
|
||||
# spec file for package openstack-ironic-image
|
||||
#
|
||||
# Copyright (c) 2023 SUSE LLC
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
# upon. The license for this file, and modifications and additions to the
|
||||
# file, is the same license as for the pristine package itself (unless the
|
||||
# license for the pristine package is not an Open Source License, in which
|
||||
# case the license is the MIT License). An "Open Source License" is a
|
||||
# license that conforms to the Open Source Definition (Version 1.9)
|
||||
# published by the Open Source Initiative.
|
||||
|
||||
# Please submit bugfixes or comments via https://bugs.opensuse.org/
|
||||
#
|
||||
# needsrootforbuild
|
||||
# needsbinariesforbuild
|
||||
|
||||
|
||||
Name: ironic-ipa-ramdisk
|
||||
Version: 3.0.9
|
||||
Release: 0
|
||||
Summary: Kernel and ramdisk image for OpenStack Ironic
|
||||
License: SUSE-EULA
|
||||
Group: System/Management
|
||||
URL: https://github.com/SUSE-Cloud/
|
||||
Source0: config.sh
|
||||
Source10: ironic-ipa-ramdisk.kiwi
|
||||
Source20: root
|
||||
|
||||
#!BuildIgnore: systemd-mini
|
||||
BuildRequires: systemd
|
||||
BuildRequires: -post-build-checks
|
||||
BuildRequires: bash
|
||||
BuildRequires: kiwi
|
||||
BuildRequires: zypper
|
||||
|
||||
BuildRequires: checkmedia
|
||||
BuildRequires: acl
|
||||
BuildRequires: ca-certificates-mozilla-prebuilt
|
||||
BuildRequires: cracklib-dict-full
|
||||
BuildRequires: cron
|
||||
BuildRequires: dbus-1
|
||||
BuildRequires: elfutils
|
||||
BuildRequires: filesystem
|
||||
BuildRequires: fipscheck
|
||||
BuildRequires: fontconfig
|
||||
BuildRequires: fonts-config
|
||||
BuildRequires: gptfdisk
|
||||
BuildRequires: grub2
|
||||
%ifarch x86_64
|
||||
BuildRequires: grub2-x86_64-efi
|
||||
%endif
|
||||
%ifarch aarch64
|
||||
BuildRequires: grub2-arm64-efi
|
||||
%endif
|
||||
BuildRequires: hdparm
|
||||
BuildRequires: hwinfo
|
||||
BuildRequires: ipmitool
|
||||
BuildRequires: iproute2
|
||||
BuildRequires: iputils
|
||||
BuildRequires: kernel-default
|
||||
BuildRequires: kernel-firmware-all
|
||||
BuildRequires: lvm2
|
||||
BuildRequires: net-tools
|
||||
BuildRequires: chrony
|
||||
BuildRequires: open-iscsi
|
||||
BuildRequires: openssh
|
||||
BuildRequires: openstack-ironic-python-agent
|
||||
BuildRequires: pam-config
|
||||
BuildRequires: parted
|
||||
BuildRequires: patterns-base-minimal_base
|
||||
BuildRequires: pinentry
|
||||
BuildRequires: pkgconfig
|
||||
BuildRequires: Mesa-gallium
|
||||
BuildRequires: plymouth
|
||||
BuildRequires: plymouth-scripts
|
||||
BuildRequires: psmisc
|
||||
BuildRequires: qemu-tools
|
||||
BuildRequires: sg3_utils
|
||||
BuildRequires: sles-release
|
||||
BuildRequires: sudo
|
||||
BuildRequires: suse-build-key
|
||||
BuildRequires: systemd-presets-branding-SLE
|
||||
BuildRequires: timezone
|
||||
BuildRequires: udev
|
||||
BuildRequires: vim
|
||||
BuildRequires: wpa_supplicant
|
||||
BuildRequires: dhcp-client
|
||||
BuildRequires: which
|
||||
BuildRequires: NetworkManager
|
||||
BuildRequires: nm-configurator
|
||||
BuildRequires: logrotate
|
||||
BuildRequires: plymouth-dracut
|
||||
BuildRequires: plymouth-theme-bgrt
|
||||
BuildRequires: dracut-kiwi-oem-dump
|
||||
BuildRequires: dracut-kiwi-oem-repart
|
||||
BuildRequires: grub2-branding-SLE
|
||||
BuildRequires: open-iscsi
|
||||
BuildRequires: plymouth-branding-SLE
|
||||
BuildRequires: lshw
|
||||
BuildRequires: kbd
|
||||
BuildRequires: dmidecode
|
||||
BuildRequires: efibootmgr
|
||||
BuildRequires: glibc-locale
|
||||
BuildRequires: krb5
|
||||
BuildRequires: gettext-runtime
|
||||
%ifarch x86_64
|
||||
BuildRequires: syslinux
|
||||
%endif
|
||||
|
||||
%description
|
||||
Kernel and ramdisk image for use with Metal3
|
||||
|
||||
%package %{_arch}
|
||||
BuildArch: noarch
|
||||
Summary: Kernel and ramdisk image for Metal3
|
||||
Group: System/Management
|
||||
|
||||
%description %{_arch}
|
||||
Kernel and ramdisk image for use with Metal3
|
||||
For %{_arch}
|
||||
|
||||
%prep
|
||||
mkdir -p /tmp/openstack-ironic-image/build /tmp/openstack-ironic-image/img
|
||||
|
||||
cp -a %{SOURCE0} /tmp/openstack-ironic-image/config.sh
|
||||
|
||||
cp -a %{SOURCE10} /tmp/openstack-ironic-image/config.kiwi
|
||||
|
||||
cp -ar %{SOURCE20} /tmp/openstack-ironic-image/root
|
||||
|
||||
%build
|
||||
if ! which kiwi; then
|
||||
cat <<EOF >&2
|
||||
kiwi not found in \$PATH; most likely this build was missing
|
||||
the --userootforbuild option. If you are invoking osc build
|
||||
manually, please use 'make buildlocal' instead.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kiwi-ng --debug --profile default system build --description /tmp/openstack-ironic-image --target-dir /tmp/openstack-ironic-image/img
|
||||
|
||||
%install
|
||||
TDIR=`mktemp -d /tmp/openstack-ironic-image.XXXXX`
|
||||
cd /tmp/openstack-ironic-image/img/build/image-root
|
||||
find . | cpio --create --format=newc --quiet > $TDIR/initrdtmp
|
||||
cd $TDIR
|
||||
zstd initrdtmp -o initrd-%{_arch}.zst
|
||||
INITRD=`ls *.zst | head -1`
|
||||
|
||||
ls /tmp/openstack-ironic-image/img/openstack-ironic-image*
|
||||
KERNEL=`ls /tmp/openstack-ironic-image/img/openstack-ironic-image*default*kernel | head -1`
|
||||
|
||||
mkdir -p %{buildroot}/srv/tftpboot/openstack-ironic-image
|
||||
install -p -m 644 $KERNEL $INITRD %{buildroot}/srv/tftpboot/openstack-ironic-image/
|
||||
|
||||
%files %{_arch}
|
||||
%defattr(644,root,root)
|
||||
%dir %attr(755, root, root) /srv/tftpboot/openstack-ironic-image
|
||||
%attr(644, root, root) /srv/tftpboot/openstack-ironic-image/*
|
||||
|
||||
%changelog
|
||||
99
ironic-python-agent-image/Dockerfile
Normal file
99
ironic-python-agent-image/Dockerfile
Normal file
@@ -0,0 +1,99 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-python-agent:3.0.8
|
||||
#!BuildTag: %%IMG_PREFIX%%ironic-python-agent:3.0.8-%RELEASE%
|
||||
ARG SLE_VERSION
|
||||
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION as target
|
||||
FROM registry.suse.com/bci/bci-base:$SLE_VERSION as build
|
||||
COPY --from=target / /target
|
||||
|
||||
RUN set -euo pipefail; mkdir -p /target
|
||||
RUN set -euo pipefail; zypper --non-interactive --gpg-auto-import-keys --installroot /target install --no-recommends -- \
|
||||
NetworkManager \
|
||||
chrony \
|
||||
dmidecode \
|
||||
efibootmgr \
|
||||
gptfdisk \
|
||||
grub2-branding-SLE \
|
||||
grub2-common \
|
||||
grub2-x86_64-efi \
|
||||
hdparm \
|
||||
hwinfo \
|
||||
ipmitool \
|
||||
iproute2 \
|
||||
iputils \
|
||||
kbd \
|
||||
kernel-default \
|
||||
kernel-firmware-all \
|
||||
krb5 \
|
||||
lshw \
|
||||
lvm2 \
|
||||
mdadm \
|
||||
net-tools \
|
||||
nm-configurator \
|
||||
open-iscsi \
|
||||
openssh \
|
||||
openstack-ironic-python-agent \
|
||||
parted \
|
||||
psmisc \
|
||||
qemu-tools \
|
||||
shim \
|
||||
timezone \
|
||||
which \
|
||||
&& \
|
||||
zypper --non-interactive --installroot /target remove -- \
|
||||
kernel-firmware-amdgpu \
|
||||
kernel-firmware-ath10k \
|
||||
kernel-firmware-ath11k \
|
||||
kernel-firmware-ath12k \
|
||||
kernel-firmware-atheros \
|
||||
kernel-firmware-bluetooth \
|
||||
kernel-firmware-brcm \
|
||||
kernel-firmware-i915 \
|
||||
kernel-firmware-iwlwifi \
|
||||
kernel-firmware-media \
|
||||
kernel-firmware-nvidia \
|
||||
kernel-firmware-qcom \
|
||||
kernel-firmware-radeon \
|
||||
kernel-firmware-realtek \
|
||||
kernel-firmware-sound \
|
||||
kernel-firmware-ueagle \
|
||||
&& \
|
||||
zypper clean --all && \
|
||||
rm -rf /target/target
|
||||
|
||||
FROM scratch
|
||||
|
||||
# Define labels according to https://en.opensuse.org/Building_derived_containers
|
||||
# labelprefix=com.suse.application.ironic
|
||||
LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)"
|
||||
LABEL org.opencontainers.image.title="SLE Based Ironic Python Agent Bootable Container Image"
|
||||
LABEL org.opencontainers.image.description="ironic-python-agent bootable image based on the SLE Base Container Image."
|
||||
LABEL org.opencontainers.image.version="3.0.8"
|
||||
LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/"
|
||||
LABEL org.opencontainers.image.created="%BUILDTIME%"
|
||||
LABEL org.opencontainers.image.vendor="SUSE LLC"
|
||||
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-python-agent:3.0.8-%RELEASE%"
|
||||
LABEL org.openbuildservice.disturl="%DISTURL%"
|
||||
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
|
||||
LABEL com.suse.eula="SUSE Combined EULA February 2024"
|
||||
LABEL com.suse.lifecycle-url="https://www.suse.com/lifecycle"
|
||||
LABEL com.suse.image-type="application"
|
||||
LABEL com.suse.release-stage="released"
|
||||
# endlabelprefix
|
||||
|
||||
COPY --from=build /target /
|
||||
ADD root /
|
||||
# Fix issue in IPA packaging while waiting for it to be fixed
|
||||
RUN sed -E 's/ironic-python-agent.conf.d/ironic-python-agent.d/' /usr/lib/systemd/system/openstack-ironic-python-agent.service > /etc/systemd/system/openstack-ironic-python-agent.service && \
|
||||
mv /etc/ironic-python-agent.conf.d /etc/ironic-python-agent.d
|
||||
RUN ln -s sbin/init /init && \
|
||||
systemctl enable \
|
||||
openstack-ironic-python-agent \
|
||||
suse-ironic-image-setup \
|
||||
sshd \
|
||||
NetworkManager \
|
||||
&& \
|
||||
echo 'DEFAULT_TIMEZONE="UTC"' >> /etc/sysconfig/clock
|
||||
|
||||
RUN sed -E 's/^(ExecStart=.*\/agetty).*(--noclear.*)/\1 \2 --autologin root/' /usr/lib/systemd/system/serial-getty@.service > /etc/systemd/system/autologin\@.service
|
||||
RUN echo 'tmpfs /tmp tmpfs size=3G 0 0' >> /etc/fstab
|
||||
13
ironic-python-agent-image/_service
Normal file
13
ironic-python-agent-image/_service
Normal file
@@ -0,0 +1,13 @@
|
||||
<services>
|
||||
<service mode="buildtime" name="kiwi_metainfo_helper"/>
|
||||
<service mode="buildtime" name="docker_label_helper"/>
|
||||
<service name="replace_using_env" mode="buildtime">
|
||||
<param name="file">Dockerfile</param>
|
||||
<param name="eval">IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})</param>
|
||||
<param name="var">IMG_PREFIX</param>
|
||||
<param name="eval">IMG_REPO=$(rpm --macros=/root/.rpmmacros -E %img_repo)</param>
|
||||
<param name="var">IMG_REPO</param>
|
||||
<param name="eval">SUPPORT_LEVEL=$(rpm --macros=/root/.rpmmacros -E %support_level)</param>
|
||||
<param name="var">SUPPORT_LEVEL</param>
|
||||
</service>
|
||||
</services>
|
||||
@@ -35,8 +35,7 @@ fi
|
||||
if [[ $PARAMS =~ (suse|coreos)\.autologin=?([^ ]*) ]]; then
|
||||
tty="${BASH_REMATCH[2]:-tty1}"
|
||||
echo "Enabling autologin on $tty..."
|
||||
systemctl stop getty@$tty
|
||||
systemctl disable getty@$tty
|
||||
systemctl disable --now getty@$tty serial-getty@$tty
|
||||
systemctl start autologin@$tty
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.22_up0.13.1
|
||||
#!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.22_up0.13.1-%RELEASE%
|
||||
#!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.23_up0.13.2
|
||||
#!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.23_up0.13.2-%RELEASE%
|
||||
apiVersion: v2
|
||||
appVersion: 0.13.0
|
||||
appVersion: 0.13.2
|
||||
dependencies:
|
||||
- alias: metal3-baremetal-operator
|
||||
name: baremetal-operator
|
||||
@@ -10,7 +10,7 @@ dependencies:
|
||||
- alias: metal3-ironic
|
||||
name: ironic
|
||||
repository: file://./charts/ironic
|
||||
version: 0.12.2
|
||||
version: 0.12.3
|
||||
- alias: metal3-mariadb
|
||||
condition: global.enable_mariadb
|
||||
name: mariadb
|
||||
@@ -25,4 +25,4 @@ description: A Helm chart that installs all of the dependencies needed for Metal
|
||||
icon: https://github.com/cncf/artwork/raw/master/projects/metal3/icon/color/metal3-icon-color.svg
|
||||
name: metal3
|
||||
type: application
|
||||
version: "%%CHART_MAJOR%%.0.22+up0.13.1"
|
||||
version: "%%CHART_MAJOR%%.0.23+up0.13.2"
|
||||
|
||||
@@ -3,4 +3,4 @@ appVersion: 32.0.0
|
||||
description: A Helm chart for Ironic, used by Metal3
|
||||
name: ironic
|
||||
type: application
|
||||
version: 0.12.2
|
||||
version: 0.12.3
|
||||
|
||||
@@ -8,5 +8,7 @@ data:
|
||||
{{- with .Values.baremetaloperator }}
|
||||
{{ if .ipaBaseUri }}
|
||||
IPA_BASEURI: {{ .ipaBaseUri }}
|
||||
{{ end }}
|
||||
{{- else if .ipaImage }}
|
||||
IPA_BASEURI: oci://{{ .ipaImage.repository }}:{{ .ipaImage.tag }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -5,6 +5,7 @@ metadata:
|
||||
labels:
|
||||
{{- include "ironic.labels" . | nindent 4 }}
|
||||
data:
|
||||
DEFAULT_CACERT_BUNDLE: /etc/ssl/ca-bundle.pem
|
||||
{{- if ( .Values.global.enable_dnsmasq ) }}
|
||||
DNSMASQ_DNS_SERVER_ADDRESS: {{ .Values.global.dnsmasqDNSServer }}
|
||||
DNSMASQ_DEFAULT_ROUTER: {{ .Values.global.dnsmasqDefaultRouter }}
|
||||
|
||||
@@ -149,6 +149,11 @@ spec:
|
||||
- mountPath: /etc/pki/trust/anchors
|
||||
name: trusted-certs
|
||||
readOnly: true
|
||||
{{- if .Values.global.additionalTrustedCAs }}
|
||||
- mountPath: /certs/ca/ipa
|
||||
name: trusted-certs
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
lifecycle:
|
||||
postStart:
|
||||
exec:
|
||||
@@ -233,6 +238,9 @@ spec:
|
||||
sources:
|
||||
- secret:
|
||||
name: ironic-cacert
|
||||
items:
|
||||
- key: ca.crt
|
||||
path: ca.crt
|
||||
{{- if .Values.global.additionalTrustedCAs }}
|
||||
- secret:
|
||||
name: tls-ca-additional
|
||||
|
||||
@@ -64,11 +64,11 @@ images:
|
||||
ironic:
|
||||
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic
|
||||
pullPolicy: IfNotPresent
|
||||
tag: 32.0.0.1
|
||||
tag: 32.0.0.2
|
||||
ironicIPADownloader:
|
||||
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic-ipa-downloader
|
||||
pullPolicy: IfNotPresent
|
||||
tag: 3.0.11
|
||||
tag: 3.1.0
|
||||
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
@@ -103,6 +103,10 @@ metal3-ironic:
|
||||
ironic:
|
||||
# storageClass for the ironic shared volume
|
||||
storageClass: ""
|
||||
baremetaloperator:
|
||||
ipaImage:
|
||||
repository: "%%IMG_REPO%%/%%IMG_PREFIX%%ironic-python-agent"
|
||||
tag: "3.0.8"
|
||||
images:
|
||||
ironic:
|
||||
repository: "%%IMG_REPO%%/%%IMG_PREFIX%%ironic"
|
||||
|
||||
@@ -92,7 +92,7 @@ spec:
|
||||
enabled: false
|
||||
- prettyName: Longhorn
|
||||
releaseName: longhorn
|
||||
chart: 'oci://dp.apps.rancher.io/charts/suse-storage'
|
||||
chart: oci://dp.apps.rancher.io/charts/suse-storage
|
||||
version: 1.10.1
|
||||
- prettyName: MetalLB
|
||||
releaseName: metallb
|
||||
@@ -161,7 +161,7 @@ spec:
|
||||
- prettyName: Metal3
|
||||
releaseName: metal3
|
||||
chart: '%%CHART_REPO%%/%%CHART_PREFIX%%metal3'
|
||||
version: '%%CHART_MAJOR%%.0.22+up0.13.1'
|
||||
version: '%%CHART_MAJOR%%.0.23+up0.13.2'
|
||||
- prettyName: RancherTurtlesProviders
|
||||
releaseName: rancher-turtles-providers
|
||||
chart: '%%CHART_REPO%%/%%CHART_PREFIX%%rancher-turtles-providers'
|
||||
|
||||
Reference in New Issue
Block a user
While it's impressive to make this all work with only bash, do you think it will be robust enough?
I'm wondering if it's worth paying the small size cost of adding a tool which handles the registry interaction, for example the
orasCLI tool is only about 11MB, I've not looked at alternatives.Most of the heavy lifting is generated through Gemini here, but I wanted to check if the naive approach is sound. Reason being that I tried with skopeo and it worked, but without support for multi-arch, and it kept re-downloading more than needed every time.
I may try with oras, but I wanted to have a reference of a "working" solution to see the impact in term of size notably (might be small)