#!/usr/bin/env bash # # qvm-rebuild - Build the base qcow2 image from user's flake # # This script builds the QVM base image by: # - Ensuring a user flake exists (copying default if needed) # - Running nix build on the user's flake configuration # - Copying the resulting qcow2 to the base image location # - Optionally warning if VM is running # set -euo pipefail # Source common library QVM_LIB_DIR="${QVM_LIB_DIR:-$(dirname "$(readlink -f "$0")")/../lib}" # shellcheck source=lib/common.sh source "$QVM_LIB_DIR/common.sh" # # ensure_user_flake - Ensure user's flake exists, copy default if missing # ensure_user_flake() { if [[ -f "$QVM_USER_FLAKE/flake.nix" ]]; then log_info "Using existing user flake: $QVM_USER_FLAKE/flake.nix" return 0 fi log_info "User flake not found, copying default template..." # Determine default flake location # In installed version: $QVM_LIB_DIR/../flake/default-vm/ # In development: $(dirname "$0")/../flake/default-vm/ local default_flake_dir="$QVM_LIB_DIR/../flake/default-vm" if [[ ! -d "$default_flake_dir" ]]; then die "Default flake template not found at: $default_flake_dir" fi if [[ ! -f "$default_flake_dir/flake.nix" ]]; then die "Default flake.nix not found at: $default_flake_dir/flake.nix" fi # Create user flake directory and copy template mkdir -p "$QVM_USER_FLAKE" cp -r "$default_flake_dir"/* "$QVM_USER_FLAKE/" log_info "Default flake copied to: $QVM_USER_FLAKE" echo "" echo "You can customize your VM by editing: $QVM_USER_FLAKE/flake.nix" echo "" } # # build_base_image - Build the base image using nix # build_base_image() { log_info "Building base image from flake..." # Build the qcow2 output from user's flake local build_result="$QVM_STATE_DIR/result" if ! nix build "$QVM_USER_FLAKE#qcow2" --out-link "$build_result"; then die "Failed to build base image. Check your flake configuration at: $QVM_USER_FLAKE/flake.nix" fi # Verify the result contains nixos.qcow2 local qcow2_path="$build_result/nixos.qcow2" if [[ ! -f "$qcow2_path" ]]; then die "Build succeeded but nixos.qcow2 not found at: $qcow2_path" fi # Copy the qcow2 to base image location log_info "Copying image to: $QVM_BASE_IMAGE" cp -L "$qcow2_path" "$QVM_BASE_IMAGE" # Remove the result symlink rm -f "$build_result" # Get image size for informational output local image_size image_size=$(du -h "$QVM_BASE_IMAGE" | cut -f1) log_info "Base image built successfully" echo "" echo "Base image: $QVM_BASE_IMAGE" echo "Image size: $image_size" } # # warn_if_running - Warn user if VM is currently running # warn_if_running() { if is_vm_running; then log_warn "VM is currently running" echo "" echo "The new base image will only take effect after restarting the VM:" echo " qvm stop" echo " qvm start" echo "" echo "Note: Changes to your VM overlay will be preserved." echo " Use 'qvm reset' to start fresh with the new base image." echo "" fi } # # main - Main execution flow # main() { log_info "Rebuilding QVM base image..." # Ensure required directories exist ensure_dirs # Ensure user has a flake configuration ensure_user_flake # Build the base image build_base_image # Warn if VM is running warn_if_running # Print next steps echo "Next steps:" if is_vm_running; then echo " 1. Stop the VM: qvm stop" echo " 2. Start the VM: qvm start" else echo " - Start the VM: qvm start" fi echo " - Customize the VM: edit $QVM_USER_FLAKE/flake.nix" echo " - Reset to fresh state: qvm reset" } # Run main function main "$@"