clawup 1.0.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/README.md +245 -0
- package/dist/adapters/api-adapter.d.ts +76 -0
- package/dist/adapters/api-adapter.js +250 -0
- package/dist/adapters/api-adapter.js.map +1 -0
- package/dist/adapters/cli-adapter.d.ts +15 -0
- package/dist/adapters/cli-adapter.js +208 -0
- package/dist/adapters/cli-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +22 -0
- package/dist/adapters/index.js +32 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/types.d.ts +135 -0
- package/dist/adapters/types.js +14 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/bin.d.ts +8 -0
- package/dist/bin.js +221 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/config.d.ts +21 -0
- package/dist/commands/config.js +323 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/deploy.d.ts +7 -0
- package/dist/commands/deploy.js +13 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/destroy.d.ts +7 -0
- package/dist/commands/destroy.js +13 -0
- package/dist/commands/destroy.js.map +1 -0
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/init.js +698 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +8 -0
- package/dist/commands/list.js +42 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/push.d.ts +7 -0
- package/dist/commands/push.js +19 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/redeploy.d.ts +7 -0
- package/dist/commands/redeploy.js +13 -0
- package/dist/commands/redeploy.js.map +1 -0
- package/dist/commands/secrets.d.ts +16 -0
- package/dist/commands/secrets.js +169 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/ssh.d.ts +9 -0
- package/dist/commands/ssh.js +108 -0
- package/dist/commands/ssh.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.js +13 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.js +126 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.js +13 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/webhooks.d.ts +7 -0
- package/dist/commands/webhooks.js +13 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/lib/__tests__/identity.test.d.ts +1 -0
- package/dist/lib/__tests__/identity.test.js +186 -0
- package/dist/lib/__tests__/identity.test.js.map +1 -0
- package/dist/lib/__tests__/validate-agent.test.d.ts +1 -0
- package/dist/lib/__tests__/validate-agent.test.js +38 -0
- package/dist/lib/__tests__/validate-agent.test.js.map +1 -0
- package/dist/lib/config.d.ts +69 -0
- package/dist/lib/config.js +218 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +5 -0
- package/dist/lib/constants.js +29 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/exec.d.ts +24 -0
- package/dist/lib/exec.js +63 -0
- package/dist/lib/exec.js.map +1 -0
- package/dist/lib/prerequisites.d.ts +8 -0
- package/dist/lib/prerequisites.js +146 -0
- package/dist/lib/prerequisites.js.map +1 -0
- package/dist/lib/process.d.ts +18 -0
- package/dist/lib/process.js +37 -0
- package/dist/lib/process.js.map +1 -0
- package/dist/lib/pulumi.d.ts +37 -0
- package/dist/lib/pulumi.js +87 -0
- package/dist/lib/pulumi.js.map +1 -0
- package/dist/lib/tailscale.d.ts +75 -0
- package/dist/lib/tailscale.js +251 -0
- package/dist/lib/tailscale.js.map +1 -0
- package/dist/lib/tool-helpers.d.ts +15 -0
- package/dist/lib/tool-helpers.js +35 -0
- package/dist/lib/tool-helpers.js.map +1 -0
- package/dist/lib/ui.d.ts +26 -0
- package/dist/lib/ui.js +86 -0
- package/dist/lib/ui.js.map +1 -0
- package/dist/lib/update-check.d.ts +8 -0
- package/dist/lib/update-check.js +151 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/vendor.d.ts +34 -0
- package/dist/lib/vendor.js +128 -0
- package/dist/lib/vendor.js.map +1 -0
- package/dist/lib/workspace.d.ts +21 -0
- package/dist/lib/workspace.js +170 -0
- package/dist/lib/workspace.js.map +1 -0
- package/dist/tools/deploy.d.ts +16 -0
- package/dist/tools/deploy.js +181 -0
- package/dist/tools/deploy.js.map +1 -0
- package/dist/tools/destroy.d.ts +16 -0
- package/dist/tools/destroy.js +119 -0
- package/dist/tools/destroy.js.map +1 -0
- package/dist/tools/index.d.ts +20 -0
- package/dist/tools/index.js +34 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/push.d.ts +29 -0
- package/dist/tools/push.js +341 -0
- package/dist/tools/push.js.map +1 -0
- package/dist/tools/redeploy.d.ts +17 -0
- package/dist/tools/redeploy.js +181 -0
- package/dist/tools/redeploy.js.map +1 -0
- package/dist/tools/status.d.ts +16 -0
- package/dist/tools/status.js +205 -0
- package/dist/tools/status.js.map +1 -0
- package/dist/tools/validate.d.ts +16 -0
- package/dist/tools/validate.js +219 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/tools/webhooks.d.ts +17 -0
- package/dist/tools/webhooks.js +181 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/infra/Pulumi.yaml +6 -0
- package/infra/dist/components/cloud-init.js +412 -0
- package/infra/dist/components/config-generator.js +254 -0
- package/infra/dist/components/hetzner-agent.js +162 -0
- package/infra/dist/components/index.js +18 -0
- package/infra/dist/components/openclaw-agent.js +287 -0
- package/infra/dist/components/shared.js +132 -0
- package/infra/dist/components/types.js +6 -0
- package/infra/dist/index.js +387 -0
- package/infra/dist/shared-vpc.js +167 -0
- package/infra/node_modules/@clawup/core/dist/__tests__/schemas.test.d.ts +2 -0
- package/infra/node_modules/@clawup/core/dist/__tests__/schemas.test.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/__tests__/schemas.test.js +124 -0
- package/infra/node_modules/@clawup/core/dist/__tests__/schemas.test.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/coding-agent-registry.d.ts +32 -0
- package/infra/node_modules/@clawup/core/dist/coding-agent-registry.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/coding-agent-registry.js +56 -0
- package/infra/node_modules/@clawup/core/dist/coding-agent-registry.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/constants.d.ts +137 -0
- package/infra/node_modules/@clawup/core/dist/constants.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/constants.js +314 -0
- package/infra/node_modules/@clawup/core/dist/constants.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/dep-registry.d.ts +25 -0
- package/infra/node_modules/@clawup/core/dist/dep-registry.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/dep-registry.js +46 -0
- package/infra/node_modules/@clawup/core/dist/dep-registry.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/deps.d.ts +18 -0
- package/infra/node_modules/@clawup/core/dist/deps.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/deps.js +39 -0
- package/infra/node_modules/@clawup/core/dist/deps.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/identity.d.ts +20 -0
- package/infra/node_modules/@clawup/core/dist/identity.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/identity.js +217 -0
- package/infra/node_modules/@clawup/core/dist/identity.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/index.d.ts +18 -0
- package/infra/node_modules/@clawup/core/dist/index.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/index.js +52 -0
- package/infra/node_modules/@clawup/core/dist/index.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/plugin-registry.d.ts +13 -0
- package/infra/node_modules/@clawup/core/dist/plugin-registry.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/plugin-registry.js +24 -0
- package/infra/node_modules/@clawup/core/dist/plugin-registry.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/identity.d.ts +74 -0
- package/infra/node_modules/@clawup/core/dist/schemas/identity.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/identity.js +45 -0
- package/infra/node_modules/@clawup/core/dist/schemas/identity.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/index.d.ts +6 -0
- package/infra/node_modules/@clawup/core/dist/schemas/index.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/index.js +13 -0
- package/infra/node_modules/@clawup/core/dist/schemas/index.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/manifest.d.ts +159 -0
- package/infra/node_modules/@clawup/core/dist/schemas/manifest.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/schemas/manifest.js +54 -0
- package/infra/node_modules/@clawup/core/dist/schemas/manifest.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/skills.d.ts +30 -0
- package/infra/node_modules/@clawup/core/dist/skills.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/skills.js +52 -0
- package/infra/node_modules/@clawup/core/dist/skills.js.map +1 -0
- package/infra/node_modules/@clawup/core/dist/types.d.ts +59 -0
- package/infra/node_modules/@clawup/core/dist/types.d.ts.map +1 -0
- package/infra/node_modules/@clawup/core/dist/types.js +30 -0
- package/infra/node_modules/@clawup/core/dist/types.js.map +1 -0
- package/infra/node_modules/@clawup/core/package.json +46 -0
- package/infra/package.json +12 -0
- package/package.json +43 -0
- package/scripts/postinstall.mjs +395 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw Agent - Reusable Pulumi ComponentResource
|
|
4
|
+
* Provisions a single OpenClaw agent on AWS EC2
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.OpenClawAgent = void 0;
|
|
41
|
+
const pulumi = __importStar(require("@pulumi/pulumi"));
|
|
42
|
+
const aws = __importStar(require("@pulumi/aws"));
|
|
43
|
+
const zlib = __importStar(require("zlib"));
|
|
44
|
+
const shared_1 = require("./shared");
|
|
45
|
+
/**
|
|
46
|
+
* OpenClaw Agent ComponentResource
|
|
47
|
+
*
|
|
48
|
+
* Provisions a complete OpenClaw agent on AWS EC2 including:
|
|
49
|
+
* - VPC, subnet, and security group (or uses existing)
|
|
50
|
+
* - EC2 instance with Ubuntu 24.04
|
|
51
|
+
* - Docker, Node.js 22, and OpenClaw installation
|
|
52
|
+
* - Tailscale for secure HTTPS access
|
|
53
|
+
* - Systemd service for auto-start
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const agent = new OpenClawAgent("my-agent", {
|
|
58
|
+
* anthropicApiKey: config.requireSecret("anthropicApiKey"),
|
|
59
|
+
* tailscaleAuthKey: config.requireSecret("tailscaleAuthKey"),
|
|
60
|
+
* tailnetDnsName: config.require("tailnetDnsName"),
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* export const url = agent.tailscaleUrl;
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
class OpenClawAgent extends pulumi.ComponentResource {
|
|
67
|
+
/** EC2 instance public IP */
|
|
68
|
+
publicIp;
|
|
69
|
+
/** EC2 instance public DNS */
|
|
70
|
+
publicDns;
|
|
71
|
+
/** Tailscale URL with authentication token */
|
|
72
|
+
tailscaleUrl;
|
|
73
|
+
/** Gateway authentication token */
|
|
74
|
+
gatewayToken;
|
|
75
|
+
/** SSH private key (Ed25519) */
|
|
76
|
+
sshPrivateKey;
|
|
77
|
+
/** SSH public key */
|
|
78
|
+
sshPublicKey;
|
|
79
|
+
/** EC2 instance ID */
|
|
80
|
+
instanceId;
|
|
81
|
+
/** VPC ID */
|
|
82
|
+
vpcId;
|
|
83
|
+
/** Subnet ID */
|
|
84
|
+
subnetId;
|
|
85
|
+
/** Security Group ID */
|
|
86
|
+
securityGroupId;
|
|
87
|
+
constructor(name, args, opts) {
|
|
88
|
+
super("clawup:aws:OpenClawAgent", name, {}, opts);
|
|
89
|
+
const defaultResourceOptions = { parent: this };
|
|
90
|
+
// Defaults
|
|
91
|
+
const instanceType = args.instanceType ?? "t3.medium";
|
|
92
|
+
const gatewayPort = args.gatewayPort ?? 18789;
|
|
93
|
+
const browserPort = args.browserPort ?? 18791;
|
|
94
|
+
const volumeSize = args.volumeSize ?? 30;
|
|
95
|
+
const model = args.model ?? "anthropic/claude-opus-4-6";
|
|
96
|
+
const enableSandbox = args.enableSandbox ?? true;
|
|
97
|
+
const baseTags = args.tags ?? {};
|
|
98
|
+
// Generate SSH key pair + gateway token
|
|
99
|
+
const { sshKey, gatewayTokenValue } = (0, shared_1.generateKeyPairAndToken)(name, defaultResourceOptions);
|
|
100
|
+
// VPC - create or use existing
|
|
101
|
+
let vpcId;
|
|
102
|
+
let internetGateway;
|
|
103
|
+
if (args.vpcId) {
|
|
104
|
+
vpcId = pulumi.output(args.vpcId);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
const vpc = new aws.ec2.Vpc(`${name}-vpc`, {
|
|
108
|
+
cidrBlock: "10.0.0.0/16",
|
|
109
|
+
enableDnsHostnames: true,
|
|
110
|
+
enableDnsSupport: true,
|
|
111
|
+
tags: pulumi.output(baseTags).apply((tags) => ({
|
|
112
|
+
...tags,
|
|
113
|
+
Name: `${name}-vpc`,
|
|
114
|
+
})),
|
|
115
|
+
}, defaultResourceOptions);
|
|
116
|
+
vpcId = vpc.id;
|
|
117
|
+
internetGateway = new aws.ec2.InternetGateway(`${name}-igw`, {
|
|
118
|
+
vpcId: vpc.id,
|
|
119
|
+
tags: pulumi.output(baseTags).apply((tags) => ({
|
|
120
|
+
...tags,
|
|
121
|
+
Name: `${name}-igw`,
|
|
122
|
+
})),
|
|
123
|
+
}, defaultResourceOptions);
|
|
124
|
+
}
|
|
125
|
+
// Subnet - create or use existing
|
|
126
|
+
let subnetId;
|
|
127
|
+
if (args.subnetId) {
|
|
128
|
+
subnetId = pulumi.output(args.subnetId);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
const subnet = new aws.ec2.Subnet(`${name}-subnet`, {
|
|
132
|
+
vpcId: vpcId,
|
|
133
|
+
cidrBlock: "10.0.1.0/24",
|
|
134
|
+
mapPublicIpOnLaunch: true,
|
|
135
|
+
tags: pulumi.output(baseTags).apply((tags) => ({
|
|
136
|
+
...tags,
|
|
137
|
+
Name: `${name}-subnet`,
|
|
138
|
+
})),
|
|
139
|
+
}, defaultResourceOptions);
|
|
140
|
+
subnetId = subnet.id;
|
|
141
|
+
// Create route table only if we created the VPC
|
|
142
|
+
if (internetGateway) {
|
|
143
|
+
const routeTable = new aws.ec2.RouteTable(`${name}-rt`, {
|
|
144
|
+
vpcId: vpcId,
|
|
145
|
+
routes: [
|
|
146
|
+
{
|
|
147
|
+
cidrBlock: "0.0.0.0/0",
|
|
148
|
+
gatewayId: internetGateway.id,
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
tags: pulumi.output(baseTags).apply((tags) => ({
|
|
152
|
+
...tags,
|
|
153
|
+
Name: `${name}-rt`,
|
|
154
|
+
})),
|
|
155
|
+
}, defaultResourceOptions);
|
|
156
|
+
new aws.ec2.RouteTableAssociation(`${name}-rta`, {
|
|
157
|
+
subnetId: subnet.id,
|
|
158
|
+
routeTableId: routeTable.id,
|
|
159
|
+
}, defaultResourceOptions);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Security Group - create or use existing
|
|
163
|
+
let securityGroupId;
|
|
164
|
+
if (args.securityGroupId) {
|
|
165
|
+
securityGroupId = pulumi.output(args.securityGroupId);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const securityGroup = new aws.ec2.SecurityGroup(`${name}-sg`, {
|
|
169
|
+
vpcId: vpcId,
|
|
170
|
+
description: `Security group for OpenClaw agent ${name}`,
|
|
171
|
+
// SSH is disabled by default — Tailscale is the primary access method.
|
|
172
|
+
// Pass allowedSshCidrs to enable SSH from specific IPs as a fallback.
|
|
173
|
+
ingress: pulumi
|
|
174
|
+
.output(args.allowedSshCidrs ?? [])
|
|
175
|
+
.apply((cidrs) => cidrs.length > 0
|
|
176
|
+
? [
|
|
177
|
+
{
|
|
178
|
+
description: "SSH access (restricted)",
|
|
179
|
+
fromPort: 22,
|
|
180
|
+
toPort: 22,
|
|
181
|
+
protocol: "tcp",
|
|
182
|
+
cidrBlocks: cidrs,
|
|
183
|
+
},
|
|
184
|
+
]
|
|
185
|
+
: []),
|
|
186
|
+
egress: [
|
|
187
|
+
{
|
|
188
|
+
fromPort: 0,
|
|
189
|
+
toPort: 0,
|
|
190
|
+
protocol: "-1",
|
|
191
|
+
cidrBlocks: ["0.0.0.0/0"],
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
tags: pulumi.output(baseTags).apply((tags) => ({
|
|
195
|
+
...tags,
|
|
196
|
+
Name: `${name}-sg`,
|
|
197
|
+
})),
|
|
198
|
+
}, defaultResourceOptions);
|
|
199
|
+
securityGroupId = securityGroup.id;
|
|
200
|
+
}
|
|
201
|
+
// Create EC2 key pair
|
|
202
|
+
const keyPair = new aws.ec2.KeyPair(`${name}-keypair`, {
|
|
203
|
+
publicKey: sshKey.publicKeyOpenssh,
|
|
204
|
+
tags: pulumi.output(baseTags).apply((tags) => ({
|
|
205
|
+
...tags,
|
|
206
|
+
Name: `${name}-keypair`,
|
|
207
|
+
})),
|
|
208
|
+
}, defaultResourceOptions);
|
|
209
|
+
// Get Ubuntu 24.04 AMI
|
|
210
|
+
const ami = aws.ec2.getAmiOutput({
|
|
211
|
+
owners: ["099720109477"], // Canonical
|
|
212
|
+
mostRecent: true,
|
|
213
|
+
filters: [
|
|
214
|
+
{
|
|
215
|
+
name: "name",
|
|
216
|
+
values: [
|
|
217
|
+
"ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*",
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
{ name: "virtualization-type", values: ["hvm"] },
|
|
221
|
+
],
|
|
222
|
+
}, defaultResourceOptions);
|
|
223
|
+
// Generate cloud-init user data
|
|
224
|
+
const userData = (0, shared_1.buildCloudInitUserData)(name, args, gatewayTokenValue, {
|
|
225
|
+
gatewayPort: gatewayPort,
|
|
226
|
+
browserPort: browserPort,
|
|
227
|
+
model: model,
|
|
228
|
+
enableSandbox: enableSandbox,
|
|
229
|
+
});
|
|
230
|
+
// Create EC2 instance
|
|
231
|
+
const instance = new aws.ec2.Instance(`${name}-instance`, {
|
|
232
|
+
ami: ami.id,
|
|
233
|
+
instanceType: instanceType,
|
|
234
|
+
subnetId: subnetId,
|
|
235
|
+
vpcSecurityGroupIds: [securityGroupId],
|
|
236
|
+
keyName: keyPair.keyName,
|
|
237
|
+
userDataBase64: userData.apply((script) => {
|
|
238
|
+
const gzipped = zlib.gzipSync(Buffer.from(script));
|
|
239
|
+
return gzipped.toString("base64");
|
|
240
|
+
}),
|
|
241
|
+
userDataReplaceOnChange: true,
|
|
242
|
+
// Enforce IMDSv2 to prevent unauthenticated metadata access
|
|
243
|
+
metadataOptions: {
|
|
244
|
+
httpTokens: "required",
|
|
245
|
+
httpEndpoint: "enabled",
|
|
246
|
+
httpPutResponseHopLimit: 2,
|
|
247
|
+
},
|
|
248
|
+
rootBlockDevice: {
|
|
249
|
+
volumeSize: volumeSize,
|
|
250
|
+
volumeType: "gp3",
|
|
251
|
+
},
|
|
252
|
+
tags: pulumi.output(baseTags).apply((tags) => ({
|
|
253
|
+
...tags,
|
|
254
|
+
Name: name,
|
|
255
|
+
Component: "openclaw-agent",
|
|
256
|
+
})),
|
|
257
|
+
}, defaultResourceOptions);
|
|
258
|
+
// Set outputs
|
|
259
|
+
this.publicIp = instance.publicIp;
|
|
260
|
+
this.publicDns = instance.publicDns;
|
|
261
|
+
this.instanceId = instance.id;
|
|
262
|
+
this.vpcId = vpcId;
|
|
263
|
+
this.subnetId = subnetId;
|
|
264
|
+
this.securityGroupId = securityGroupId;
|
|
265
|
+
this.sshPrivateKey = pulumi.secret(sshKey.privateKeyOpenssh);
|
|
266
|
+
this.sshPublicKey = sshKey.publicKeyOpenssh;
|
|
267
|
+
this.gatewayToken = pulumi.secret(gatewayTokenValue);
|
|
268
|
+
// Tailscale hostname includes stack name to avoid conflicts (e.g., dev-agent-pm)
|
|
269
|
+
const tsHostname = `${pulumi.getStack()}-${name}`;
|
|
270
|
+
this.tailscaleUrl = pulumi.secret(pulumi.interpolate `https://${tsHostname}.${args.tailnetDnsName}/?token=${gatewayTokenValue}`);
|
|
271
|
+
// Register outputs
|
|
272
|
+
this.registerOutputs({
|
|
273
|
+
publicIp: this.publicIp,
|
|
274
|
+
publicDns: this.publicDns,
|
|
275
|
+
tailscaleUrl: this.tailscaleUrl,
|
|
276
|
+
gatewayToken: this.gatewayToken,
|
|
277
|
+
sshPrivateKey: this.sshPrivateKey,
|
|
278
|
+
sshPublicKey: this.sshPublicKey,
|
|
279
|
+
instanceId: this.instanceId,
|
|
280
|
+
vpcId: this.vpcId,
|
|
281
|
+
subnetId: this.subnetId,
|
|
282
|
+
securityGroupId: this.securityGroupId,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
exports.OpenClawAgent = OpenClawAgent;
|
|
287
|
+
//# sourceMappingURL=openclaw-agent.js.map
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared helpers for OpenClaw agent components (AWS + Hetzner)
|
|
4
|
+
*
|
|
5
|
+
* Extracts the duplicated SSH key generation, gateway token derivation,
|
|
6
|
+
* and cloud-init user data assembly that was identical across providers.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.generateKeyPairAndToken = generateKeyPairAndToken;
|
|
43
|
+
exports.buildCloudInitUserData = buildCloudInitUserData;
|
|
44
|
+
const pulumi = __importStar(require("@pulumi/pulumi"));
|
|
45
|
+
const tls = __importStar(require("@pulumi/tls"));
|
|
46
|
+
const crypto = __importStar(require("crypto"));
|
|
47
|
+
const cloud_init_1 = require("./cloud-init");
|
|
48
|
+
/**
|
|
49
|
+
* Generate an SSH key pair and a gateway authentication token.
|
|
50
|
+
* Both providers use the same ED25519 key generation pattern.
|
|
51
|
+
*/
|
|
52
|
+
function generateKeyPairAndToken(name, resourceOptions) {
|
|
53
|
+
const sshKey = new tls.PrivateKey(`${name}-ssh-key`, { algorithm: "ED25519" }, resourceOptions);
|
|
54
|
+
const tokenKey = new tls.PrivateKey(`${name}-gateway-token-key`, { algorithm: "ED25519" }, resourceOptions);
|
|
55
|
+
const gatewayTokenValue = tokenKey.publicKeyOpenssh.apply((key) => {
|
|
56
|
+
const hash = crypto.createHash("sha256").update(key).digest("hex");
|
|
57
|
+
return hash.substring(0, 48);
|
|
58
|
+
});
|
|
59
|
+
return { sshKey, gatewayTokenValue };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Build the cloud-init user data script from base agent args.
|
|
63
|
+
*
|
|
64
|
+
* Resolves all Pulumi secrets/outputs, assembles a CloudInitConfig,
|
|
65
|
+
* generates + interpolates the script, and optionally compresses it.
|
|
66
|
+
*/
|
|
67
|
+
function buildCloudInitUserData(name, args, gatewayTokenValue, defaults) {
|
|
68
|
+
const pluginSecretEntries = Object.entries(args.pluginSecrets ?? {});
|
|
69
|
+
const pluginSecretOutputs = pluginSecretEntries.map(([, v]) => pulumi.output(v));
|
|
70
|
+
const depSecretEntries = Object.entries(args.depSecrets ?? {});
|
|
71
|
+
const depSecretOutputs = depSecretEntries.map(([, v]) => pulumi.output(v));
|
|
72
|
+
// Stage 1: resolve all string secrets (same type, safe in one pulumi.all)
|
|
73
|
+
return pulumi
|
|
74
|
+
.all([
|
|
75
|
+
args.tailscaleAuthKey,
|
|
76
|
+
args.anthropicApiKey,
|
|
77
|
+
gatewayTokenValue,
|
|
78
|
+
...pluginSecretOutputs,
|
|
79
|
+
...depSecretOutputs,
|
|
80
|
+
])
|
|
81
|
+
.apply(([tsAuthKey, apiKey, gwToken, ...secretValues]) => {
|
|
82
|
+
// Stage 2: resolve mixed-type Input<> config values
|
|
83
|
+
return pulumi
|
|
84
|
+
.all([
|
|
85
|
+
pulumi.output(defaults?.gatewayPort ?? args.gatewayPort ?? 18789),
|
|
86
|
+
pulumi.output(defaults?.browserPort ?? args.browserPort ?? 18791),
|
|
87
|
+
pulumi.output(defaults?.model ?? args.model ?? "anthropic/claude-opus-4-6"),
|
|
88
|
+
pulumi.output(defaults?.enableSandbox ?? args.enableSandbox ?? true),
|
|
89
|
+
])
|
|
90
|
+
.apply(([gatewayPort, browserPort, model, enableSandbox]) => {
|
|
91
|
+
const tsHostname = `${pulumi.getStack()}-${name}`;
|
|
92
|
+
// Build additional secrets map from plugin secrets + dep secrets
|
|
93
|
+
const additionalSecrets = {};
|
|
94
|
+
pluginSecretEntries.forEach(([envVar], idx) => {
|
|
95
|
+
additionalSecrets[envVar] = secretValues[idx];
|
|
96
|
+
});
|
|
97
|
+
depSecretEntries.forEach(([envVar], idx) => {
|
|
98
|
+
additionalSecrets[envVar] = secretValues[pluginSecretEntries.length + idx];
|
|
99
|
+
});
|
|
100
|
+
const cloudInitConfig = {
|
|
101
|
+
anthropicApiKey: apiKey,
|
|
102
|
+
tailscaleAuthKey: tsAuthKey,
|
|
103
|
+
gatewayToken: gwToken,
|
|
104
|
+
gatewayPort: gatewayPort,
|
|
105
|
+
browserPort: browserPort,
|
|
106
|
+
model: model,
|
|
107
|
+
backupModel: args.backupModel,
|
|
108
|
+
codingAgent: args.codingAgent,
|
|
109
|
+
enableSandbox: enableSandbox,
|
|
110
|
+
tailscaleHostname: tsHostname,
|
|
111
|
+
workspaceFiles: args.workspaceFiles,
|
|
112
|
+
envVars: args.envVars,
|
|
113
|
+
postSetupCommands: args.postSetupCommands,
|
|
114
|
+
createUbuntuUser: defaults?.createUbuntuUser,
|
|
115
|
+
plugins: args.plugins,
|
|
116
|
+
enableFunnel: args.enableFunnel,
|
|
117
|
+
clawhubSkills: args.clawhubSkills,
|
|
118
|
+
deps: args.deps,
|
|
119
|
+
depSecrets: additionalSecrets,
|
|
120
|
+
};
|
|
121
|
+
const script = (0, cloud_init_1.generateCloudInit)(cloudInitConfig);
|
|
122
|
+
const interpolated = (0, cloud_init_1.interpolateCloudInit)(script, {
|
|
123
|
+
anthropicApiKey: apiKey,
|
|
124
|
+
tailscaleAuthKey: tsAuthKey,
|
|
125
|
+
gatewayToken: gwToken,
|
|
126
|
+
additionalSecrets,
|
|
127
|
+
});
|
|
128
|
+
return defaults?.compress ? (0, cloud_init_1.compressCloudInit)(interpolated) : interpolated;
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=shared.js.map
|