#!/usr/bin/env bash # collect-state.sh — Collect high-level VM state summary. # # Usage: bash collect-state.sh # Output: JSON to stdout # # This is an advisory probe — output informs the game but is never the # sole basis for quest validation. Host-authoritative checks always win. # # AGENT RULES: # - Read-only. Never modify VM state. # - Always output valid JSON, even on error (use {"error": "..."}). # - Complete within 15 seconds. set -euo pipefail DOMAIN="${1:-}" ssh_login_user() { case "$1" in sc-workstation) printf '%s\n' "opsbridge" ;; *) printf '%s\n' "player" ;; esac } LOGIN_USER="$(ssh_login_user "$DOMAIN")" if [ -z "$DOMAIN" ]; then echo '{"error": "No domain specified"}' exit 0 fi # Get VM IP via guest agent VM_IP=$(virsh domifaddr "$DOMAIN" --source agent 2>/dev/null \ | grep ipv4 | awk '{print $4}' | cut -d/ -f1 | head -1) if [ -z "$VM_IP" ]; then echo '{"error": "Cannot get VM IP — guest agent may not be running", "domain": "'"$DOMAIN"'"}' exit 0 fi SSH_OPTS="-o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 -i $HOME/.ssh/sc_host_key" # Collect state via SSH DISK_USAGE=$(ssh $SSH_OPTS "$LOGIN_USER"@"$VM_IP" "df -P / | tail -1 | awk '{print \$5}'" 2>/dev/null | tr -d '%' || echo "-1") UPTIME=$(ssh $SSH_OPTS "$LOGIN_USER"@"$VM_IP" "cat /proc/uptime | awk '{print int(\$1)}'" 2>/dev/null || echo "0") SERVICES=$(ssh $SSH_OPTS "$LOGIN_USER"@"$VM_IP" "systemctl list-units --state=failed --no-legend --no-pager | wc -l" 2>/dev/null || echo "0") cat << JSON { "domain": "$DOMAIN", "ip": "$VM_IP", "disk_usage_root_pct": $DISK_USAGE, "uptime_seconds": $UPTIME, "failed_service_count": $SERVICES, "collected_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)" } JSON