Add Fedora 44 GNOME virtual machine
This commit is contained in:
1 parent
58a0a2d1ff
commit
a0cd640ffe
10 files changed
+267
-2
No files matched your search
@@ -5,6 +5,7 @@ Start the required operating system with its distribution-specific launcher:
|
|||||||
```bash
|
```bash
|
||||||
./run-debian13.sh
|
./run-debian13.sh
|
||||||
./run-almalinux10.sh
|
./run-almalinux10.sh
|
||||||
|
./run-fedora44.sh
|
||||||
./run-windows11.sh
|
./run-windows11.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -71,6 +72,29 @@ stored alongside the VM disk at `.vm/almalinux10/seed.iso`. If it already
|
|||||||
exists after editing its source files, rebuild it explicitly with
|
exists after editing its source files, rebuild it explicitly with
|
||||||
`./seediso/almalinux10/build-seed.sh .vm/almalinux10/seed.iso`.
|
`./seediso/almalinux10/build-seed.sh .vm/almalinux10/seed.iso`.
|
||||||
|
|
||||||
|
## Fedora 44
|
||||||
|
|
||||||
|
Start a Fedora 44 Cloud Base VM with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./run-fedora44.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The launcher downloads the `fedora44` image through the shared helper when it
|
||||||
|
is missing, creates `.vm/fedora44/disk.qcow2`, and builds its NoCloud seed from
|
||||||
|
`seediso/fedora44/`. SSH is forwarded to host port `2224` by default:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -p 2224 guofang@localhost
|
||||||
|
```
|
||||||
|
|
||||||
|
On the first boot, cloud-init updates package metadata and installs Fedora's
|
||||||
|
GNOME package group through its native package module, then reboots the guest.
|
||||||
|
Keep the VM running until this initial installation and reboot have completed.
|
||||||
|
|
||||||
|
Fedora settings use the `FEDORA_VM_` prefix. Run `./run-fedora44.sh --help`
|
||||||
|
for the complete list of overrides.
|
||||||
|
|
||||||
## Windows 11 23H2
|
## Windows 11 23H2
|
||||||
|
|
||||||
On first boot, the Windows 11 launcher creates a writable system-disk overlay
|
On first boot, the Windows 11 launcher creates a writable system-disk overlay
|
||||||
|
|||||||
Executable
+153
@@ -0,0 +1,153 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
if [[ -n "${VM_IMAGE_HELPER:-}" ]]; then
|
||||||
|
image_downloader="$VM_IMAGE_HELPER"
|
||||||
|
elif [[ -x "${script_dir}/vm-images/download-images.sh" ]]; then
|
||||||
|
image_downloader="${script_dir}/vm-images/download-images.sh"
|
||||||
|
else
|
||||||
|
image_downloader="${script_dir}/../vm-images/download-images.sh"
|
||||||
|
fi
|
||||||
|
uses_shared_base_image=false
|
||||||
|
if [[ -n "${FEDORA_VM_BASE_IMAGE:-}" ]]; then
|
||||||
|
base_image="$FEDORA_VM_BASE_IMAGE"
|
||||||
|
else
|
||||||
|
[[ -x "$image_downloader" ]] || { printf 'Error: shared image helper is unavailable: %s\n' "$image_downloader" >&2; exit 1; }
|
||||||
|
base_image="$("$image_downloader" --print-path fedora44)"
|
||||||
|
uses_shared_base_image=true
|
||||||
|
fi
|
||||||
|
state_dir="${FEDORA_VM_STATE_DIR:-${script_dir}/.vm/fedora44}"
|
||||||
|
disk_image="${FEDORA_VM_DISK_IMAGE:-${state_dir}/disk.qcow2}"
|
||||||
|
seed_image="${FEDORA_VM_SEED_IMAGE:-$(dirname -- "$disk_image")/seed.iso}"
|
||||||
|
disk_size="${FEDORA_VM_DISK_SIZE:-20G}"
|
||||||
|
memory="${FEDORA_VM_MEMORY:-8G}"
|
||||||
|
cpus="${FEDORA_VM_CPUS:-8}"
|
||||||
|
ssh_port="${FEDORA_VM_SSH_PORT:-2224}"
|
||||||
|
uefi_code="${FEDORA_VM_UEFI_CODE:-/usr/share/OVMF/OVMF_CODE_4M.fd}"
|
||||||
|
uefi_vars_template="${FEDORA_VM_UEFI_VARS:-/usr/share/OVMF/OVMF_VARS_4M.fd}"
|
||||||
|
uefi_vars="${state_dir}/OVMF_VARS_4M.fd"
|
||||||
|
pid_file="${state_dir}/qemu.pid"
|
||||||
|
log_file="${state_dir}/console.log"
|
||||||
|
daemonize=false
|
||||||
|
extra_args=()
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $(basename "$0") [--daemon] [-- QEMU_ARGUMENT ...]
|
||||||
|
|
||||||
|
Start a Fedora 44 Cloud Base virtual machine. The launcher obtains a missing
|
||||||
|
base image through the shared image helper and creates a writable overlay
|
||||||
|
under .vm/fedora44/, leaving the base image unchanged.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--daemon Run in the background while keeping the graphical window
|
||||||
|
-h, --help Show this help
|
||||||
|
|
||||||
|
Environment variables:
|
||||||
|
FEDORA_VM_MEMORY Guest memory (default: 8G)
|
||||||
|
FEDORA_VM_CPUS Virtual CPU count (default: 8)
|
||||||
|
FEDORA_VM_SSH_PORT Host port forwarded to guest SSH (default: 2224)
|
||||||
|
FEDORA_VM_BASE_IMAGE Base qcow2 image path (default: resolved by shared image helper)
|
||||||
|
FEDORA_VM_SEED_IMAGE cloud-init seed ISO path (default: alongside the VM disk)
|
||||||
|
FEDORA_VM_STATE_DIR Runtime state directory (default: .vm/fedora44)
|
||||||
|
FEDORA_VM_DISK_IMAGE Writable overlay path
|
||||||
|
FEDORA_VM_DISK_SIZE New overlay virtual capacity (default: 20G)
|
||||||
|
FEDORA_VM_UEFI_CODE OVMF read-only firmware path
|
||||||
|
FEDORA_VM_UEFI_VARS OVMF variable-store template path
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
while (($#)); do
|
||||||
|
case "$1" in
|
||||||
|
--daemon) daemonize=true; shift ;;
|
||||||
|
-h|--help) usage; exit 0 ;;
|
||||||
|
--) shift; extra_args+=("$@"); break ;;
|
||||||
|
*) printf 'Error: unknown option: %s\n' "$1" >&2; usage >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
for command_name in qemu-system-x86_64 qemu-img; do
|
||||||
|
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||||
|
printf 'Error: %s is not installed.\n' "$command_name" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ! -f "$base_image" ]]; then
|
||||||
|
if [[ "$uses_shared_base_image" == true ]]; then
|
||||||
|
"$image_downloader" fedora44
|
||||||
|
else
|
||||||
|
printf 'Error: Fedora base image was not found: %s\n' "$base_image" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
[[ -f "$base_image" ]] || { printf 'Error: downloader did not create: %s\n' "$base_image" >&2; exit 1; }
|
||||||
|
for firmware_file in "$uefi_code" "$uefi_vars_template"; do
|
||||||
|
[[ -f "$firmware_file" ]] || { printf 'Error: required UEFI firmware was not found: %s\n' "$firmware_file" >&2; exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ! -f "$seed_image" ]]; then
|
||||||
|
seed_builder="${script_dir}/seediso/fedora44/build-seed.sh"
|
||||||
|
if [[ ! -x "$seed_builder" ]]; then
|
||||||
|
printf 'Error: seed image is missing and builder is unavailable: %s\n' "$seed_builder" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
printf 'Seed image not found; building %s...\n' "$seed_image"
|
||||||
|
"$seed_builder" "$seed_image"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$state_dir"
|
||||||
|
[[ -f "$uefi_vars" ]] || cp -- "$uefi_vars_template" "$uefi_vars"
|
||||||
|
|
||||||
|
if [[ -f "$pid_file" ]]; then
|
||||||
|
old_pid="$(<"$pid_file")"
|
||||||
|
if [[ "$old_pid" =~ ^[0-9]+$ ]] && kill -0 "$old_pid" 2>/dev/null; then
|
||||||
|
printf 'Error: the Fedora virtual machine is already running (PID %s).\n' "$old_pid" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rm -f "$pid_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$disk_image" ]]; then
|
||||||
|
qemu-img create -q -f qcow2 -F qcow2 -b "$base_image" "$disk_image" "$disk_size"
|
||||||
|
printf 'Created writable disk overlay: %s\n' "$disk_image"
|
||||||
|
fi
|
||||||
|
|
||||||
|
qemu_args=(
|
||||||
|
-name fedora44
|
||||||
|
-machine q35
|
||||||
|
-display gtk
|
||||||
|
-m "$memory"
|
||||||
|
-smp "$cpus"
|
||||||
|
-drive "if=pflash,format=raw,readonly=on,file=${uefi_code}"
|
||||||
|
-drive "if=pflash,format=raw,file=${uefi_vars}"
|
||||||
|
-drive "file=${disk_image},if=virtio,format=qcow2"
|
||||||
|
-drive "file=${seed_image},media=cdrom,readonly=on"
|
||||||
|
-nic "user,model=virtio-net-pci,hostfwd=tcp::${ssh_port}-:22"
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ -r /dev/kvm && -w /dev/kvm ]]; then
|
||||||
|
qemu_args+=(-enable-kvm -cpu host)
|
||||||
|
accelerator=KVM
|
||||||
|
else
|
||||||
|
qemu_args+=(-accel tcg -cpu max)
|
||||||
|
accelerator=TCG
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'Starting Fedora 44 with %s acceleration; SSH is forwarded to localhost:%s.\n' \
|
||||||
|
"$accelerator" "$ssh_port"
|
||||||
|
|
||||||
|
if [[ "$daemonize" == true ]]; then
|
||||||
|
: >"$log_file"
|
||||||
|
qemu_args+=(
|
||||||
|
-serial "file:${log_file}"
|
||||||
|
-monitor none
|
||||||
|
-daemonize
|
||||||
|
-pidfile "$pid_file"
|
||||||
|
)
|
||||||
|
qemu-system-x86_64 "${qemu_args[@]}" "${extra_args[@]}"
|
||||||
|
printf 'VM started (PID %s); console log: %s\n' "$(<"$pid_file")" "$log_file"
|
||||||
|
else
|
||||||
|
exec qemu-system-x86_64 "${qemu_args[@]}" "${extra_args[@]}"
|
||||||
|
fi
|
||||||
+2
-1
@@ -6,7 +6,8 @@ Each operating system has an independent NoCloud configuration and generated
|
|||||||
```text
|
```text
|
||||||
seediso/
|
seediso/
|
||||||
├── debian13/
|
├── debian13/
|
||||||
└── almalinux10/
|
├── almalinux10/
|
||||||
|
└── fedora44/
|
||||||
```
|
```
|
||||||
|
|
||||||
Keeping per-OS metadata separate allows each VM to use a distinct hostname and
|
Keeping per-OS metadata separate allows each VM to use a distinct hostname and
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
seed.iso
|
||||||
|
*.iso
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Fedora 44 seed.iso
|
||||||
|
|
||||||
|
This directory contains the cloud-init NoCloud configuration used by
|
||||||
|
`run-fedora44.sh`. On first boot, cloud-init's package module installs Fedora's
|
||||||
|
GNOME package group and reboots the guest.
|
||||||
|
|
||||||
|
After changing `user-data`, `meta-data`, or `network-config`, remove the old
|
||||||
|
`seed.iso` and rebuild it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./seediso/fedora44/build-seed.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Use a unique `instance-id` when cloning this configuration for another VM.
|
||||||
Executable
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
output="${1:-${script_dir}/seed.iso}"
|
||||||
|
files=(user-data meta-data)
|
||||||
|
|
||||||
|
mkdir -p "$(dirname -- "$output")"
|
||||||
|
if [[ -f "${script_dir}/network-config" ]]; then
|
||||||
|
files+=(network-config)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v cloud-localds >/dev/null 2>&1; then
|
||||||
|
args=()
|
||||||
|
[[ -f "${script_dir}/network-config" ]] && args+=(--network-config="${script_dir}/network-config")
|
||||||
|
cloud-localds "${args[@]}" "$output" "${script_dir}/user-data" "${script_dir}/meta-data"
|
||||||
|
elif command -v xorriso >/dev/null 2>&1; then
|
||||||
|
xorriso -as mkisofs -quiet -volid cidata -joliet -rock -output "$output" "${files[@]/#/${script_dir}/}"
|
||||||
|
elif command -v genisoimage >/dev/null 2>&1; then
|
||||||
|
genisoimage -quiet -output "$output" -volid cidata -joliet -rock "${files[@]/#/${script_dir}/}"
|
||||||
|
elif command -v mkisofs >/dev/null 2>&1; then
|
||||||
|
mkisofs -quiet -output "$output" -volid cidata -joliet -rock "${files[@]/#/${script_dir}/}"
|
||||||
|
else
|
||||||
|
printf 'Error: install cloud-image-utils, xorriso, genisoimage, or mkisofs.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf 'Created %s\n' "$output"
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
instance-id: fedora44-host-001
|
||||||
|
local-hostname: fedora44-host
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
version: 2
|
||||||
|
ethernets:
|
||||||
|
all-en:
|
||||||
|
match:
|
||||||
|
name: "en*"
|
||||||
|
dhcp4: true
|
||||||
|
all-eth:
|
||||||
|
match:
|
||||||
|
name: "eth*"
|
||||||
|
dhcp4: true
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#cloud-config
|
||||||
|
preserve_hostname: false
|
||||||
|
manage_etc_hosts: true
|
||||||
|
ssh_pwauth: true
|
||||||
|
|
||||||
|
users:
|
||||||
|
- name: guofang
|
||||||
|
gecos: Guofang
|
||||||
|
groups: [wheel]
|
||||||
|
shell: /bin/bash
|
||||||
|
sudo: "ALL=(ALL) NOPASSWD: ALL"
|
||||||
|
lock_passwd: false
|
||||||
|
hashed_passwd: $6$0NtCERV3eO12t9oJ$nlFE2sSc66nFfuD5X0xMnOla1cuzOnHfeGNRY5X7dCDHg.WzWVmuRe7M17Puj44.eCWLnJAWt4WNjd9vP9X0D0
|
||||||
|
|
||||||
|
chpasswd:
|
||||||
|
expire: false
|
||||||
|
|
||||||
|
package_update: true
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- "@gnome-desktop"
|
||||||
|
|
||||||
|
runcmd:
|
||||||
|
- [systemctl, set-default, graphical.target]
|
||||||
|
# - [systemctl, enable, gdm.service]
|
||||||
|
|
||||||
|
power_state:
|
||||||
|
delay: now
|
||||||
|
mode: reboot
|
||||||
|
message: "GNOME installation completed; rebooting into graphical mode."
|
||||||
|
condition: true
|
||||||
+1
-1
Submodule vm-images updated: 04c0109baa...d2b46066d4.
Reference in new issue
Block a user