qvm/bin/qvm-rebuild

137 lines
3.8 KiB
Bash
Executable file

#!/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 "$@"