Runs `livemedia-creator --no-virt --make-disk` directly on the host to produce a disk image any VM manager can consume (e.g. via virtpull's `virtpull local ... --wonder-vm NAME`), instead of deploy.sh's live virt-install/libvirt session. An earlier version wrapped this in `mock`, mirroring .gitea/workflows/build-iso.yaml's ISO build. That doesn't work for --make-disk: mock's chroot has no live systemd-udevd, so udev never populates properties for the loop device livemedia-creator creates, and blivet's device scan crashes. --make-iso never hits this since it never touches block devices. Reproduced identically on Fedora 44 and 43 mock chroots, confirmed fixed by running directly on the host instead (root required, for /dev/loop-control access). Also fixes two real kickstart incompatibilities with the --no-virt disk-image path (applied to a scratch copy, not the shared ingredients): the `text` display-mode directive (needed for virt-install's netinstall console) conflicts with livemedia-creator's own display handling, and `part / --grow` with no explicit --size crashes livemedia-creator's upfront disk-size calculation (works fine under virt-install, which pre-creates the disk at a known size instead) — now configurable via --root-size. New --extra-ks FILE flag layers one-off local content (e.g. a bespoke user/rootpw override) onto the scratch copy without touching tracked ingredients, following the README's existing "bespoke dish not part of the matrix" pattern. Factored deploy/deploy-distro.sh's dish-picker into deploy/select-dish.sh, shared by both scripts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
202 lines
6.8 KiB
Bash
Executable File
202 lines
6.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Default values
|
|
DEFAULT_MEMORY=4096
|
|
DEFAULT_DISK_SIZE=10
|
|
|
|
# Function to find Fedora ISO based on dish name
|
|
find_fedora_iso() {
|
|
local iso_dir="/var/lib/libvirt/isos"
|
|
local dish_name="$1"
|
|
local fedora_iso=""
|
|
|
|
# Check if directory exists
|
|
if [ -d "$iso_dir" ]; then
|
|
# Parse dish name to extract version or "rawhide"
|
|
local version=""
|
|
if [[ "$dish_name" == *"rawhide"* ]]; then
|
|
version="Rawhide"
|
|
elif [[ "$dish_name" == *"_43"* ]]; then
|
|
version="43"
|
|
elif [[ "$dish_name" == *"_44"* ]]; then
|
|
version="44"
|
|
elif [[ "$dish_name" == *"_45"* ]]; then
|
|
version="45"
|
|
fi
|
|
|
|
# If we found a version, try to match with that version in ISO name
|
|
if [ -n "$version" ]; then
|
|
if [ "$version" = "Rawhide" ]; then
|
|
# For rawhide, look for ISO with "Rawhide" in the name
|
|
fedora_iso=$(find "$iso_dir" -maxdepth 1 -name "Fedora-Everything*.iso" -type f | grep -i "rawhide" | head -n 1)
|
|
else
|
|
# For regular versions, look for ISO with that version number in the name
|
|
fedora_iso=$(find "$iso_dir" -maxdepth 1 -name "Fedora-Everything*.iso" -type f | grep -i "$version" | head -n 1)
|
|
fi
|
|
|
|
# If no specific version match found, fallback to any Fedora-Everything ISO
|
|
if [ -z "$fedora_iso" ] || [ ! -f "$fedora_iso" ]; then
|
|
fedora_iso=$(find "$iso_dir" -maxdepth 1 -name "Fedora-Everything*.iso" -type f | head -n 1)
|
|
fi
|
|
else
|
|
# No version match found, fallback to any Fedora-Everything ISO
|
|
fedora_iso=$(find "$iso_dir" -maxdepth 1 -name "Fedora-Everything*.iso" -type f | head -n 1)
|
|
fi
|
|
|
|
# If found, return the full path
|
|
if [ -n "$fedora_iso" ] && [ -f "$fedora_iso" ]; then
|
|
echo "$fedora_iso"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
# Return empty if no ISO found
|
|
echo ""
|
|
return 1
|
|
}
|
|
|
|
# Function to find Fedora ISO (backward compatibility)
|
|
find_fedora_iso_old() {
|
|
local iso_dir="/var/lib/libvirt/isos"
|
|
local fedora_iso=""
|
|
|
|
# Check if directory exists
|
|
if [ -d "$iso_dir" ]; then
|
|
# Find the first Fedora-Everything*.iso file
|
|
fedora_iso=$(find "$iso_dir" -maxdepth 1 -name "Fedora-Everything*.iso" -type f | head -n 1)
|
|
|
|
# If found, return the full path
|
|
if [ -n "$fedora_iso" ] && [ -f "$fedora_iso" ]; then
|
|
echo "$fedora_iso"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
# Return empty if no ISO found
|
|
echo ""
|
|
return 1
|
|
}
|
|
|
|
# Prompt user for VM memory size
|
|
read -r -p "Provide desired VM memory in MB or press Enter to keep default value of $DEFAULT_MEMORY MB): " memory_size
|
|
memory_size=${memory_size:-$DEFAULT_MEMORY}
|
|
|
|
# Validate memory size
|
|
if ! [[ "$memory_size" =~ ^[0-9]+$ ]] || (( memory_size < 2048 )); then
|
|
echo "Invalid memory size. Must be a number greater than or equal to 2048. Using default value of $DEFAULT_MEMORY MB."
|
|
memory_size=$DEFAULT_MEMORY
|
|
fi
|
|
|
|
# Prompt user for VM disk size
|
|
read -r -p "Provide desired disk size of VM in GB or press Enter to use default disk size of $DEFAULT_DISK_SIZE GB: " disk_size
|
|
disk_size=${disk_size:-$DEFAULT_DISK_SIZE}
|
|
|
|
# Validate disk size
|
|
if ! [[ "$disk_size" =~ ^[0-9]+$ ]] || (( disk_size < 10 )); then
|
|
echo "Invalid disk size. Must be a number greater than or equal to 10 GiB. Using default value of $DEFAULT_DISK_SIZE."
|
|
disk_size=$DEFAULT_DISK_SIZE
|
|
fi
|
|
|
|
# Set the choices
|
|
CHOICE_SYSTEM="qemu:///system"
|
|
CHOICE_SESSION="qemu:///session"
|
|
|
|
# Display the choices to the user
|
|
echo "Please select an option or press Enter to keep default value of $CHOICE_SESSION):"
|
|
echo "1) $CHOICE_SYSTEM (system-based or rootfull virtual machine)"
|
|
echo "2) $CHOICE_SESSION (session-based or rootless virtual machine)"
|
|
|
|
# Prompt the user for input
|
|
IFS= read -r -p "Enter your choice (1 or 2): " user_choice
|
|
|
|
# Validate the user's input
|
|
if [[ ! "$user_choice" =~ ^[12]$ ]]; then
|
|
echo "Invalid choice. Defaulting to session-based VM."
|
|
uri="$CHOICE_SESSION" # Default to session-based if input is invalid
|
|
else
|
|
# Determine the selected option
|
|
case "$user_choice" in
|
|
1)
|
|
uri="$CHOICE_SYSTEM"
|
|
;;
|
|
2)
|
|
uri="$CHOICE_SESSION"
|
|
;;
|
|
*)
|
|
echo "Unexpected error: Invalid choice. This should not happen due to validation."
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Conditional variable assignment based on URI
|
|
if [[ "$uri" == "qemu:///system" ]]; then
|
|
disk_path="/var/lib/libvirt/images/"
|
|
network_type="default"
|
|
elif [[ "$uri" == "qemu:///session" ]]; then
|
|
disk_path="$HOME/.local/share/libvirt/images/"
|
|
network_type="user"
|
|
fi
|
|
fi
|
|
|
|
# Display the selected option (optional)
|
|
echo "You selected: $uri"
|
|
|
|
# Pick a dish (shared with build-image.sh)
|
|
# shellcheck source=./select-dish.sh
|
|
source "$(dirname "$0")/select-dish.sh"
|
|
vm_name="$selected_dish"
|
|
|
|
# Find Fedora ISO based on the dish name
|
|
fedora_iso=$(find_fedora_iso "$vm_name")
|
|
if [ -n "$fedora_iso" ]; then
|
|
location_param="$fedora_iso"
|
|
echo "Using local ISO: $fedora_iso"
|
|
else
|
|
# Fallback to original behavior if no specific ISO found
|
|
fedora_iso=$(find_fedora_iso_old)
|
|
if [ -n "$fedora_iso" ]; then
|
|
location_param="$fedora_iso"
|
|
echo "Using local ISO: $fedora_iso"
|
|
else
|
|
location_param="https://download.fedoraproject.org/pub/fedora/linux/releases/44/Everything/x86_64/os/"
|
|
echo "Using default online repository"
|
|
fi
|
|
fi
|
|
|
|
# virt-install command with user-defined VM name
|
|
virt-install \
|
|
--connect "$uri" \
|
|
--os-variant fedora-unknown \
|
|
--virt-type kvm \
|
|
--arch x86_64 \
|
|
--machine q35 \
|
|
--name "$vm_name" \
|
|
--boot uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no \
|
|
--cpu host-model,topology.sockets=1,topology.cores=1,topology.threads=1 \
|
|
--vcpus 1 \
|
|
--cpu host-passthrough,cache.mode=passthrough \
|
|
--memory "$memory_size" \
|
|
--video virtio \
|
|
--graphics spice,listen=0.0.0.0 \
|
|
--channel unix,target.type=virtio,target.name=org.qemu.guest_agent.0 \
|
|
--autoconsole none \
|
|
--console pty,target.type=virtio \
|
|
--sound none \
|
|
--network type="$network_type",model=virtio \
|
|
--controller type=virtio-serial \
|
|
--controller type=usb,model=none \
|
|
--controller type=scsi,model=virtio-scsi \
|
|
--input type=keyboard,bus=virtio \
|
|
--input type=mouse,bus=virtio \
|
|
--rng /dev/urandom,model=virtio \
|
|
--tpm none \
|
|
--iommu model=virtio \
|
|
--watchdog none \
|
|
--memballoon none \
|
|
--disk path="${disk_path}/${vm_name}.img",format=raw,bus=virtio,cache=writeback,size="$disk_size" \
|
|
--location="$location_param" \
|
|
--initrd-inject cook/dishes/"$vm_name".cfg \
|
|
--extra-args "inst.ks=file:/$vm_name.cfg"
|
|
|
|
echo "virt-install command executed with VM name: $vm_name"
|