#!/bin/bash
vms_array=""
cts_array=""
# ---------- VMs ----------
readarray -t vm_ids < <(qm list | awk 'NR>1 {print $1}')
# If no VMs are available, vm_ids will be empty
# Collect all snapshots for each VM ID
vm_json_parts=() # Here we store sub-arrays (if the VM has snapshots)
for vm in "${vm_ids[@]}"; do
[[ -z "$vm" ]] && continue
snapshot_list=$(qm listsnapshot "$vm" | grep -v "current" | awk '{$1=""; print $0}' | sed 's/^ *//')
# If no snapshots, skip
[[ -z "$snapshot_list" ]] && continue
# We build a JSON array for this VM, where each element is a JSON object representing a snapshot.
this_vm_snapshots="["
# Parse line by line
first_line=true
while read -r line; do
[[ -z "$line" ]] && continue
# line typically contains: <snapshotName> <YYYY-MM-DD> <HH:MM:SS> <description...>
# We split it:
name=$(awk '{print $1}' <<< "$line" | sed 's/->//g')
date=$(awk '{print $2}' <<< "$line")
time=$(awk '{print $3}' <<< "$line")
desc=$(awk '{$1=""; $2=""; $3=""; print $0}' <<< "$line" | xargs)
[[ -z "$desc" ]] && desc="no-description"
timestamp="$date $time"
# First entry -> no comma, after that always add a comma
if $first_line; then
first_line=false
else
this_vm_snapshots+=","
fi
# Convert into JSON objects
this_vm_snapshots+="{\"vmid\":\"$vm\",\"name\":\"$name\",\"timestamp\":\"$timestamp\",\"description\":\"$desc\"}"
done <<< "$snapshot_list"
this_vm_snapshots+="]" # Close array
# Add this array block to vms_array
vm_json_parts+=( "$this_vm_snapshots" )
done
# Now assemble vm_json_parts into a JSON array
# (Each element of vm_json_parts is already an array, e.g., "[ {...}, {...} ]")
if ((${#vm_json_parts[@]} == 0)); then
# No snapshots found -> empty array
vms_array="[]"
else
# Join with commas
vms_array="["
for (( i=0; i<${#vm_json_parts[@]}; i++ )); do
[[ $i -gt 0 ]] && vms_array+=","
vms_array+="${vm_json_parts[$i]}"
done
vms_array+="]"
fi
# ---------- Containers ----------
readarray -t ct_ids < <(pct list | awk 'NR>1 {print $1}')
ct_json_parts=()
for ct in "${ct_ids[@]}"; do
[[ -z "$ct" ]] && continue
snapshot_list=$(pct listsnapshot "$ct" | grep -v "current" | awk '{$1=""; print $0}' | sed 's/^ *//')
[[ -z "$snapshot_list" ]] && continue
this_ct_snapshots="["
first_line=true
while read -r line; do
[[ -z "$line" ]] && continue
name=$(awk '{print $1}' <<< "$line" | sed 's/->//g')
date=$(awk '{print $2}' <<< "$line")
time=$(awk '{print $3}' <<< "$line")
desc=$(awk '{$1=""; $2=""; $3=""; print $0}' <<< "$line" | xargs)
[[ -z "$desc" ]] && desc="no-description"
timestamp="$date $time"
if $first_line; then
first_line=false
else
this_ct_snapshots+=","
fi
this_ct_snapshots+="{\"ctid\":\"$ct\",\"name\":\"$name\",\"timestamp\":\"$timestamp\",\"description\":\"$desc\"}"
done <<< "$snapshot_list"
this_ct_snapshots+="]"
ct_json_parts+=( "$this_ct_snapshots" )
done
if ((${#ct_json_parts[@]} == 0)); then
cts_array="[]"
else
cts_array="["
for (( i=0; i<${#ct_json_parts[@]}; i++ )); do
[[ $i -gt 0 ]] && cts_array+=","
cts_array+="${ct_json_parts[$i]}"
done
cts_array+="]"
fi
# Assemble final JSON
snapshots_json="{\"vms\":$vms_array,\"containers\":$cts_array}"
echo "$snapshots_json" | jq