#!/bin/bash
set -e
echo "🚀 Starting Cortex Agent Provisioning for node: {{ node_id }}"
# Determine OS and Arch
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
ARCH="$(uname -m)"
if [ "$ARCH" = "x86_64" ]; then
ARCH="amd64"
elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
ARCH="arm64"
fi
if [ "$OS" = "darwin" ]; then
# Currently fallback to python method or generic binary if available
# For now assume arm64 if darwin and M1
if [ "$ARCH" = "amd64" ]; then
BIN_ARCH="darwin_amd64"
else
BIN_ARCH="darwin_arm64"
fi
else
BIN_ARCH="${OS}_${ARCH}"
fi
# 1. Create .cortex/agent-node directory
INSTALL_DIR="$HOME/.cortex/agent-node"
mkdir -p "$INSTALL_DIR"
cd "$INSTALL_DIR"
# 2. Write agent_config.yaml
echo "[*] Writing configuration..."
mkdir -p "$HOME/.cortex"
cat > "$HOME/.cortex/agent.yaml" << 'EOF'
{{ config_yaml }}
EOF
# 3. Download standalone binary or Source fallback
echo "[*] Downloading agent core..."
INSTALLER_URL="{{ base_url }}/api/v1/agent/binary/$BIN_ARCH"
if curl -sSLf "$INSTALLER_URL" -o cortex-agent; then
echo "✅ Downloaded standalone binary for $BIN_ARCH"
chmod +x cortex-agent
BINARY_PATH="$INSTALL_DIR/cortex-agent"
else
echo "⚠️ Standalone binary for $BIN_ARCH was not found (404). Falling back to Source + Venv..."
SOURCE_URL="{{ base_url }}/api/v1/nodes/provision/{{ node_id }}?token={{ invite_token }}"
echo "[*] Downloading bootstrap source installer..."
# Use python to run the legacy bootstrap installer which handles platform-native installs
if ! curl -sSLf "$SOURCE_URL" | python3; then
echo "❌ Provisioning failed via python bootstrap fallback."
exit 1
fi
# If the python script ran correctly, it would have already handled the rest of the install!
echo "✅ Python-based bootstrap provisioning successful!"
exit 0
fi
# 4. Bootstrap daemon installation
BINARY_PATH="$INSTALL_DIR/cortex-agent"
echo "[*] Bootstrapping agent daemon..."
# Run the standalone binary with the install-daemon flags (must implement in main.py)
# Or we can just run it in the background if systemd is unavailable
systemctl --user list-units >/dev/null 2>&1 && HAS_SYSTEMD=true || HAS_SYSTEMD=false
if [ "$OS" = "darwin" ]; then
echo "Installing macOS launchd service..."
AGENTS_DIR="$HOME/Library/LaunchAgents"
mkdir -p "$AGENTS_DIR"
PLIST_PATH="$AGENTS_DIR/com.jerxie.cortex.agent.plist"
cat > "$PLIST_PATH" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.jerxie.cortex.agent</string>
<key>ProgramArguments</key>
<array>
<string>$INSTALL_DIR/cortex-agent</string>
</array>
<key>WorkingDirectory</key>
<string>$INSTALL_DIR</string>
<key>KeepAlive</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>$HOME/.cortex/agent.err.log</string>
<key>StandardOutPath</key>
<string>$HOME/.cortex/agent.out.log</string>
</dict>
</plist>
EOF
launchctl unload "$PLIST_PATH" 2>/dev/null || true
launchctl load "$PLIST_PATH"
echo "✅ macOS launchd daemon successfully started!"
elif [ "$HAS_SYSTEMD" = true ]; then
echo "Installing Linux systemd user service..."
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/cortex-agent.service << EOF
[Unit]
Description=Cortex Agent Node
After=network.target
[Service]
Type=simple
ExecStart=$INSTALL_DIR/cortex-agent
WorkingDirectory=$INSTALL_DIR
Restart=always
RestartSec=5
StandardOutput=append:$HOME/.cortex/agent.out.log
StandardError=append:$HOME/.cortex/agent.err.log
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable cortex-agent
systemctl --user restart cortex-agent
loginctl enable-linger "$USER" 2>/dev/null || true
echo "✅ Systemd Daemon successfully started!"
else
echo "Systemd not available. Falling back to background loop (nohup)..."
nohup ./cortex-agent >> "$HOME/.cortex/agent.out.log" 2>&1 &
echo $! > agent.pid
echo "✅ Background Agent started (PID $!)"
fi
echo "✅ Provisioning complete! Node should be online in the Mesh Dashboard shortly."