prvng_platform/scripts/start-provisioning-daemon.sh
Jesús Pérez 93b0e5225c
feat(platform): control plane — NATS JetStream + SurrealDB + SOLID enforcement
New crates
  - platform-nats: async_nats JetStream bridge; pull/push consumers, explicit ACK,
    subject prefixing under provisioning.>, 6 stream definitions on startup
  - platform-db: SurrealDB pool (embedded RocksDB solo, Surreal<Mem> tests,
    WebSocket server multi-user); migrate() with DEFINE TABLE IF NOT EXISTS DDL

  Service integrations
  - orchestrator: NATS pub on task state transitions, execution_logs → SurrealDB,
    webhook handler (HMAC-SHA256), AuditCollector (batch INSERT, 100-event/1s flush)
  - control-center: solo_auth_middleware (intentional bypass, --mode solo only),
    NATS session events, WebSocket bridge via JetStream subscription (no polling)
  - vault-service: NATS lease flow; credentials over HTTPS only (lease_id in NATS);
    SurrealDB storage backend with MVCC retry + exponential backoff
  - secretumvault: complete SurrealDB backend replacing HashMap; 9 unit + 19 integration tests
  - extension-registry: NATS lifecycle events, vault:// credential resolver with TTL cache,
    cache invalidation via provisioning.workspace.*.deploy.done

  Clippy workspace clean
  cargo clippy --workspace -- -D warnings: 0 errors
  Patterns fixed: derivable_impls (#[default] on enum variants), excessive_nesting
  (let-else, boolean arithmetic in retain, extracted helpers), io_error_other,
  redundant_closure, iter_kv_map, manual_range_contains, pathbuf_instead_of_path
2026-02-17 23:58:14 +00:00

193 lines
4.0 KiB
Bash
Executable File

#!/bin/bash
# Provisioning Daemon Management Script
# Controls starting, stopping, and monitoring the provisioning-daemon-cli
DAEMON_PORT=9091
DAEMON_HOST="127.0.0.1"
DAEMON_PID_FILE="/tmp/provisioning-daemon-cli.pid"
DAEMON_LOG_FILE="data/provisioning-daemon-cli.log"
# Find daemon binary
if command -v provisioning-daemon-cli >/dev/null 2>&1; then
DAEMON_BINARY="provisioning-daemon-cli"
elif [ -f "/usr/local/bin/provisioning-daemon-cli" ]; then
DAEMON_BINARY="/usr/local/bin/provisioning-daemon-cli"
elif [ -f "$HOME/.cargo/bin/provisioning-daemon-cli" ]; then
DAEMON_BINARY="$HOME/.cargo/bin/provisioning-daemon-cli"
elif [ -f "($env.HOME | path join "Development/prov-ecosystem/target/release/provisioning-daemon-cli")" ]; then
DAEMON_BINARY="($env.HOME | path join "Development/prov-ecosystem/target/release/provisioning-daemon-cli")"
else
DAEMON_BINARY="provisioning-daemon-cli"
fi
get_pid() {
if [ -f "$DAEMON_PID_FILE" ]; then
tr -d '\n' < "$DAEMON_PID_FILE"
fi
}
is_running() {
local pid=$1
if [ -z "$pid" ]; then
return 1
fi
if ps -p "$pid" > /dev/null 2>&1; then
return 0
else
return 1
fi
}
save_pid() {
local pid=$1
local pid_dir=$(dirname "$DAEMON_PID_FILE")
mkdir -p "$pid_dir"
echo "$pid" > "$DAEMON_PID_FILE"
}
remove_pid() {
rm -f "$DAEMON_PID_FILE"
}
start_daemon() {
local pid=$(get_pid)
if is_running "$pid"; then
echo "✗ Daemon already running (PID: $pid)"
return 1
fi
echo "🚀 Starting provisioning-daemon-cli..."
local log_dir=$(dirname "$DAEMON_LOG_FILE")
mkdir -p "$log_dir"
nohup "$DAEMON_BINARY" --nushell-path ~/.config/provisioning > "$DAEMON_LOG_FILE" 2>&1 &
local daemon_pid=$!
save_pid "$daemon_pid"
sleep 1
if is_running "$daemon_pid"; then
echo "✓ Daemon started successfully (PID: $daemon_pid)"
echo " HTTP API: http://$DAEMON_HOST:$DAEMON_PORT/api/v1"
echo " Nushell: http://$DAEMON_HOST:$DAEMON_PORT/api/v1/execute"
echo " Logs: $DAEMON_LOG_FILE"
return 0
else
echo "✗ Daemon failed to start"
echo " Check logs: $DAEMON_LOG_FILE"
remove_pid
return 1
fi
}
stop_daemon() {
local pid=$(get_pid)
if ! is_running "$pid"; then
echo "✗ Daemon is not running"
return 1
fi
echo "Stopping daemon (PID: $pid)..."
kill "$pid" 2>/dev/null
sleep 0.5
if is_running "$pid"; then
echo "Force killing daemon..."
kill -9 "$pid" 2>/dev/null
fi
remove_pid
echo "✓ Daemon stopped"
return 0
}
status_daemon() {
local pid=$(get_pid)
if ! is_running "$pid"; then
echo "✗ Daemon is not running"
return 1
fi
echo "✓ Daemon is running (PID: $pid)"
echo " HTTP API: http://$DAEMON_HOST:$DAEMON_PORT/api/v1"
echo " Nushell: http://$DAEMON_HOST:$DAEMON_PORT/api/v1/execute"
if command -v curl >/dev/null 2>&1; then
local response=$(curl -s "http://$DAEMON_HOST:$DAEMON_PORT/api/v1/health" 2>/dev/null)
if [ -n "$response" ]; then
echo " Status: $(echo "$response" | grep -o '"status":"[^"]*"' | cut -d'"' -f4)"
fi
fi
return 0
}
logs_daemon() {
if [ ! -f "$DAEMON_LOG_FILE" ]; then
echo "✗ Log file not found: $DAEMON_LOG_FILE"
return 1
fi
tail -n 100 "$DAEMON_LOG_FILE"
}
restart_daemon() {
local pid=$(get_pid)
if is_running "$pid"; then
echo "Stopping daemon..."
stop_daemon
sleep 1
fi
start_daemon
}
help_daemon() {
cat <<EOF
Provisioning Daemon CLI Management
Usage: start-provisioning-daemon.sh <command>
Commands:
start Start the daemon in background
stop Stop the running daemon
status Show daemon status
logs Show daemon logs (last 100 lines)
restart Restart the daemon
help Show this help message
EOF
}
case "${1:-help}" in
start)
start_daemon
;;
stop)
stop_daemon
;;
status)
status_daemon
;;
logs)
logs_daemon
;;
restart)
restart_daemon
;;
help)
help_daemon
;;
*)
echo "Unknown command: $1"
help_daemon
exit 1
;;
esac