@gravito/launchpad 1.0.0-beta.1 → 1.1.0
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/CHANGELOG.md +27 -0
- package/README.md +79 -21
- package/debug-launch.ts +7 -4
- package/dist/index.d.mts +205 -0
- package/dist/index.d.ts +205 -0
- package/dist/index.js +818 -0
- package/dist/index.mjs +785 -0
- package/package.json +13 -4
- package/server.ts +3 -1
- package/src/Application/MissionControl.ts +1 -0
- package/src/Application/PayloadInjector.ts +24 -3
- package/src/Domain/Interfaces.ts +20 -0
- package/src/Infrastructure/Docker/DockerAdapter.ts +29 -23
- package/src/Infrastructure/Git/ShellGitAdapter.ts +14 -3
- package/src/Infrastructure/Persistence/CachedRocketRepository.ts +1 -1
- package/src/Infrastructure/Router/BunProxyAdapter.ts +3 -1
- package/src/index.ts +1 -1
- package/tests/Integration.test.ts +1 -1
- package/tests/Rocket.test.ts +35 -0
- package/tests/docker-adapter.test.ts +100 -2
- package/tests/payload-injector.test.ts +73 -0
- package/tsconfig.json +26 -7
- package/.turbo/turbo-test.log +0 -82
- package/.turbo/turbo-typecheck.log +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @gravito/launchpad
|
|
2
|
+
|
|
3
|
+
## 1.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Launch standalone high-performance engine and core optimizations.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- q
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @gravito/core@1.1.0
|
|
15
|
+
- @gravito/enterprise@1.0.1
|
|
16
|
+
- @gravito/ripple@2.0.0
|
|
17
|
+
- @gravito/stasis@2.0.0
|
|
18
|
+
|
|
19
|
+
## 1.0.0
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies
|
|
24
|
+
- @gravito/core@1.0.0
|
|
25
|
+
- @gravito/enterprise@1.0.0
|
|
26
|
+
- @gravito/ripple@1.0.0
|
|
27
|
+
- @gravito/stasis@1.0.0
|
package/README.md
CHANGED
|
@@ -1,44 +1,102 @@
|
|
|
1
1
|
# @gravito/launchpad
|
|
2
2
|
|
|
3
|
-
> 🚀
|
|
3
|
+
> 🚀 Instant Deployment System for Bun. Container lifecycle management and zero-downtime deployment.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Gravito Launchpad** is a specialized orchestration system built for the Bun runtime. It uses a unique "Rocket Pool" architecture to pre-warm containers, enabling sub-second deployments by injecting code into already running instances instead of building images from scratch.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **Payload Injection**: 跳過 Docker Build,透過 `docker cp` 秒級注入代碼。
|
|
9
|
-
- **DDD 架構**: 基於 `@gravito/enterprise` 實作,具備嚴謹的狀態機管理。
|
|
10
|
-
- **可回收性**: 任務結束後自動翻新容器,資源零浪費。
|
|
7
|
+
## ✨ Core Features
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
- **🔥 Rocket Pool**: Pre-warmed container pool eliminates cold start times.
|
|
10
|
+
- **💉 Payload Injection**: Skip `docker build`. Code is injected via `docker cp` in milliseconds.
|
|
11
|
+
- **🏗️ DDD Architecture**: Built on `@gravito/enterprise` with rigorous state machine management.
|
|
12
|
+
- **♻️ Auto-Recycling**: Containers are automatically refurbished and returned to the pool after missions.
|
|
13
|
+
- **🤖 GitHub Integration**: Built-in webhook handler for PR previews and automated comments.
|
|
14
|
+
- **🛡️ Secure Isolation**: Each deployment runs in an isolated container environment.
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
## 🏗️ Architecture Overview
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
- **Application**: `PoolManager` (調度) 與 `PayloadInjector` (部署)。
|
|
18
|
-
- **Infrastructure**: 底層 Docker 與 Git 操作實作。
|
|
18
|
+
Launchpad follows **Clean Architecture** principles:
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
### Domain Layer
|
|
21
|
+
- **Rocket**: The aggregate root representing a container instance.
|
|
22
|
+
- **Mission**: Represents a deployment task (repo, commit, branch).
|
|
23
|
+
- **Status Machine**: Strictly manages transitions (Idle -> Assigned -> Deployed -> Recycling).
|
|
24
|
+
|
|
25
|
+
### Application Layer
|
|
26
|
+
- **PoolManager**: Orchestrates the lifecycle of Rockets (warmup, assignment, recycling).
|
|
27
|
+
- **PayloadInjector**: Handles the git clone and code injection process.
|
|
28
|
+
- **MissionControl**: High-level facade for launching missions.
|
|
29
|
+
- **RefurbishUnit**: Cleans up used containers for reuse.
|
|
30
|
+
|
|
31
|
+
### Infrastructure Layer
|
|
32
|
+
- **DockerAdapter**: Low-level communication with Docker daemon.
|
|
33
|
+
- **ShellGitAdapter**: Git operations via shell commands.
|
|
34
|
+
- **BunProxyAdapter**: Manages reverse proxying to active containers.
|
|
35
|
+
|
|
36
|
+
## 🚀 Quick Start
|
|
37
|
+
|
|
38
|
+
### Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
bun add @gravito/launchpad
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Basic Usage
|
|
21
45
|
|
|
22
46
|
```typescript
|
|
23
|
-
import { PoolManager, PayloadInjector } from '@gravito/launchpad'
|
|
47
|
+
import { PoolManager, PayloadInjector, Mission } from '@gravito/launchpad'
|
|
24
48
|
import { DockerAdapter, ShellGitAdapter, InMemoryRocketRepository } from '@gravito/launchpad/infra'
|
|
25
49
|
|
|
26
|
-
|
|
27
|
-
const
|
|
50
|
+
// Initialize adapters
|
|
51
|
+
const docker = new DockerAdapter()
|
|
52
|
+
const repo = new InMemoryRocketRepository()
|
|
53
|
+
const manager = new PoolManager(docker, repo)
|
|
28
54
|
|
|
29
|
-
// 1.
|
|
55
|
+
// 1. Warmup the pool (Create 3 idle containers)
|
|
30
56
|
await manager.warmup(3)
|
|
31
57
|
|
|
32
|
-
// 2.
|
|
33
|
-
const mission = Mission.create({
|
|
34
|
-
|
|
58
|
+
// 2. Create a mission
|
|
59
|
+
const mission = Mission.create({
|
|
60
|
+
id: 'mission-1',
|
|
61
|
+
repoUrl: 'https://github.com/user/repo.git',
|
|
62
|
+
commitSha: 'latest'
|
|
63
|
+
})
|
|
35
64
|
|
|
36
|
-
// 3.
|
|
65
|
+
// 3. Launch! (Assigns a rocket and injects code)
|
|
66
|
+
const rocket = await manager.assignMission(mission)
|
|
67
|
+
const injector = new PayloadInjector(docker, new ShellGitAdapter())
|
|
37
68
|
await injector.deploy(rocket)
|
|
69
|
+
|
|
70
|
+
console.log(`Mission deployed to http://localhost:${rocket.port}`)
|
|
38
71
|
```
|
|
39
72
|
|
|
40
|
-
|
|
73
|
+
### Running as a Service (Orbit)
|
|
74
|
+
|
|
75
|
+
Launchpad can run as a Gravito Orbit, providing a REST API and Webhook support.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { bootstrapLaunchpad } from '@gravito/launchpad'
|
|
79
|
+
|
|
80
|
+
const { port } = await bootstrapLaunchpad()
|
|
81
|
+
console.log(`Launchpad Server running on port ${port}`)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## ⚙️ Configuration
|
|
85
|
+
|
|
86
|
+
Launchpad relies on Docker. Ensure Docker is installed and running.
|
|
87
|
+
|
|
88
|
+
| Environment Variable | Description | Default |
|
|
89
|
+
|----------------------|-------------|---------|
|
|
90
|
+
| `GITHUB_TOKEN` | Token for GitHub API access | (Required for PR comments) |
|
|
91
|
+
| `GITHUB_WEBHOOK_SECRET` | Secret for verifying webhooks | (Optional) |
|
|
92
|
+
| `POOL_SIZE` | Target number of pre-warmed containers | `3` |
|
|
93
|
+
|
|
94
|
+
## 🧪 Testing
|
|
41
95
|
|
|
42
96
|
```bash
|
|
43
97
|
bun test
|
|
44
98
|
```
|
|
99
|
+
|
|
100
|
+
## 📄 License
|
|
101
|
+
|
|
102
|
+
MIT © Gravito Framework
|
package/debug-launch.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getRuntimeAdapter } from '@gravito/core'
|
|
1
2
|
import { DockerAdapter } from './src/Infrastructure/Docker/DockerAdapter'
|
|
2
3
|
import { bootstrapLaunchpad } from './src/index'
|
|
3
4
|
|
|
@@ -6,23 +7,25 @@ async function run() {
|
|
|
6
7
|
|
|
7
8
|
// 1. Cleanup
|
|
8
9
|
const _docker = new DockerAdapter()
|
|
10
|
+
const runtime = getRuntimeAdapter()
|
|
9
11
|
try {
|
|
10
|
-
const
|
|
12
|
+
const listProc = runtime.spawn([
|
|
11
13
|
'docker',
|
|
12
14
|
'ps',
|
|
13
15
|
'-aq',
|
|
14
16
|
'--filter',
|
|
15
17
|
'label=gravito-origin=launchpad',
|
|
16
|
-
])
|
|
18
|
+
])
|
|
19
|
+
const containers = await new Response(listProc.stdout ?? null).text()
|
|
17
20
|
if (containers.trim()) {
|
|
18
21
|
console.log('🧹 Cleaning up old containers...')
|
|
19
|
-
await
|
|
22
|
+
await runtime.spawn(['docker', 'rm', '-f', ...containers.trim().split('\n')]).exited
|
|
20
23
|
}
|
|
21
24
|
} catch (_e) {}
|
|
22
25
|
|
|
23
26
|
// 2. Start Server
|
|
24
27
|
const config = await bootstrapLaunchpad()
|
|
25
|
-
const server =
|
|
28
|
+
const server = runtime.serve(config)
|
|
26
29
|
console.log(`🚀 Server started at http://localhost:${config.port}`)
|
|
27
30
|
|
|
28
31
|
// 3. Launch Mission
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import * as _gravito_ripple from '@gravito/ripple';
|
|
2
|
+
import { OrbitRipple } from '@gravito/ripple';
|
|
3
|
+
import { GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
4
|
+
import { ValueObject, AggregateRoot } from '@gravito/enterprise';
|
|
5
|
+
|
|
6
|
+
interface MissionProps {
|
|
7
|
+
id: string;
|
|
8
|
+
repoUrl: string;
|
|
9
|
+
branch: string;
|
|
10
|
+
commitSha: string;
|
|
11
|
+
}
|
|
12
|
+
declare class Mission extends ValueObject<MissionProps> {
|
|
13
|
+
get id(): string;
|
|
14
|
+
get repoUrl(): string;
|
|
15
|
+
get branch(): string;
|
|
16
|
+
get commitSha(): string;
|
|
17
|
+
static create(props: MissionProps): Mission;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 火箭生命週期狀態
|
|
22
|
+
*/
|
|
23
|
+
declare enum RocketStatus {
|
|
24
|
+
IDLE = "IDLE",// 待命:容器運行中,無任務
|
|
25
|
+
PREPARING = "PREPARING",// 裝填:正在注入代碼 (Locked)
|
|
26
|
+
ORBITING = "ORBITING",// 運行:應用服務中
|
|
27
|
+
REFURBISHING = "REFURBISHING",// 翻新:正在清理環境
|
|
28
|
+
DECOMMISSIONED = "DECOMMISSIONED"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare class Rocket extends AggregateRoot<string> {
|
|
32
|
+
private _status;
|
|
33
|
+
private _currentMission;
|
|
34
|
+
private _containerId;
|
|
35
|
+
private _assignedDomain;
|
|
36
|
+
constructor(id: string, containerId: string);
|
|
37
|
+
get status(): RocketStatus;
|
|
38
|
+
get currentMission(): Mission | null;
|
|
39
|
+
get containerId(): string;
|
|
40
|
+
get assignedDomain(): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* 分配域名
|
|
43
|
+
*/
|
|
44
|
+
assignDomain(domain: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* 分配任務 (指派任務給 IDLE 的火箭)
|
|
47
|
+
*/
|
|
48
|
+
assignMission(mission: Mission): void;
|
|
49
|
+
/**
|
|
50
|
+
* 點火啟動 (應用程式啟動成功)
|
|
51
|
+
*/
|
|
52
|
+
ignite(): void;
|
|
53
|
+
/**
|
|
54
|
+
* 任務降落 (PR 合併或關閉,暫停服務)
|
|
55
|
+
*/
|
|
56
|
+
splashDown(): void;
|
|
57
|
+
/**
|
|
58
|
+
* 翻新完成 (清理完畢,回歸池中)
|
|
59
|
+
*/
|
|
60
|
+
finishRefurbishment(): void;
|
|
61
|
+
/**
|
|
62
|
+
* 火箭除役 (移除容器)
|
|
63
|
+
*/
|
|
64
|
+
decommission(): void;
|
|
65
|
+
toJSON(): {
|
|
66
|
+
id: string;
|
|
67
|
+
containerId: string;
|
|
68
|
+
status: RocketStatus;
|
|
69
|
+
currentMission: Mission | null;
|
|
70
|
+
assignedDomain: string | null;
|
|
71
|
+
};
|
|
72
|
+
static fromJSON(data: any): Rocket;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 負責與底層容器引擎(如 Docker)溝通的轉接器介面
|
|
77
|
+
*/
|
|
78
|
+
interface IDockerAdapter {
|
|
79
|
+
createBaseContainer(): Promise<string>;
|
|
80
|
+
copyFiles(containerId: string, sourcePath: string, targetPath: string): Promise<void>;
|
|
81
|
+
executeCommand(containerId: string, command: string[]): Promise<{
|
|
82
|
+
stdout: string;
|
|
83
|
+
stderr: string;
|
|
84
|
+
exitCode: number;
|
|
85
|
+
}>;
|
|
86
|
+
/**
|
|
87
|
+
* 獲取容器映射到宿主機的真實端口
|
|
88
|
+
*/
|
|
89
|
+
getExposedPort(containerId: string, containerPort?: number): Promise<number>;
|
|
90
|
+
removeContainer(containerId: string): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* 根據 Label 批量移除容器
|
|
93
|
+
*/
|
|
94
|
+
removeContainerByLabel(label: string): Promise<void>;
|
|
95
|
+
streamLogs(containerId: string, onData: (data: string) => void): void;
|
|
96
|
+
getStats(containerId: string): Promise<{
|
|
97
|
+
cpu: string;
|
|
98
|
+
memory: string;
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 負責代碼獲取
|
|
103
|
+
*/
|
|
104
|
+
interface IGitAdapter {
|
|
105
|
+
clone(repoUrl: string, branch: string): Promise<string>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 負責動態反向代理與域名路由的轉接器
|
|
109
|
+
*/
|
|
110
|
+
interface IRouterAdapter {
|
|
111
|
+
/**
|
|
112
|
+
* 註冊一個域名映射到指定的目標 (URL)
|
|
113
|
+
*/
|
|
114
|
+
register(domain: string, targetUrl: string): void;
|
|
115
|
+
/**
|
|
116
|
+
* 註銷域名
|
|
117
|
+
*/
|
|
118
|
+
unregister(domain: string): void;
|
|
119
|
+
/**
|
|
120
|
+
* 啟動代理伺服器
|
|
121
|
+
*/
|
|
122
|
+
start(port: number): void;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 負責動態反向代理與域名路由的轉接器
|
|
126
|
+
*/
|
|
127
|
+
interface IRouterAdapter {
|
|
128
|
+
register(domain: string, targetUrl: string): void;
|
|
129
|
+
unregister(domain: string): void;
|
|
130
|
+
start(port: number): void;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 負責持久化火箭狀態的儲存庫介面
|
|
134
|
+
*/
|
|
135
|
+
interface IRocketRepository {
|
|
136
|
+
save(rocket: Rocket): Promise<void>;
|
|
137
|
+
findById(id: string): Promise<Rocket | null>;
|
|
138
|
+
findIdle(): Promise<Rocket | null>;
|
|
139
|
+
findAll(): Promise<Rocket[]>;
|
|
140
|
+
delete(id: string): Promise<void>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
declare class PayloadInjector {
|
|
144
|
+
private docker;
|
|
145
|
+
private git;
|
|
146
|
+
constructor(docker: IDockerAdapter, git: IGitAdapter);
|
|
147
|
+
deploy(rocket: Rocket): Promise<void>;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
declare class RefurbishUnit {
|
|
151
|
+
private docker;
|
|
152
|
+
constructor(docker: IDockerAdapter);
|
|
153
|
+
/**
|
|
154
|
+
* 執行火箭翻新邏輯
|
|
155
|
+
*/
|
|
156
|
+
refurbish(rocket: Rocket): Promise<void>;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
declare class PoolManager {
|
|
160
|
+
private dockerAdapter;
|
|
161
|
+
private rocketRepository;
|
|
162
|
+
private refurbishUnit?;
|
|
163
|
+
private router?;
|
|
164
|
+
constructor(dockerAdapter: IDockerAdapter, rocketRepository: IRocketRepository, refurbishUnit?: RefurbishUnit | undefined, router?: IRouterAdapter | undefined);
|
|
165
|
+
/**
|
|
166
|
+
* 初始化發射場:預先準備指定數量的火箭
|
|
167
|
+
*/
|
|
168
|
+
warmup(count: number): Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* 獲取一架可用的火箭並分配任務
|
|
171
|
+
*/
|
|
172
|
+
assignMission(mission: Mission): Promise<Rocket>;
|
|
173
|
+
/**
|
|
174
|
+
* 回收指定任務的火箭
|
|
175
|
+
*/
|
|
176
|
+
recycle(missionId: string): Promise<void>;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
declare class MissionControl {
|
|
180
|
+
private poolManager;
|
|
181
|
+
private injector;
|
|
182
|
+
private docker;
|
|
183
|
+
private router?;
|
|
184
|
+
constructor(poolManager: PoolManager, injector: PayloadInjector, docker: IDockerAdapter, router?: IRouterAdapter | undefined);
|
|
185
|
+
launch(mission: Mission, onTelemetry: (type: string, data: any) => void): Promise<string>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Gravito Launchpad Orbit
|
|
190
|
+
*/
|
|
191
|
+
declare class LaunchpadOrbit implements GravitoOrbit {
|
|
192
|
+
private ripple;
|
|
193
|
+
constructor(ripple: OrbitRipple);
|
|
194
|
+
install(core: PlanetCore): Promise<void>;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* 一鍵啟動 Launchpad 應用程式
|
|
198
|
+
*/
|
|
199
|
+
declare function bootstrapLaunchpad(): Promise<{
|
|
200
|
+
port: number;
|
|
201
|
+
websocket: _gravito_ripple.WebSocketHandlerConfig;
|
|
202
|
+
fetch: (req: Request, server: any) => Response | Promise<Response> | undefined;
|
|
203
|
+
}>;
|
|
204
|
+
|
|
205
|
+
export { LaunchpadOrbit, Mission, MissionControl, PayloadInjector, PoolManager, RefurbishUnit, Rocket, RocketStatus, bootstrapLaunchpad };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import * as _gravito_ripple from '@gravito/ripple';
|
|
2
|
+
import { OrbitRipple } from '@gravito/ripple';
|
|
3
|
+
import { GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
4
|
+
import { ValueObject, AggregateRoot } from '@gravito/enterprise';
|
|
5
|
+
|
|
6
|
+
interface MissionProps {
|
|
7
|
+
id: string;
|
|
8
|
+
repoUrl: string;
|
|
9
|
+
branch: string;
|
|
10
|
+
commitSha: string;
|
|
11
|
+
}
|
|
12
|
+
declare class Mission extends ValueObject<MissionProps> {
|
|
13
|
+
get id(): string;
|
|
14
|
+
get repoUrl(): string;
|
|
15
|
+
get branch(): string;
|
|
16
|
+
get commitSha(): string;
|
|
17
|
+
static create(props: MissionProps): Mission;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 火箭生命週期狀態
|
|
22
|
+
*/
|
|
23
|
+
declare enum RocketStatus {
|
|
24
|
+
IDLE = "IDLE",// 待命:容器運行中,無任務
|
|
25
|
+
PREPARING = "PREPARING",// 裝填:正在注入代碼 (Locked)
|
|
26
|
+
ORBITING = "ORBITING",// 運行:應用服務中
|
|
27
|
+
REFURBISHING = "REFURBISHING",// 翻新:正在清理環境
|
|
28
|
+
DECOMMISSIONED = "DECOMMISSIONED"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare class Rocket extends AggregateRoot<string> {
|
|
32
|
+
private _status;
|
|
33
|
+
private _currentMission;
|
|
34
|
+
private _containerId;
|
|
35
|
+
private _assignedDomain;
|
|
36
|
+
constructor(id: string, containerId: string);
|
|
37
|
+
get status(): RocketStatus;
|
|
38
|
+
get currentMission(): Mission | null;
|
|
39
|
+
get containerId(): string;
|
|
40
|
+
get assignedDomain(): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* 分配域名
|
|
43
|
+
*/
|
|
44
|
+
assignDomain(domain: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* 分配任務 (指派任務給 IDLE 的火箭)
|
|
47
|
+
*/
|
|
48
|
+
assignMission(mission: Mission): void;
|
|
49
|
+
/**
|
|
50
|
+
* 點火啟動 (應用程式啟動成功)
|
|
51
|
+
*/
|
|
52
|
+
ignite(): void;
|
|
53
|
+
/**
|
|
54
|
+
* 任務降落 (PR 合併或關閉,暫停服務)
|
|
55
|
+
*/
|
|
56
|
+
splashDown(): void;
|
|
57
|
+
/**
|
|
58
|
+
* 翻新完成 (清理完畢,回歸池中)
|
|
59
|
+
*/
|
|
60
|
+
finishRefurbishment(): void;
|
|
61
|
+
/**
|
|
62
|
+
* 火箭除役 (移除容器)
|
|
63
|
+
*/
|
|
64
|
+
decommission(): void;
|
|
65
|
+
toJSON(): {
|
|
66
|
+
id: string;
|
|
67
|
+
containerId: string;
|
|
68
|
+
status: RocketStatus;
|
|
69
|
+
currentMission: Mission | null;
|
|
70
|
+
assignedDomain: string | null;
|
|
71
|
+
};
|
|
72
|
+
static fromJSON(data: any): Rocket;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 負責與底層容器引擎(如 Docker)溝通的轉接器介面
|
|
77
|
+
*/
|
|
78
|
+
interface IDockerAdapter {
|
|
79
|
+
createBaseContainer(): Promise<string>;
|
|
80
|
+
copyFiles(containerId: string, sourcePath: string, targetPath: string): Promise<void>;
|
|
81
|
+
executeCommand(containerId: string, command: string[]): Promise<{
|
|
82
|
+
stdout: string;
|
|
83
|
+
stderr: string;
|
|
84
|
+
exitCode: number;
|
|
85
|
+
}>;
|
|
86
|
+
/**
|
|
87
|
+
* 獲取容器映射到宿主機的真實端口
|
|
88
|
+
*/
|
|
89
|
+
getExposedPort(containerId: string, containerPort?: number): Promise<number>;
|
|
90
|
+
removeContainer(containerId: string): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* 根據 Label 批量移除容器
|
|
93
|
+
*/
|
|
94
|
+
removeContainerByLabel(label: string): Promise<void>;
|
|
95
|
+
streamLogs(containerId: string, onData: (data: string) => void): void;
|
|
96
|
+
getStats(containerId: string): Promise<{
|
|
97
|
+
cpu: string;
|
|
98
|
+
memory: string;
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 負責代碼獲取
|
|
103
|
+
*/
|
|
104
|
+
interface IGitAdapter {
|
|
105
|
+
clone(repoUrl: string, branch: string): Promise<string>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 負責動態反向代理與域名路由的轉接器
|
|
109
|
+
*/
|
|
110
|
+
interface IRouterAdapter {
|
|
111
|
+
/**
|
|
112
|
+
* 註冊一個域名映射到指定的目標 (URL)
|
|
113
|
+
*/
|
|
114
|
+
register(domain: string, targetUrl: string): void;
|
|
115
|
+
/**
|
|
116
|
+
* 註銷域名
|
|
117
|
+
*/
|
|
118
|
+
unregister(domain: string): void;
|
|
119
|
+
/**
|
|
120
|
+
* 啟動代理伺服器
|
|
121
|
+
*/
|
|
122
|
+
start(port: number): void;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 負責動態反向代理與域名路由的轉接器
|
|
126
|
+
*/
|
|
127
|
+
interface IRouterAdapter {
|
|
128
|
+
register(domain: string, targetUrl: string): void;
|
|
129
|
+
unregister(domain: string): void;
|
|
130
|
+
start(port: number): void;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 負責持久化火箭狀態的儲存庫介面
|
|
134
|
+
*/
|
|
135
|
+
interface IRocketRepository {
|
|
136
|
+
save(rocket: Rocket): Promise<void>;
|
|
137
|
+
findById(id: string): Promise<Rocket | null>;
|
|
138
|
+
findIdle(): Promise<Rocket | null>;
|
|
139
|
+
findAll(): Promise<Rocket[]>;
|
|
140
|
+
delete(id: string): Promise<void>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
declare class PayloadInjector {
|
|
144
|
+
private docker;
|
|
145
|
+
private git;
|
|
146
|
+
constructor(docker: IDockerAdapter, git: IGitAdapter);
|
|
147
|
+
deploy(rocket: Rocket): Promise<void>;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
declare class RefurbishUnit {
|
|
151
|
+
private docker;
|
|
152
|
+
constructor(docker: IDockerAdapter);
|
|
153
|
+
/**
|
|
154
|
+
* 執行火箭翻新邏輯
|
|
155
|
+
*/
|
|
156
|
+
refurbish(rocket: Rocket): Promise<void>;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
declare class PoolManager {
|
|
160
|
+
private dockerAdapter;
|
|
161
|
+
private rocketRepository;
|
|
162
|
+
private refurbishUnit?;
|
|
163
|
+
private router?;
|
|
164
|
+
constructor(dockerAdapter: IDockerAdapter, rocketRepository: IRocketRepository, refurbishUnit?: RefurbishUnit | undefined, router?: IRouterAdapter | undefined);
|
|
165
|
+
/**
|
|
166
|
+
* 初始化發射場:預先準備指定數量的火箭
|
|
167
|
+
*/
|
|
168
|
+
warmup(count: number): Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* 獲取一架可用的火箭並分配任務
|
|
171
|
+
*/
|
|
172
|
+
assignMission(mission: Mission): Promise<Rocket>;
|
|
173
|
+
/**
|
|
174
|
+
* 回收指定任務的火箭
|
|
175
|
+
*/
|
|
176
|
+
recycle(missionId: string): Promise<void>;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
declare class MissionControl {
|
|
180
|
+
private poolManager;
|
|
181
|
+
private injector;
|
|
182
|
+
private docker;
|
|
183
|
+
private router?;
|
|
184
|
+
constructor(poolManager: PoolManager, injector: PayloadInjector, docker: IDockerAdapter, router?: IRouterAdapter | undefined);
|
|
185
|
+
launch(mission: Mission, onTelemetry: (type: string, data: any) => void): Promise<string>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Gravito Launchpad Orbit
|
|
190
|
+
*/
|
|
191
|
+
declare class LaunchpadOrbit implements GravitoOrbit {
|
|
192
|
+
private ripple;
|
|
193
|
+
constructor(ripple: OrbitRipple);
|
|
194
|
+
install(core: PlanetCore): Promise<void>;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* 一鍵啟動 Launchpad 應用程式
|
|
198
|
+
*/
|
|
199
|
+
declare function bootstrapLaunchpad(): Promise<{
|
|
200
|
+
port: number;
|
|
201
|
+
websocket: _gravito_ripple.WebSocketHandlerConfig;
|
|
202
|
+
fetch: (req: Request, server: any) => Response | Promise<Response> | undefined;
|
|
203
|
+
}>;
|
|
204
|
+
|
|
205
|
+
export { LaunchpadOrbit, Mission, MissionControl, PayloadInjector, PoolManager, RefurbishUnit, Rocket, RocketStatus, bootstrapLaunchpad };
|