Skip to content
Open
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
29 changes: 29 additions & 0 deletions deploy/microshift-bootc/Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM ghcr.io/microshift-io/microshift:4.21.0_gbc8e20c07_4.21.0_okd_scos.ec.14
# Install dependencies for config-svc
RUN dnf install -y epel-release && \
dnf install -y python3 iproute python3-flask python3-pip && \
pip3 install python-pam && \
dnf clean all
Comment on lines +3 to +6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use dnf for python-pam instead of pip3.

The package python3-pam is available in EPEL and can be installed via dnf. Using system packages avoids version inconsistencies and missing dependencies. Apply this change:

 RUN dnf install -y epel-release && \
-    dnf install -y python3 iproute python3-flask python3-pip && \
-    pip3 install python-pam && \
+    dnf install -y python3 iproute python3-flask python3-pam && \
     dnf clean all
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RUN dnf install -y epel-release && \
dnf install -y python3 iproute python3-flask python3-pip && \
pip3 install python-pam && \
dnf clean all
RUN dnf install -y epel-release && \
dnf install -y python3 iproute python3-flask python3-pam && \
dnf clean all
🤖 Prompt for AI Agents
In deploy/microshift-bootc/Containerfile around lines 3 to 6, the Dockerfile
installs python-pam via pip3 which should instead use the EPEL/system package;
replace the pip3 install python-pam step with the dnf package name (python3-pam)
so dnf installs it along with other system deps, ensuring the package list and
cleanup commands remain in the same RUN chain.


# Install MicroShift manifests
RUN mkdir -p /etc/microshift/manifests.d/002-jumpstarter
COPY deploy/microshift-bootc/kustomization.yaml /etc/microshift/manifests.d/002-jumpstarter/kustomization.yaml
COPY deploy/operator/dist/install.yaml /etc/microshift/manifests.d/002-jumpstarter/install-operator.yaml

# Configure firewalld to open required ports
# Use firewall-offline-cmd since firewalld is not running during build
RUN firewall-offline-cmd --add-service=http && \
firewall-offline-cmd --add-service=https && \
firewall-offline-cmd --add-port=8880/tcp

# Set root password
RUN echo "root:jumpstarter" | chpasswd
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this be set in config.toml?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then it doesn't work when ran as a container :D

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mor detail, we have make bootc-run that starts microshift+jumpstarter in a bootc container, it's quick and nice for iterating on the development before creating an image and flashing something.


# Install config-svc systemd service
COPY deploy/microshift-bootc/config-svc/app.py /usr/local/bin/config-svc
RUN chmod +x /usr/local/bin/config-svc
COPY deploy/microshift-bootc/config-svc/update-banner.sh /usr/local/bin/update-banner.sh
RUN chmod +x /usr/local/bin/update-banner.sh
COPY deploy/microshift-bootc/config-svc/config-svc.service /etc/systemd/system/config-svc.service
COPY deploy/microshift-bootc/config-svc/update-banner.service /etc/systemd/system/update-banner.service
RUN systemctl enable config-svc.service update-banner.service
154 changes: 154 additions & 0 deletions deploy/microshift-bootc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
.PHONY: help build bootc-build bootc-build-multi push bootc-push bootc-push-multi bootc-run bootc-stop bootc-sh bootc-rm build-image build-iso build-all build-all-multi push-all push-all-multi

# Default image tags
BOOTC_IMG ?= quay.io/jumpstarter-dev/microshift/bootc:latest


help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

##@ Build

build: bootc-build ## Build bootc image (default target)

bootc-build: ## Build the bootc image with MicroShift
@echo "Building bootc image: $(BOOTC_IMG): building as root to be on the container storage from root"
sudo podman build -t $(BOOTC_IMG) -f Containerfile ../..
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there is a way of building the bootc container as user, but then copying to the root container storage when you want to build the image, also we need to look at how this is possibly usable from MacOS, I'll fight that on a 2nd round.


bootc-build-multi: ## Build the bootc image for multiple architectures (amd64, arm64)
@echo "Building multiarch bootc image: $(BOOTC_IMG)"
@echo "This will build for linux/amd64 and linux/arm64"
@# Remove existing manifest if it exists
-podman manifest rm $(BOOTC_IMG) 2>/dev/null || true
@# Create a new manifest
podman manifest create $(BOOTC_IMG)
@# Build for amd64
@echo "Building for linux/amd64..."
podman build --platform linux/amd64 -t $(BOOTC_IMG)-amd64 -f Containerfile ../..
@# Build for arm64
@echo "Building for linux/arm64..."
podman build --platform linux/arm64 -t $(BOOTC_IMG)-arm64 -f Containerfile ../..
@# Add both images to the manifest
podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-amd64
podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-arm64
@echo "Multiarch manifest created successfully!"
@echo "To inspect: podman manifest inspect $(BOOTC_IMG)"
@echo "To push: make bootc-push-multi"
Comment on lines +18 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Inconsistent sudo usage in multi-arch build.

The bootc-build-multi target uses podman without sudo (lines 22, 24, 27, 30, 32-33), while bootc-build uses sudo podman (line 16). This places images in different container storage locations (user vs. root), which can cause:

  1. The manifest won't include the base image if it was built with bootc-build first
  2. The bootc-push-multi target (line 105) won't find the images in root's storage

Apply this diff to ensure consistency:

 bootc-build-multi: ## Build the bootc image for multiple architectures (amd64, arm64)
 	@echo "Building multiarch bootc image: $(BOOTC_IMG)"
 	@echo "This will build for linux/amd64 and linux/arm64"
 	@# Remove existing manifest if it exists
-	-podman manifest rm $(BOOTC_IMG) 2>/dev/null || true
+	-sudo podman manifest rm $(BOOTC_IMG) 2>/dev/null || true
 	@# Create a new manifest
-	podman manifest create $(BOOTC_IMG)
+	sudo podman manifest create $(BOOTC_IMG)
 	@# Build for amd64
 	@echo "Building for linux/amd64..."
-	podman build --platform linux/amd64 -t $(BOOTC_IMG)-amd64 -f Containerfile ../..
+	sudo podman build --platform linux/amd64 -t $(BOOTC_IMG)-amd64 -f Containerfile ../..
 	@# Build for arm64
 	@echo "Building for linux/arm64..."
-	podman build --platform linux/arm64 -t $(BOOTC_IMG)-arm64 -f Containerfile ../..
+	sudo podman build --platform linux/arm64 -t $(BOOTC_IMG)-arm64 -f Containerfile ../..
 	@# Add both images to the manifest
-	podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-amd64
-	podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-arm64
+	sudo podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-amd64
+	sudo podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-arm64
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
bootc-build-multi: ## Build the bootc image for multiple architectures (amd64, arm64)
@echo "Building multiarch bootc image: $(BOOTC_IMG)"
@echo "This will build for linux/amd64 and linux/arm64"
@# Remove existing manifest if it exists
-podman manifest rm $(BOOTC_IMG) 2>/dev/null || true
@# Create a new manifest
podman manifest create $(BOOTC_IMG)
@# Build for amd64
@echo "Building for linux/amd64..."
podman build --platform linux/amd64 -t $(BOOTC_IMG)-amd64 -f Containerfile ../..
@# Build for arm64
@echo "Building for linux/arm64..."
podman build --platform linux/arm64 -t $(BOOTC_IMG)-arm64 -f Containerfile ../..
@# Add both images to the manifest
podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-amd64
podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-arm64
@echo "Multiarch manifest created successfully!"
@echo "To inspect: podman manifest inspect $(BOOTC_IMG)"
@echo "To push: make bootc-push-multi"
bootc-build-multi: ## Build the bootc image for multiple architectures (amd64, arm64)
@echo "Building multiarch bootc image: $(BOOTC_IMG)"
@echo "This will build for linux/amd64 and linux/arm64"
@# Remove existing manifest if it exists
-sudo podman manifest rm $(BOOTC_IMG) 2>/dev/null || true
@# Create a new manifest
sudo podman manifest create $(BOOTC_IMG)
@# Build for amd64
@echo "Building for linux/amd64..."
sudo podman build --platform linux/amd64 -t $(BOOTC_IMG)-amd64 -f Containerfile ../..
@# Build for arm64
@echo "Building for linux/arm64..."
sudo podman build --platform linux/arm64 -t $(BOOTC_IMG)-arm64 -f Containerfile ../..
@# Add both images to the manifest
sudo podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-amd64
sudo podman manifest add $(BOOTC_IMG) $(BOOTC_IMG)-arm64
@echo "Multiarch manifest created successfully!"
@echo "To inspect: podman manifest inspect $(BOOTC_IMG)"
@echo "To push: make bootc-push-multi"
🤖 Prompt for AI Agents
In deploy/microshift-bootc/Makefile around lines 18 to 36, the bootc-build-multi
target mixes non-root podman invocations while bootc-build uses sudo, causing
images to be placed in different container storages; update every podman
invocation in this target (manifest rm/create, build, and manifest add) to use
sudo (e.g., change podman ... to sudo podman ...) so all builds/manifests run as
root and reside in the same storage as bootc-build.


output/qcow2/disk.qcow2: ## Build a bootable QCOW2 image from the bootc image
@echo "Building QCOW2 image from: $(BOOTC_IMG)"a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix typo: remove trailing 'a'.

Line 39 has a stray character at the end.

Apply this diff:

-	@echo "Building QCOW2 image from: $(BOOTC_IMG)"a
+	@echo "Building QCOW2 image from: $(BOOTC_IMG)"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@echo "Building QCOW2 image from: $(BOOTC_IMG)"a
@echo "Building QCOW2 image from: $(BOOTC_IMG)"
🤖 Prompt for AI Agents
In deploy/microshift-bootc/Makefile around line 39, there's a stray trailing 'a'
at the end of the echo command; remove the extraneous character so the line
reads the intended echo statement without the trailing 'a'.

@echo "Running bootc-image-builder..."
@mkdir -p output
sudo podman run \
--rm \
-it \
--privileged \
--pull=newer \
--security-opt label=type:unconfined_t \
-v ./config.toml:/config.toml:ro \
-v ./output:/output \
-v /var/lib/containers/storage:/var/lib/containers/storage \
quay.io/centos-bootc/bootc-image-builder:latest \
--type qcow2 \
-v \
$(BOOTC_IMG)
@echo "QCOW2 image built successfully in ./output/"

output/iso/disk.iso: ## Build a bootable ISO image from the bootc image
@echo "Building ISO image from: $(BOOTC_IMG)"
@echo "Running bootc-image-builder..."
@mkdir -p output
sudo podman run \
--rm \
-it \
--privileged \
--pull=newer \
--security-opt label=type:unconfined_t \
-v ./config.toml:/config.toml:ro \
-v ./output:/output \
-v /var/lib/containers/storage:/var/lib/containers/storage \
quay.io/centos-bootc/bootc-image-builder:latest \
--type iso \
-v \
$(BOOTC_IMG)
@echo "ISO image built successfully in ./output/"

build-image: bootc-build ## Build the bootc based qcow2 image
@echo "Building image: output/qcow2/disk.qcow2"
@echo "Cleaning up any existing LVM resources to avoid conflicts..."
-sudo vgs --noheadings -o vg_name,vg_uuid | grep myvg1 | while read vg uuid; do sudo vgremove -f --select vg_uuid=$$uuid 2>/dev/null || true; done
-sudo losetup -D 2>/dev/null || true
sudo rm -f output/qcow2/disk.qcow2
make output/qcow2/disk.qcow2
@echo "Image built successfully in ./output/"

build-iso: bootc-build ## Build the bootc based ISO image
@echo "Building ISO image: output/iso/disk.iso"
@echo "Cleaning up any existing LVM resources to avoid conflicts..."
-sudo vgs --noheadings -o vg_name,vg_uuid | grep myvg1 | while read vg uuid; do sudo vgremove -f --select vg_uuid=$$uuid 2>/dev/null || true; done
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember doing this when building bootc images, it lvm necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is something that needs to be cleaned up, if you ran the container locally the run-microshift.sh stolen from their repo and modified... creates a loop back device to mount the PVs.

-sudo losetup -D 2>/dev/null || true
sudo rm -f output/iso/disk.iso
make output/iso/disk.iso
@echo "ISO image built successfully in ./output/"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a build-ks-iso: target with INPUT_ISO=fedora/centos10

by using a mkksiso from lorax + the netboot isos of fedora/centos10 I managed to make a 1GB iso that just downloads the latests bootc container at install time.

We should probably just publish that somewhere :) the one generated in build-iso is 3G although it comes with the whole bootc image embedded, it will still require the download of the microshift and jumpstarter containers.


##@ Push

push: bootc-push ## Push bootc image to registry

bootc-push: ## Push the bootc image to registry
@echo "Pushing bootc image: $(BOOTC_IMG)"
sudo podman push $(BOOTC_IMG)

bootc-push-multi: ## Push the multiarch manifest to registry
@echo "Pushing multiarch manifest: $(BOOTC_IMG)"
@echo "This will push the manifest list with amd64 and arm64 images"
podman manifest push $(BOOTC_IMG) $(BOOTC_IMG)
@echo "Multiarch manifest pushed successfully!"
@echo "Images available for linux/amd64 and linux/arm64"
Comment on lines +102 to +107
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

bootc-push-multi needs sudo for consistency.

Since bootc-build-multi should use sudo (per previous comment) to match where bootc-build stores images, this push target must also use sudo.

Apply this diff:

 bootc-push-multi: ## Push the multiarch manifest to registry
 	@echo "Pushing multiarch manifest: $(BOOTC_IMG)"
 	@echo "This will push the manifest list with amd64 and arm64 images"
-	podman manifest push $(BOOTC_IMG) $(BOOTC_IMG)
+	sudo podman manifest push $(BOOTC_IMG) $(BOOTC_IMG)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
bootc-push-multi: ## Push the multiarch manifest to registry
@echo "Pushing multiarch manifest: $(BOOTC_IMG)"
@echo "This will push the manifest list with amd64 and arm64 images"
podman manifest push $(BOOTC_IMG) $(BOOTC_IMG)
@echo "Multiarch manifest pushed successfully!"
@echo "Images available for linux/amd64 and linux/arm64"
bootc-push-multi: ## Push the multiarch manifest to registry
@echo "Pushing multiarch manifest: $(BOOTC_IMG)"
@echo "This will push the manifest list with amd64 and arm64 images"
sudo podman manifest push $(BOOTC_IMG) $(BOOTC_IMG)
@echo "Multiarch manifest pushed successfully!"
@echo "Images available for linux/amd64 and linux/arm64"
🤖 Prompt for AI Agents
In deploy/microshift-bootc/Makefile around lines 102 to 107, the podman manifest
push is missing sudo which makes its behavior inconsistent with
bootc-build-multi; update the target to run podman under sudo (e.g., prefix the
podman manifest push command with sudo and keep the leading @) so the push
operates with the same root-owned image store as the build step.


##@ Development

build-all: bootc-build ## Build bootc image

build-all-multi: bootc-build-multi ## Build multiarch bootc image

push-all: bootc-push ## Push bootc image to registry

push-all-multi: bootc-push-multi ## Push multiarch bootc image to registry

bootc-run: ## Run MicroShift in a bootc container
@echo "Running MicroShift container with image: $(BOOTC_IMG)"
@BOOTC_IMG=$(BOOTC_IMG) sudo -E ./run-microshift.sh

bootc-stop: ## Stop the running MicroShift container
@echo "Stopping MicroShift container..."
-sudo podman stop jumpstarter-microshift-okd

bootc-rm: bootc-stop ## Remove the MicroShift container
@echo "Removing MicroShift container..."
-sudo podman rm -f jumpstarter-microshift-okd
@echo "Cleaning up LVM resources..."
-sudo vgremove -f myvg1 2>/dev/null || true
-sudo losetup -d $$(sudo losetup -j /var/lib/microshift-okd/lvmdisk.image | cut -d: -f1) 2>/dev/null || true
@echo "LVM cleanup complete"

bootc-sh: ## Open a shell in the running MicroShift container
@echo "Opening shell in MicroShift container..."
sudo podman exec -it jumpstarter-microshift-okd /bin/bash -l

bootc-reload-app: ## Reload the config service app without rebuilding (dev mode)
@echo "Reloading config-svc app..."
sudo podman cp config-svc/app.py jumpstarter-microshift-okd:/usr/local/bin/config-svc
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

splitting the app would probably need a more involved installing, but I think it may be fine. (create wheel locally, pushing and installing on in the container at runtime)

sudo podman exec jumpstarter-microshift-okd systemctl restart config-svc
@echo "Config service reloaded successfully!"

clean: ## Clean up local images and build artifacts
@echo "Removing local images..."
-sudo podman rmi $(BOOTC_IMG)
@echo "Removing QCOW2 output..."
-sudo rm -rf output/qcow2/disk.qcow2
@echo "Removing ISO output..."
-sudo rm -rf output/iso/disk.iso
@echo "Removing LVM disk image..."
-sudo rm -f /var/lib/microshift-okd/lvmdisk.image

Loading