chore: bootstrap lean sysadmin-chronicles repo
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.
This commit is contained in:
Executable
+97
@@ -0,0 +1,97 @@
|
||||
#!/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"
|
||||
}
|
||||
Reference in New Issue
Block a user