#!/bin/bash # Convert bootc container to qcow2 image # This script extracts the bootc container contents and creates a bootable qcow2 set -e # Configuration CONTAINER_IMAGE="git.raines.xyz/particle-os/debian-bootc:latest-with-fixes" OUTPUT_FILE="debian-bootc-final.qcow2" SIZE="10G" echo "๐Ÿ—๏ธ Converting bootc container to qcow2" echo "====================================" echo "Container: $CONTAINER_IMAGE" echo "Output: $OUTPUT_FILE" echo "Size: $SIZE" echo "" # Clean up any existing files echo "๐Ÿงน Cleaning up previous builds..." rm -f "$OUTPUT_FILE" sudo rm -rf /tmp/bootc-container /tmp/bootc-mount # Create directories mkdir -p /tmp/bootc-container /tmp/bootc-mount echo "๐Ÿ“ฆ Extracting container contents..." # Export the container to a tar file podman save "$CONTAINER_IMAGE" -o /tmp/bootc-container.tar # Create a qcow2 image echo "๐Ÿ’พ Creating qcow2 disk image..." qemu-img create -f qcow2 "$OUTPUT_FILE" "$SIZE" # Set up loop device echo "๐Ÿ”ง Setting up loopback device..." sudo losetup -f "$OUTPUT_FILE" LOOP_DEVICE=$(sudo losetup -j "$OUTPUT_FILE" | cut -d: -f1) echo "๐Ÿ“€ Creating partition table..." # Create GPT partition table sudo sgdisk -Z "$LOOP_DEVICE" sudo sgdisk -g "$LOOP_DEVICE" # Create partitions sudo sgdisk -n 1:2048:+256M -t 1:ef00 -c 1:"EFI System" "$LOOP_DEVICE" # EFI partition sudo sgdisk -n 2:0:0 -t 2:8300 -c 2:"Linux filesystem" "$LOOP_DEVICE" # Root partition # Inform kernel of partition changes sudo partprobe "$LOOP_DEVICE" echo "๐Ÿ“ Formatting partitions..." # Format partitions sudo mkfs.fat -F32 "${LOOP_DEVICE}p1" # EFI partition sudo mkfs.ext4 -F "${LOOP_DEVICE}p2" # Root partition echo "๐Ÿ”— Mounting partitions..." # Mount root partition sudo mount "${LOOP_DEVICE}p2" /tmp/bootc-mount # Create EFI mount point and mount EFI partition sudo mkdir -p /tmp/bootc-mount/boot/efi sudo mount "${LOOP_DEVICE}p1" /tmp/bootc-mount/boot/efi echo "๐Ÿ“‹ Extracting container filesystem..." # Extract container filesystem to mounted root cd /tmp/bootc-container tar -xf /tmp/bootc-container.tar # Find the layer with the filesystem LAYER_DIR=$(find . -name "layer.tar" | head -1 | xargs dirname) if [ -n "$LAYER_DIR" ]; then echo "๐Ÿ“‚ Found layer: $LAYER_DIR" cd "$LAYER_DIR" sudo tar -xf layer.tar -C /tmp/bootc-mount --exclude='dev/*' else echo "โŒ Could not find container layer" exit 1 fi echo "๐Ÿ”ง Setting up basic system files..." # Create essential directories if they don't exist sudo mkdir -p /tmp/bootc-mount/{dev,proc,sys,run,tmp} sudo mkdir -p /tmp/bootc-mount/boot/grub # Create basic /etc/fstab sudo tee /tmp/bootc-mount/etc/fstab > /dev/null << 'EOF' # Static filesystem table UUID=ROOT_UUID / ext4 defaults 0 1 UUID=EFI_UUID /boot/efi vfat defaults 0 2 EOF # Get actual UUIDs and update fstab ROOT_UUID=$(sudo blkid -s UUID -o value "${LOOP_DEVICE}p2") EFI_UUID=$(sudo blkid -s UUID -o value "${LOOP_DEVICE}p1") sudo sed -i "s/ROOT_UUID/$ROOT_UUID/g" /tmp/bootc-mount/etc/fstab sudo sed -i "s/EFI_UUID/$EFI_UUID/g" /tmp/bootc-mount/etc/fstab echo "๐Ÿš€ Installing bootloader..." # Install GRUB bootloader sudo grub-install --target=x86_64-efi --efi-directory=/tmp/bootc-mount/boot/efi --boot-directory=/tmp/bootc-mount/boot --removable # Generate GRUB configuration sudo tee /tmp/bootc-mount/boot/grub/grub.cfg > /dev/null << EOF set timeout=5 set default=0 menuentry "Debian Bootc System" { linux /boot/vmlinuz root=UUID=$ROOT_UUID ro quiet splash initrd /boot/initrd.img } EOF echo "๐Ÿ”ง Final system configuration..." # Ensure proper permissions sudo chmod 755 /tmp/bootc-mount sudo chmod 1777 /tmp/bootc-mount/tmp echo "๐Ÿงน Cleaning up..." # Unmount filesystems sudo umount /tmp/bootc-mount/boot/efi sudo umount /tmp/bootc-mount # Detach loop device sudo losetup -d "$LOOP_DEVICE" # Clean up temporary files sudo rm -rf /tmp/bootc-container /tmp/bootc-mount /tmp/bootc-container.tar echo "โœ… Successfully created qcow2 image: $OUTPUT_FILE" echo "๐Ÿš€ You can now boot this image with:" echo " qemu-system-x86_64 -m 2G -drive file=$OUTPUT_FILE,format=qcow2 -netdev user,id=net0 -device e1000,netdev=net0 -bios /usr/share/ovmf/OVMF.fd"