Repository navigation
Expand file tree
/
Copy pathinstall.ps1
More file actions
224 lines (207 loc) · 9.28 KB
/
Copy pathinstall.ps1
File metadata and controls
224 lines (207 loc) · 9.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# ======================================================================
# KiroCrew — Windows setup (cloud mode)
# ======================================================================
# This is the CLOUD path: Kiro Crew runs on an EC2 Linux instance in YOUR OWN
# AWS account and this machine is the thin client. Use it when you want the
# gateway always-on and off your laptop.
#
# It is NOT the only Windows option. Kiro Crew also builds and runs natively
# on Windows from source (`.\make.ps1 build`, then `kirocrew gateway`) — see
# docs/guides/windows-install.md, which is the supported default and covers
# the per-feature limits.
#
# This script only ensures the client prerequisites — Python, the AWS CLI,
# and the SSM Session Manager plugin — then hands off to the Python launcher
# wizard (`kirocrew cloud launch`).
#
# It NEVER stores AWS credentials: the aws CLI resolves them from your
# configured profile/SSO.
#
# Usage (from a clone): powershell -ExecutionPolicy Bypass -File install.ps1
# Options:
# -NonInteractive Do not launch the wizard; just install prerequisites.
# -Size <tier> Pass a size tier straight through (light|balanced|power).
# ======================================================================
[CmdletBinding()]
param(
[switch]$NonInteractive,
[string]$Size = ""
)
$ErrorActionPreference = "Stop"
function Write-Step($n, $total, $msg) { Write-Host ""; Write-Host (" [{0}/{1}] {2}" -f $n, $total, $msg) -ForegroundColor Cyan }
function Write-Ok($msg) { Write-Host " [ok] $msg" -ForegroundColor Green }
function Write-Warn($msg) { Write-Host " [!] $msg" -ForegroundColor Yellow }
function Write-Info($msg) { Write-Host " -> $msg" -ForegroundColor Gray }
function Have($cmd) { return [bool](Get-Command $cmd -ErrorAction SilentlyContinue) }
# Emulation-invariant architecture detection: %PROCESSOR_ARCHITECTURE% lies
# under WOW64 / Prism emulation, so read the CIM processor architecture.
function Get-RealArch {
try {
$arch = (Get-CimInstance Win32_Processor | Select-Object -First 1).Architecture
switch ($arch) { 12 { return "arm64" } 9 { return "x86_64" } default { return "x86_64" } }
} catch { return "x86_64" }
}
# Pinned AWS CLI / SSM plugin versions and their sha256: the same KEY=VALUE
# file cloud-install.sh sources (packaging/pins/aws-tools.env).
function Read-ToolPins {
$pins = @{}
$path = Join-Path $PSScriptRoot "packaging\pins\aws-tools.env"
foreach ($line in Get-Content -LiteralPath $path) {
if ($line -match '^\s*([A-Z0-9_]+)=(\S+)\s*$') { $pins[$Matches[1]] = $Matches[2] }
}
return $pins
}
# Download $Uri to $OutFile and keep it only if its sha256 is $Sha256.
# Returns $false (file removed) on a failed download or a mismatch, so the
# caller installs nothing.
function Get-VerifiedFile($Uri, $OutFile, $Sha256) {
try {
Invoke-WebRequest -Uri $Uri -OutFile $OutFile -UseBasicParsing
} catch {
Write-Warn "Download failed: $Uri"
Remove-Item $OutFile -ErrorAction SilentlyContinue
return $false
}
$got = (Get-FileHash -LiteralPath $OutFile -Algorithm SHA256).Hash.ToLowerInvariant()
if ($got -ne $Sha256.ToLowerInvariant()) {
Write-Warn "Checksum mismatch for $Uri - not installing"
Remove-Item $OutFile -ErrorAction SilentlyContinue
return $false
}
return $true
}
function Ensure-WingetOrChoco {
if (Have "winget") { return "winget" }
if (Have "choco") { return "choco" }
return ""
}
Write-Host ""
Write-Host " KiroCrew — Windows setup (cloud mode)" -ForegroundColor Magenta
Write-Host " Runs KiroCrew on your own AWS EC2; this PC is the client." -ForegroundColor DarkGray
Write-Host " For a native local install instead: .\make.ps1 build" -ForegroundColor DarkGray
$arch = Get-RealArch
Write-Info "Detected architecture: $arch"
$toolPins = Read-ToolPins
$pm = Ensure-WingetOrChoco
# --- 1. Python -------------------------------------------------------------
Write-Step 1 4 "Python"
# Version-gated, not a bare existence check: the package declares
# requires-python >= 3.12, so a 3.10/3.11 already on PATH would pass an
# existence test here and then be refused by pip at step 4 -- after the AWS CLI
# and the SSM plugin had already been installed. Resolve the interpreter ONCE
# and use that same command for every later python call.
function Resolve-Python312 {
foreach ($candidate in @("python3.12", "python", "python3")) {
if (-not (Have $candidate)) { continue }
& $candidate -c "import sys; sys.exit(0 if sys.version_info >= (3, 12) else 1)" *> $null
if ($LASTEXITCODE -eq 0) { return $candidate }
}
return $null
}
$PyExe = Resolve-Python312
if ($PyExe) {
Write-Ok ("python found ({0})" -f (& $PyExe --version 2>&1))
} else {
if ($pm -eq "winget") {
Write-Info "Installing Python 3.12 via winget..."
winget install -e --id Python.Python.3.12 --accept-source-agreements --accept-package-agreements
} elseif ($pm -eq "choco") {
Write-Info "Installing Python 3.12 via choco..."
choco install -y python312
} else {
Write-Warn "No package manager found. Install Python 3.12+ from https://python.org and re-run."
exit 1
}
$PyExe = Resolve-Python312
if (-not $PyExe) {
Write-Warn "Python 3.12+ still not on PATH - restart the shell and re-run this installer."
exit 1
}
Write-Ok ("Python installed ({0})" -f (& $PyExe --version 2>&1))
}
# --- 2. AWS CLI ------------------------------------------------------------
Write-Step 2 4 "AWS CLI"
if (Have "aws") {
Write-Ok ("aws found ({0})" -f (aws --version 2>&1))
} else {
Write-Info "Installing the AWS CLI v2 (MSI)..."
$msi = Join-Path $env:TEMP "AWSCLIV2.msi"
$awsUrl = "https://awscli.amazonaws.com/AWSCLIV2-{0}.msi" -f $toolPins["AWSCLI_VERSION"]
if (Get-VerifiedFile $awsUrl $msi $toolPins["AWSCLI_SHA256_WINDOWS_MSI"]) {
Start-Process msiexec.exe -Wait -ArgumentList "/i `"$msi`" /qn"
Remove-Item $msi -ErrorAction SilentlyContinue
if (Have "aws") { Write-Ok "aws CLI installed" } else { Write-Warn "aws CLI installed; restart the shell so it lands on PATH" }
} else {
Write-Warn "aws CLI not installed - see https://aws.amazon.com/cli/"
}
}
# --- 3. SSM Session Manager plugin ----------------------------------------
Write-Step 3 4 "SSM Session Manager plugin"
if (Have "session-manager-plugin") {
Write-Ok "session-manager-plugin found"
} else {
Write-Info "Installing the SSM Session Manager plugin..."
$ssmMsi = Join-Path $env:TEMP "SessionManagerPluginSetup.exe"
$ssmUrl = "https://session-manager-downloads.s3.amazonaws.com/plugin/{0}/windows/SessionManagerPluginSetup.exe" -f $toolPins["SSM_PLUGIN_VERSION"]
if (Get-VerifiedFile $ssmUrl $ssmMsi $toolPins["SSM_SHA256_WINDOWS_EXE"]) {
Start-Process $ssmMsi -Wait -ArgumentList "/quiet"
Remove-Item $ssmMsi -ErrorAction SilentlyContinue
Write-Ok "session-manager-plugin installed (restart the shell if not yet on PATH)"
} else {
Write-Warn "SSM plugin not installed (needed to connect) - see the AWS Session Manager docs"
}
}
# --- 4. KiroCrew client + launch ------------------------------------------
Write-Step 4 4 "KiroCrew client"
$repoRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
Push-Location $repoRoot
try {
Write-Info "Installing the Kiro Crew client (pip)..."
& $PyExe -m pip install --upgrade pip *> $null
$env:KIROCREW_SKIP_FRONTEND = "1"
& $PyExe -m pip install -e . 2>&1 | Select-Object -Last 5
# PowerShell has no `set -e`: a failed pip install would otherwise fall
# through to a misleading "installed" + a launch that dies opaquely. Check
# the exit code and fail closed, matching cloud-install.sh's behavior.
if ($LASTEXITCODE -ne 0) {
# `finally` below runs Pop-Location before the process exits.
Write-Warn "pip install failed (exit $LASTEXITCODE) - fix the error above, then re-run this installer."
exit 1
}
Write-Ok "KiroCrew client installed"
} finally {
Pop-Location
}
if (-not (Have "aws")) {
Write-Warn "Restart your terminal so aws / session-manager-plugin are on PATH, then run: kirocrew cloud launch"
exit 0
}
if (-not (Have "session-manager-plugin")) {
# Freshly installed above, but not yet on this shell's PATH — launching now
# would get through provisioning and then fail at the tunnel step.
Write-Warn "session-manager-plugin is not on PATH yet. Restart your terminal, then run: kirocrew cloud launch"
exit 0
}
# Check AWS is configured before launching.
$identity = ""
try { $identity = (aws sts get-caller-identity --output text 2>$null) } catch {}
if (-not $identity) {
Write-Warn "AWS credentials aren't configured yet."
Write-Info "Run one of:"
Write-Info " aws configure sso (recommended)"
Write-Info " aws configure (access keys)"
Write-Info "Then run: kirocrew cloud launch"
exit 0
}
Write-Ok "AWS credentials resolve."
if ($NonInteractive) {
Write-Info "Prerequisites ready. Launch when you're set: kirocrew cloud launch"
exit 0
}
Write-Host ""
Write-Host " Launching KiroCrew on AWS..." -ForegroundColor Cyan
if ($Size -ne "") {
& $PyExe -m kiro_crew cloud launch --size $Size
} else {
& $PyExe -m kiro_crew cloud launch
}