From febf74c9589c1eff9d04bd90831df874059387fb Mon Sep 17 00:00:00 2001 From: Praveen Kumar Date: Fri, 10 Jan 2025 14:14:40 +0530 Subject: [PATCH] Create MicroShift iso using image mode and bootc image builder With 4.18 microshift removed the steps of creating the iso using image builder and there is no more `build.sh` script which is consumed by mircoshift.sh script to create it. This PR use the image mode and bootc image builder (BIB) to create the iso which is now microshift team also pushing forward. --- 00-microshift-dns.yaml | 15 -- createdisk.sh | 3 - image-mode/microshift/build.sh | 155 ++++++++++++++++++ .../config/Containerfile.bootc-rhel9 | 25 +++ .../microshift/config/config.toml.template | 99 +++++++++++ microshift.sh | 107 ++---------- podman_changes.ks | 26 --- 7 files changed, 297 insertions(+), 133 deletions(-) delete mode 100644 00-microshift-dns.yaml create mode 100755 image-mode/microshift/build.sh create mode 100644 image-mode/microshift/config/Containerfile.bootc-rhel9 create mode 100644 image-mode/microshift/config/config.toml.template delete mode 100644 podman_changes.ks diff --git a/00-microshift-dns.yaml b/00-microshift-dns.yaml deleted file mode 100644 index 569173a5..00000000 --- a/00-microshift-dns.yaml +++ /dev/null @@ -1,15 +0,0 @@ -dns: - # baseDomain is the base domain of the cluster. All managed DNS records will - # be sub-domains of this base. - - - # For example, given the base domain `example.com`, router exposed - # domains will be formed as `*.apps.example.com` by default, - # and API service will have a DNS entry for `api.example.com`, - # as well as "api-int.example.com" for internal k8s API access. - - - # Once set, this field cannot be changed. - # example: - # microshift.example.com - baseDomain: example.com diff --git a/createdisk.sh b/createdisk.sh index 0e167009..33964e38 100755 --- a/createdisk.sh +++ b/createdisk.sh @@ -72,9 +72,6 @@ EOF # also in case of microshift the ports like 2222, 443, 80 ..etc need to be manually added # and OCP/OKD/podman bundles have it disabled by default. ${SSH} core@${VM_IP} -- sudo systemctl disable firewalld - ${YQ} eval --inplace ".dns.baseDomain = \"${SNC_PRODUCT_NAME}.${BASE_DOMAIN}\"" 00-microshift-dns.yaml - ${SCP} 00-microshift-dns.yaml core@${VM_IP}:/home/core - ${SSH} core@${VM_IP} -- 'sudo mv /home/core/00-microshift-dns.yaml /etc/microshift/config.d/00-microshift-dns.yaml' # Make sure `baseDomain` is set to crc.testing ${SSH} core@${VM_IP} -- "grep '^\s\+baseDomain: ${SNC_PRODUCT_NAME}.${BASE_DOMAIN}' /etc/microshift/config.d/00-microshift-dns.yaml" # Remove the lvm system.device file since it have diskID and deviceName which changes diff --git a/image-mode/microshift/build.sh b/image-mode/microshift/build.sh new file mode 100755 index 00000000..58a8a7e4 --- /dev/null +++ b/image-mode/microshift/build.sh @@ -0,0 +1,155 @@ +#!/bin/bash +set -eo pipefail + +ROOTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../" && pwd )" +SCRIPTDIR=${ROOTDIR}/image-mode/microshift +IMGNAME=microshift +MICROSHIFT_VERSION=4.18 +BUILD_ARCH=$(uname -m) +OSVERSION=$(awk -F: '{print $5}' /etc/system-release-cpe) +LVM_SYSROOT_SIZE_MIN=10240 +LVM_SYSROOT_SIZE=${LVM_SYSROOT_SIZE_MIN} +OCP_PULL_SECRET_FILE= +AUTHORIZED_KEYS_FILE= +AUTHORIZED_KEYS= +USE_MIRROR_REPO= + +# shellcheck disable=SC2034 +STARTTIME="$(date +%s)" +BUILDDIR=${BUILDDIR:-${ROOTDIR}/_output/image-mode} + +usage() { + local error_message="$1" + + if [ -n "${error_message}" ]; then + echo "ERROR: ${error_message}" + echo + fi + + echo "Usage: $(basename "$0") <-pull_secret_file path_to_file> [OPTION]..." + echo "" + echo " -pull_secret_file path_to_file" + echo " Path to a file containing the OpenShift pull secret, which can be" + echo " obtained from https://console.redhat.com/openshift/downloads#tool-pull-secret" + echo "" + echo "Optional arguments:" + echo " -lvm_sysroot_size num_in_MB" + echo " Size of the system root LVM partition. The remaining" + echo " disk space will be allocated for data (default: ${LVM_SYSROOT_SIZE})" + echo " -authorized_keys_file path_to_file" + echo " Path to an SSH authorized_keys file to allow SSH access" + echo " into the default 'redhat' account" + echo " -use-unreleased-mirror-repo " + echo " Use unreleased mirror repo to get release candidate and engineering preview rpms" + echo " like (https://mirror.openshift.com/pub/openshift-v4/x86_64/microshift/ocp-dev-preview/latest-4.18/el9/os/)" + echo " -microshift-version " + echo " Version of microshift for image generation (default: ${MICROSHIFT_VERSION}" + echo " -hostname " + echo " Hostname of the machine" + echo " -base-domain " + echo " Base domain for microshift cluster" + exit 1 +} + +title() { + echo -e "\E[34m\n# $1\E[00m" +} + +# Parse the command line +while [ $# -gt 0 ] ; do + case $1 in + -pull_secret_file) + shift + OCP_PULL_SECRET_FILE="$1" + [ -z "${OCP_PULL_SECRET_FILE}" ] && usage "Pull secret file not specified" + [ ! -s "${OCP_PULL_SECRET_FILE}" ] && usage "Empty or missing pull secret file" + shift + ;; + -lvm_sysroot_size) + shift + LVM_SYSROOT_SIZE="$1" + [ -z "${LVM_SYSROOT_SIZE}" ] && usage "System root LVM partition size not specified" + [ "${LVM_SYSROOT_SIZE}" -lt ${LVM_SYSROOT_SIZE_MIN} ] && usage "System root LVM partition size cannot be smaller than ${LVM_SYSROOT_SIZE_MIN}MB" + shift + ;; + -authorized_keys_file) + shift + AUTHORIZED_KEYS_FILE="$1" + [ -z "${AUTHORIZED_KEYS_FILE}" ] && usage "Authorized keys file not specified" + shift + ;; + -use-unreleased-mirror-repo) + shift + USE_UNRELEASED_MIRROR_REPO="$1" + [ -z "${USE_UNRELEASED_MIRROR_REPO}" ] && usage "Mirror repo not specified" + shift + ;; + -microshift-version) + shift + MICROSHIFT_VERSION="$1" + [ -z "${MICROSHIFT_VERSION}" ] && usage "MicroShift version not specified" + shift + ;; + -hostname) + shift + HOSTNAME="$1" + [ -z "${HOSTNAME}" ] && usage "Hostname not specified" + shift + ;; + -base-domain) + shift + BASE_DOMAIN="$1" + [ -z "${BASE_DOMAIN}" ] && usage "Base domain not specified" + shift + ;; + *) + usage + ;; + esac +done + +if [ ! -r "${OCP_PULL_SECRET_FILE}" ] ; then + echo "ERROR: pull_secret_file file does not exist or not readable: ${OCP_PULL_SECRET_FILE}" + exit 1 +fi +if [ -n "${AUTHORIZED_KEYS_FILE}" ]; then + if [ ! -e "${AUTHORIZED_KEYS_FILE}" ]; then + echo "ERROR: authorized_keys_file does not exist: ${AUTHORIZED_KEYS_FILE}" + exit 1 + else + AUTHORIZED_KEYS=$(cat "${AUTHORIZED_KEYS_FILE}") + fi +fi + +mkdir -p "${BUILDDIR}" + +title "Preparing kickstart config" +# Create a kickstart file from a template, compacting pull secret contents if necessary +cat < "${SCRIPTDIR}/config/config.toml.template" \ + | sed "s;REPLACE_HOSTNAME;${HOSTNAME};g" \ + | sed "s;REPLACE_BASE_DOMAIN;${BASE_DOMAIN};g" \ + | sed "s;REPLACE_LVM_SYSROOT_SIZE;${LVM_SYSROOT_SIZE};g" \ + | sed "s;REPLACE_OCP_PULL_SECRET_CONTENTS;$(cat < "${OCP_PULL_SECRET_FILE}" | jq -c);g" \ + | sed "s^REPLACE_CORE_AUTHORIZED_KEYS_CONTENTS^${AUTHORIZED_KEYS}^g" \ + > "${BUILDDIR}"/config.toml + +title "Building bootc image for microshift" +sudo podman build --authfile ${OCP_PULL_SECRET_FILE} -t ${IMGNAME}:${MICROSHIFT_VERSION} \ + --build-arg USHIFT_VER=${MICROSHIFT_VERSION} \ + --env UNRELEASED_MIRROR_REPO=${USE_UNRELEASED_MIRROR_REPO} \ + -f "${SCRIPTDIR}/config/Containerfile.bootc-rhel9" + +# As of now we are generating the ISO to have same previous behavior +# TODO: Try to use qcow2 directly for vm creation +title "Creating ISO image" +sudo podman run --authfile ${OCP_PULL_SECRET_FILE} --rm -it \ + --privileged \ + --security-opt label=type:unconfined_t \ + -v /var/lib/containers/storage:/var/lib/containers/storage \ + -v "${BUILDDIR}"/config.toml:/config.toml \ + -v "${BUILDDIR}":/output \ + registry.redhat.io/rhel9/bootc-image-builder:latest \ + --local \ + --type iso \ + --config /config.toml \ + localhost/${IMGNAME}:${MICROSHIFT_VERSION} diff --git a/image-mode/microshift/config/Containerfile.bootc-rhel9 b/image-mode/microshift/config/Containerfile.bootc-rhel9 new file mode 100644 index 00000000..9b4522b9 --- /dev/null +++ b/image-mode/microshift/config/Containerfile.bootc-rhel9 @@ -0,0 +1,25 @@ +FROM registry.redhat.io/rhel9/rhel-bootc:9.4 + +ARG MICROSHIFT_VER=4.18 +RUN if [ -z "${UNRELEASED_MIRROR_REPO}" ]; then \ + dnf config-manager --set-enabled "rhocp-${USHIFT_VER}-for-rhel-9-$(uname -m)-rpms" \ + --set-enabled "fast-datapath-for-rhel-9-$(uname -m)-rpms"; \ + else \ + # This is required to update the gpgcheck for repoID + # Add the specified OpenShift v4 dependencies repository to get packages like crio, runc, openvswitch ..etc. + # to which microshift package depend on for the current architecture and MICROSHIFT_VER version (e.g., 4.18). + repoID=$(echo "${UNRELEASED_MIRROR_REPO#*://}" | tr '/:' '_'); \ + dnf config-manager --add-repo "${UNRELEASED_MIRROR_REPO}" \ + --add-repo "https://mirror.openshift.com/pub/openshift-v4/$(uname -m)/dependencies/rpms/${MICROSHIFT_VER}-el9-beta" \ + --set-enabled "fast-datapath-for-rhel-9-$(uname -m)-rpms"; \ + dnf config-manager --save --setopt="${repoID}".gpgcheck=0 --setopt=*-el9-beta.gpgcheck=0; \ + fi +RUN dnf install -y firewalld microshift microshift-release-info cloud-utils-growpart qemu-guest-agent dnsmasq && \ + dnf clean all && rm -fr /etc/yum.repos.d/* + +# https://github.com/containers/bootc/discussions/1036 +# /Users is created to make sure share directory works on +# mac because on linux it is /home and for windows it is /mnt +# and both are symlink to `var` already +RUN rm -fr /opt && ln -sf var/opt /opt && mkdir /var/opt +RUN ln -sf var/Users /Users && mkdir /var/Users diff --git a/image-mode/microshift/config/config.toml.template b/image-mode/microshift/config/config.toml.template new file mode 100644 index 00000000..806ed6d1 --- /dev/null +++ b/image-mode/microshift/config/config.toml.template @@ -0,0 +1,99 @@ +[customizations.installer.kickstart] +contents = """ +lang en_US.UTF-8 +keyboard us +timezone UTC +text +reboot + +# Configure network to use DHCP and activate on boot +network --bootproto=dhcp --device=link --activate --onboot=on + +# Partition disk with a 1MB BIOS boot, 200M EFI, 800M boot XFS partition and +# an LVM volume containing a 10GB+ system root. The remainder of the volume +# will be used by the CSI driver for storing data +# +# For example, a 20GB disk would be partitioned in the following way: +# +# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT +# sda 8:0 0 20G 0 disk +# ├─sda1 8:1 0 1M 0 part +# ├─sda2 8:2 0 200M 0 part /boot/efi +# ├─sda3 8:3 0 800M 0 part /boot +# └─sda4 8:4 0 19G 0 part +# └─rhel-root 253:0 0 10G 0 lvm /sysroot +# +zerombr +clearpart --all --disklabel gpt +part biosboot --fstype=biosboot --size=1 +part /boot/efi --fstype=efi --size=200 +part /boot --fstype=xfs --asprimary --size=800 +# Uncomment this line to add a SWAP partition of the recommended size +#part swap --fstype=swap --recommended +part pv.01 --grow +volgroup rhel pv.01 +logvol / --vgname=rhel --fstype=xfs --size=REPLACE_LVM_SYSROOT_SIZE --name=root + +# Lock root user account +rootpw --lock + + +%post --log=/var/log/anaconda/post-install.log --erroronfail + +# The pull secret is mandatory for MicroShift builds on top of OpenShift, but not OKD +# The /etc/crio/crio.conf.d/microshift.conf references the /etc/crio/openshift-pull-secret file +cat > /etc/crio/openshift-pull-secret < /etc/microshift/config.d/00-microshift-dns.yaml < /etc/sudoers.d/microshift + +# Add authorized ssh keys +mkdir -m 700 /home/core/.ssh +cat > /home/core/.ssh/authorized_keys < /etc/hostname +chmod 644 /etc/hostname + +# Support to boot for UEFI and legacy mode +grub2-install --target=i386-pc /dev/vda + +# Make podman rootless available +mkdir -p /home/core/.config/systemd/user/default.target.wants +ln -s /usr/lib/systemd/user/podman.socket /home/core/.config/systemd/user/default.target.wants/podman.socket + +mkdir -p /home/core/.config/containers +tee /home/core/.config/containers/containers.conf <> scripts/image-builder/config/blueprint_v0.0.1.toml -[[packages]] -name = "microshift-release-info" -version = "*" -[[packages]] -name = "cloud-utils-growpart" -version = "*" -[[packages]] -name = "qemu-guest-agent" -version = "*" -EOF - sed -i 's/redhat/core/g' scripts/image-builder/config/kickstart.ks.template - sed -i "/--bootproto=dhcp/a\network --hostname=api.${SNC_PRODUCT_NAME}.${BASE_DOMAIN}" scripts/image-builder/config/kickstart.ks.template - sed -i 's/clearpart --all --initlabel/clearpart --all --disklabel gpt/g' scripts/image-builder/config/kickstart.ks.template - sed -i "/clearpart --all/a\part biosboot --fstype=biosboot --size=1" scripts/image-builder/config/kickstart.ks.template - sed -i '$i\grub2-install --target=i386-pc /dev/vda' scripts/image-builder/config/kickstart.ks.template - sed -i '$e cat podman_changes.ks' scripts/image-builder/config/kickstart.ks.template - scripts/image-builder/cleanup.sh -full - # The home dir and files must have read permissions to group - # and others because osbuilder is running from another non-priviledged user account - # and allow it to read the files on current user home (like reading yum repo which is created as part of build script), it is required. - # https://github.com/openshift/microshift/blob/main/scripts/image-builder/configure.sh#L29-L32 - chmod 0755 $HOME - - scripts/image-builder/build.sh -microshift_rpms ${pkgDir} -pull_secret_file ${OPENSHIFT_PULL_SECRET_PATH} -lvm_sysroot_size 15360 -authorized_keys_file $(realpath ../id_ecdsa_crc.pub) - popd + local buildDir=$1 + local extra_args="" + if [ -n "${MICROSHIFT_PRERELEASE-}" ]; then + extra_args="-use-unreleased-mirror-repo ${MIRROR_REPO}" + fi + BUILDDIR=${buildDir} image-mode/microshift/build.sh -pull_secret_file ${OPENSHIFT_PULL_SECRET_PATH} \ + -lvm_sysroot_size 15360 \ + -authorized_keys_file $(realpath id_ecdsa_crc.pub) \ + -microshift-version ${MICROSHIFT_VERSION} \ + -hostname api.${SNC_PRODUCT_NAME}.${BASE_DOMAIN} \ + -base-domain ${SNC_PRODUCT_NAME}.${BASE_DOMAIN} \ + ${extra_args} } -configure_host - -enable_repos microshift_pkg_dir=$(mktemp -p /tmp -d tmp-rpmXXX) -# This directory contains the microshift rpm passed to osbuilder, worker for osbuilder -# running as non-priviledged user and this tmp directory have 0700 permission. To allow -# worker to read/execute this file we need to change the permission to 0755 -chmod 0755 ${microshift_pkg_dir} -download_microshift_rpm ${microshift_pkg_dir} + create_iso ${microshift_pkg_dir} -sudo cp -Z microshift/_output/image-builder/microshift-installer-*.iso /var/lib/libvirt/${SNC_PRODUCT_NAME}/microshift-installer.iso -OPENSHIFT_RELEASE_VERSION=$(rpm -qp --qf '%{VERSION}' ${microshift_pkg_dir}/microshift-4.*.rpm) +sudo cp -Z ${microshift_pkg_dir}/bootiso/install.iso /var/lib/libvirt/${SNC_PRODUCT_NAME}/microshift-installer.iso +OPENSHIFT_RELEASE_VERSION=$(sudo podman run --rm -it localhost/microshift:${MICROSHIFT_VERSION} /usr/bin/rpm -q --qf '%{VERSION}' microshift) # Change 4.x.0~ec0 to 4.x.0-ec0 # https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/#_complex_versioning OPENSHIFT_RELEASE_VERSION=$(echo ${OPENSHIFT_RELEASE_VERSION} | tr '~' '-') -rm -fr ${microshift_pkg_dir} +sudo rm -fr ${microshift_pkg_dir} # Download the oc binary for specific OS environment OC=./openshift-clients/linux/oc diff --git a/podman_changes.ks b/podman_changes.ks deleted file mode 100644 index 4ec37d48..00000000 --- a/podman_changes.ks +++ /dev/null @@ -1,26 +0,0 @@ -# This file is used as part of microshift VM creation -# to have podman specific configuration in place which -# we do using ignition for podman bundle - -# Make podman rootless available -mkdir -p /home/core/.config/systemd/user/default.target.wants -ln -s /usr/lib/systemd/user/podman.socket /home/core/.config/systemd/user/default.target.wants/podman.socket -chown -R core:core /home/core/.config - -mkdir -p /home/core/.config/containers -tee /home/core/.config/containers/containers.conf <