#!/bin/bash set -uo pipefail # all_status.sh - Get status and ports for all services on this server # # Usage: all_status.sh [EXPECTED_AGENT_HASH] # # Output: JSON object with status and ports for each service # { # "agent_hash": "hash-of-remote-agent", # "agent_match": true|false, # "services": [ # { # "name": "service-name", # "status": "Running|Stopped|Error|Unknown", # "ports": "port output or empty" # }, # ... # ] # } # -- Determine paths -- SCRIPT_PATH="$(readlink -f "${BASH_SOURCE[0]}")" AGENT_PATH="$(dirname "${SCRIPT_PATH}")" DROPSHELL_DIR="$(dirname "${AGENT_PATH}")" SERVICES_DIR="${DROPSHELL_DIR}/services" # -- Get agent hash -- EXPECTED_HASH="${1:-}" LOCAL_HASH="" AGENT_MATCH="true" if [[ -f "${AGENT_PATH}/agent.hash" ]]; then LOCAL_HASH=$(cat "${AGENT_PATH}/agent.hash" | tr -d '[:space:]') fi if [[ -n "${EXPECTED_HASH}" && "${LOCAL_HASH}" != "${EXPECTED_HASH}" ]]; then AGENT_MATCH="false" fi # -- Helper to escape JSON strings -- json_escape() { local str="$1" # Escape backslashes, quotes, and control characters str="${str//\\/\\\\}" str="${str//\"/\\\"}" str="${str//$'\n'/\\n}" str="${str//$'\r'/\\r}" str="${str//$'\t'/\\t}" echo -n "$str" } # -- Start JSON output -- echo -n '{"agent_hash":"' json_escape "$LOCAL_HASH" echo -n '","agent_match":' echo -n "$AGENT_MATCH" echo -n ',"services":[' first=true # -- Check if services directory exists -- if [[ -d "${SERVICES_DIR}" ]]; then # Iterate through all service directories for service_dir in "${SERVICES_DIR}"/*/; do # Skip if no directories found (glob returned literal) [[ -d "$service_dir" ]] || continue service_name="$(basename "$service_dir")" # Skip if no config directory (not a valid service) [[ -d "${service_dir}config" ]] || continue # Get template path template_path="${service_dir}template" # -- Get status -- status="Unknown" if [[ -f "${template_path}/status.sh" ]] || [[ -f "${template_path}/status" ]]; then # Run status via ds_run.sh, capture output status_output=$("${AGENT_PATH}/ds_run.sh" "$service_name" "status" 2>/dev/null) || true # Take first line, trim whitespace status=$(echo "$status_output" | head -n1 | tr -d '[:space:]') # Validate status value case "$status" in Running|Stopped|Error|Unknown) ;; *) status="Unknown" ;; esac fi # -- Get ports -- ports="" if [[ -f "${template_path}/ports.sh" ]] || [[ -f "${template_path}/ports" ]]; then # Run ports via ds_run.sh, capture output ports_output=$("${AGENT_PATH}/ds_run.sh" "$service_name" "ports" 2>/dev/null) || true ports="$ports_output" fi # -- Output JSON for this service -- if [[ "$first" == "true" ]]; then first=false else echo -n ',' fi echo -n '{"name":"' json_escape "$service_name" echo -n '","status":"' json_escape "$status" echo -n '","ports":"' json_escape "$ports" echo -n '"}' done fi echo ']}'