From 215da79284566cb61cd2a892ddc1140c234bf519 Mon Sep 17 00:00:00 2001 From: bunker-admin Date: Wed, 8 Apr 2026 15:04:38 -0600 Subject: [PATCH] Add register-with-ccp.sh for existing installations Interactive script that configures .env, adds ccp-agent to COMPOSE_PROFILES, and starts the agent container. Supports --ccp-url, --invite-code, --agent-url flags for non-interactive use, and --unregister to remove registration. Bunker Admin --- scripts/register-with-ccp.sh | 208 +++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100755 scripts/register-with-ccp.sh diff --git a/scripts/register-with-ccp.sh b/scripts/register-with-ccp.sh new file mode 100755 index 00000000..871d9884 --- /dev/null +++ b/scripts/register-with-ccp.sh @@ -0,0 +1,208 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ============================================================================= +# Register an existing Changemaker Lite instance with a Control Panel (CCP) +# +# Usage: +# bash scripts/register-with-ccp.sh +# bash scripts/register-with-ccp.sh --ccp-url https://ccp.example.com --invite-code ABCD-1234 --agent-url https://myhost:7443 +# ============================================================================= + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BASE_DIR="$(dirname "$SCRIPT_DIR")" +ENV_FILE="$BASE_DIR/.env" + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +CYAN='\033[0;36m' +YELLOW='\033[1;33m' +BOLD='\033[1m' +NC='\033[0m' + +info() { echo -e "${CYAN}[INFO]${NC} $*"; } +success() { echo -e "${GREEN}[OK]${NC} $*"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +error() { echo -e "${RED}[ERR]${NC} $*" >&2; } + +header() { + echo "" + echo -e "${BOLD}── $* ──${NC}" + echo "" +} + +update_env_var() { + local key=$1 + local value=$2 + if grep -q "^${key}=" "$ENV_FILE"; then + local tmpfile + tmpfile=$(mktemp) + while IFS= read -r line; do + if [[ "$line" =~ ^${key}= ]]; then + echo "${key}=${value}" >> "$tmpfile" + else + echo "$line" >> "$tmpfile" + fi + done < "$ENV_FILE" + mv "$tmpfile" "$ENV_FILE" + else + echo "${key}=${value}" >> "$ENV_FILE" + fi +} + +# --- Parse args --- +CCP_URL="" +INVITE_CODE="" +AGENT_URL="" +UNREGISTER=false + +while [[ $# -gt 0 ]]; do + case "$1" in + --ccp-url) CCP_URL="$2"; shift 2 ;; + --invite-code) INVITE_CODE="$2"; shift 2 ;; + --agent-url) AGENT_URL="$2"; shift 2 ;; + --unregister) UNREGISTER=true; shift ;; + --help|-h) + echo "Usage: bash scripts/register-with-ccp.sh [OPTIONS]" + echo "" + echo "Options:" + echo " --ccp-url URL Control Panel URL (e.g., https://ccp.example.com)" + echo " --invite-code CODE Invite code from CCP admin" + echo " --agent-url URL How the CCP can reach this host (e.g., https://myhost:7443)" + echo " --unregister Remove CCP registration and stop agent" + echo " --help Show this help" + echo "" + echo "If options are omitted, you will be prompted interactively." + exit 0 + ;; + *) + error "Unknown option: $1" + exit 1 + ;; + esac +done + +# --- Verify .env exists --- +if [[ ! -f "$ENV_FILE" ]]; then + error ".env file not found at $ENV_FILE" + error "Run config.sh first to initialize the environment." + exit 1 +fi + +# --- Unregister mode --- +if [[ "$UNREGISTER" == "true" ]]; then + header "Unregister from Control Panel" + + update_env_var "ENABLE_CCP_AGENT" "false" + update_env_var "CCP_URL" "" + update_env_var "CCP_INVITE_CODE" "" + update_env_var "CCP_AGENT_URL" "" + + # Remove ccp-agent from COMPOSE_PROFILES + existing_profiles=$(grep -oP 'COMPOSE_PROFILES=\K.*' "$ENV_FILE" 2>/dev/null || echo "") + new_profiles=$(echo "$existing_profiles" | sed 's/,*ccp-agent//g; s/^,//; s/,$//') + update_env_var "COMPOSE_PROFILES" "$new_profiles" + + # Stop the agent container if running + info "Stopping ccp-agent container..." + cd "$BASE_DIR" + docker compose --profile ccp-agent stop ccp-agent 2>/dev/null || true + docker compose --profile ccp-agent rm -f ccp-agent 2>/dev/null || true + + success "CCP registration removed. Agent stopped." + exit 0 +fi + +# --- Interactive prompts --- +header "Register with Changemaker Control Panel" + +if [[ -z "$CCP_URL" ]]; then + read -rp " Control Panel URL (e.g., https://ccp.example.com): " CCP_URL +fi +if [[ -z "$CCP_URL" ]]; then + error "CCP URL is required." + exit 1 +fi + +if [[ -z "$INVITE_CODE" ]]; then + read -rp " Invite code from CCP admin: " INVITE_CODE +fi +if [[ -z "$INVITE_CODE" ]]; then + error "Invite code is required." + exit 1 +fi + +if [[ -z "$AGENT_URL" ]]; then + echo "" + info "The Agent URL is how the CCP will reach this machine." + info "It must be accessible from the CCP server (e.g., via public IP, VPN, or Pangolin tunnel)." + echo "" + # Try to auto-detect + local_ip=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "") + if [[ -n "$local_ip" ]]; then + info "Detected local IP: $local_ip" + read -rp " Agent URL [https://${local_ip}:7443]: " AGENT_URL + AGENT_URL="${AGENT_URL:-https://${local_ip}:7443}" + else + read -rp " Agent URL (e.g., https://this-host:7443): " AGENT_URL + fi +fi +if [[ -z "$AGENT_URL" ]]; then + error "Agent URL is required." + exit 1 +fi + +# --- Confirm --- +echo "" +info "Configuration:" +echo " CCP URL: $CCP_URL" +echo " Invite Code: $INVITE_CODE" +echo " Agent URL: $AGENT_URL" +echo "" +read -rp "Proceed with registration? (y/n): " confirm +if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then + info "Registration cancelled." + exit 0 +fi + +# --- Update .env --- +header "Updating Configuration" + +update_env_var "ENABLE_CCP_AGENT" "true" +update_env_var "CCP_URL" "$CCP_URL" +update_env_var "CCP_INVITE_CODE" "$INVITE_CODE" +update_env_var "CCP_AGENT_URL" "$AGENT_URL" +success "Environment variables set" + +# Add ccp-agent to compose profiles +existing_profiles=$(grep -oP 'COMPOSE_PROFILES=\K.*' "$ENV_FILE" 2>/dev/null || echo "") +if [[ "$existing_profiles" != *"ccp-agent"* ]]; then + if [[ -n "$existing_profiles" ]]; then + update_env_var "COMPOSE_PROFILES" "${existing_profiles},ccp-agent" + else + update_env_var "COMPOSE_PROFILES" "ccp-agent" + fi + success "Added ccp-agent to COMPOSE_PROFILES" +fi + +# --- Start the agent --- +header "Starting CCP Agent" + +cd "$BASE_DIR" +docker compose --profile ccp-agent up -d ccp-agent +success "CCP Agent container started" + +echo "" +info "The agent is now phoning home to $CCP_URL" +info "It will poll every 30 seconds until the CCP admin approves the registration." +info "" +info "Once approved, the agent will:" +info " 1. Receive mTLS certificates automatically" +info " 2. Restart with secure communication enabled" +info " 3. Begin accepting management commands from the CCP" +echo "" +info "You can monitor the agent with:" +echo " docker compose --profile ccp-agent logs -f ccp-agent" +echo "" +success "Registration initiated! Waiting for CCP admin approval..."