Skip to content

Commit

Permalink
Create MicroShift iso using image mode and bootc image builder
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
praveenkumar committed Jan 17, 2025
1 parent 9a22f43 commit 2c867a0
Show file tree
Hide file tree
Showing 5 changed files with 307 additions and 115 deletions.
144 changes: 144 additions & 0 deletions image-mode/microshift/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/bin/bash
set -eo 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 <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 <microshift-version>"
echo " Version of microshift for image generation (default: ${USHIFT_VERSION}"
echo " -hostname <hostname>"
echo " Hostname of the machine"
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
;;
-hostname)
shift
HOSTNAME="$1"
[ -z "${HOSTNAME}" ] && usage "hostname 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_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}
34 changes: 34 additions & 0 deletions image-mode/microshift/config/Containerfile.bootc-rhel9
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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 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

# 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
112 changes: 112 additions & 0 deletions image-mode/microshift/config/config.toml.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
[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 <<EOF
REPLACE_OCP_PULL_SECRET_CONTENTS
EOF
chmod 600 /etc/crio/openshift-pull-secret

# Create a default core user, allowing it to run sudo commands without password
useradd -m -d /home/core core
echo -e 'core\tALL=(ALL)\tNOPASSWD: ALL' > /etc/sudoers.d/microshift

# Add authorized ssh keys
mkdir -m 700 /home/core/.ssh
cat > /home/core/.ssh/authorized_keys <<EOF
REPLACE_CORE_AUTHORIZED_KEYS_CONTENTS
EOF
chmod 600 /home/core/.ssh/authorized_keys

# Make sure core user directory contents ownership is correct
chown -R core:core /home/core/

# Set static hostname
echo "REPLACE_HOSTNAME" > /etc/hostname
chmod 644 /etc/hostname

# Configure the firewall (rules reload is not necessary here)
firewall-offline-cmd --zone=trusted --add-source=10.42.0.0/16
firewall-offline-cmd --zone=trusted --add-source=169.254.169.1


# 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 <<EOF
[Journal]
Storage=persistent
SystemMaxUse=1G
RuntimeMaxUse=1G
EOF

# Update certificate trust storage in case new certificates were
# installed at /etc/pki/ca-trust/source/anchors directory
update-ca-trust

# 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
chown -R core:core /home/core/.config

mkdir -p /home/core/.config/containers
tee /home/core/.config/containers/containers.conf <<EOF
[containers]
netns="bridge"
rootless_networking="cni"
EOF
chown -R core:core /home/core/.config/containers

touch /etc/containers/podman-machine

tee /etc/containers/registries.conf.d/999-podman-machine.conf <<EOF
unqualified-search-registries=["docker.io"]
EOF

# Enable linger for core user to make sure podman socket work when user not logged in
mkdir -p /var/lib/systemd/linger/
touch /var/lib/systemd/linger/core
%end
"""
Loading

0 comments on commit 2c867a0

Please sign in to comment.