banger/dns.sh
Thales Maciel 9191b7e370
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.
2026-03-15 17:48:47 -03:00

98 lines
2.2 KiB
Bash

#!/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"
}