anycloud 0.0.12 → 0.0.13
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/binaries/anycloud-darwin-arm64 +0 -0
- package/binaries/anycloud-darwin-x64 +0 -0
- package/binaries/anycloud-linux-arm64 +0 -0
- package/binaries/anycloud-linux-x64 +0 -0
- package/dist/cli/commands/daemon/index.js +34 -14
- package/dist/cli/commands/daemon/index.js.map +1 -1
- package/dist/cli/commands/status.js +3 -3
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/daemon/cluster.js +23 -25
- package/dist/daemon/cluster.js.map +1 -1
- package/dist/shared/types.js +5 -0
- package/dist/shared/types.js.map +1 -1
- package/package.json +4 -4
- package/dist/daemon/cert.js +0 -31
- package/dist/daemon/cert.js.map +0 -1
- package/dist/daemon/docker.js +0 -208
- package/dist/daemon/docker.js.map +0 -1
- package/dist/daemon/server.js +0 -255
- package/dist/daemon/server.js.map +0 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,28 +1,36 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { startServer } from '../../../daemon/server.js';
|
|
3
2
|
import { log } from '../../../daemon/logger.js';
|
|
4
|
-
import {
|
|
3
|
+
import { Coordinator } from '../../../daemon/cluster.js';
|
|
5
4
|
export function createDaemonCommand() {
|
|
6
5
|
return new Command('daemon')
|
|
7
6
|
.description('Start the AnyCloud daemon (runs on VMs)')
|
|
8
|
-
.argument('<
|
|
7
|
+
.argument('<props-json>', 'JSON string containing DeploymentProps')
|
|
9
8
|
.argument('<conductor-url>', 'URL of the conductor to connect to')
|
|
10
|
-
.
|
|
11
|
-
.action(async (secret, conductorUrl, options) => {
|
|
9
|
+
.action(async (propsJson, conductorUrl) => {
|
|
12
10
|
try {
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
options.type !== DeploymentType.Job) {
|
|
16
|
-
log.error('Invalid deployment type. Must be either "server" or "job"');
|
|
17
|
-
process.exit(1);
|
|
18
|
-
}
|
|
19
|
-
const deploymentType = options.type;
|
|
11
|
+
// Parse deployment props from JSON string
|
|
12
|
+
const deploymentProps = JSON.parse(propsJson);
|
|
20
13
|
log.info('Starting AnyCloud Daemon', {
|
|
21
|
-
|
|
14
|
+
deploymentId: deploymentProps.id,
|
|
15
|
+
deploymentType: deploymentProps.deploymentType,
|
|
22
16
|
nodeVersion: process.version,
|
|
23
17
|
});
|
|
24
|
-
|
|
18
|
+
// Setup process handlers
|
|
19
|
+
setupProcessHandlers();
|
|
20
|
+
// Create coordinator and start
|
|
21
|
+
const coordinator = new Coordinator();
|
|
22
|
+
await coordinator.start(conductorUrl, deploymentProps);
|
|
23
|
+
// Graceful shutdown
|
|
24
|
+
const shutdown = async () => {
|
|
25
|
+
log.info('Shutdown signal received');
|
|
26
|
+
await coordinator.stop();
|
|
27
|
+
process.exit(0);
|
|
28
|
+
};
|
|
29
|
+
process.on('SIGTERM', shutdown);
|
|
30
|
+
process.on('SIGINT', shutdown);
|
|
25
31
|
log.info('Daemon started successfully');
|
|
32
|
+
// Keep process alive
|
|
33
|
+
await new Promise(() => { });
|
|
26
34
|
}
|
|
27
35
|
catch (error) {
|
|
28
36
|
log.error('Failed to start daemon', error);
|
|
@@ -30,4 +38,16 @@ export function createDaemonCommand() {
|
|
|
30
38
|
}
|
|
31
39
|
});
|
|
32
40
|
}
|
|
41
|
+
function setupProcessHandlers() {
|
|
42
|
+
process.on('uncaughtException', (error) => {
|
|
43
|
+
log.error('Uncaught exception', {
|
|
44
|
+
error: error.message,
|
|
45
|
+
stack: error.stack,
|
|
46
|
+
});
|
|
47
|
+
setTimeout(() => process.exit(1), 1000);
|
|
48
|
+
});
|
|
49
|
+
process.on('unhandledRejection', (reason) => {
|
|
50
|
+
log.warn('Unhandled promise rejection', { reason: String(reason) });
|
|
51
|
+
});
|
|
52
|
+
}
|
|
33
53
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/commands/daemon/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGzD,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACzB,WAAW,CAAC,yCAAyC,CAAC;SACtD,QAAQ,CAAC,cAAc,EAAE,wCAAwC,CAAC;SAClE,QAAQ,CAAC,iBAAiB,EAAE,oCAAoC,CAAC;SACjE,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,YAAoB,EAAE,EAAE;QACxD,IAAI,CAAC;YACH,0CAA0C;YAC1C,MAAM,eAAe,GAAoB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAE/D,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE;gBACnC,YAAY,EAAE,eAAe,CAAC,EAAE;gBAChC,cAAc,EAAE,eAAe,CAAC,cAAc;gBAC9C,WAAW,EAAE,OAAO,CAAC,OAAO;aAC7B,CAAC,CAAC;YAEH,yBAAyB;YACzB,oBAAoB,EAAE,CAAC;YAEvB,+BAA+B;YAC/B,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;YACtC,MAAM,WAAW,CAAC,KAAK,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;YAEvD,oBAAoB;YACpB,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;gBAC1B,GAAG,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;gBACrC,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;gBACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC;YAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAE/B,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YAExC,qBAAqB;YACrB,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAY,EAAE,EAAE;QAC/C,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE;YAC9B,KAAK,EAAE,KAAK,CAAC,OAAO;YACpB,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC,CAAC;QACH,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAe,EAAE,EAAE;QACnD,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -23,7 +23,7 @@ Examples:
|
|
|
23
23
|
$ anycloud status
|
|
24
24
|
|
|
25
25
|
Output:
|
|
26
|
-
|
|
26
|
+
🟢 running
|
|
27
27
|
|
|
28
28
|
VMs:
|
|
29
29
|
✓ 1.2.3.4 healthy
|
|
@@ -88,13 +88,13 @@ Output:
|
|
|
88
88
|
const spinner = createSpinner(`Fetching status...`).start();
|
|
89
89
|
const response = await getDeploymentStatus(deploymentId, accessToken, packageJson.version);
|
|
90
90
|
spinner.stop();
|
|
91
|
-
// Header: ID
|
|
91
|
+
// Header: state only (ID already shown in selection or logs)
|
|
92
92
|
const emoji = deploymentState
|
|
93
93
|
? stateEmoji[deploymentState] || '❓'
|
|
94
94
|
: '❓';
|
|
95
95
|
const stateText = deploymentState || 'unknown';
|
|
96
96
|
console.log('');
|
|
97
|
-
console.log(`${
|
|
97
|
+
console.log(`${emoji} ${stateText}`);
|
|
98
98
|
console.log('');
|
|
99
99
|
// Show per-VM status if available
|
|
100
100
|
if (response.vmStatuses && response.vmStatuses.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon/cluster.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
import { promises as dns } from 'dns';
|
|
6
6
|
import crypto from 'crypto';
|
|
7
|
-
import { CloudType } from '../shared/types.js';
|
|
7
|
+
import { CloudType, } from '../shared/types.js';
|
|
8
8
|
import { MetricsCollector } from './metrics.js';
|
|
9
9
|
import { PreemptionDetector } from './preemption.js';
|
|
10
10
|
import { log } from './logger.js';
|
|
@@ -15,29 +15,29 @@ const AWS_METADATA_URL = process.env.AWS_METADATA_URL || 'http://169.254.169.254
|
|
|
15
15
|
const AZURE_METADATA_URL = process.env.AZURE_METADATA_URL || 'http://169.254.169.254';
|
|
16
16
|
const GCP_METADATA_URL = process.env.GCP_METADATA_URL || 'http://metadata.google.internal';
|
|
17
17
|
export class Coordinator {
|
|
18
|
-
constructor(
|
|
19
|
-
this.
|
|
18
|
+
constructor() {
|
|
19
|
+
this.conductorUrl = null;
|
|
20
|
+
this.deploymentProps = null;
|
|
20
21
|
this.clusterInfo = null;
|
|
21
22
|
this.privateIp = null;
|
|
22
23
|
this.publicIp = null;
|
|
23
24
|
this.ackInterval = null;
|
|
24
25
|
this.metricsInterval = null;
|
|
25
26
|
this.preemptionDetector = null;
|
|
26
|
-
this.deploymentSecret = deploymentSecret;
|
|
27
27
|
this.metricsCollector = new MetricsCollector();
|
|
28
|
-
this.conductorUrl = conductorUrl;
|
|
29
28
|
}
|
|
30
29
|
/**
|
|
31
30
|
* Start deployment coordination
|
|
32
31
|
*/
|
|
33
|
-
async start(
|
|
34
|
-
this.
|
|
32
|
+
async start(conductorUrl, deploymentProps) {
|
|
33
|
+
this.conductorUrl = conductorUrl;
|
|
34
|
+
this.deploymentProps = deploymentProps;
|
|
35
35
|
// Get this VM's IP addresses
|
|
36
36
|
await this.discoverOwnIps();
|
|
37
37
|
// Detect cloud provider
|
|
38
38
|
const cloudProvider = await this.detectCloudProvider();
|
|
39
39
|
log.info('Cluster coordinator started', {
|
|
40
|
-
id:
|
|
40
|
+
id: deploymentProps.id,
|
|
41
41
|
privateIp: this.privateIp,
|
|
42
42
|
publicIp: this.publicIp,
|
|
43
43
|
cloudProvider,
|
|
@@ -88,14 +88,14 @@ export class Coordinator {
|
|
|
88
88
|
*/
|
|
89
89
|
startAckHeartbeat() {
|
|
90
90
|
this.ackInterval = setInterval(async () => {
|
|
91
|
-
if (!this.
|
|
91
|
+
if (!this.deploymentProps)
|
|
92
92
|
return;
|
|
93
93
|
try {
|
|
94
94
|
await axios.post(`${this.conductorUrl}/v1/ack`, {
|
|
95
|
-
conductorToken: this.
|
|
96
|
-
id: this.
|
|
97
|
-
deploymentSecret: this.deploymentSecret,
|
|
98
|
-
githubUsername: this.
|
|
95
|
+
conductorToken: this.deploymentProps.conductorToken,
|
|
96
|
+
id: this.deploymentProps.id,
|
|
97
|
+
deploymentSecret: this.deploymentProps.deploymentSecret,
|
|
98
|
+
githubUsername: this.deploymentProps.githubUsername,
|
|
99
99
|
});
|
|
100
100
|
log.debug('Ack sent successfully');
|
|
101
101
|
}
|
|
@@ -128,10 +128,10 @@ export class Coordinator {
|
|
|
128
128
|
* Discover all VMs in the deployment via DNS TXT records
|
|
129
129
|
*/
|
|
130
130
|
async discoverClusterVMs() {
|
|
131
|
-
if (!this.
|
|
131
|
+
if (!this.deploymentProps)
|
|
132
132
|
return;
|
|
133
133
|
try {
|
|
134
|
-
const domain = this.
|
|
134
|
+
const domain = this.deploymentProps.domain;
|
|
135
135
|
const txtRecords = await dns.resolveTxt(domain);
|
|
136
136
|
const vms = [];
|
|
137
137
|
for (const record of txtRecords) {
|
|
@@ -189,7 +189,7 @@ export class Coordinator {
|
|
|
189
189
|
* Check metrics and trigger scaling if needed
|
|
190
190
|
*/
|
|
191
191
|
async checkAndScale() {
|
|
192
|
-
if (!this.
|
|
192
|
+
if (!this.deploymentProps)
|
|
193
193
|
return;
|
|
194
194
|
const scalingFactor = this.metricsCollector.calculateScalingFactor();
|
|
195
195
|
if (scalingFactor === 1.0) {
|
|
@@ -197,7 +197,9 @@ export class Coordinator {
|
|
|
197
197
|
}
|
|
198
198
|
log.info('Triggering scale operation', { scalingFactor });
|
|
199
199
|
try {
|
|
200
|
-
await axios.post(`${this.conductorUrl}/v1/scale`,
|
|
200
|
+
await axios.post(`${this.conductorUrl}/v1/scale`, {
|
|
201
|
+
...this.deploymentProps,
|
|
202
|
+
});
|
|
201
203
|
log.info('Scale request sent successfully');
|
|
202
204
|
}
|
|
203
205
|
catch (error) {
|
|
@@ -273,17 +275,13 @@ export class Coordinator {
|
|
|
273
275
|
* This triggers a zero-downtime upgrade to replace corrupted VMs with fresh instances.
|
|
274
276
|
*/
|
|
275
277
|
async triggerPanic(reason) {
|
|
276
|
-
if (!this.
|
|
277
|
-
log.error('Cannot trigger panic
|
|
278
|
-
|
|
278
|
+
if (!this.deploymentProps) {
|
|
279
|
+
log.error('Cannot trigger panic: daemonProps not set');
|
|
280
|
+
return;
|
|
279
281
|
}
|
|
280
282
|
try {
|
|
281
283
|
log.error('DAEMON PANIC: Triggering self-recovery', { reason });
|
|
282
|
-
|
|
283
|
-
await axios.post(`${this.conductorUrl}/v1/panic`, {
|
|
284
|
-
...this.daemonProps,
|
|
285
|
-
message: reason, // Include reason for debugging
|
|
286
|
-
}, { timeout: 30000 });
|
|
284
|
+
await axios.post(`${this.conductorUrl}/v1/panic`, { ...this.deploymentProps, message: reason }, { timeout: 30000 });
|
|
287
285
|
log.info('Panic request sent successfully - awaiting replacement');
|
|
288
286
|
}
|
|
289
287
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cluster.js","sourceRoot":"","sources":["../../src/daemon/cluster.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"cluster.js","sourceRoot":"","sources":["../../src/daemon/cluster.ts"],"names":[],"mappings":"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"}
|
package/dist/shared/types.js
CHANGED
|
@@ -14,6 +14,7 @@ export var CloudType;
|
|
|
14
14
|
CloudType["AWS"] = "AWS";
|
|
15
15
|
CloudType["GCP"] = "GCP";
|
|
16
16
|
CloudType["Azure"] = "Azure";
|
|
17
|
+
CloudType["Local"] = "Local";
|
|
17
18
|
})(CloudType || (CloudType = {}));
|
|
18
19
|
// Deployment type enum
|
|
19
20
|
export var DeploymentType;
|
|
@@ -53,6 +54,10 @@ const DEFAULT_VM_TYPES_AND_REGIONS = {
|
|
|
53
54
|
region: 'eastus',
|
|
54
55
|
vmType: 'Standard_B1s',
|
|
55
56
|
},
|
|
57
|
+
Local: {
|
|
58
|
+
region: 'local',
|
|
59
|
+
vmType: 'local',
|
|
60
|
+
},
|
|
56
61
|
};
|
|
57
62
|
// Cloud configuration class
|
|
58
63
|
export class CloudConfig {
|
package/dist/shared/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,iBAAiB,MAAM,2CAA2C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChG,OAAO,iBAAiB,MAAM,2CAA2C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChG,OAAO,mBAAmB,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACpG,OAAO,iBAAiB,MAAM,2CAA2C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChG,OAAO,iBAAiB,MAAM,2CAA2C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChG,OAAO,mBAAmB,MAAM,6CAA6C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEpG,sBAAsB;AACtB,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anycloud",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Deploy containerized jobs and servers to any cloud provider",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -30,9 +30,7 @@
|
|
|
30
30
|
"test:watch": "LOCAL=true vitest",
|
|
31
31
|
"test:integration": "yarn test:daemon && yarn test:preemption",
|
|
32
32
|
"terminate": "export $(cat .dev.vars.staging | xargs) && ts-node-dev scripts/forceTerminate.ts",
|
|
33
|
-
"
|
|
34
|
-
"test:daemon": "bash test/integration/daemon-basic.test.sh",
|
|
35
|
-
"test:daemon-private-image": "bash test/integration/daemon-private-image.test.sh",
|
|
33
|
+
"test:private-image": "bash test/integration/daemon-private-image.test.sh",
|
|
36
34
|
"test:preemption": "bash test/integration/daemon-preemption.test.sh",
|
|
37
35
|
"test:vmstartup": "bash test/integration/vmstartup.test.sh",
|
|
38
36
|
"test:conductor": "bash test/integration/conductor-startup.test.sh",
|
|
@@ -77,6 +75,7 @@
|
|
|
77
75
|
"posthog-node": "^5.11.2",
|
|
78
76
|
"prompts": "^2.4.2",
|
|
79
77
|
"semver": "^7.6.3",
|
|
78
|
+
"ssh2": "^1.17.0",
|
|
80
79
|
"systeminformation": "^5.21.0",
|
|
81
80
|
"unique-names-generator": "^4.3.1",
|
|
82
81
|
"uuid": "^11.0.5"
|
|
@@ -88,6 +87,7 @@
|
|
|
88
87
|
"@types/jest": "^26.0.20",
|
|
89
88
|
"@types/node-forge": "^0.9.7",
|
|
90
89
|
"@types/prompts": "^2.4.9",
|
|
90
|
+
"@types/ssh2": "^1.15.5",
|
|
91
91
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
|
92
92
|
"@typescript-eslint/parser": "^6.21.0",
|
|
93
93
|
"bun": "^1.3.3",
|
package/dist/daemon/cert.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate self-signed SSL certificates for daemon HTTPS server
|
|
3
|
-
*/
|
|
4
|
-
import forge from 'node-forge';
|
|
5
|
-
export function generateSelfSignedCert() {
|
|
6
|
-
const keys = forge.pki.rsa.generateKeyPair(2048);
|
|
7
|
-
const cert = forge.pki.createCertificate();
|
|
8
|
-
cert.publicKey = keys.publicKey;
|
|
9
|
-
cert.serialNumber = '01';
|
|
10
|
-
cert.validity.notBefore = new Date();
|
|
11
|
-
cert.validity.notAfter = new Date();
|
|
12
|
-
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
|
|
13
|
-
const attrs = [
|
|
14
|
-
{ name: 'commonName', value: 'anycloud-daemon' },
|
|
15
|
-
{ name: 'countryName', value: 'US' },
|
|
16
|
-
{ shortName: 'ST', value: 'California' },
|
|
17
|
-
{ name: 'localityName', value: 'San Francisco' },
|
|
18
|
-
{ name: 'organizationName', value: 'AnyCloud' },
|
|
19
|
-
{ shortName: 'OU', value: 'Daemon' },
|
|
20
|
-
];
|
|
21
|
-
cert.setSubject(attrs);
|
|
22
|
-
cert.setIssuer(attrs);
|
|
23
|
-
cert.sign(keys.privateKey);
|
|
24
|
-
const pemCert = forge.pki.certificateToPem(cert);
|
|
25
|
-
const pemKey = forge.pki.privateKeyToPem(keys.privateKey);
|
|
26
|
-
return {
|
|
27
|
-
cert: pemCert,
|
|
28
|
-
key: pemKey,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=cert.js.map
|
package/dist/daemon/cert.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cert.js","sourceRoot":"","sources":["../../src/daemon/cert.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,MAAM,UAAU,sBAAsB;IACpC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;IAE3C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IACzB,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IACrC,IAAI,CAAC,QAAQ,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC;IACpC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;IAE9E,MAAM,KAAK,GAAG;QACZ,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,iBAAiB,EAAE;QAChD,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE;QACpC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE;QACxC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE;QAChD,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,UAAU,EAAE;QAC/C,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE;KACrC,CAAC;IAEF,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACvB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACtB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAE3B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAE1D,OAAO;QACL,IAAI,EAAE,OAAO;QACb,GAAG,EAAE,MAAM;KACZ,CAAC;AACJ,CAAC"}
|
package/dist/daemon/docker.js
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Docker container management
|
|
3
|
-
*/
|
|
4
|
-
import Docker from 'dockerode';
|
|
5
|
-
import { log } from './logger.js';
|
|
6
|
-
import { DeploymentType } from '../shared/types.js';
|
|
7
|
-
const docker = new Docker();
|
|
8
|
-
const DEFAULT_SERVER_PORT = 8088;
|
|
9
|
-
export class DockerManager {
|
|
10
|
-
constructor() {
|
|
11
|
-
this.containerId = null;
|
|
12
|
-
this.containerName = null;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Run container from pre-built image
|
|
16
|
-
*/
|
|
17
|
-
async runFromImage(props) {
|
|
18
|
-
const { githubUsername, githubToken, image } = props;
|
|
19
|
-
try {
|
|
20
|
-
log.info('Pulling Docker image', { image });
|
|
21
|
-
// Prepare authentication for private registries
|
|
22
|
-
const pullOptions = {};
|
|
23
|
-
if (githubToken && githubUsername && image.includes('ghcr.io')) {
|
|
24
|
-
log.info('Using GitHub authentication for private registry', {
|
|
25
|
-
username: githubUsername,
|
|
26
|
-
});
|
|
27
|
-
// GitHub Container Registry authentication using OAuth token
|
|
28
|
-
pullOptions.authconfig = {
|
|
29
|
-
username: githubUsername,
|
|
30
|
-
password: githubToken, // OAuth access token with read:packages scope
|
|
31
|
-
serveraddress: 'ghcr.io',
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
// Pull image with optional authentication
|
|
35
|
-
const stream = await docker.pull(image, pullOptions);
|
|
36
|
-
await new Promise((resolve, reject) => {
|
|
37
|
-
docker.modem.followProgress(stream, (err, res) => {
|
|
38
|
-
if (err) {
|
|
39
|
-
log.error('Image pull failed', { error: err, image });
|
|
40
|
-
reject(err);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
resolve(res);
|
|
44
|
-
}
|
|
45
|
-
}, (event) => {
|
|
46
|
-
// Log pull progress events
|
|
47
|
-
if (event.error) {
|
|
48
|
-
log.error('Pull event error', { event });
|
|
49
|
-
}
|
|
50
|
-
else if (event.status) {
|
|
51
|
-
log.debug('Pull progress', {
|
|
52
|
-
status: event.status,
|
|
53
|
-
id: event.id,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
log.info('Image pulled successfully', { image });
|
|
59
|
-
// Run container
|
|
60
|
-
await this.runContainer(props);
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
log.error('Failed to run from image', error);
|
|
64
|
-
throw error;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Run Docker container with proper configuration
|
|
69
|
-
*/
|
|
70
|
-
async runContainer(props) {
|
|
71
|
-
const { id, image, deploymentType, domain, env, githubToken, bucketName, bucketHostPath, } = props;
|
|
72
|
-
this.containerName = `anycloud-${id}`;
|
|
73
|
-
// Stop and remove existing container if it exists
|
|
74
|
-
await this.stopContainer();
|
|
75
|
-
log.info('Starting container', {
|
|
76
|
-
image,
|
|
77
|
-
containerName: this.containerName,
|
|
78
|
-
deploymentType,
|
|
79
|
-
bucketName,
|
|
80
|
-
bucketHostPath,
|
|
81
|
-
});
|
|
82
|
-
// Only expose ports for app deployments (not for jobs)
|
|
83
|
-
const isJob = deploymentType === DeploymentType.Job;
|
|
84
|
-
const exposedPorts = isJob ? {} : { [`${DEFAULT_SERVER_PORT}/tcp`]: {} };
|
|
85
|
-
const portBindings = isJob
|
|
86
|
-
? {}
|
|
87
|
-
: {
|
|
88
|
-
[`${DEFAULT_SERVER_PORT}/tcp`]: [
|
|
89
|
-
{ HostPort: String(DEFAULT_SERVER_PORT) },
|
|
90
|
-
],
|
|
91
|
-
};
|
|
92
|
-
// Configure bucket volume mount if bucketName is provided
|
|
93
|
-
// Bind mount provides zero-copy access to bucket sync directory
|
|
94
|
-
let binds = [];
|
|
95
|
-
if (bucketName) {
|
|
96
|
-
// Use bucketHostPath if provided, otherwise read from file (written by VM startup script),
|
|
97
|
-
// otherwise fall back to /mnt for backward compatibility
|
|
98
|
-
let hostPath = bucketHostPath;
|
|
99
|
-
if (!hostPath) {
|
|
100
|
-
try {
|
|
101
|
-
const fs = await import('fs');
|
|
102
|
-
hostPath = fs
|
|
103
|
-
.readFileSync('/etc/anycloud-bucket-path', 'utf-8')
|
|
104
|
-
.trim();
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
// File doesn't exist, use default
|
|
108
|
-
hostPath = `/mnt/${bucketName}`;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
binds = [`${hostPath}:/mnt/${bucketName}`];
|
|
112
|
-
}
|
|
113
|
-
// Merge user-provided env vars with system env vars
|
|
114
|
-
// System env vars take priority
|
|
115
|
-
const userEnvArray = env
|
|
116
|
-
? Object.entries(env).map(([key, value]) => `${key}=${value}`)
|
|
117
|
-
: [];
|
|
118
|
-
const systemEnvArray = [
|
|
119
|
-
`ID=${id}`,
|
|
120
|
-
`DOMAIN=${domain}`,
|
|
121
|
-
`PORT=${DEFAULT_SERVER_PORT}`,
|
|
122
|
-
`DEPLOYMENT_TYPE=${deploymentType}`,
|
|
123
|
-
`GITHUB_TOKEN=${githubToken}`,
|
|
124
|
-
];
|
|
125
|
-
const mergedEnv = [...userEnvArray, ...systemEnvArray];
|
|
126
|
-
const container = await docker.createContainer({
|
|
127
|
-
Image: image,
|
|
128
|
-
name: this.containerName,
|
|
129
|
-
Env: mergedEnv,
|
|
130
|
-
ExposedPorts: exposedPorts,
|
|
131
|
-
HostConfig: {
|
|
132
|
-
Binds: binds,
|
|
133
|
-
PortBindings: portBindings,
|
|
134
|
-
RestartPolicy: {
|
|
135
|
-
Name: 'unless-stopped',
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
this.containerId = container.id;
|
|
140
|
-
await container.start();
|
|
141
|
-
log.info('Container started', { containerId: this.containerId });
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Check if container is running and healthy
|
|
145
|
-
*/
|
|
146
|
-
async isContainerHealthy() {
|
|
147
|
-
if (!this.containerId) {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
try {
|
|
151
|
-
const container = docker.getContainer(this.containerId);
|
|
152
|
-
const info = await container.inspect();
|
|
153
|
-
return info.State.Running === true;
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
log.debug('Container health check failed', error);
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Stop and remove container
|
|
162
|
-
*/
|
|
163
|
-
async stopContainer() {
|
|
164
|
-
if (!this.containerName) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
try {
|
|
168
|
-
const container = docker.getContainer(this.containerName);
|
|
169
|
-
const info = await container.inspect();
|
|
170
|
-
if (info.State.Running) {
|
|
171
|
-
log.info('Stopping existing container', {
|
|
172
|
-
containerName: this.containerName,
|
|
173
|
-
});
|
|
174
|
-
await container.stop();
|
|
175
|
-
}
|
|
176
|
-
await container.remove();
|
|
177
|
-
log.info('Container removed', { containerName: this.containerName });
|
|
178
|
-
}
|
|
179
|
-
catch (error) {
|
|
180
|
-
// Container doesn't exist, which is fine
|
|
181
|
-
if (error.statusCode !== 404) {
|
|
182
|
-
log.warn('Failed to stop container', error);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Get container logs
|
|
188
|
-
*/
|
|
189
|
-
async getLogs(tail = 100) {
|
|
190
|
-
if (!this.containerId) {
|
|
191
|
-
return '';
|
|
192
|
-
}
|
|
193
|
-
try {
|
|
194
|
-
const container = docker.getContainer(this.containerId);
|
|
195
|
-
const logs = await container.logs({
|
|
196
|
-
stdout: true,
|
|
197
|
-
stderr: true,
|
|
198
|
-
tail,
|
|
199
|
-
});
|
|
200
|
-
return logs.toString();
|
|
201
|
-
}
|
|
202
|
-
catch (error) {
|
|
203
|
-
log.error('Failed to get container logs', error);
|
|
204
|
-
return '';
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
//# sourceMappingURL=docker.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/daemon/docker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAe,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEjE,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;AAC5B,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC,MAAM,OAAO,aAAa;IAA1B;QACU,gBAAW,GAAkB,IAAI,CAAC;QAClC,kBAAa,GAAkB,IAAI,CAAC;IAkO9C,CAAC;IAhOC;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,KAAkB;QACnC,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QACrD,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAE5C,gDAAgD;YAChD,MAAM,WAAW,GAAQ,EAAE,CAAC;YAC5B,IAAI,WAAW,IAAI,cAAc,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC/D,GAAG,CAAC,IAAI,CAAC,kDAAkD,EAAE;oBAC3D,QAAQ,EAAE,cAAc;iBACzB,CAAC,CAAC;gBAEH,6DAA6D;gBAC7D,WAAW,CAAC,UAAU,GAAG;oBACvB,QAAQ,EAAE,cAAc;oBACxB,QAAQ,EAAE,WAAW,EAAE,8CAA8C;oBACrE,aAAa,EAAE,SAAS;iBACzB,CAAC;YACJ,CAAC;YAED,0CAA0C;YAC1C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YACrD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACpC,MAAM,CAAC,KAAK,CAAC,cAAc,CACzB,MAAM,EACN,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;oBACX,IAAI,GAAG,EAAE,CAAC;wBACR,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;wBACtD,MAAM,CAAC,GAAG,CAAC,CAAC;oBACd,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,GAAG,CAAC,CAAC;oBACf,CAAC;gBACH,CAAC,EACD,CAAC,KAAU,EAAE,EAAE;oBACb,2BAA2B;oBAC3B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;wBAChB,GAAG,CAAC,KAAK,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC3C,CAAC;yBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;wBACxB,GAAG,CAAC,KAAK,CAAC,eAAe,EAAE;4BACzB,MAAM,EAAE,KAAK,CAAC,MAAM;4BACpB,EAAE,EAAE,KAAK,CAAC,EAAE;yBACb,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CACF,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAEjD,gBAAgB;YAChB,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YAC7C,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CAAC,KAAkB;QAC3C,MAAM,EACJ,EAAE,EACF,KAAK,EACL,cAAc,EACd,MAAM,EACN,GAAG,EACH,WAAW,EACX,UAAU,EACV,cAAc,GACf,GAAG,KAAK,CAAC;QACV,IAAI,CAAC,aAAa,GAAG,YAAY,EAAE,EAAE,CAAC;QAEtC,kDAAkD;QAClD,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAE3B,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE;YAC7B,KAAK;YACL,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,cAAc;YACd,UAAU;YACV,cAAc;SACf,CAAC,CAAC;QAEH,uDAAuD;QACvD,MAAM,KAAK,GAAG,cAAc,KAAK,cAAc,CAAC,GAAG,CAAC;QACpD,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,mBAAmB,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC;QACzE,MAAM,YAAY,GAAG,KAAK;YACxB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC;gBACE,CAAC,GAAG,mBAAmB,MAAM,CAAC,EAAE;oBAC9B,EAAE,QAAQ,EAAE,MAAM,CAAC,mBAAmB,CAAC,EAAE;iBAC1C;aACF,CAAC;QAEN,0DAA0D;QAC1D,gEAAgE;QAChE,IAAI,KAAK,GAAa,EAAE,CAAC;QACzB,IAAI,UAAU,EAAE,CAAC;YACf,2FAA2F;YAC3F,yDAAyD;YACzD,IAAI,QAAQ,GAAG,cAAc,CAAC;YAC9B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAI,CAAC;oBACH,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;oBAC9B,QAAQ,GAAG,EAAE;yBACV,YAAY,CAAC,2BAA2B,EAAE,OAAO,CAAC;yBAClD,IAAI,EAAE,CAAC;gBACZ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,kCAAkC;oBAClC,QAAQ,GAAG,QAAQ,UAAU,EAAE,CAAC;gBAClC,CAAC;YACH,CAAC;YACD,KAAK,GAAG,CAAC,GAAG,QAAQ,SAAS,UAAU,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,oDAAoD;QACpD,gCAAgC;QAChC,MAAM,YAAY,GAAG,GAAG;YACtB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;YAC9D,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,cAAc,GAAG;YACrB,MAAM,EAAE,EAAE;YACV,UAAU,MAAM,EAAE;YAClB,QAAQ,mBAAmB,EAAE;YAC7B,mBAAmB,cAAc,EAAE;YACnC,gBAAgB,WAAW,EAAE;SAC9B,CAAC;QACF,MAAM,SAAS,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,cAAc,CAAC,CAAC;QAEvD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC;YAC7C,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,IAAI,CAAC,aAAa;YACxB,GAAG,EAAE,SAAS;YACd,YAAY,EAAE,YAAY;YAC1B,UAAU,EAAE;gBACV,KAAK,EAAE,KAAK;gBACZ,YAAY,EAAE,YAAY;gBAC1B,aAAa,EAAE;oBACb,IAAI,EAAE,gBAAgB;iBACvB;aACF;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,CAAC;QAEhC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;QAExB,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,kBAAkB;QACtB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACxD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;YAEvC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC;QACrC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YAClD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC1D,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;YAEvC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBACvB,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE;oBACtC,aAAa,EAAE,IAAI,CAAC,aAAa;iBAClC,CAAC,CAAC;gBACH,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;YACzB,CAAC;YAED,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,yCAAyC;YACzC,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBAC7B,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG;QACtB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACxD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC;gBAChC,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,IAAI;gBACZ,IAAI;aACL,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YACjD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
|
package/dist/daemon/server.js
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HTTP server for daemon control port (4142)
|
|
3
|
-
*/
|
|
4
|
-
import express from 'express';
|
|
5
|
-
import https from 'https';
|
|
6
|
-
import { log } from './logger.js';
|
|
7
|
-
import { generateSelfSignedCert } from './cert.js';
|
|
8
|
-
import { DockerManager } from './docker.js';
|
|
9
|
-
import { MetricsCollector } from './metrics.js';
|
|
10
|
-
import { Coordinator } from './cluster.js';
|
|
11
|
-
export const CONTROL_PORT = 4142;
|
|
12
|
-
let dockerManager;
|
|
13
|
-
let metricsCollector;
|
|
14
|
-
let clusterCoordinator;
|
|
15
|
-
/**
|
|
16
|
-
* Middleware to authenticate requests with deployment secret
|
|
17
|
-
*/
|
|
18
|
-
function authenticateRequest(deploymentSecret) {
|
|
19
|
-
return (req, res, next) => {
|
|
20
|
-
const providedSecret = req.headers[deploymentSecret.toLowerCase()];
|
|
21
|
-
if (providedSecret !== 'true') {
|
|
22
|
-
log.warn('Unauthorized request', { path: req.path, ip: req.ip });
|
|
23
|
-
return res.status(401).json({ error: 'Unauthorized' });
|
|
24
|
-
}
|
|
25
|
-
next();
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Check rclone supervisor service status
|
|
30
|
-
*/
|
|
31
|
-
async function getRcloneStatus() {
|
|
32
|
-
const { exec } = await import('child_process');
|
|
33
|
-
const { promisify } = await import('util');
|
|
34
|
-
const execAsync = promisify(exec);
|
|
35
|
-
try {
|
|
36
|
-
// Check if rclone service exists and is running via supervisor
|
|
37
|
-
const { stdout: statusOutput } = await execAsync('supervisorctl status rclone-sync');
|
|
38
|
-
// Supervisor status format: "rclone-sync RUNNING pid 1234, uptime 0:01:23"
|
|
39
|
-
const isActive = statusOutput.includes('RUNNING');
|
|
40
|
-
const status = statusOutput.split(/\s+/)[1] || 'unknown'; // Extract state (RUNNING, STOPPED, etc.)
|
|
41
|
-
// Get recent logs if service exists
|
|
42
|
-
let logs = '';
|
|
43
|
-
try {
|
|
44
|
-
const { stdout: logOutput } = await execAsync('supervisorctl tail -100 rclone-sync');
|
|
45
|
-
logs = logOutput.trim();
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
// Logs not available
|
|
49
|
-
logs = 'Unable to retrieve logs';
|
|
50
|
-
}
|
|
51
|
-
return {
|
|
52
|
-
active: isActive,
|
|
53
|
-
status,
|
|
54
|
-
logs,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
// Service doesn't exist or supervisor failed
|
|
59
|
-
return {
|
|
60
|
-
active: false,
|
|
61
|
-
status: 'not-found',
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
// ============================================================================
|
|
66
|
-
// Application Factory
|
|
67
|
-
// ============================================================================
|
|
68
|
-
/**
|
|
69
|
-
* Creates and configures the Express application.
|
|
70
|
-
* Exported for testability - doesn't start the server.
|
|
71
|
-
*/
|
|
72
|
-
export function createApp(deploymentSecret, conductorUrl) {
|
|
73
|
-
const app = express();
|
|
74
|
-
app.use(express.json({ limit: '100mb' }));
|
|
75
|
-
// Authentication middleware
|
|
76
|
-
app.use(authenticateRequest(deploymentSecret));
|
|
77
|
-
// Initialize managers
|
|
78
|
-
dockerManager = new DockerManager();
|
|
79
|
-
metricsCollector = new MetricsCollector();
|
|
80
|
-
clusterCoordinator = new Coordinator(deploymentSecret, conductorUrl);
|
|
81
|
-
/**
|
|
82
|
-
* GET /health
|
|
83
|
-
* Basic health check - is the daemon alive?
|
|
84
|
-
*/
|
|
85
|
-
app.get('/health', (req, res) => {
|
|
86
|
-
res.json({ status: 'healthy', timestamp: Date.now() });
|
|
87
|
-
});
|
|
88
|
-
/**
|
|
89
|
-
* GET /deploymentHealth
|
|
90
|
-
* Check if the application container is running and healthy
|
|
91
|
-
*/
|
|
92
|
-
app.get('/deploymentHealth', async (req, res) => {
|
|
93
|
-
// Always get rclone status, even if other checks fail
|
|
94
|
-
const rclone = await getRcloneStatus();
|
|
95
|
-
try {
|
|
96
|
-
const isHealthy = await dockerManager.isContainerHealthy();
|
|
97
|
-
const metrics = await metricsCollector.collect();
|
|
98
|
-
if (!isHealthy) {
|
|
99
|
-
return res.status(503).json({
|
|
100
|
-
status: 'unhealthy',
|
|
101
|
-
reason: 'Container not running',
|
|
102
|
-
rclone,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
res.json({
|
|
106
|
-
status: 'healthy',
|
|
107
|
-
metrics,
|
|
108
|
-
rclone,
|
|
109
|
-
timestamp: Date.now(),
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
catch (error) {
|
|
113
|
-
log.error('Health check failed', error);
|
|
114
|
-
res.status(500).json({ status: 'error', error: String(error), rclone });
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
/**
|
|
118
|
-
* GET /logs
|
|
119
|
-
* Get Docker container logs
|
|
120
|
-
*/
|
|
121
|
-
app.get('/logs', async (req, res) => {
|
|
122
|
-
try {
|
|
123
|
-
const tail = req.query.tail ? parseInt(req.query.tail) : 100;
|
|
124
|
-
log.info('Fetching container logs', { tail });
|
|
125
|
-
const logsString = await dockerManager.getLogs(tail);
|
|
126
|
-
const response = { logs: logsString };
|
|
127
|
-
res.json(response);
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
log.error('Failed to fetch logs', error);
|
|
131
|
-
const errorResponse = {
|
|
132
|
-
error: error instanceof Error ? error.message : String(error),
|
|
133
|
-
};
|
|
134
|
-
res.status(500).json(errorResponse);
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
/**
|
|
138
|
-
* POST /start
|
|
139
|
-
* Receive deployment configuration and start the container
|
|
140
|
-
*/
|
|
141
|
-
app.post('/start', async (req, res) => {
|
|
142
|
-
try {
|
|
143
|
-
const props = req.body;
|
|
144
|
-
log.info('Received start command', {
|
|
145
|
-
id: props.id,
|
|
146
|
-
image: props.image,
|
|
147
|
-
});
|
|
148
|
-
if (!props.image) {
|
|
149
|
-
throw new Error('Image parameter is required');
|
|
150
|
-
}
|
|
151
|
-
// Pull and run container from image
|
|
152
|
-
await dockerManager.runFromImage(props);
|
|
153
|
-
// Start deployment coordination (metrics, scaling, etc.)
|
|
154
|
-
await clusterCoordinator.start(props);
|
|
155
|
-
res.sendStatus(200);
|
|
156
|
-
}
|
|
157
|
-
catch (error) {
|
|
158
|
-
log.error('Failed to start', error);
|
|
159
|
-
const errorResponse = {
|
|
160
|
-
error: error instanceof Error ? error.message : String(error),
|
|
161
|
-
};
|
|
162
|
-
res.status(500).json(errorResponse);
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
/**
|
|
166
|
-
* Error handler
|
|
167
|
-
*/
|
|
168
|
-
app.use((err, req, res, _next) => {
|
|
169
|
-
log.error('Unhandled error', err);
|
|
170
|
-
res.status(500).json({ error: err.message });
|
|
171
|
-
});
|
|
172
|
-
return app;
|
|
173
|
-
}
|
|
174
|
-
// ============================================================================
|
|
175
|
-
// Process-Level Error Handlers
|
|
176
|
-
// ============================================================================
|
|
177
|
-
/**
|
|
178
|
-
* Sets up process-level error handlers for graceful degradation.
|
|
179
|
-
* Exported for testability.
|
|
180
|
-
*/
|
|
181
|
-
export function setupProcessHandlers() {
|
|
182
|
-
// Process-level error handlers to prevent crashes
|
|
183
|
-
process.on('uncaughtException', (error) => {
|
|
184
|
-
log.error('Uncaught exception - shutting down gracefully', {
|
|
185
|
-
error: error.message,
|
|
186
|
-
stack: error.stack,
|
|
187
|
-
});
|
|
188
|
-
// For uncaught exceptions, we should exit as the process is in an unknown state
|
|
189
|
-
// Give time for logs to flush
|
|
190
|
-
setTimeout(() => {
|
|
191
|
-
process.exit(1);
|
|
192
|
-
}, 1000);
|
|
193
|
-
});
|
|
194
|
-
process.on('unhandledRejection', (reason) => {
|
|
195
|
-
log.warn('Unhandled promise rejection', {
|
|
196
|
-
reason: String(reason),
|
|
197
|
-
});
|
|
198
|
-
// Log but don't exit - might be a background task
|
|
199
|
-
// Note: Future Node.js versions will exit on unhandled rejections
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
// ============================================================================
|
|
203
|
-
// Cluster Coordinator Access
|
|
204
|
-
// ============================================================================
|
|
205
|
-
/**
|
|
206
|
-
* Get the cluster coordinator instance.
|
|
207
|
-
* Exported for shutdown sequence.
|
|
208
|
-
*/
|
|
209
|
-
export function getCoordinator() {
|
|
210
|
-
return clusterCoordinator;
|
|
211
|
-
}
|
|
212
|
-
// ============================================================================
|
|
213
|
-
// Server Startup
|
|
214
|
-
// ============================================================================
|
|
215
|
-
/**
|
|
216
|
-
* Start the daemon HTTPS server.
|
|
217
|
-
* Used by CLI for backwards compatibility.
|
|
218
|
-
*/
|
|
219
|
-
export async function startServer(deploymentSecret, conductorUrl) {
|
|
220
|
-
// Setup process handlers first
|
|
221
|
-
setupProcessHandlers();
|
|
222
|
-
const app = createApp(deploymentSecret, conductorUrl);
|
|
223
|
-
// Generate self-signed SSL certificate
|
|
224
|
-
const { cert, key } = generateSelfSignedCert();
|
|
225
|
-
// Start HTTPS server
|
|
226
|
-
const server = https.createServer({ cert, key }, app);
|
|
227
|
-
// Graceful shutdown handlers
|
|
228
|
-
const shutdown = async () => {
|
|
229
|
-
log.info('Shutdown signal received, shutting down gracefully');
|
|
230
|
-
// Stop coordinator intervals
|
|
231
|
-
const coordinator = getCoordinator();
|
|
232
|
-
if (coordinator) {
|
|
233
|
-
await coordinator.stop();
|
|
234
|
-
}
|
|
235
|
-
// Close server
|
|
236
|
-
server.close(() => {
|
|
237
|
-
log.info('HTTPS server closed');
|
|
238
|
-
process.exit(0);
|
|
239
|
-
});
|
|
240
|
-
// Force exit if graceful shutdown takes too long
|
|
241
|
-
setTimeout(() => {
|
|
242
|
-
log.error('Graceful shutdown timed out, forcing exit');
|
|
243
|
-
process.exit(1);
|
|
244
|
-
}, 10000);
|
|
245
|
-
};
|
|
246
|
-
process.on('SIGTERM', shutdown);
|
|
247
|
-
process.on('SIGINT', shutdown);
|
|
248
|
-
await new Promise((resolve) => {
|
|
249
|
-
server.listen(CONTROL_PORT, () => {
|
|
250
|
-
log.info(`Daemon control port listening on https://0.0.0.0:${CONTROL_PORT}`);
|
|
251
|
-
resolve();
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
//# sourceMappingURL=server.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}
|