-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
102 lines (90 loc) · 3.07 KB
/
index.js
File metadata and controls
102 lines (90 loc) · 3.07 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
import { ApiClient, ApiClientInMemoryContextProvider } from '@northflank/js-client';
const PROJECT_ID = process.env.NORTHFLANK_PROJECT_ID;
const TOKEN = process.env.NORTHFLANK_TOKEN;
if (!TOKEN) {
console.error('Missing NORTHFLANK_TOKEN environment variable');
process.exit(1);
}
if (!PROJECT_ID) {
console.error('Missing NORTHFLANK_PROJECT_ID environment variable');
process.exit(1);
}
// --- Init SDK ---
console.log('Initializing API client...');
const contextProvider = new ApiClientInMemoryContextProvider();
await contextProvider.addContext({
name: 'context',
token: TOKEN,
});
const apiClient = new ApiClient(contextProvider, {
throwErrorOnHttpErrorCode: true,
});
console.log('API client initialized');
// --- Create sandbox ---
const sandboxId = `sandbox-${crypto.randomUUID().split('-')[4]}`;
console.log(`Creating sandbox service: ${sandboxId}`);
await apiClient.create.service.deployment({
parameters: { projectId: PROJECT_ID },
data: {
name: sandboxId,
billing: { deploymentPlan: 'nf-compute-200' },
deployment: {
instances: 0,
external: { imagePath: 'ubuntu:22.04' },
storage: { ephemeralStorage: { storageSize: 2048 } },
},
},
});
console.log('Sandbox service created');
// --- Attach volume ---
console.log(`Attaching volume data-${sandboxId} at /workspace...`);
await apiClient.create.volume({
parameters: { projectId: PROJECT_ID },
data: {
name: `data-${sandboxId}`,
mounts: [{ containerMountPath: '/workspace' }],
spec: {
accessMode: 'ReadWriteMany',
storageClassName: 'nf-multi-rw',
storageSize: 10240,
},
attachedObjects: [{ id: sandboxId, type: 'service' }],
},
});
console.log('Volume attached');
// --- Boot ---
console.log('Scaling sandbox to 1 instance...');
await apiClient.scale.service({
parameters: { projectId: PROJECT_ID, serviceId: sandboxId },
data: { instances: 1 },
});
console.log('Waiting for sandbox to be ready...');
// Wait for ready
while (true) {
const svc = await apiClient.get.service({
parameters: { projectId: PROJECT_ID, serviceId: sandboxId },
});
const status = svc.data?.status?.deployment?.status;
if (status === 'COMPLETED') break;
if (status === 'FAILED') throw new Error('Sandbox failed to start');
console.log(` Status: ${status ?? 'PENDING'}`);
await new Promise((r) => setTimeout(r, 1000));
}
console.log('Sandbox is ready');
// --- Execute code ---
console.log('Executing command: echo \'Hello from the sandbox!\'');
const handle = await apiClient.exec.execServiceSession(
{ projectId: PROJECT_ID, serviceId: sandboxId },
{ shell: 'bash -c', command: "echo 'Hello from the sandbox!'" }
);
const stdout = [];
handle.stdOut.on('data', (d) => stdout.push(d.toString()));
const result = await handle.waitForCommandResult();
console.log(`Command finished with exit code ${result.exitCode}`);
console.log(`Output: ${stdout.join('')}`);
// --- Cleanup ---
console.log(`Deleting sandbox service ${sandboxId}...`);
await apiClient.delete.service({
parameters: { projectId: PROJECT_ID, serviceId: sandboxId },
});
console.log('Sandbox deleted. Done.');