Add Gitea Actions runner, ansible-lint CI, vault setup, and fix group_vars layout
- Move group_vars into inventory/ so playbooks can find them (was only visible to ad-hoc commands via CWD) - Add Ansible Vault for sensitive variables (gitea/grafana passwords, tokens, db credentials) with vault_password_file outside the repo - Enable Gitea Actions and deploy act_runner with Docker backend on the gitea VM - Add .gitea/workflows/lint.yml to run ansible-lint on every push - Set up Gitea → GitHub push mirror (sync_on_commit) - Fix ansible.cfg stdout_callback for ansible-core 2.20 compatibility - Add python-psycopg2 to gitea role (required for postgresql modules) - Add docker to gitea_runner role (required by act_runner at startup) - Exclude password hashes and VM images from git Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Executable
+174
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run in the Arch live environment to generate archinstall-config-physical.json
|
||||
# with correct partition sizes for the target SSD.
|
||||
#
|
||||
# Usage:
|
||||
# ./generate-physical-config.sh /dev/sda # outputs to /tmp/config.json
|
||||
# ./generate-physical-config.sh /dev/nvme0n1p0 # NVMe example
|
||||
set -euo pipefail
|
||||
|
||||
info() { echo -e "\033[1;34m==>\033[0m $*"; }
|
||||
die() { echo -e "\033[1;31mERROR:\033[0m $*" >&2; exit 1; }
|
||||
|
||||
DEVICE="${1:-}"
|
||||
if [[ -z "$DEVICE" ]]; then
|
||||
echo "Usage: $0 <ssd-device>"
|
||||
echo
|
||||
echo "Available disks:"
|
||||
lsblk -d -o NAME,SIZE,MODEL
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[[ -b "$DEVICE" ]] || die "Device '$DEVICE' not found or is not a block device."
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Partition layout
|
||||
# ---------------------------------------------------------------------------
|
||||
# Layout:
|
||||
# [1 MiB gap] [1 GiB ESP /boot] [rest: BTRFS root with subvolumes]
|
||||
#
|
||||
START_PADDING_B=1048576 # 1 MiB
|
||||
ESP_B=1073741824 # 1 GiB
|
||||
END_PADDING_B=1048576 # 1 MiB — leave 1 MiB at end for partition table alignment
|
||||
ROOT_START_B=$(( START_PADDING_B + ESP_B )) # = 1074790400
|
||||
|
||||
DISK_BYTES=$(lsblk -b -d -n -o SIZE "$DEVICE")
|
||||
ROOT_SIZE_B=$(( DISK_BYTES - ROOT_START_B - END_PADDING_B ))
|
||||
|
||||
info "Device: $DEVICE"
|
||||
info "Disk size: $DISK_BYTES bytes ($(( DISK_BYTES / 1024 / 1024 / 1024 )) GiB)"
|
||||
info "ESP start: $START_PADDING_B size: $ESP_B"
|
||||
info "Root start: $ROOT_START_B size: $ROOT_SIZE_B"
|
||||
|
||||
(( ROOT_SIZE_B > 0 )) || die "Disk is too small to partition."
|
||||
|
||||
OUT="/tmp/config.json"
|
||||
|
||||
cat > "$OUT" << EOF
|
||||
{
|
||||
"app_config": null,
|
||||
"archinstall-language": "English",
|
||||
"auth_config": {},
|
||||
"bootloader_config": {
|
||||
"bootloader": "Systemd-boot",
|
||||
"removable": true,
|
||||
"uki": false
|
||||
},
|
||||
"custom_commands": [
|
||||
"mkdir -p /home/adyrem/.ssh && chmod 700 /home/adyrem/.ssh && echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILdW4rhQFv561bYs8w0/VgR6AFgOLvVsAh6pcjZ/CO2R homelab' > /home/adyrem/.ssh/authorized_keys && chmod 600 /home/adyrem/.ssh/authorized_keys && chown -R adyrem:adyrem /home/adyrem/.ssh",
|
||||
"mkdir -p /vms/infra /vms/dev"
|
||||
],
|
||||
"disk_config": {
|
||||
"btrfs_options": {
|
||||
"snapshot_config": null
|
||||
},
|
||||
"config_type": "manual_partitioning",
|
||||
"device_modifications": [
|
||||
{
|
||||
"device": "$DEVICE",
|
||||
"wipe": true,
|
||||
"partitions": [
|
||||
{
|
||||
"btrfs": [],
|
||||
"dev_path": null,
|
||||
"flags": ["boot", "esp"],
|
||||
"fs_type": "fat32",
|
||||
"mount_options": [],
|
||||
"mountpoint": "/boot",
|
||||
"obj_id": "part-esp",
|
||||
"size": {
|
||||
"sector_size": { "unit": "B", "value": 512 },
|
||||
"unit": "GiB",
|
||||
"value": 1
|
||||
},
|
||||
"start": {
|
||||
"sector_size": { "unit": "B", "value": 512 },
|
||||
"unit": "MiB",
|
||||
"value": 1
|
||||
},
|
||||
"status": "create",
|
||||
"type": "primary"
|
||||
},
|
||||
{
|
||||
"btrfs": [
|
||||
{ "name": "@", "mountpoint": "/" },
|
||||
{ "name": "@home", "mountpoint": "/home" },
|
||||
{ "name": "@var", "mountpoint": "/var" },
|
||||
{ "name": "@snapshots", "mountpoint": "/.snapshots" },
|
||||
{ "name": "@vms-infra", "mountpoint": "/vms/infra" },
|
||||
{ "name": "@vms-dev", "mountpoint": "/vms/dev" }
|
||||
],
|
||||
"dev_path": null,
|
||||
"flags": [],
|
||||
"fs_type": "btrfs",
|
||||
"mount_options": ["compress=zstd", "noatime"],
|
||||
"mountpoint": null,
|
||||
"obj_id": "part-root",
|
||||
"size": {
|
||||
"sector_size": { "unit": "B", "value": 512 },
|
||||
"unit": "B",
|
||||
"value": $ROOT_SIZE_B
|
||||
},
|
||||
"start": {
|
||||
"sector_size": { "unit": "B", "value": 512 },
|
||||
"unit": "B",
|
||||
"value": $ROOT_START_B
|
||||
},
|
||||
"status": "create",
|
||||
"type": "primary"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"hostname": "homelab",
|
||||
"kernels": ["linux"],
|
||||
"locale_config": {
|
||||
"kb_layout": "de_CH-latin1",
|
||||
"sys_enc": "UTF-8",
|
||||
"sys_lang": "en_US"
|
||||
},
|
||||
"mirror_config": {
|
||||
"custom_repositories": [],
|
||||
"custom_servers": [],
|
||||
"mirror_regions": {
|
||||
"Worldwide": ["https://geo.mirror.pkgbuild.com/\$repo/os/\$arch"]
|
||||
},
|
||||
"optional_repositories": []
|
||||
},
|
||||
"network_config": {
|
||||
"type": "nm"
|
||||
},
|
||||
"ntp": true,
|
||||
"packages": [
|
||||
"base-devel",
|
||||
"git",
|
||||
"openssh",
|
||||
"networkmanager",
|
||||
"vim",
|
||||
"btrbk",
|
||||
"nftables"
|
||||
],
|
||||
"parallel_downloads": 5,
|
||||
"script": "guided",
|
||||
"services": ["sshd", "NetworkManager", "nftables"],
|
||||
"swap": {
|
||||
"algorithm": "zstd",
|
||||
"enabled": false
|
||||
},
|
||||
"timezone": "Europe/Zurich",
|
||||
"version": "4.1",
|
||||
"users": [
|
||||
{
|
||||
"enc_password": "\$y\$j9T\$pqMooSvLvxBg2YP7eCQlq/\$Ae8.dvSYB817bQkj5w9S4wu9OtWIq.p/pbWY6A/ythD",
|
||||
"groups": ["wheel"],
|
||||
"sudo": true,
|
||||
"username": "adyrem"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "Config written to $OUT"
|
||||
echo "Run: archinstall --config $OUT"
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run this inside the Arch live environment on physical hardware.
|
||||
# Fetches the config generator from the host HTTP server, generates the config
|
||||
# for the correct SSD device, then starts archinstall.
|
||||
#
|
||||
# Usage:
|
||||
# curl http://<host-ip>:8080/scripts/physical-install.sh | bash
|
||||
# or with device override:
|
||||
# curl http://<host-ip>:8080/scripts/physical-install.sh -o /tmp/install.sh
|
||||
# bash /tmp/install.sh /dev/sda
|
||||
set -euo pipefail
|
||||
|
||||
HOST="${HOST:-http://192.168.1.1:8080}" # update to your host's LAN IP
|
||||
DEVICE="${1:-}"
|
||||
|
||||
echo "==> Available disks:"
|
||||
lsblk -d -o NAME,SIZE,MODEL
|
||||
echo
|
||||
|
||||
if [[ -z "$DEVICE" ]]; then
|
||||
read -rp "Enter SSD device for OS install (e.g. /dev/sda): " DEVICE
|
||||
fi
|
||||
|
||||
echo "==> Fetching config generator..."
|
||||
curl -fsSL "$HOST/scripts/generate-physical-config.sh" -o /tmp/generate-config.sh
|
||||
chmod +x /tmp/generate-config.sh
|
||||
|
||||
echo "==> Generating config for $DEVICE..."
|
||||
/tmp/generate-config.sh "$DEVICE"
|
||||
|
||||
echo "==> Starting archinstall..."
|
||||
archinstall --config /tmp/config.json
|
||||
Executable
+268
@@ -0,0 +1,268 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# setup-arch-vm.sh
|
||||
# Creates a minimal Arch Linux VM on the local Fedora host using KVM/libvirt.
|
||||
# VM disk images are stored under homelab/vms/.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
VM_DIR="$PROJECT_DIR/vms"
|
||||
ISO_DIR="$VM_DIR/iso"
|
||||
|
||||
VM_NAME="arch-base"
|
||||
VM_DISK="$VM_DIR/${VM_NAME}.qcow2"
|
||||
VM_RAM=2048 # MiB
|
||||
VM_CPUS=2
|
||||
VM_DISK_SIZE=20 # GiB
|
||||
|
||||
ARCH_ISO_URL="https://geo.mirror.pkgbuild.com/iso/2026.04.01/archlinux-2026.04.01-x86_64.iso"
|
||||
ARCH_ISO_SHA256="f14bf46afbe782d28835aed99bfa2fe447903872cb9f4b21153196d6ed1d48ae"
|
||||
ARCH_ISO="$ISO_DIR/archlinux-2026.04.01-x86_64.iso"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
info() { echo -e "\033[1;34m==>\033[0m $*"; }
|
||||
ok() { echo -e "\033[1;32m ✓\033[0m $*"; }
|
||||
warn() { echo -e "\033[1;33m !\033[0m $*"; }
|
||||
die() { echo -e "\033[1;31mERROR:\033[0m $*" >&2; exit 1; }
|
||||
|
||||
require_cmd() { command -v "$1" &>/dev/null || die "'$1' not found. Install it and re-run."; }
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pre-flight checks
|
||||
# ---------------------------------------------------------------------------
|
||||
info "Running pre-flight checks..."
|
||||
|
||||
require_cmd virsh
|
||||
require_cmd virt-install
|
||||
require_cmd qemu-img
|
||||
require_cmd sha256sum
|
||||
|
||||
# KVM modules — load if not already present
|
||||
if ! lsmod | grep -q '^kvm'; then
|
||||
info "KVM modules not loaded — attempting to load..."
|
||||
if grep -q "GenuineIntel" /proc/cpuinfo 2>/dev/null; then
|
||||
sudo modprobe kvm_intel || die "Failed to load kvm_intel. Enable virtualisation in BIOS/UEFI."
|
||||
else
|
||||
sudo modprobe kvm_amd || die "Failed to load kvm_amd. Enable virtualisation in BIOS/UEFI."
|
||||
fi
|
||||
fi
|
||||
ok "KVM modules loaded"
|
||||
|
||||
# br_netfilter — required for virtnetworkd to configure bridge netfilter rules;
|
||||
# without it /proc/sys/net/bridge/ doesn't exist and net-start fails with EPERM
|
||||
if ! lsmod | grep -q '^br_netfilter'; then
|
||||
info "Loading br_netfilter module..."
|
||||
sudo modprobe br_netfilter || die "Failed to load br_netfilter kernel module."
|
||||
fi
|
||||
# Persist across reboots
|
||||
if [[ ! -f /etc/modules-load.d/libvirt.conf ]]; then
|
||||
echo -e "kvm_intel\nbr_netfilter" | sudo tee /etc/modules-load.d/libvirt.conf >/dev/null
|
||||
fi
|
||||
ok "br_netfilter loaded"
|
||||
|
||||
# libvirt daemons — Fedora uses modular socket-activated daemons, not monolithic libvirtd
|
||||
LIBVIRT_SOCKETS=(virtqemud virtnetworkd virtnodedevd virtstoraged virtsecretd)
|
||||
info "Enabling libvirt modular daemons..."
|
||||
for svc in "${LIBVIRT_SOCKETS[@]}"; do
|
||||
if ! systemctl is-active --quiet "${svc}.socket"; then
|
||||
sudo systemctl enable --now "${svc}.socket"
|
||||
fi
|
||||
# Remove the idle timeout so daemons don't shut down mid-operation
|
||||
if [[ ! -f /etc/systemd/system/${svc}.service.d/notimeout.conf ]]; then
|
||||
sudo mkdir -p "/etc/systemd/system/${svc}.service.d"
|
||||
printf '[Service]\nEnvironment=%s_ARGS=\n' "${svc^^}" \
|
||||
| sudo tee "/etc/systemd/system/${svc}.service.d/notimeout.conf" >/dev/null
|
||||
fi
|
||||
if ! systemctl is-active --quiet "${svc}.service"; then
|
||||
sudo systemctl start "${svc}.service" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
sudo systemctl daemon-reload
|
||||
ok "libvirt modular daemons ready"
|
||||
|
||||
# Group membership — required for polkit to allow bridge/network operations
|
||||
if ! id -nG | grep -qw libvirt; then
|
||||
info "Adding $USER to libvirt and kvm groups..."
|
||||
sudo usermod -aG libvirt,kvm "$USER"
|
||||
echo
|
||||
echo " ┌─────────────────────────────────────────────────────────┐"
|
||||
echo " │ Group membership updated. You must start a new shell │"
|
||||
echo " │ for the change to take effect, then re-run the script. │"
|
||||
echo " │ │"
|
||||
echo " │ Run: newgrp libvirt │"
|
||||
echo " │ Then: ./scripts/setup-arch-vm.sh │"
|
||||
echo " └─────────────────────────────────────────────────────────┘"
|
||||
exit 0
|
||||
fi
|
||||
ok "User is in libvirt group"
|
||||
VIRSH="virsh --connect qemu:///system"
|
||||
VIRT_INSTALL="virt-install --connect qemu:///system"
|
||||
QEMU_IMG="qemu-img"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Default network
|
||||
# ---------------------------------------------------------------------------
|
||||
info "Checking libvirt default network..."
|
||||
if ! $VIRSH net-list --all | grep -q 'default'; then
|
||||
info "Default network not defined — creating it..."
|
||||
$VIRSH net-define /usr/share/libvirt/networks/default.xml \
|
||||
|| die "Could not define default network. Is libvirt-daemon-config-network installed?"
|
||||
fi
|
||||
if ! $VIRSH net-list | grep -q 'default'; then
|
||||
# Remove a stale virbr0 left over from a previous failed start
|
||||
if ip link show virbr0 &>/dev/null; then
|
||||
info "Removing stale virbr0 bridge..."
|
||||
sudo ip link set virbr0 down 2>/dev/null || true
|
||||
sudo ip link delete virbr0 2>/dev/null || true
|
||||
fi
|
||||
$VIRSH net-start default || true # ignore "already active" race
|
||||
ok "Default network started"
|
||||
fi
|
||||
$VIRSH net-autostart default &>/dev/null || true
|
||||
ok "Default network ready"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Directory setup
|
||||
# ---------------------------------------------------------------------------
|
||||
info "Creating VM storage directories..."
|
||||
mkdir -p "$VM_DIR" "$ISO_DIR"
|
||||
|
||||
# Grant the qemu user search (execute) permission on every directory component
|
||||
# leading to the VM storage — QEMU runs as uid qemu and can't traverse home dirs.
|
||||
if command -v setfacl &>/dev/null; then
|
||||
dir="$VM_DIR"
|
||||
while [[ "$dir" != "/" ]]; do
|
||||
setfacl -m u:qemu:x "$dir" 2>/dev/null || sudo setfacl -m u:qemu:x "$dir"
|
||||
dir="$(dirname "$dir")"
|
||||
done
|
||||
# Also allow qemu to read/write inside the vms directory itself
|
||||
setfacl -m u:qemu:rwx "$VM_DIR" 2>/dev/null || sudo setfacl -m u:qemu:rwx "$VM_DIR"
|
||||
setfacl -m u:qemu:rx "$ISO_DIR" 2>/dev/null || sudo setfacl -m u:qemu:rx "$ISO_DIR"
|
||||
else
|
||||
warn "setfacl not found — install 'acl' package if QEMU reports permission denied."
|
||||
fi
|
||||
ok "Directories ready: $VM_DIR"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ISO download
|
||||
# ---------------------------------------------------------------------------
|
||||
if [[ -f "$ARCH_ISO" ]]; then
|
||||
info "ISO already present — verifying checksum..."
|
||||
echo "$ARCH_ISO_SHA256 $ARCH_ISO" | sha256sum --check --quiet \
|
||||
&& ok "Checksum OK" \
|
||||
|| { warn "Checksum mismatch — re-downloading ISO..."; rm -f "$ARCH_ISO"; }
|
||||
fi
|
||||
|
||||
if [[ ! -f "$ARCH_ISO" ]]; then
|
||||
info "Downloading Arch Linux ISO (~1.1 GB)..."
|
||||
curl -L --progress-bar -o "$ARCH_ISO" "$ARCH_ISO_URL"
|
||||
info "Verifying checksum..."
|
||||
echo "$ARCH_ISO_SHA256 $ARCH_ISO" | sha256sum --check --quiet \
|
||||
|| die "ISO checksum verification failed. File may be corrupt."
|
||||
ok "ISO downloaded and verified"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# VM disk image
|
||||
# ---------------------------------------------------------------------------
|
||||
if [[ -f "$VM_DISK" ]]; then
|
||||
warn "Disk image already exists at $VM_DISK"
|
||||
read -rp " Delete and recreate? [y/N] " confirm
|
||||
[[ "$confirm" =~ ^[Yy]$ ]] || die "Aborting — existing disk left intact."
|
||||
rm -f "$VM_DISK"
|
||||
fi
|
||||
|
||||
info "Creating ${VM_DISK_SIZE}G qcow2 disk image..."
|
||||
$QEMU_IMG create -f qcow2 "$VM_DISK" "${VM_DISK_SIZE}G" -q
|
||||
ok "Disk image created: $VM_DISK"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# VM definition
|
||||
# ---------------------------------------------------------------------------
|
||||
if $VIRSH dominfo "$VM_NAME" &>/dev/null; then
|
||||
warn "VM '$VM_NAME' already defined in libvirt."
|
||||
read -rp " Undefine and recreate? [y/N] " confirm
|
||||
[[ "$confirm" =~ ^[Yy]$ ]] || die "Aborting — existing VM left intact."
|
||||
$VIRSH destroy "$VM_NAME" 2>/dev/null || true
|
||||
$VIRSH undefine "$VM_NAME" --remove-all-storage 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Verify virbr0 is actually up — virtnetworkd may have timed out and torn it down
|
||||
if ! ip link show virbr0 &>/dev/null; then
|
||||
info "virbr0 is gone — restarting default network..."
|
||||
sudo systemctl restart virtnetworkd.service
|
||||
sleep 2
|
||||
$VIRSH net-start default 2>/dev/null || true
|
||||
ip link show virbr0 &>/dev/null || die "virbr0 still missing after restart — check virtnetworkd logs."
|
||||
fi
|
||||
|
||||
OVMF_CODE="/usr/share/edk2/ovmf/OVMF_CODE.fd"
|
||||
OVMF_VARS="/usr/share/edk2/ovmf/OVMF_VARS.fd"
|
||||
|
||||
info "Defining VM '$VM_NAME'..."
|
||||
$VIRT_INSTALL \
|
||||
--name "$VM_NAME" \
|
||||
--ram "$VM_RAM" \
|
||||
--vcpus "$VM_CPUS" \
|
||||
--cpu host-passthrough \
|
||||
--os-variant archlinux \
|
||||
--disk "path=$VM_DISK,format=qcow2,bus=virtio,cache=writeback" \
|
||||
--disk "path=$ARCH_ISO,device=cdrom,readonly=on,bus=sata" \
|
||||
--network network=default,model=virtio \
|
||||
--graphics spice,listen=127.0.0.1 \
|
||||
--video qxl \
|
||||
--boot "loader=${OVMF_CODE},loader.readonly=yes,loader.type=pflash,nvram.template=${OVMF_VARS},cdrom,hd" \
|
||||
--noautoconsole
|
||||
|
||||
ok "VM '$VM_NAME' defined and started"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Get VM IP (may take a moment for DHCP)
|
||||
# ---------------------------------------------------------------------------
|
||||
info "Waiting for VM to get a DHCP address (up to 60s)..."
|
||||
VM_IP=""
|
||||
for i in $(seq 1 12); do
|
||||
sleep 5
|
||||
VM_IP=$($VIRSH domifaddr "$VM_NAME" 2>/dev/null | grep -oP '\d+\.\d+\.\d+\.\d+' | head -1 || true)
|
||||
[[ -n "$VM_IP" ]] && break
|
||||
echo -n "."
|
||||
done
|
||||
echo
|
||||
|
||||
if [[ -n "$VM_IP" ]]; then
|
||||
ok "VM IP address: $VM_IP"
|
||||
else
|
||||
warn "Could not detect VM IP yet — it may still be booting."
|
||||
warn "Run: virsh domifaddr $VM_NAME to check later."
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Summary
|
||||
# ---------------------------------------------------------------------------
|
||||
echo
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo " VM '$VM_NAME' is booting into the Arch Linux live environment."
|
||||
echo
|
||||
echo " Open the console in virt-manager, then run:"
|
||||
echo
|
||||
echo " 1. On your host — serve the config (if not already running):"
|
||||
echo " cd ~/dev/homelab && python3 -m http.server 8080"
|
||||
echo
|
||||
echo " 2. In the VM console — one-liner to fetch config and start install:"
|
||||
echo " curl http://192.168.122.1:8080/scripts/vm-install.sh | bash"
|
||||
echo
|
||||
echo " 3. After install completes, select Reboot."
|
||||
echo " SSH will be available on the installed system:"
|
||||
if [[ -n "$VM_IP" ]]; then
|
||||
echo " ssh -i ~/dev/homelab/keys/homelab_ed25519 adyrem@$VM_IP"
|
||||
fi
|
||||
echo
|
||||
echo " Arch ISO: $ARCH_ISO"
|
||||
echo " Disk image: $VM_DISK"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run this inside the Arch live environment to fetch the config and start archinstall.
|
||||
# Usage: curl http://192.168.122.1:8080/scripts/vm-install.sh | bash
|
||||
set -euo pipefail
|
||||
|
||||
HOST="http://192.168.122.1:8080"
|
||||
|
||||
echo "==> Fetching archinstall config..."
|
||||
curl -fsSL "$HOST/archinstall-config.json" -o /tmp/config.json
|
||||
|
||||
echo "==> Starting archinstall..."
|
||||
archinstall --config /tmp/config.json
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
VM_NAME="arch-base"
|
||||
|
||||
virsh --connect qemu:///system change-media "$VM_NAME" sda --eject 2>/dev/null && echo "ISO ejected" || echo "No ISO to eject"
|
||||
virsh --connect qemu:///system reboot "$VM_NAME"
|
||||
echo "Rebooting $VM_NAME..."
|
||||
Reference in New Issue
Block a user