From 6ea56465a1cd02b3cf99ee608c29eb24b9783b10 Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Wed, 13 May 2026 16:00:12 +0200 Subject: [PATCH 1/3] feat: add macOS support to quickstart scripts quickstart.sh and quickclean.sh now detect macOS and handle podman machine validation (rootful mode required) and LVM setup via `podman machine ssh`. Co-Authored-By: Claude Opus 4.6 pre-commit.check-secrets: ENABLED --- README.md | 3 +- src/quickclean.sh | 59 ++++++++++++++++++++++-------------- src/quickstart.sh | 76 +++++++++++++++++++++++++++++++++++++---------- 3 files changed, 98 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index ce024fcf..9984861e 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,11 @@ run on the following operating systems. | CentOS 10 | RPM | Y | Y | Y | Y | Y | Latest version in Stream 10 | | Fedora | RPM | Y | N | Y | Y | Y | Latest released version (e.g. 42) | | Ubuntu | DEB | N | N | Y | Y | N | Latest LTS version (e.g. 24.04) | +| macOS | N | Y | N | Y | Y | N | Via Podman machine in rootful mode | Notes: - MicroShift Bootc container images can be run on `x86_64` and `aarch64` systems - using any OS supported by [Podman](https://podman.io/). + using any OS supported by [Podman](https://podman.io/), including macOS. - OKD builds for the `aarch64` architecture are performed using MicroShift-specific build procedure until [OKD Build of OpenShift on Arm](https://issues.redhat.com/browse/OKD-215) is implemented by the OKD team. diff --git a/src/quickclean.sh b/src/quickclean.sh index 898b8533..7bbff68e 100755 --- a/src/quickclean.sh +++ b/src/quickclean.sh @@ -12,34 +12,47 @@ if [ "$(id -u)" -ne 0 ]; then fi # Clean up the MicroShift container and image -image_ref="$(podman inspect --format '{{.Image}}' microshift-okd 2>/dev/null || true)" +image_ref="$(podman inspect --format '{{.Image}}' "microshift-okd" 2>/dev/null || true)" if [ -n "${image_ref:-}" ]; then - podman rm -f --time 0 microshift-okd || true + podman rm -f --time 0 "microshift-okd" || true podman rmi -f "${image_ref}" || true fi -# Clean up the MicroShift data and uninstall RPMs -if rpm -q microshift &>/dev/null ; then - echo y | microshift-cleanup-data --all +if [[ "$(uname -s)" == "Darwin" ]]; then + # macOS: clean up LVM inside the podman machine VM + sudo -u "${SUDO_USER}" podman machine ssh " + if [ -f '${LVM_DISK}' ]; then + sudo lvremove -y '${VG_NAME}' || true + sudo vgremove -y '${VG_NAME}' || true + DEVICE_NAME=\$(sudo losetup -j '${LVM_DISK}' | cut -d: -f1) + [ -n \"\${DEVICE_NAME}\" ] && sudo losetup -d \${DEVICE_NAME} + sudo rm -rf '$(dirname "${LVM_DISK}")' + fi + " /dev/null ; then + echo y | microshift-cleanup-data --all - # Remove the LVM configuration - if [ -f "${LVM_CONFIG}" ] ; then - rm -f "${LVM_CONFIG}" - systemctl daemon-reload - fi + # Remove the LVM configuration + if [ -f "${LVM_CONFIG}" ] ; then + rm -f "${LVM_CONFIG}" + systemctl daemon-reload + fi - dnf remove -y 'microshift*' - # Undo post-installation configuration - rm -f /etc/sysctl.d/99-microshift.conf - rm -f /root/.kube/config -fi + dnf remove -y 'microshift*' + # Undo post-installation configuration + rm -f /etc/sysctl.d/99-microshift.conf + rm -f /root/.kube/config + fi -# Remove the LVM disk -if [ -f "${LVM_DISK}" ]; then - lvremove -y "${VG_NAME}" || true - vgremove -y "${VG_NAME}" || true - DEVICE_NAME="$(losetup -j "${LVM_DISK}" | cut -d: -f1)" - # shellcheck disable=SC2086 - [ -n "${DEVICE_NAME}" ] && losetup -d ${DEVICE_NAME} - rm -rf "$(dirname "${LVM_DISK}")" + # Remove the LVM disk + if [ -f "${LVM_DISK}" ]; then + lvremove -y "${VG_NAME}" || true + vgremove -y "${VG_NAME}" || true + DEVICE_NAME="$(losetup -j "${LVM_DISK}" | cut -d: -f1)" + # shellcheck disable=SC2086 + [ -n "${DEVICE_NAME}" ] && losetup -d ${DEVICE_NAME} + rm -rf "$(dirname "${LVM_DISK}")" + fi fi diff --git a/src/quickstart.sh b/src/quickstart.sh index 14757c04..38d02371 100755 --- a/src/quickstart.sh +++ b/src/quickstart.sh @@ -17,6 +17,8 @@ function check_prerequisites() { echo "Install it with:" if command -v dnf &>/dev/null; then echo " sudo dnf install -y ${tool}" + elif command -v brew &>/dev/null; then + echo " brew install ${tool}" elif command -v apt-get &>/dev/null; then echo " sudo apt-get install -y ${tool}" elif command -v zypper &>/dev/null; then @@ -57,17 +59,38 @@ function prepare_lvm_disk() { local -r lvm_disk="$1" local -r vg_name="$2" - if [ -f "${lvm_disk}" ]; then - echo "INFO: '${lvm_disk}' already exists. Clearing and reusing it." - dd if=/dev/zero of="${lvm_disk}" bs=1M count=100 >/dev/null - return 0 - fi + if [[ "$(uname -s)" == "Darwin" ]]; then + local lvm_dir + lvm_dir="$(dirname "${lvm_disk}")" + sudo -u "${SUDO_USER}" podman machine ssh " + sudo mkdir -p '${lvm_dir}' + if [ -f '${lvm_disk}' ]; then + echo 'INFO: LVM disk already exists. Clearing and reusing it.' + sudo dd if=/dev/zero of='${lvm_disk}' bs=1M count=100 >/dev/null + else + sudo truncate --size=1G '${lvm_disk}' + fi + if sudo vgs '${vg_name}' &>/dev/null; then + echo 'INFO: Volume group ${vg_name} already exists, reusing' + else + DEVICE=\$(sudo losetup --find --show --nooverlap '${lvm_disk}') + sudo vgcreate -f -y '${vg_name}' \"\${DEVICE}\" + echo 'INFO: Created volume group ${vg_name}' + fi + " /dev/null + return 0 + fi - mkdir -p "$(dirname "${lvm_disk}")" - truncate --size=1G "${lvm_disk}" + mkdir -p "$(dirname "${lvm_disk}")" + truncate --size=1G "${lvm_disk}" - local -r device_name="$(losetup --find --show --nooverlap "${lvm_disk}")" - vgcreate -f -y "${vg_name}" "${device_name}" + local -r device_name="$(losetup --find --show --nooverlap "${lvm_disk}")" + vgcreate -f -y "${vg_name}" "${device_name}" + fi } function run_bootc_image() { @@ -79,7 +102,9 @@ function run_bootc_image() { # - If the TopoLVM CSI driver is used (`WITH_TOPOLVM=1` default image build # option), the /dev/dm-* device must be shared with the container. echo "Running '${image_ref}'" - modprobe openvswitch || true + if [[ "$(uname -s)" != "Darwin" ]]; then + modprobe openvswitch || true + fi # Share the /dev directory with the container to enable TopoLVM CSI driver. # Mask the devices that may conflict with the host by sharing them on a @@ -93,7 +118,7 @@ function run_bootc_image() { podman run --privileged --rm -d \ --replace \ ${vol_opts} \ - --name microshift-okd \ + --name "microshift-okd" \ --hostname 127.0.0.1.nip.io \ "${image_ref}" @@ -102,7 +127,7 @@ function run_bootc_image() { local -r max_wait=300 local waited=0 while [ "${waited}" -lt "${max_wait}" ] ; do - if podman exec microshift-okd /bin/test -f "${kubeconfig}" &>/dev/null ; then + if podman exec "microshift-okd" /bin/test -f "${kubeconfig}" &>/dev/null ; then break fi sleep 1 @@ -112,7 +137,7 @@ function run_bootc_image() { echo "ERROR: Timed out waiting for MicroShift to start after ${max_wait}s" echo echo "Stopping the container..." - podman stop microshift-okd &>/dev/null || true + podman stop "microshift-okd" &>/dev/null || true exit 1 fi @@ -120,7 +145,7 @@ function run_bootc_image() { # VPN connections or custom DNS configurations on the host may # prevent the container from resolving external hostnames, causing # pods to stay in ContainerCreating while image pulls time out. - if ! podman exec microshift-okd getent hosts quay.io &>/dev/null ; then + if ! podman exec "microshift-okd" getent hosts quay.io &>/dev/null ; then echo echo "ERROR: DNS resolution for 'quay.io' failed inside the container." echo "MicroShift pods will not be able to pull container images." @@ -130,7 +155,7 @@ function run_bootc_image() { echo "Consider disconnecting from VPN or configuring DNS manually." echo echo "Stopping the container..." - podman stop microshift-okd &>/dev/null || true + podman stop "microshift-okd" &>/dev/null || true exit 1 fi } @@ -141,6 +166,25 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi +# Platform-specific initialization +if [[ "$(uname -s)" == "Darwin" ]]; then + if ! sudo -u "${SUDO_USER}" podman info &>/dev/null /dev/null || echo "false")" + if [[ "${local_rootful}" != "true" ]]; then + echo "ERROR: Podman machine must be in rootful mode (required for MicroShift)." + echo " podman machine stop && podman machine set --rootful && podman machine start" + exit 1 + fi +fi + check_prerequisites podman check_podman_version @@ -174,4 +218,4 @@ echo "To verify that MicroShift pods are up and running, run the following comma echo " - sudo podman exec -it microshift-okd kubectl get pods -A" echo echo "To uninstall MicroShift, run the following command:" -echo " - curl -s https://${OWNER}.github.io/${REPO}/quickclean.sh | sudo bash" +echo " - curl -s https://${OWNER}.github.io/${REPO}/quickclean.sh | sudo bash -s ${CONTAINER_NAME}" From ac430d02a796a341e117e990a71cc397034fc38b Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Wed, 13 May 2026 16:03:35 +0200 Subject: [PATCH 2/3] feat: make container name configurable via parameter Usage: ./src/quickstart.sh [name] ./src/quickclean.sh [name] Defaults to 'microshift-okd' when no argument is provided. Co-Authored-By: Claude Opus 4.6 pre-commit.check-secrets: ENABLED --- src/quickclean.sh | 5 +++-- src/quickstart.sh | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/quickclean.sh b/src/quickclean.sh index 7bbff68e..88f0c47a 100755 --- a/src/quickclean.sh +++ b/src/quickclean.sh @@ -1,6 +1,7 @@ #!/bin/bash set -euo pipefail +CONTAINER_NAME="${CONTAINER_NAME:-microshift-okd}" LVM_DISK="/var/lib/microshift-okd/lvmdisk.image" LVM_CONFIG="/etc/systemd/system/microshift.service.d/99-lvm-config.conf" VG_NAME="myvg1" @@ -12,9 +13,9 @@ if [ "$(id -u)" -ne 0 ]; then fi # Clean up the MicroShift container and image -image_ref="$(podman inspect --format '{{.Image}}' "microshift-okd" 2>/dev/null || true)" +image_ref="$(podman inspect --format '{{.Image}}' "${CONTAINER_NAME}" 2>/dev/null || true)" if [ -n "${image_ref:-}" ]; then - podman rm -f --time 0 "microshift-okd" || true + podman rm -f --time 0 "${CONTAINER_NAME}" || true podman rmi -f "${image_ref}" || true fi diff --git a/src/quickstart.sh b/src/quickstart.sh index 38d02371..f9f9d2a4 100755 --- a/src/quickstart.sh +++ b/src/quickstart.sh @@ -6,6 +6,7 @@ REPO=${REPO:-microshift} IMAGE=${IMAGE:-"ghcr.io/${OWNER}/${REPO}"} TAG=${TAG:-latest} +CONTAINER_NAME="${CONTAINER_NAME:-microshift-okd}" LVM_DISK="/var/lib/microshift-okd/lvmdisk.image" VG_NAME="myvg1" PODMAN_VMAJOR=4 @@ -118,7 +119,7 @@ function run_bootc_image() { podman run --privileged --rm -d \ --replace \ ${vol_opts} \ - --name "microshift-okd" \ + --name "${CONTAINER_NAME}" \ --hostname 127.0.0.1.nip.io \ "${image_ref}" @@ -127,7 +128,7 @@ function run_bootc_image() { local -r max_wait=300 local waited=0 while [ "${waited}" -lt "${max_wait}" ] ; do - if podman exec "microshift-okd" /bin/test -f "${kubeconfig}" &>/dev/null ; then + if podman exec "${CONTAINER_NAME}" /bin/test -f "${kubeconfig}" &>/dev/null ; then break fi sleep 1 @@ -137,7 +138,7 @@ function run_bootc_image() { echo "ERROR: Timed out waiting for MicroShift to start after ${max_wait}s" echo echo "Stopping the container..." - podman stop "microshift-okd" &>/dev/null || true + podman stop "${CONTAINER_NAME}" &>/dev/null || true exit 1 fi @@ -145,7 +146,7 @@ function run_bootc_image() { # VPN connections or custom DNS configurations on the host may # prevent the container from resolving external hostnames, causing # pods to stay in ContainerCreating while image pulls time out. - if ! podman exec "microshift-okd" getent hosts quay.io &>/dev/null ; then + if ! podman exec "${CONTAINER_NAME}" getent hosts quay.io &>/dev/null ; then echo echo "ERROR: DNS resolution for 'quay.io' failed inside the container." echo "MicroShift pods will not be able to pull container images." @@ -155,7 +156,7 @@ function run_bootc_image() { echo "Consider disconnecting from VPN or configuring DNS manually." echo echo "Stopping the container..." - podman stop "microshift-okd" &>/dev/null || true + podman stop "${CONTAINER_NAME}" &>/dev/null || true exit 1 fi } @@ -207,15 +208,15 @@ run_bootc_image "${IMAGE}:${TAG}" echo echo "MicroShift is running in a bootc container" echo "Hostname: 127.0.0.1.nip.io" -echo "Container: microshift-okd" +echo "Container: ${CONTAINER_NAME}" echo "LVM disk: ${LVM_DISK}" echo "VG name: ${VG_NAME}" echo echo "To access the container, run the following command:" -echo " - sudo podman exec -it microshift-okd /bin/bash -l" +echo " - sudo podman exec -it ${CONTAINER_NAME} /bin/bash -l" echo echo "To verify that MicroShift pods are up and running, run the following command:" -echo " - sudo podman exec -it microshift-okd kubectl get pods -A" +echo " - sudo podman exec -it ${CONTAINER_NAME} kubectl get pods -A" echo echo "To uninstall MicroShift, run the following command:" -echo " - curl -s https://${OWNER}.github.io/${REPO}/quickclean.sh | sudo bash -s ${CONTAINER_NAME}" +echo " - curl -s https://${OWNER}.github.io/${REPO}/quickclean.sh | sudo CONTAINER_NAME=${CONTAINER_NAME} bash" From 7f6e1d391cd4a79c4e4e99ea892f3394f993cf6b Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Thu, 14 May 2026 17:09:06 +0200 Subject: [PATCH 3/3] fix: validate SUDO_USER on macOS and document podman machine usage Co-Authored-By: Claude Opus 4.6 (1M context) pre-commit.check-secrets: ENABLED --- src/quickclean.sh | 6 ++++++ src/quickstart.sh | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/quickclean.sh b/src/quickclean.sh index 88f0c47a..74976b12 100755 --- a/src/quickclean.sh +++ b/src/quickclean.sh @@ -20,7 +20,13 @@ if [ -n "${image_ref:-}" ]; then fi if [[ "$(uname -s)" == "Darwin" ]]; then + if [ -z "${SUDO_USER:-}" ]; then + echo "ERROR: SUDO_USER is not set. Run this script with 'sudo', not as root directly." + exit 1 + fi + # macOS: clean up LVM inside the podman machine VM + # Podman machine is per-user; run as the invoking user, not root sudo -u "${SUDO_USER}" podman machine ssh " if [ -f '${LVM_DISK}' ]; then sudo lvremove -y '${VG_NAME}' || true diff --git a/src/quickstart.sh b/src/quickstart.sh index f9f9d2a4..a5312dfa 100755 --- a/src/quickstart.sh +++ b/src/quickstart.sh @@ -63,6 +63,7 @@ function prepare_lvm_disk() { if [[ "$(uname -s)" == "Darwin" ]]; then local lvm_dir lvm_dir="$(dirname "${lvm_disk}")" + # Podman machine is per-user; run as the invoking user, not root sudo -u "${SUDO_USER}" podman machine ssh " sudo mkdir -p '${lvm_dir}' if [ -f '${lvm_disk}' ]; then @@ -169,15 +170,22 @@ fi # Platform-specific initialization if [[ "$(uname -s)" == "Darwin" ]]; then + if [ -z "${SUDO_USER:-}" ]; then + echo "ERROR: SUDO_USER is not set. Run this script with 'sudo', not as root directly." + exit 1 + fi + + # Podman machine is per-user; run as the invoking user, not root if ! sudo -u "${SUDO_USER}" podman info &>/dev/null /dev/null || echo "false")" if [[ "${local_rootful}" != "true" ]]; then echo "ERROR: Podman machine must be in rootful mode (required for MicroShift)."