chore: bootstrap lean sysadmin-chronicles repo
Import the runnable game code, content, docs, scripts, and repo guidance while leaving local agent state, dependency installs, build output, and backup copies out of the published tree.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
# host-validate.sh — Quest-specific host validation probe.
|
||||
#
|
||||
# Usage: bash host-validate.sh <domain> <quest_id>
|
||||
# Output: JSON to stdout
|
||||
#
|
||||
# This is a supplementary probe. ValidationService uses SSH-based checks
|
||||
# as the authoritative path; this probe provides higher-level summaries
|
||||
# for quests that need them.
|
||||
#
|
||||
# AGENT RULES:
|
||||
# - Read-only. Never modify VM state.
|
||||
# - Output valid JSON always, even on error.
|
||||
# - Quest-specific logic should be minimal — prefer generic rule evaluation.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DOMAIN="${1:-}"
|
||||
QUEST_ID="${2:-}"
|
||||
|
||||
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" ] || [ -z "$QUEST_ID" ]; then
|
||||
echo '{"error": "Usage: host-validate.sh <domain> <quest_id>"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
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", "domain": "'"$DOMAIN"'", "quest_id": "'"$QUEST_ID"'"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
SSH_OPTS="-o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 -i $HOME/.ssh/sc_host_key"
|
||||
SSH="ssh $SSH_OPTS $LOGIN_USER@$VM_IP"
|
||||
|
||||
case "$QUEST_ID" in
|
||||
Q002)
|
||||
# nginx config validity check
|
||||
NGINX_OK=$($SSH "nginx -t 2>&1 | grep -c 'syntax is ok'" 2>/dev/null || echo "0")
|
||||
NGINX_ACTIVE=$($SSH "systemctl is-active nginx 2>/dev/null" || echo "inactive")
|
||||
echo "{\"quest_id\": \"Q002\", \"nginx_config_valid\": $([ "$NGINX_OK" -gt 0 ] && echo true || echo false), \"nginx_state\": \"$NGINX_ACTIVE\"}"
|
||||
;;
|
||||
Q003)
|
||||
# Disk and logrotate check
|
||||
LOG_SIZE=$($SSH "du -sm /var/log/nginx/access.log 2>/dev/null | awk '{print \$1}'" || echo "0")
|
||||
HAS_LOGROTATE=$($SSH "test -f /etc/logrotate.d/nginx && echo true || echo false" 2>/dev/null || echo "false")
|
||||
DISK_PCT=$($SSH "df -P /var/log | tail -1 | awk '{print \$5}'" | tr -d '%' || echo "-1")
|
||||
echo "{\"quest_id\": \"Q003\", \"access_log_size_mb\": $LOG_SIZE, \"logrotate_configured\": $HAS_LOGROTATE, \"disk_usage_pct\": $DISK_PCT}"
|
||||
;;
|
||||
Q004)
|
||||
# Web root ownership check
|
||||
OWNER=$($SSH "stat -c '%U:%G' /var/www/axiomworks 2>/dev/null" || echo "unknown:unknown")
|
||||
echo "{\"quest_id\": \"Q004\", \"webroot_owner\": \"$OWNER\", \"correct\": $([ "$OWNER" = "player:player" ] && echo true || echo false)}"
|
||||
;;
|
||||
*)
|
||||
# Generic state for unknown quests
|
||||
echo "{\"quest_id\": \"$QUEST_ID\", \"domain\": \"$DOMAIN\", \"note\": \"No specific probe for this quest — use generic validation rules\"}"
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user