diff --git a/image-mode/microshift/build.sh b/image-mode/microshift/build.sh new file mode 100755 index 00000000..c1fe3274 --- /dev/null +++ b/image-mode/microshift/build.sh @@ -0,0 +1,135 @@ +#!/bin/bash +set -exo pipefail + +ROOTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../" && pwd )" +SCRIPTDIR=${ROOTDIR}/image-mode/microshift +IMGNAME=microshift +USHIFT_VERSION=4.17 +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-mirror-repo " + echo " Use 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 " -ushift-version " + echo " Version of microshift for image generation (default: ${USHIFT_VERSION}" + 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-mirror-repo) + shift + USE_MIRROR_REPO="$1" + [ -z "${USE_MIRROR_REPO}" ] && usage "Mirror repo not specified" + shift + ;; + -ushift-version) + shift + USHIFT_VERSION="$1" + [ -z "${USHIFT_VERSION}" ] && usage "MicroShift version 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_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}:${USHIFT_VERSION} \ + --build-arg USHIFT_VER=${USHIFT_VERSION} \ + --env MIRROR_REPO=${USE_MIRROR_REPO} \ + -f "${SCRIPTDIR}/config/Containerfile.bootc-rhel9" + +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}:${USHIFT_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..5892cc21 --- /dev/null +++ b/image-mode/microshift/config/Containerfile.bootc-rhel9 @@ -0,0 +1,30 @@ +FROM registry.redhat.io/rhel9/rhel-bootc:9.4 + +ARG USHIFT_VER=4.17 +RUN if [ -z "${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 + repoID=$(echo "${MIRROR_REPO#*://}" | tr '/:' '_'); \ + dnf config-manager --add-repo "${MIRROR_REPO}" \ + --add-repo "https://mirror.openshift.com/pub/openshift-v4/$(uname -m)/dependencies/rpms/${USHIFT_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 && \ + systemctl enable microshift && \ + dnf clean all && rm -fr /etc/yum.repos.d/* + +RUN rm -fr /opt && ln -sf /var/opt /opt && mkdir /var/opt + +# Mandatory firewall configuration +RUN firewall-offline-cmd --zone=public --add-port=22/tcp && \ + firewall-offline-cmd --zone=trusted --add-source=10.42.0.0/16 && \ + firewall-offline-cmd --zone=trusted --add-source=169.254.169.1 && \ + firewall-offline-cmd --zone=trusted --add-source=fd01::/48 +# Application-specific firewall configuration +RUN firewall-offline-cmd --zone=public --add-port=80/tcp && \ + firewall-offline-cmd --zone=public --add-port=443/tcp && \ + firewall-offline-cmd --zone=public --add-port=30000-32767/tcp && \ + firewall-offline-cmd --zone=public --add-port=30000-32767/udp diff --git a/image-mode/microshift/config/config.toml.template b/image-mode/microshift/config/config.toml.template new file mode 100644 index 00000000..d365206b --- /dev/null +++ b/image-mode/microshift/config/config.toml.template @@ -0,0 +1,84 @@ +[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/sudoers.d/microshift + +# Add authorized ssh keys +mkdir -m 700 /home/core/.ssh +cat > /home/core/.ssh/authorized_keys <> /root/.profile + +# Configure systemd journal service to persist logs between boots and limit their size to 1G +sudo mkdir -p /etc/systemd/journald.conf.d +cat > /etc/systemd/journald.conf.d/microshift.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 mirror_repo="" + if [ -n "${MICROSHIFT_PRERELEASE-}" ]; then + 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) \ + -ushift-version ${MICROSHIFT_VERSION} \ + -use-mirror-repo ${mirror_repo} } -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