Lima VM Testing#
Immutablue supports local VM testing using Lima, a lightweight VM manager that provides a seamless experience for running Linux VMs with automatic SSH, port forwarding, and file mounts.
Prerequisites#
- Lima installed:
brew install lima - QEMU installed:
dnf install qemu-system-x86(or via your package manager) - A built and pushed Immutablue container image
Quick Start#
# Build qcow2 with Lima SSH key support
make LIMA=1 qcow2
# Generate Lima configuration
make lima
# Start the VM
make lima-start
# Shell into the VM
make lima-shell
# Stop the VM when done
make lima-stopBuild Options#
Interactive Configuration#
Use qcow2-config to interactively configure your qcow2 image:
make qcow2-configThis prompts for:
- Username (default:
immutablue) - Password
- Wheel group membership (sudo access)
- SSH public key
For Lima builds, use LIMA=1 to auto-add your SSH key:
make LIMA=1 qcow2-configBasic qcow2 Build#
Build a qcow2 without custom configuration (uses defaults):
make qcow2Default credentials: immutablue / immutablue
If a config exists from qcow2-config, it will be used automatically.
Lima-enabled qcow2 Build#
Build a qcow2 with SSH keys for Lima access (without running qcow2-config):
make LIMA=1 qcow2This automatically adds your SSH key to the image:
- Lima key (
~/.lima/_config/user.pub) - preferred - ED25519 key (
~/.ssh/id_ed25519.pub) - fallback - RSA key (
~/.ssh/id_rsa.pub) - fallback
Building Variants#
All build options work with Lima:
# Trueblue variant with Lima support
make TRUEBLUE=1 LIMA=1 qcow2
# Kinoite (KDE) with LTS kernel
make KINOITE=1 LTS=1 LIMA=1 qcow2
# Kuberblue variant
make KUBERBLUE=1 LIMA=1 qcow2Makefile Targets#
| Target | Description |
|---|---|
make qcow2-config | Interactive configuration for qcow2 (add LIMA=1 for auto SSH key) |
make qcow2 | Build qcow2 image (uses config if exists, or add LIMA=1 for SSH key support) |
make lima | Generate Lima YAML configuration |
make lima-start | Start the Lima VM |
make lima-shell | Open a shell in the running VM |
make lima-stop | Stop the Lima VM |
make lima-delete | Delete the Lima VM instance |
Lima Configuration#
The make lima target generates a Lima YAML configuration at .lima/immutablue-<TAG>.yaml with:
- VM Type: QEMU with KVM acceleration
- Resources: 4 CPUs, 4GB RAM, 100GB disk
- User:
immutablue - Mounts: Home directory (read-only)
- SSH: Auto-assigned port with key-based auth
- Mode: Plain mode (skips Lima provisioning for pre-built images)
Generated Configuration#
minimumLimaVersion: "2.0.0"
vmType: qemu
arch: x86_64
user:
name: immutablue
images:
- location: "/path/to/images/qcow2/43/qcow2/disk.qcow2"
arch: "x86_64"
cpus: 4
memory: "4GiB"
disk: "100GiB"
mounts:
- location: "~"
writable: false
ssh:
localPort: 0
loadDotSSHPubKeys: true
overVsock: false # Required for Fedora 43 SELinux compatibility
containerd:
system: false
user: false
plain: true # Skip Lima provisioning for pre-built imagesAlternative: Raw QEMU#
If you prefer raw QEMU without Lima:
# Build qcow2
make qcow2
# Run with QEMU directly
make run_qcow2This starts QEMU with:
- SSH on port 2222
- Serial console (exit with
Ctrl-A X) - KVM acceleration
SSH access: ssh -p 2222 immutablue@localhost (password: immutablue)
Workflow Examples#
Testing a New Build#
# Build and push the image
make build push
# Option A: Quick build with LIMA=1 (auto SSH keys)
make LIMA=1 qcow2
# Option B: Interactive config first
make LIMA=1 qcow2-config
make qcow2
# Start Lima VM
make lima lima-start
# Shell in and test
make lima-shell
# Inside VM: verify the build
rpm-ostree status
cat /etc/immutablue-release
# Exit and stop
exit
make lima-stopTesting Multiple Variants#
# Test default Silverblue
make LIMA=1 qcow2 lima lima-start
make lima-shell
# ... test ...
make lima-stop
make lima-delete
# Test Trueblue
make TRUEBLUE=1 LIMA=1 qcow2 lima lima-start
make TRUEBLUE=1 lima-shell
# ... test ...
make TRUEBLUE=1 lima-stopCleaning Up#
# Delete specific VM
make lima-delete
# Or with variant
make TRUEBLUE=1 lima-delete
# Clean all generated files
make cleanTroubleshooting#
SSH Connection Issues#
If Lima hangs on “Waiting for ssh”:
Ensure you built with
LIMA=1:make LIMA=1 qcow2Verify the SSH key was added:
cat ./images/qcow2/43/config.toml | grep keyDelete and recreate the VM:
make lima-delete make lima lima-start
VM Won’t Start#
Check if KVM is available:
ls /dev/kvmVerify QEMU is installed:
which qemu-system-x86_64Check Lima logs:
cat ~/.lima/immutablue-43/serial*.log
User Session Issues#
If Lima hangs on “user session is ready”:
The plain: true setting should prevent this. If you still see it:
Regenerate the Lima config:
make limaVerify
plain: trueis in the YAML:grep plain .lima/immutablue-43.yaml
File Permission Issues#
After make qcow2, if files are owned by root:
sudo chown -R $(id -u):$(id -g) ./images/This is normally handled automatically by the Makefile.
Architecture Notes#
Why Plain Mode?#
Immutablue qcow2 images are pre-built bootc images, not cloud images with cloud-init. Lima’s normal provisioning workflow expects to inject SSH keys and set up the user environment via cloud-init, which doesn’t apply to our images.
Setting plain: true tells Lima:
- Skip user session requirement checks
- Skip cloud-init provisioning
- Skip containerd setup
- Just boot the VM and provide SSH access
SSH Key Injection#
Since we can’t use cloud-init, SSH keys are baked into the qcow2 at build time via the bootc-image-builder config. There are two ways to inject SSH keys:
Option A: Interactive configuration
- Run
make qcow2-config(ormake LIMA=1 qcow2-configfor auto SSH key) - Config is saved to
./images/qcow2/<TAG>/config-<TAG>.toml - Run
make qcow2to build using that config
Option B: LIMA=1 flag (quick method)
- Run
make LIMA=1 qcow2directly - Makefile generates a temporary
config.tomlwith your SSH public key - bootc-image-builder creates the qcow2 with the
immutablueuser and your SSH key
In both cases, Lima can then SSH in using your private key.
Image Location#
qcow2 images are stored at:
./images/qcow2/<TAG>/qcow2/disk.qcow2qcow2 configuration files (from qcow2-config) are stored at:
./images/qcow2/<TAG>/config-<TAG>.tomlLima configurations are stored at:
./.lima/immutablue-<TAG>.yamlBoth directories are gitignored as they contain machine-specific paths and large binary files.