Improve VM lifecycle tooling
Make spawned VMs easier to use and restore from the host. Add shared DNS and runtime helpers, publish <vm-name>.vm records through mapdns, and teach run/customize/interactive/restore to persist the metadata needed for SSH, DNS cleanup, and clean restores. Seed per-VM /home and /var disks from the rootfs snapshot so package state is present on first boot, add an interactive customization entrypoint plus ssh.sh and human-friendly list output, and let stop/kill/rm operate on multiple VM identifiers. Tear down stale TAP, dm, and loop state when VMs stop so restore can recreate them safely, and validate the updated scripts with bash -n plus targeted dry-run harnesses for teardown and restore paths.
This commit is contained in:
parent
a8078f2393
commit
9191b7e370
11 changed files with 966 additions and 144 deletions
98
dns.sh
Normal file
98
dns.sh
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
MAPDNS_BIN="${MAPDNS_BIN:-mapdns}"
|
||||
MAPDNS_DATA_FILE="/home/thales/.local/share/mapdns/records.json"
|
||||
|
||||
banger_mapdns_cmd() {
|
||||
local subcommand="$1"
|
||||
shift
|
||||
|
||||
"$MAPDNS_BIN" "$subcommand" --data-file "$MAPDNS_DATA_FILE" "$@"
|
||||
}
|
||||
|
||||
banger_dns_name() {
|
||||
local vm_name="$1"
|
||||
printf '%s.vm' "$vm_name"
|
||||
}
|
||||
|
||||
banger_dns_write_record() {
|
||||
local vm_name="$1"
|
||||
local guest_ip="$2"
|
||||
local dns_name
|
||||
|
||||
mkdir -p "$(dirname "$MAPDNS_DATA_FILE")"
|
||||
dns_name="$(banger_dns_name "$vm_name")"
|
||||
banger_mapdns_cmd set "$dns_name" "$guest_ip" >/dev/null
|
||||
}
|
||||
|
||||
banger_dns_record_exists() {
|
||||
local dns_name="$1"
|
||||
|
||||
[[ -n "$dns_name" ]] || return 1
|
||||
banger_mapdns_cmd list | awk '{print $1}' | rg -Fxq "$dns_name"
|
||||
}
|
||||
|
||||
banger_dns_remove_record_name() {
|
||||
local dns_name="${1:-}"
|
||||
[[ -n "$dns_name" ]] || return 0
|
||||
if ! banger_dns_record_exists "$dns_name"; then
|
||||
return 0
|
||||
fi
|
||||
banger_mapdns_cmd rm "$dns_name" >/dev/null
|
||||
}
|
||||
|
||||
banger_vm_process_running() {
|
||||
local pid="$1"
|
||||
local api_sock="$2"
|
||||
|
||||
[[ -n "$pid" && -n "$api_sock" ]] || return 1
|
||||
ps -p "$pid" -o comm=,args= 2>/dev/null | rg -q "firecracker.*--api-sock $api_sock"
|
||||
}
|
||||
|
||||
banger_wait_for_vm_exit() {
|
||||
local pid="$1"
|
||||
local api_sock="$2"
|
||||
local timeout_secs="${3:-30}"
|
||||
local deadline=$((SECONDS + timeout_secs))
|
||||
|
||||
while banger_vm_process_running "$pid" "$api_sock"; do
|
||||
if (( SECONDS >= deadline )); then
|
||||
return 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
}
|
||||
|
||||
banger_teardown_vm_runtime() {
|
||||
local tap="${1:-}"
|
||||
local api_sock="${2:-}"
|
||||
local dm_name="${3:-}"
|
||||
local dm_dev="${4:-}"
|
||||
local cow_loop="${5:-}"
|
||||
local base_loop="${6:-}"
|
||||
|
||||
if [[ -n "$tap" ]]; then
|
||||
sudo ip link del "$tap" 2>/dev/null || true
|
||||
fi
|
||||
if [[ -n "$api_sock" ]]; then
|
||||
rm -f "$api_sock"
|
||||
fi
|
||||
if [[ -n "$dm_name" || -n "$dm_dev" ]]; then
|
||||
sudo dmsetup remove "${dm_name:-$dm_dev}" 2>/dev/null || true
|
||||
fi
|
||||
if [[ -n "$cow_loop" ]]; then
|
||||
sudo losetup -d "$cow_loop" 2>/dev/null || true
|
||||
fi
|
||||
if [[ -n "$base_loop" ]]; then
|
||||
sudo losetup -d "$base_loop" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
banger_mark_vm_stopped() {
|
||||
local vm_json="$1"
|
||||
|
||||
[[ -f "$vm_json" ]] || return 0
|
||||
jq \
|
||||
'del(.meta.pid, .meta.base_loop, .meta.cow_loop, .meta.dm_dev)' \
|
||||
"$vm_json" > "$vm_json.tmp" && mv "$vm_json.tmp" "$vm_json"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue