# 建立 VM 端點

本頁說明 `POST /api/vm/install` 的請求欄位、預設值與回應。

## 請求

```bash
curl -N -X POST http://192.168.0.11:8080/api/vm/install \
  -H "Content-Type: application/json" \
  -d '{
    "name": "web",
    "os": "ubuntu",
    "version": "24.04",
    "cpu": 2,
    "ram": 4096,
    "disk": "32G",
    "node": "pve2",
    "pubkey": "ssh-ed25519 AAAA... user@laptop"
  }'
```

## 欄位

| 欄位 | 型別 | 必要 | 預設 | 規則 |
|---|---|---|---|---|
| `os` | string | 是 | — | `debian`／`ubuntu`／`rockylinux` |
| `version` | string | 是 | — | 見 [支援版本](/zh/os-init-scripts#支援版本與映像) |
| `id` | int | 否 | 自動配置 | 指定時直接使用，不檢查是否占用；同時決定 IP 末段 |
| `name` | string | 否 | VMID | 實際名稱為 `<name>-<vmid>` |
| `node` | string | 否 | 主節點 | 建立後遷移到此節點再開機 |
| `cpu` | int | 否 | `1` | ≤ 0 → 1；上限 `VM_MAX_CPU` |
| `ram` | int | 否 | `512` | MB；< 512 → 512；上限 `VM_MAX_RAM` |
| `disk` | string | 否 | `16G` | 解析去掉 `G` 的數字；< 16 → `16G`；≥ `VM_MAX_DISK` → 上限值 |
| `user` | string | 否 | 依 OS | Cloud-Init 使用者；預設 `debian`／`ubuntu`／`rocky` |
| `passwd` | string | 否 | `passwd` | Cloud-Init 使用者密碼 |
| `pubkey` | string | 否 | — | 追加注入的 SSH 公鑰 |

`ip`、`gateway`、`storage` 由伺服器依 VMID、`GATEWAY`、`ASSIGN_STORAGE` 覆寫，傳入無效。

SSH 就緒檢查固定以 OS 預設使用者（`debian`／`ubuntu`／`rocky`）登入，初始化腳本則以 `user` 登入；自訂 `user` 時，兩個帳號都必須能以主節點金鑰登入。

## 回應

| 情況 | 回應 |
|---|---|
| JSON 解析或 `os`／`version` 驗證失敗 | `400` JSON：`{"success": false, "message": "please check your input:..."}` |
| 來源 IP 不在 `ALLOW_IPS` | `200` 單行 `data:` 錯誤訊息 |
| 其他 | SSE 串流，逐步回報 [佈建流程](/zh/provisioning-pipeline) 各階段，最後 `event: close` |

成功時最後四個事件：

```text
data: {"step":"VM initialization > finalizing","status":"success","message":"[+] VM installation completed in 182.41s"}

data: {"step":"VM initialization > finalizing","status":"success","message":"[*] VMID: 120"}

data: {"step":"VM initialization > finalizing","status":"success","message":"[*] IP: 192.168.0.120"}

data: {"step":"VM initialization > finalizing","status":"success","message":"[*] User: ubuntu"}
```

SSE 串流一律回 HTTP 200；是否成功要看是否出現 `status: "error"` 的事件。
