0265afa054
Import the runnable game code, content, docs, scripts, and repo guidance while leaving local agent state, dependency installs, build output, and backup copies out of the published tree.
98 lines
2.6 KiB
Bash
Executable File
98 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# VM operations for Sysadmin Chronicles.
|
|
# Source this file; requires lib/libvirt.sh and PROJECT_ROOT set.
|
|
|
|
SC_VM_TOOLS="${SC_VM_TOOLS:-${PROJECT_ROOT:-}/tools/vm}"
|
|
|
|
_sc_validate_snapshot_name() {
|
|
[[ "$1" =~ ^[a-zA-Z0-9][a-zA-Z0-9-]*$ ]]
|
|
}
|
|
|
|
_sc_protected_snapshot() {
|
|
[[ "$1" == baseline.* ]] || [[ "$1" == checkpoint.* ]]
|
|
}
|
|
|
|
vm_build() {
|
|
local profile="$1"
|
|
shift
|
|
local dry_run=false force=false
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--dry-run) dry_run=true ;;
|
|
--force) force=true ;;
|
|
esac
|
|
done
|
|
local script="$SC_VM_TOOLS/build-${profile}.sh"
|
|
[ -f "$script" ] || { echo " ✗ No build script for profile: $profile"; return 1; }
|
|
local args=()
|
|
[ "$dry_run" = true ] && args+=(--dry-run)
|
|
[ "$force" = true ] && args+=(--force)
|
|
bash "$script" "${args[@]}"
|
|
}
|
|
|
|
vm_rebuild() {
|
|
local profile="$1"
|
|
shift
|
|
local dry_run=false
|
|
for arg in "$@"; do [ "$arg" = "--dry-run" ] && dry_run=true; done
|
|
|
|
local domain="sc-${profile}"
|
|
if domain_exists "$domain" && [ "$dry_run" = false ]; then
|
|
virsh destroy "$domain" >/dev/null 2>&1 || true
|
|
virsh undefine "$domain" --nvram --snapshots-metadata >/dev/null 2>&1 \
|
|
|| virsh undefine "$domain" --snapshots-metadata >/dev/null 2>&1 \
|
|
|| virsh undefine "$domain" >/dev/null 2>&1 || true
|
|
fi
|
|
local extra_args=()
|
|
[ "$dry_run" = true ] && extra_args+=(--dry-run)
|
|
vm_build "$profile" "${extra_args[@]}"
|
|
}
|
|
|
|
vm_revert() {
|
|
snapshot_revert "$1" "$2"
|
|
}
|
|
|
|
vm_status() {
|
|
local vm_id="$1"
|
|
domain_exists "$vm_id" && domain_state "$vm_id" || printf 'missing'
|
|
}
|
|
|
|
vm_start() {
|
|
virsh start "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
vm_stop() {
|
|
virsh shutdown "$1" >/dev/null 2>&1 || virsh destroy "$1" >/dev/null 2>&1 || true
|
|
}
|
|
|
|
vm_snapshot_create() {
|
|
local vm_id="$1"
|
|
local name="$2"
|
|
_sc_validate_snapshot_name "$name" \
|
|
|| { echo " ✗ Invalid name (letters, numbers, hyphens only): $name"; return 1; }
|
|
snapshot_create "$vm_id" "$name" "User snapshot — $(date '+%Y-%m-%d %H:%M')"
|
|
}
|
|
|
|
vm_snapshot_list() {
|
|
local vm_id="$1"
|
|
virsh snapshot-list "$vm_id" 2>/dev/null || true
|
|
}
|
|
|
|
vm_snapshot_revert() {
|
|
local vm_id="$1"
|
|
local name="$2"
|
|
snapshot_exists "$vm_id" "$name" \
|
|
|| { echo " ✗ Snapshot not found: $name"; return 1; }
|
|
snapshot_revert "$vm_id" "$name"
|
|
}
|
|
|
|
vm_snapshot_delete() {
|
|
local vm_id="$1"
|
|
local name="$2"
|
|
if _sc_protected_snapshot "$name"; then
|
|
echo " ✗ Cannot delete protected snapshot: $name"
|
|
return 1
|
|
fi
|
|
snapshot_delete "$vm_id" "$name"
|
|
}
|