@cocorograph/hub-agent 0.6.71 → 0.6.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,6 +22,26 @@ curl -fsSL https://api.hub.cocorograph.com/api/cockpit/agents/install-script | b
22
22
  - `hub-agent enroll <token>` (token は Hub session 経由で埋め込み済、5 分有効)
23
23
  - `hub-agent install-service` で OS サービス登録
24
24
 
25
+ ### Windows (WSL2 方式)
26
+
27
+ Windows では WSL2 (Ubuntu) の中で hub-agent を動かします。Cockpit Agents ページで
28
+ OS を Windows に切り替えると **管理者 PowerShell 用ワンライナー**が表示されるので、
29
+ **管理者として実行した PowerShell** にコピペします:
30
+
31
+ ```powershell
32
+ $env:HUB_AGENT_TOKEN="<tok>"; $env:HUB_AGENT_URL="https://api.hub.cocorograph.com"; `
33
+ irm https://unpkg.com/@cocorograph/hub-agent@latest/scripts/install.ps1 | iex
34
+ ```
35
+
36
+ このスクリプトは WSL2 (`Ubuntu-24.04`) を導入 (要再起動 1 回・再起動後に自動再開)、
37
+ Ubuntu 初回ユーザーを無人作成 (Windows と同名 / パスワードなし / NOPASSWD sudo)、
38
+ WSL 内で既存 `install.sh` を実行、Task Scheduler でログオン時の常駐起動を登録します。
39
+
40
+ > ⚠️ 作業リポジトリは **WSL 内 FS** (`/home/<user>/...`) に置いてください。Windows ドライブ
41
+ > (`/mnt/c/...`) はファイル監視 (inotify) が WSL 跨ぎで不安定です。
42
+
43
+ 詳細・設計判断は `scripts/install.ps1` と `docs/windows-installer-design.md` を参照。
44
+
25
45
  ### 手動インストール (デバッグ用)
26
46
 
27
47
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocorograph/hub-agent",
3
- "version": "0.6.71",
3
+ "version": "0.6.72",
4
4
  "description": "Hub Hosted Cockpit のローカル常駐 agent。Hub と outbound WSS で接続し、ローカルの tmux/pty を中継する。",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -0,0 +1,260 @@
1
+ # =============================================================================
2
+ # hub-agent Windows ワンライナーインストーラ (WSL2 方式)
3
+ #
4
+ # Hub UI が enrollment token + hub url を埋め込んだ PowerShell one-liner を表示し、
5
+ # ユーザーが「管理者 PowerShell」にコピペ実行する。bash 版 install.sh の Windows 版。
6
+ #
7
+ # 設計書: D00000_hub-agent/docs/windows-installer-design.md
8
+ # 方針判断: Hub ナレッジ `ナレッジ/Cockpit/Windows対応の設計判断` (id 7385)
9
+ #
10
+ # 単独使用 (token なし):
11
+ # irm https://unpkg.com/@cocorograph/hub-agent@latest/scripts/install.ps1 | iex
12
+ #
13
+ # Hub UI が生成する形 (token/url 埋め込み):
14
+ # $env:HUB_AGENT_TOKEN="<tok>"; $env:HUB_AGENT_URL="https://api.hub.cocorograph.com"; `
15
+ # irm https://unpkg.com/@cocorograph/hub-agent@latest/scripts/install.ps1 | iex
16
+ #
17
+ # 内容:
18
+ # フェーズ1: WSL2 導入 (管理者必須・再起動またぎを RunOnce で吸収)
19
+ # 再起動後 : Ubuntu 初回ユーザーを無人作成 (cloud-init → root install フォールバック)
20
+ # フェーズ2: WSL の中で既存 install.sh を呼ぶ (tmux/node/hub-agent/claude/enroll)
21
+ # 常駐化 : Task Scheduler のログオンタスクで distro を起こす (中の systemd が hub-agent を起動)
22
+ # =============================================================================
23
+
24
+ #Requires -Version 5.1
25
+ $ErrorActionPreference = "Stop"
26
+
27
+ # --- 定数 -------------------------------------------------------------------
28
+ # distro は LTS 固定 (将来の非互換回避)。launcher 実行ファイル名も distro に対応して固定。
29
+ $DISTRO = "Ubuntu-24.04"
30
+ $LAUNCHER = "ubuntu2404.exe"
31
+ $INSTALL_SH = "https://unpkg.com/@cocorograph/hub-agent@latest/scripts/install.sh"
32
+ $PS1_URL = "https://unpkg.com/@cocorograph/hub-agent@latest/scripts/install.ps1"
33
+ $RUNONCE_NAME = "HubAgentSetup"
34
+ $TASK_NAME = "HubAgentWSLBoot"
35
+ $DEFAULT_HUB = "https://api.hub.cocorograph.com"
36
+
37
+ # --- env からパラメータ取得 -------------------------------------------------
38
+ $Token = $env:HUB_AGENT_TOKEN
39
+ $HubUrl = if ($env:HUB_AGENT_URL) { $env:HUB_AGENT_URL } else { $DEFAULT_HUB }
40
+ $IsResume = ($env:HUB_AGENT_RESUME -eq "1") # 再起動後の RunOnce 自動再開フラグ
41
+
42
+ # --- カラーログ -------------------------------------------------------------
43
+ function Write-Step($m) { Write-Host "==> $m" -ForegroundColor Cyan }
44
+ function Write-Ok($m) { Write-Host "[OK] $m" -ForegroundColor Green }
45
+ function Write-Warn($m) { Write-Host "[!] $m" -ForegroundColor Yellow }
46
+ function Write-Err($m) { Write-Host "[x] $m" -ForegroundColor Red }
47
+
48
+ # --- ヘルパー ---------------------------------------------------------------
49
+ function Test-IsAdmin {
50
+ $id = [Security.Principal.WindowsIdentity]::GetCurrent()
51
+ $pr = New-Object Security.Principal.WindowsPrincipal($id)
52
+ return $pr.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
53
+ }
54
+
55
+ # wsl -l -q は UTF-16LE + NUL 混じりで出すため、サニタイズして配列化する。
56
+ function Get-WslDistros {
57
+ try {
58
+ $raw = (wsl.exe -l -q) 2>$null
59
+ if (-not $raw) { return @() }
60
+ return ($raw -replace "`0", "") -split "`r?`n" | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne "" }
61
+ } catch { return @() }
62
+ }
63
+
64
+ function Test-DistroExists { return (Get-WslDistros) -contains $DISTRO }
65
+
66
+ # WSL 機能そのもの (カーネル + プラットフォーム) が使える状態か。
67
+ function Test-WslReady {
68
+ try { wsl.exe --status *> $null; return ($LASTEXITCODE -eq 0) } catch { return $false }
69
+ }
70
+
71
+ # distro 内に対象ユーザーが存在するか (無人作成の冪等チェック)。
72
+ function Test-WslUserReady($user) {
73
+ if (-not $user) { return $false }
74
+ try { wsl.exe -d $DISTRO -u root -- id $user *> $null; return ($LASTEXITCODE -eq 0) } catch { return $false }
75
+ }
76
+
77
+ # Windows ユーザー名を Linux 命名規則にサニタイズ ([a-z_][a-z0-9_-]*)。
78
+ function Get-LinuxUserName {
79
+ $u = ($env:USERNAME).ToLower() -replace '[^a-z0-9_-]', ''
80
+ if ($u -eq '' -or $u -match '^[0-9]') { $u = "hub$u" }
81
+ return $u
82
+ }
83
+
84
+ # RunOnce に「再起動後に自身を RESUME=1 で再実行」を仕込む。token/url を引き継ぐ。
85
+ function Set-ResumeOnReboot {
86
+ $cmd = "powershell -NoProfile -ExecutionPolicy Bypass -Command " +
87
+ "`"`$env:HUB_AGENT_TOKEN='$Token'; `$env:HUB_AGENT_URL='$HubUrl'; " +
88
+ "`$env:HUB_AGENT_RESUME='1'; irm $PS1_URL | iex`""
89
+ Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce" `
90
+ -Name $RUNONCE_NAME -Value $cmd
91
+ }
92
+
93
+ # 再起動はユーザーに委ねる (自動実行はデータ保全リスク)。RunOnce 登録済なので「あとで」でも自動再開。
94
+ function Prompt-RebootDecision {
95
+ Write-Host ""
96
+ Write-Step "WSL2 を導入しました。続行には Windows の再起動が必要です。"
97
+ Write-Host " 再起動後、セットアップは自動で続行します (手動操作は不要)。" -ForegroundColor Cyan
98
+ $ans = Read-Host "今すぐ再起動しますか? [Y=今すぐ / N=あとで自分で再起動]"
99
+ if ($ans -match '^[Yy]') {
100
+ Restart-Computer
101
+ } else {
102
+ Write-Warn "あとで Windows を再起動すると、セットアップが自動で続きます。"
103
+ }
104
+ }
105
+
106
+ # cloud-init 用 user-data を「初回起動前」に配置する。
107
+ # %USERPROFILE%\.cloud-init\<DistroName>.user-data に置くと初回起動で OOBE 無しに反映される。
108
+ function Write-CloudInit($user) {
109
+ $ciDir = Join-Path $env:USERPROFILE ".cloud-init"
110
+ New-Item -ItemType Directory -Force -Path $ciDir | Out-Null
111
+ $yaml = @"
112
+ #cloud-config
113
+ users:
114
+ - name: $user
115
+ groups: [sudo]
116
+ shell: /bin/bash
117
+ sudo: ['ALL=(ALL) NOPASSWD:ALL']
118
+ lock_passwd: true
119
+ write_files:
120
+ - path: /etc/wsl.conf
121
+ content: |
122
+ [user]
123
+ default=$user
124
+ [boot]
125
+ systemd=true
126
+ "@
127
+ # WSL/cloud-init は LF + UTF-8(BOM なし) を期待するため改行を正規化して書く。
128
+ $yaml = $yaml -replace "`r`n", "`n"
129
+ $path = Join-Path $ciDir "$DISTRO.user-data"
130
+ [System.IO.File]::WriteAllText($path, $yaml, (New-Object System.Text.UTF8Encoding($false)))
131
+ Write-Ok "cloud-init user-data を配置: $path"
132
+ }
133
+
134
+ # 方式A: cloud-init が完了するまで待つ。成功で $true。
135
+ function Invoke-CloudInitProvision($user) {
136
+ Write-Step "Ubuntu 初回ユーザーを無人作成 (cloud-init)"
137
+ try {
138
+ # 初回起動をトリガー。cloud-init が user-data を適用する。
139
+ wsl.exe -d $DISTRO -u root -- cloud-init status --wait *> $null
140
+ } catch {
141
+ Write-Warn "cloud-init status --wait に失敗 (cloud-init 非対応の可能性)"
142
+ return $false
143
+ }
144
+ return (Test-WslUserReady $user)
145
+ }
146
+
147
+ # 方式B (フォールバック): launcher install --root → useradd で無人作成。
148
+ function Invoke-RootInstallProvision($user) {
149
+ Write-Step "Ubuntu 初回ユーザーを無人作成 (root install フォールバック)"
150
+ try {
151
+ # OOBE 無しで root のみ初期化。既に登録済みなら無害。
152
+ & $LAUNCHER install --root *> $null
153
+ } catch {
154
+ Write-Warn "$LAUNCHER install --root に失敗 (続行して useradd を試行)"
155
+ }
156
+ $script = @"
157
+ set -e
158
+ useradd -m -s /bin/bash -G sudo '$user' 2>/dev/null || true
159
+ passwd -d '$user'
160
+ echo '$user ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/90-hub-$user
161
+ chmod 0440 /etc/sudoers.d/90-hub-$user
162
+ printf '[user]\ndefault=$user\n[boot]\nsystemd=true\n' > /etc/wsl.conf
163
+ "@
164
+ $script = $script -replace "`r`n", "`n"
165
+ wsl.exe -d $DISTRO -u root -- bash -lc $script
166
+ wsl.exe --shutdown
167
+ return (Test-WslUserReady $user)
168
+ }
169
+
170
+ # distro 内の /etc/wsl.conf に systemd=true が無ければ追記 (冪等)。
171
+ function Ensure-Systemd {
172
+ $has = (wsl.exe -d $DISTRO -u root -- bash -lc "grep -q 'systemd=true' /etc/wsl.conf 2>/dev/null && echo yes || echo no")
173
+ if (($has -replace "`0","").Trim() -ne "yes") {
174
+ wsl.exe -d $DISTRO -u root -- bash -lc "printf '[boot]\nsystemd=true\n' >> /etc/wsl.conf"
175
+ wsl.exe --shutdown
176
+ }
177
+ }
178
+
179
+ # Task Scheduler に「ログオン時に distro を起こす」タスクを登録 (Mac に無い新ピース)。
180
+ function Register-BootTask($user) {
181
+ Write-Step "Windows 起動時の常駐起動を登録 (Task Scheduler)"
182
+ $action = New-ScheduledTaskAction -Execute "wsl.exe" -Argument "-d $DISTRO -u $user -- /bin/true"
183
+ $trigger = New-ScheduledTaskTrigger -AtLogOn
184
+ $set = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
185
+ Register-ScheduledTask -TaskName $TASK_NAME -Action $action -Trigger $trigger -Settings $set `
186
+ -RunLevel Limited -Force | Out-Null
187
+ Write-Ok "ログオンタスク '$TASK_NAME' を登録しました"
188
+ }
189
+
190
+ # WSL の中で既存 install.sh を呼ぶ (tmux/node/hub-agent/claude/enroll/install-service)。
191
+ function Invoke-WslInstaller($user) {
192
+ Write-Step "WSL 内で hub-agent をセットアップ (既存 install.sh)"
193
+ $tok = if ($Token) { $Token } else { "" }
194
+ $inner = "curl -fsSL '$INSTALL_SH' | HUB_AGENT_TOKEN='$tok' HUB_AGENT_URL='$HubUrl' bash"
195
+ wsl.exe -d $DISTRO -u $user -- bash -lc $inner
196
+ if ($LASTEXITCODE -ne 0) { throw "WSL 内 install.sh が失敗しました (exit $LASTEXITCODE)" }
197
+ }
198
+
199
+ # =============================================================================
200
+ # メイン
201
+ # =============================================================================
202
+ function Main {
203
+ Write-Step "hub-agent Windows セットアップを開始 (WSL2 方式)"
204
+
205
+ if (-not (Test-IsAdmin)) {
206
+ Write-Err "管理者権限が必要です。PowerShell を『管理者として実行』で開き直してください。"
207
+ exit 1
208
+ }
209
+
210
+ $user = Get-LinuxUserName
211
+
212
+ # --- フェーズ1: WSL2 / distro 導入 (未導入時のみ。再起動をまたぐ) ---
213
+ if (-not $IsResume -and (-not (Test-WslReady) -or -not (Test-DistroExists))) {
214
+ Write-Step "WSL2 + $DISTRO を導入します"
215
+ Set-ResumeOnReboot # 再起動後に自動再開する仕掛けを先に仕込む
216
+ Write-CloudInit $user # 初回起動前に cloud-init を配置 (方式A の前提)
217
+ wsl.exe --install -d $DISTRO --no-launch
218
+ Prompt-RebootDecision # 再起動は Y/N でユーザーに委ねる
219
+ return
220
+ }
221
+
222
+ # --- 再起動後 or 既に WSL 導入済み: ユーザー無人作成 ---
223
+ if (-not (Test-DistroExists)) {
224
+ # RESUME なのに distro が無い = wsl --install が再起動後に展開中のことがある。
225
+ Write-Warn "$DISTRO がまだ見つかりません。展開を待って初回起動を試みます..."
226
+ Write-CloudInit $user
227
+ }
228
+
229
+ if (-not (Test-WslUserReady $user)) {
230
+ # 方式A (cloud-init) → 失敗時 方式B (root install) へ自動フォールバック。
231
+ if (-not (Test-Path (Join-Path $env:USERPROFILE ".cloud-init\$DISTRO.user-data"))) {
232
+ Write-CloudInit $user
233
+ }
234
+ $ok = Invoke-CloudInitProvision $user
235
+ if (-not $ok) {
236
+ Write-Warn "cloud-init での作成を確認できませんでした。root install 方式に切り替えます。"
237
+ $ok = Invoke-RootInstallProvision $user
238
+ }
239
+ if (-not $ok) { throw "Ubuntu ユーザー '$user' の無人作成に失敗しました" }
240
+ Write-Ok "Ubuntu ユーザー '$user' を作成しました (パスワードなし / NOPASSWD sudo)"
241
+ } else {
242
+ Write-Ok "Ubuntu ユーザー '$user' は既に存在します"
243
+ }
244
+
245
+ Ensure-Systemd
246
+
247
+ # --- フェーズ2: WSL 内ワンライナー ---
248
+ Invoke-WslInstaller $user
249
+
250
+ # --- 常駐化 ---
251
+ Register-BootTask $user
252
+
253
+ Write-Host ""
254
+ Write-Ok "セットアップ完了。Hub UI で online 表示を確認してください"
255
+ Write-Host " https://hub.cocorograph.com/user/cockpit/agents" -ForegroundColor Cyan
256
+ Write-Warn "注意: 作業リポジトリは WSL 内 (例: /home/$user/...) に置いてください。"
257
+ Write-Warn " Windows ドライブ (/mnt/c/...) はファイル監視が不安定です。"
258
+ }
259
+
260
+ Main