Newer
Older
cortex-hub / agent-node / bootstrap_windows.ps1
param (
    [string]$NodeId = "",
    [string]$AuthToken = "",
    [string]$HubUrl = "",
    [string]$GrpcUrl = ""
)

$ErrorActionPreference = "Stop"

Write-Host "==========================================" -ForegroundColor Cyan
Write-Host "   CORTEX AGENT WINDOWS BOOTSTRAP        " -ForegroundColor Cyan
Write-Host "==========================================" -ForegroundColor Cyan

# 1. Check Python installation (defensively avoid Microsoft Store alias)
$pythonValid = $false
try {
    $out = python --version 2>&1
    if ($out -like "*Python *") { $pythonValid = $true }
} catch { }

if (!$pythonValid) {
    Write-Host "[!] Python not found or invalid. Installing via winget..." -ForegroundColor Yellow
    winget install -e --id Python.Python.3.12 --accept-package-agreements --accept-source-agreements
    # Refresh PATH
    $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
}

# 2. Verify Python version
$pyVer = python --version
Write-Host "[*] Found $pyVer"

# 3. Create working directory
$workDir = "C:\CortexAgent"
if (!(Test-Path $workDir)) {
    New-Item -ItemType Directory -Path $workDir
}
Set-Location $workDir

# 4. Download agent code from Hub (Matching Linux pattern)
if ((-not $HubUrl) -or (-not $AuthToken)) {
    Write-Host "[!] Hub details missing. Will prompt for them later after basic setup." -ForegroundColor Yellow
} else {
    Write-Host "[*] Fetching agent source from Hub..." -ForegroundColor Cyan
    $baseUrl = $HubUrl.Split(":")[0]
    if ($HubUrl.Contains("http")) {
        $downloadUrl = "$HubUrl/api/v1/agent/download"
    } else {
        $downloadUrl = "http://$baseUrl:8002/api/v1/agent/download"
    }

    $tarPath = Join-Path $workDir "agent.tar.gz"
    $headers = @{"X-Agent-Token" = $AuthToken}
    
    try {
        Invoke-WebRequest -Uri $downloadUrl -Headers $headers -OutFile $tarPath
        Write-Host "[+] Download complete. Extracting..." -ForegroundColor Green
        
        # Windows 10+ has tar.exe built-in. Fallback to Expand-Archive if needed.
        if (Get-Command tar -ErrorAction SilentlyContinue) {
            tar -xzf $tarPath --strip-components=1
        } else {
            Write-Warning "tar.exe not found. Attempting Expand-Archive (may not support tar.gz natively without 7-Zip/etc)."
            # Note: PowerShell's Expand-Archive usually only likes .zip. 
            # We recommend users have tar or we provide a zip endpoint.
        }
        Remove-Item $tarPath
    } catch {
        Write-Warning "Failed to download code directly: $_"
        Write-Host "[!] Please ensure agent-node source is manually placed at $workDir" -ForegroundColor Yellow
    }
}

# 5. Setup Virtual Environment
Write-Host "[*] Creating Virtual Environment..."
python -m venv venv
.\venv\Scripts\Activate.ps1

# 6. Install Dependencies
Write-Host "[*] Installing Dependencies..."
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip install pywinpty pypiwin32  # Windows-specific requirements

# 7. Environment Setup
Write-Host "------------------------------------------"
Write-Host " Enter Agent Configuration Details:"

if (-not $NodeId) { $NodeId = Read-Host " AGENT_NODE_ID (e.g. pc-node-1)" }
if (-not $AuthToken) { $AuthToken = Read-Host " AGENT_AUTH_TOKEN" }
if (-not $HubUrl) { $HubUrl = Read-Host " HUB_URL (e.g. http://192.168.68.140:8002)" }
if (-not $GrpcUrl) { $GrpcUrl = Read-Host " GRPC_ENDPOINT (e.g. 192.168.68.140:50051)" }

$envFile = @"
AGENT_NODE_ID=$NodeId
AGENT_AUTH_TOKEN=$AuthToken
AGENT_HUB_URL=$HubUrl
GRPC_ENDPOINT=$GrpcUrl
AGENT_TLS_ENABLED=false
PYTHONUTF8=1
"@
$envFile | Out-File -FilePath ".env" -Encoding ascii

# 8. Test Execution
Write-Host "[*] Bootstrap complete. You can now run the agent with:" -ForegroundColor Green
Write-Host "    .\venv\Scripts\python.exe src\agent_node\main.py" -ForegroundColor Yellow

# 9. Optional Service Registration
$installService = Read-Host "Would you like to register this as a startup task? (y/n)"
if ($installService -eq "y") {
    Write-Host "[*] Registering Scheduled Task..."
    python install_service.py --name "CortexAgent" --run
}

# 10. Security & Firewall Check
Write-Host "------------------------------------------"
Write-Host "[*] Checking Windows Firewall status..." -ForegroundColor Cyan
$profiles = Get-NetFirewallProfile
$disabled = $profiles | Where-Object { $_.Enabled -eq "False" }

if ($disabled) {
    Write-Host "[!] Warning: One or more Firewall profiles are DISABLED." -ForegroundColor Yellow
    $enable = Read-Host "Would you like to ENABLE the Windows Firewall now? (y/n)"
    if ($enable -eq "y") {
        Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
        Write-Host "[+] Windows Firewall enabled." -ForegroundColor Green
    }
}

# Add rule for Python communication
Write-Host "[*] Adding firewall exception for agent communication..."
$pythonPath = (Get-Command python).Source
if ($pythonPath) {
    New-NetFirewallRule -DisplayName "Cortex Agent Communication" -Direction Outbound -Program $pythonPath -Action Allow -Description "Allows Cortex Agent to reach the Hub" -ErrorAction SilentlyContinue
    New-NetFirewallRule -DisplayName "Cortex Agent Communication" -Direction Inbound -Program $pythonPath -Action Allow -Description "Allows Cortex Agent Mesh Communication" -Profile Any -ErrorAction SilentlyContinue
}

Write-Host "=========================================="
Write-Host "   DONE! Check the Hub for node status.  " -ForegroundColor Cyan
Write-Host "=========================================="