Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create MicroShift iso using image mode and bootc image builder #999

Merged
merged 2 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions createdisk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,8 @@ 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
${SSH} core@${VM_IP} -- cat /etc/microshift/config.yaml.default > config.yaml
${YQ} eval --inplace ".dns.baseDomain = \"${SNC_PRODUCT_NAME}.${BASE_DOMAIN}\"" config.yaml
${SCP} config.yaml core@${VM_IP}:/home/core
${SSH} core@${VM_IP} -- 'sudo mv /home/core/config.yaml /etc/microshift/config.yaml'
# Make sure `baseDomain` is set to crc.testing
${SSH} core@${VM_IP} -- "grep '^\s\+baseDomain: ${SNC_PRODUCT_NAME}.${BASE_DOMAIN}' /etc/microshift/config.yaml"
${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
# for different hypervisor and as per `man lvmdevices` if the file does not exist, or if lvm.conf
# includes use_devicesfile=0, then lvm will not use a devices file.
Expand Down
155 changes: 155 additions & 0 deletions image-mode/microshift/build.sh
Original file line number Diff line number Diff line change
@@ -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 <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 <microshift-version>"
echo " Version of microshift for image generation (default: ${MICROSHIFT_VERSION}"
echo " -hostname <hostname>"
echo " Hostname of the machine"
echo " -base-domain <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 \
cfergeau marked this conversation as resolved.
Show resolved Hide resolved
--config /config.toml \
localhost/${IMGNAME}:${MICROSHIFT_VERSION}
25 changes: 25 additions & 0 deletions image-mode/microshift/config/Containerfile.bootc-rhel9
Original file line number Diff line number Diff line change
@@ -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
cfergeau marked this conversation as resolved.
Show resolved Hide resolved
99 changes: 99 additions & 0 deletions image-mode/microshift/config/config.toml.template
Original file line number Diff line number Diff line change
@@ -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 <<EOF
REPLACE_OCP_PULL_SECRET_CONTENTS
EOF
chmod 600 /etc/crio/openshift-pull-secret

# Drop in file for microshift base domain
cat > /etc/microshift/config.d/00-microshift-dns.yaml <<EOF
dns:
baseDomain: REPLACE_BASE_DOMAIN
EOF

# 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


# Set static hostname
echo "REPLACE_HOSTNAME" > /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 <<EOF
[containers]
netns="bridge"
rootless_networking="cni"
EOF

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

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