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
73
list.sh
73
list.sh
|
|
@ -3,6 +3,67 @@ set -euo pipefail
|
|||
|
||||
shopt -s nullglob
|
||||
|
||||
format_count_unit() {
|
||||
local count="$1"
|
||||
local singular="$2"
|
||||
local plural="$3"
|
||||
|
||||
if (( count == 1 )); then
|
||||
printf '%s %s ago' "$count" "$singular"
|
||||
else
|
||||
printf '%s %s ago' "$count" "$plural"
|
||||
fi
|
||||
}
|
||||
|
||||
humanize_created_at() {
|
||||
local created_at="$1"
|
||||
local created_epoch elapsed
|
||||
|
||||
if [[ -z "$created_at" ]]; then
|
||||
printf '%s' "-"
|
||||
return 0
|
||||
fi
|
||||
|
||||
created_epoch="$(date -d "$created_at" +%s 2>/dev/null || true)"
|
||||
if [[ -z "$created_epoch" ]]; then
|
||||
printf '%s' "$created_at"
|
||||
return 0
|
||||
fi
|
||||
|
||||
elapsed=$((NOW_EPOCH - created_epoch))
|
||||
if (( elapsed < 0 )); then
|
||||
elapsed=0
|
||||
fi
|
||||
|
||||
if (( elapsed < 45 )); then
|
||||
printf '%s' "a few moments ago"
|
||||
elif (( elapsed < 90 )); then
|
||||
printf '%s' "about a minute ago"
|
||||
elif (( elapsed < 3600 )); then
|
||||
format_count_unit "$((elapsed / 60))" "minute" "minutes"
|
||||
elif (( elapsed < 5400 )); then
|
||||
printf '%s' "about an hour ago"
|
||||
elif (( elapsed < 86400 )); then
|
||||
format_count_unit "$((elapsed / 3600))" "hour" "hours"
|
||||
elif (( elapsed < 172800 )); then
|
||||
printf '%s' "1 day ago"
|
||||
elif (( elapsed < 604800 )); then
|
||||
format_count_unit "$((elapsed / 86400))" "day" "days"
|
||||
elif (( elapsed < 1209600 )); then
|
||||
printf '%s' "1 week ago"
|
||||
elif (( elapsed < 2592000 )); then
|
||||
format_count_unit "$((elapsed / 604800))" "week" "weeks"
|
||||
elif (( elapsed < 5184000 )); then
|
||||
printf '%s' "1 month ago"
|
||||
elif (( elapsed < 31536000 )); then
|
||||
format_count_unit "$((elapsed / 2592000))" "month" "months"
|
||||
elif (( elapsed < 63072000 )); then
|
||||
printf '%s' "1 year ago"
|
||||
else
|
||||
format_count_unit "$((elapsed / 31536000))" "year" "years"
|
||||
fi
|
||||
}
|
||||
|
||||
statuses=()
|
||||
ids=()
|
||||
names=()
|
||||
|
|
@ -10,14 +71,17 @@ ips=()
|
|||
created=()
|
||||
max_name=4
|
||||
max_ip=2
|
||||
max_created=7
|
||||
GREEN='\033[32m'
|
||||
YELLOW='\033[33m'
|
||||
RESET='\033[0m'
|
||||
NOW_EPOCH="$(date +%s)"
|
||||
|
||||
for vm_json in state/vms/*/vm.json; do
|
||||
id="$(jq -r '.meta.id // empty' "$vm_json")"
|
||||
name="$(jq -r '.meta.name // empty' "$vm_json")"
|
||||
created_at="$(jq -r '.meta.created_at // empty' "$vm_json")"
|
||||
created_display="$(humanize_created_at "$created_at")"
|
||||
guest_ip="$(jq -r '.meta.guest_ip // empty' "$vm_json")"
|
||||
pid="$(jq -r '.meta.pid // empty' "$vm_json")"
|
||||
api_sock="$(jq -r '.meta.api_sock // empty' "$vm_json")"
|
||||
|
|
@ -34,13 +98,16 @@ for vm_json in state/vms/*/vm.json; do
|
|||
ids+=("$short_id")
|
||||
names+=("$name")
|
||||
ips+=("$guest_ip")
|
||||
created+=("$created_at")
|
||||
created+=("$created_display")
|
||||
if (( ${#name} > max_name )); then
|
||||
max_name=${#name}
|
||||
fi
|
||||
if (( ${#guest_ip} > max_ip )); then
|
||||
max_ip=${#guest_ip}
|
||||
fi
|
||||
if (( ${#created_display} > max_created )); then
|
||||
max_created=${#created_display}
|
||||
fi
|
||||
done
|
||||
|
||||
for i in "${!ids[@]}"; do
|
||||
|
|
@ -48,6 +115,6 @@ for i in "${!ids[@]}"; do
|
|||
if [[ "${statuses[$i]}" == "running" ]]; then
|
||||
color="$GREEN"
|
||||
fi
|
||||
printf '%-10b %-12s %-*s %-*s %s\n' \
|
||||
"${color}[${statuses[$i]}]${RESET}" "${ids[$i]}" "$max_name" "${names[$i]}" "$max_ip" "${ips[$i]}" "${created[$i]}"
|
||||
printf '%-10b %-12s %-*s %-*s %-*s\n' \
|
||||
"${color}[${statuses[$i]}]${RESET}" "${ids[$i]}" "$max_name" "${names[$i]}" "$max_ip" "${ips[$i]}" "$max_created" "${created[$i]}"
|
||||
done
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue