zioinfo-mail/setup/install_auto.ps1
DESKTOP-TKLFCPR\ython bae659adba feat(setup): Claude Code Desktop 자동 설치 + 30일 라이선스 + 서비스 자동 실행
[Claude Code Desktop 자동 설치 환경]
- setup/CLAUDE.md: 트리거 키워드 + 설치 패키지 설명
- setup/.claude/skills/guardia-install/SKILL.md: 6단계 설치 오케스트레이터
  Phase 0: 의도 파악 → Phase 1: OS 감지 → Phase 2: 사전 확인
  Phase 3: 설치 실행 → Phase 4: 라이선스 발급 → Phase 5: 검증 → Phase 6: 완료보고

[통합 자동 설치 스크립트]
- setup/install_auto.sh: Linux 통합 (OS 자동 감지 ubuntu/centos/rhel)
  - --license trial30|trial7|<key> 파라미터
  - 설치 완료 후 GUARDiA 자동 실행 + 브라우저 자동 열기
  - --test 검증 모드
- setup/install_auto.ps1: Windows 통합 (ASCII 전용, PS 5.1 호환)
  - 설치 후 NSSM 서비스 자동 시작 + 브라우저 자동 열기
  - -Test 파라미터로 검증 전용 실행

[라이선스 엔진 개선]
- core/license.py: generate_trial_key(days=None) 파라미터 추가
- TRIAL_DURATION_DAYS = TRIAL_DURATION_DAYS 환경변수로 조정 가능
- routers/license.py: TrialRequest.days 필드 + 30일 체험판 지원
  POST /api/license/trial {"days": 30} 로 30일 발급

사용자 경험:
  1. setup/ 폴더를 새 PC에 복사
  2. Claude Code Desktop 열고 해당 폴더 open
  3. "GUARDiA 시스템 1달 사용자로 설치해 줘" 입력
  4. 자동으로 OS 감지 → 설치 → 30일 라이선스 → 브라우저 열림

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 09:06:14 +09:00

255 lines
11 KiB
PowerShell

# =============================================================
# GUARDiA ITSM Auto Install Script (Windows)
# Claude Code Desktop auto-invoked
# Usage: PowerShell -ExecutionPolicy Bypass -File install_auto.ps1
#
# Parameters:
# -LicenseType trial30|trial7|<key> (default: trial30)
# -Test : verification only
# -Offline : offline mode
# -SkipOllama : skip Ollama
# -SkipGitea : skip Gitea
# =============================================================
param(
[string]$LicenseType = "trial30",
[switch]$Test = $false,
[switch]$Offline = $false,
[switch]$SkipOllama = $false,
[switch]$SkipGitea = $false
)
$ErrorActionPreference = "Continue"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$LogFile = "C:\guardia_auto_install.log"
$StartTime = Get-Date
function Write-OK { param($m) Write-Host "[OK] $m" -ForegroundColor Green; Add-Content $LogFile "[OK] $m" }
function Write-Warn { param($m) Write-Host "[WARN] $m" -ForegroundColor Yellow; Add-Content $LogFile "[WARN] $m" }
function Write-Fail { param($m) Write-Host "[FAIL] $m" -ForegroundColor Red; Add-Content $LogFile "[FAIL] $m"; exit 1 }
function Write-Info { param($m) Write-Host "[INFO] $m" -ForegroundColor Cyan; Add-Content $LogFile "[INFO] $m" }
function Write-Step { param($m) Write-Host "`n=== $m ===" -ForegroundColor Cyan }
"=== GUARDiA ITSM Auto Install Start: $(Get-Date) ===" | Out-File $LogFile
# ── Admin check ───────────────────────────────────────────────
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)
if (-not $isAdmin -and -not $Test) {
Write-Host "Administrator privileges required." -ForegroundColor Red
Write-Host "Run: Start-Process powershell -Verb RunAs -ArgumentList '-File $($MyInvocation.MyCommand.Path)'"
exit 1
}
# ── Verification mode ─────────────────────────────────────────
function Run-Tests {
Write-Host "=== GUARDiA ITSM Verification ===" -ForegroundColor Cyan
$pass = 0; $fail = 0
function Check-Item {
param($desc, [scriptblock]$cmd)
try {
& $cmd | Out-Null
Write-OK $desc; $script:pass++
} catch {
Write-Host "[FAIL] $desc" -ForegroundColor Red; $script:fail++
}
}
Check-Item "Java 17 (OpenJDK)" { java -version 2>&1 | Select-String "17" }
Check-Item "Python 3.11+" { python --version 2>&1 | Select-String "3\.(1[1-9])" }
Check-Item "GUARDiA service" { Get-Service "guardia-itsm" -ErrorAction Stop }
Check-Item "GUARDiA HTTP" { (Invoke-WebRequest "http://localhost:8001/" -UseBasicParsing -TimeoutSec 5).StatusCode -eq 200 }
Check-Item "GUARDiA login" {
$b = '{"username":"admin","password":"1111"}'
$r = Invoke-WebRequest "http://localhost:8001/api/auth/login" -Method POST -Body $b -ContentType "application/json" -UseBasicParsing -TimeoutSec 5
$r.StatusCode -eq 200
}
if (-not $SkipOllama) {
Check-Item "Ollama API" { (Invoke-WebRequest "http://localhost:11434/api/version" -UseBasicParsing -TimeoutSec 5).StatusCode -eq 200 }
}
if (-not $SkipGitea) {
Check-Item "Gitea HTTP" { (Invoke-WebRequest "http://localhost:3000/api/v1/version" -UseBasicParsing -TimeoutSec 5).StatusCode -eq 200 }
}
Check-Item "License status" { (Invoke-WebRequest "http://localhost:8001/api/license/status" -UseBasicParsing -TimeoutSec 5).StatusCode -eq 200 }
Write-Host ""
Write-Host "Results: Pass $pass / Fail $fail"
if ($fail -eq 0) { Write-OK "All checks passed!" } else { Write-Warn "$fail checks need attention" }
return $fail
}
# ── License issuance ──────────────────────────────────────────
function Issue-License {
param([string]$LicType)
Write-Info "Issuing license: $LicType"
# Wait for GUARDiA
$attempt = 0
while ($true) {
try { $null = Invoke-WebRequest "http://localhost:8001/" -UseBasicParsing -TimeoutSec 3; break } catch {}
Start-Sleep -Seconds 3; $attempt++
if ($attempt -ge 20) { Write-Warn "GUARDiA not responding - manual license required"; return }
}
# Login to get token
$loginBody = '{"username":"admin","password":"1111"}'
$token = ""
try {
$loginResp = Invoke-WebRequest "http://localhost:8001/api/auth/login" -Method POST -Body $loginBody -ContentType "application/json" -UseBasicParsing -TimeoutSec 10
$token = ($loginResp.Content | ConvertFrom-Json).access_token
} catch {
Write-Warn "Login failed - manual license required"
return
}
$authHeader = "Bearer $token"
$jsonHeader = "application/json"
if ($LicType -like "trial*") {
$days = if ($LicType -eq "trial7") { 7 } else { 30 }
$customer = "GUARDiA Trial $days days"
$body = "{`"customer`":`"$customer`",`"days`":$days}"
$trialOk = $false
try {
$resp = Invoke-WebRequest "http://localhost:8001/api/license/trial" -Method POST -Headers @{"Authorization"=$authHeader; "Content-Type"=$jsonHeader} -Body $body -UseBasicParsing -TimeoutSec 30
$data = $resp.Content | ConvertFrom-Json
$expDate = $data.expires_at.Substring(0, 10)
Write-OK "Trial license issued (expires: $expDate)"
$trialOk = $true
# Save to .env
$envPath = Get-ChildItem "C:\GUARDiA\itsm" -Filter ".env" -ErrorAction SilentlyContinue | Select-Object -First 1
if ($envPath -and $trialOk) {
$licKey = $data.license_key
$envContent = Get-Content $envPath.FullName -Raw
if ($envContent -match "GUARDIA_LICENSE_KEY") {
$envContent = $envContent -replace "GUARDIA_LICENSE_KEY=.*", "GUARDIA_LICENSE_KEY=$licKey"
} else {
$envContent = $envContent.TrimEnd() + "`nGUARDIA_LICENSE_KEY=$licKey`n"
}
Set-Content $envPath.FullName -Value $envContent -Encoding UTF8 -NoNewline
Write-OK "License key saved to .env"
}
} catch {
Write-Warn "Trial license failed - may already be used"
Write-Info "Manual: http://[server-ip]/license"
}
} else {
$body = "{`"license_key`":`"$LicType`"}"
try {
$null = Invoke-WebRequest "http://localhost:8001/api/license/activate" -Method POST -Headers @{"Authorization"=$authHeader; "Content-Type"=$jsonHeader} -Body $body -UseBasicParsing -TimeoutSec 30
Write-OK "License registered successfully"
} catch {
Write-Warn "License registration failed"
}
}
}
# ── Auto-start services + open browser ───────────────────────
function Start-GuardiaServices {
Write-Info "Checking GUARDiA services..."
$services = @("guardia-itsm", "tomcat9", "ollama", "redis-server")
foreach ($svc in $services) {
$s = Get-Service $svc -ErrorAction SilentlyContinue
if ($s) {
if ($s.Status -ne "Running") {
try { Start-Service $svc; Write-Info "$svc started" } catch { Write-Warn "$svc failed to start" }
} else {
Write-Info "$svc already running"
}
}
}
# Wait for GUARDiA response (max 60s)
Write-Info "Waiting for GUARDiA response..."
$isUp = $false
for ($i=0; $i -lt 20; $i++) {
Start-Sleep -Seconds 3
try {
$r = Invoke-WebRequest "http://localhost:8001/" -UseBasicParsing -TimeoutSec 3
if ($r.StatusCode -eq 200) { $isUp = $true; break }
} catch {}
}
if ($isUp) {
Write-OK "GUARDiA ITSM is running!"
} else {
Write-Warn "GUARDiA response timeout - check manually"
return
}
# Open browser
$serverIp = ""
$ipResult = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue |
Where-Object { $_.InterfaceAlias -notlike "*Loopback*" -and $_.PrefixOrigin -ne "WellKnown" } |
Select-Object -First 1
if ($ipResult) { $serverIp = $ipResult.IPAddress }
$url = if ($serverIp) { "http://$serverIp" } else { "http://localhost:8001" }
Write-OK "Opening browser: $url"
Start-Process $url
}
# ── Summary ───────────────────────────────────────────────────
function Print-Summary {
$serverIp = ""
$ipResult = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue |
Where-Object { $_.InterfaceAlias -notlike "*Loopback*" -and $_.PrefixOrigin -ne "WellKnown" } |
Select-Object -First 1
if ($ipResult) { $serverIp = $ipResult.IPAddress }
$elapsed = [int](((Get-Date) - $StartTime).TotalMinutes)
$url = if ($serverIp) { "http://$serverIp" } else { "http://localhost:8001" }
Write-Host ""
Write-Host "==================================================" -ForegroundColor Green
Write-Host " GUARDiA ITSM Installation Complete!" -ForegroundColor Green
Write-Host ""
Write-Host " Time: ${elapsed}min"
Write-Host " URL: $url"
Write-Host " Account: admin / 1111"
Write-Host " License: $LicenseType"
Write-Host ""
Write-Host " Next steps:"
Write-Host " 1. Open $url -> login with admin/1111"
Write-Host " 2. Change password"
Write-Host " 3. Register servers in CMDB"
Write-Host ""
Write-Host " Verify: .\install_auto.ps1 -Test"
Write-Host " Log: $LogFile"
Write-Host "==================================================" -ForegroundColor Green
}
# ── Main ──────────────────────────────────────────────────────
if ($Test) {
$fails = Run-Tests
exit $fails
}
Write-Host ""
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host " GUARDiA ITSM Auto Install - Windows" -ForegroundColor Cyan
Write-Host " License: $LicenseType" -ForegroundColor Cyan
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host ""
Write-Step "Windows Installation"
$env:OLLAMA_INSTALL = if ($SkipOllama) { "skip" } else { "online" }
$env:INSTALL_GITEA = if ($SkipGitea) { "false" } else { "true" }
& "$ScriptDir\setup_windows.ps1"
Write-Step "License Issuance"
Issue-License -LicType $LicenseType
Write-Step "Auto Start Services"
Start-GuardiaServices
Write-Step "Installation Verification"
Run-Tests | Out-Null
Write-Step "Installation Complete"
Print-Summary