@kapeta/local-cluster-service 0.17.0 → 0.19.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 +14 -0
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/src/assetManager.d.ts +2 -2
- package/dist/cjs/src/assetManager.js +16 -16
- package/dist/cjs/src/assets/routes.js +2 -2
- package/dist/cjs/src/authManager.d.ts +12 -0
- package/dist/cjs/src/authManager.js +60 -0
- package/dist/cjs/src/codeGeneratorManager.d.ts +1 -1
- package/dist/cjs/src/codeGeneratorManager.js +3 -3
- package/dist/cjs/src/configManager.js +2 -2
- package/dist/cjs/src/containerManager.d.ts +15 -0
- package/dist/cjs/src/containerManager.js +190 -37
- package/dist/cjs/src/definitionsManager.d.ts +7 -6
- package/dist/cjs/src/definitionsManager.js +102 -18
- package/dist/cjs/src/instanceManager.d.ts +1 -1
- package/dist/cjs/src/instanceManager.js +7 -12
- package/dist/cjs/src/instances/routes.js +2 -2
- package/dist/cjs/src/operatorManager.d.ts +1 -1
- package/dist/cjs/src/operatorManager.js +7 -9
- package/dist/cjs/src/providerManager.d.ts +2 -1
- package/dist/cjs/src/providerManager.js +23 -15
- package/dist/cjs/src/repositoryManager.d.ts +2 -2
- package/dist/cjs/src/repositoryManager.js +8 -9
- package/dist/cjs/src/socketManager.d.ts +2 -2
- package/dist/cjs/src/socketManager.js +39 -14
- package/dist/cjs/src/utils/BlockInstanceRunner.js +6 -8
- package/dist/esm/index.js +4 -2
- package/dist/esm/src/assetManager.d.ts +2 -2
- package/dist/esm/src/assetManager.js +16 -16
- package/dist/esm/src/assets/routes.js +2 -2
- package/dist/esm/src/authManager.d.ts +12 -0
- package/dist/esm/src/authManager.js +60 -0
- package/dist/esm/src/codeGeneratorManager.d.ts +1 -1
- package/dist/esm/src/codeGeneratorManager.js +3 -3
- package/dist/esm/src/configManager.js +2 -2
- package/dist/esm/src/containerManager.d.ts +15 -0
- package/dist/esm/src/containerManager.js +190 -37
- package/dist/esm/src/definitionsManager.d.ts +7 -6
- package/dist/esm/src/definitionsManager.js +102 -18
- package/dist/esm/src/instanceManager.d.ts +1 -1
- package/dist/esm/src/instanceManager.js +7 -12
- package/dist/esm/src/instances/routes.js +2 -2
- package/dist/esm/src/operatorManager.d.ts +1 -1
- package/dist/esm/src/operatorManager.js +7 -9
- package/dist/esm/src/providerManager.d.ts +2 -1
- package/dist/esm/src/providerManager.js +23 -15
- package/dist/esm/src/repositoryManager.d.ts +2 -2
- package/dist/esm/src/repositoryManager.js +8 -9
- package/dist/esm/src/socketManager.d.ts +2 -2
- package/dist/esm/src/socketManager.js +39 -14
- package/dist/esm/src/utils/BlockInstanceRunner.js +6 -8
- package/index.ts +4 -2
- package/package.json +1 -1
- package/src/assetManager.ts +18 -16
- package/src/assets/routes.ts +2 -2
- package/src/authManager.ts +62 -0
- package/src/codeGeneratorManager.ts +3 -3
- package/src/configManager.ts +2 -2
- package/src/containerManager.ts +210 -40
- package/src/definitionsManager.ts +132 -17
- package/src/instanceManager.ts +7 -14
- package/src/instances/routes.ts +2 -2
- package/src/operatorManager.ts +7 -12
- package/src/providerManager.ts +27 -19
- package/src/repositoryManager.ts +8 -11
- package/src/socketManager.ts +42 -15
- package/src/utils/BlockInstanceRunner.ts +6 -8
@@ -3,36 +3,120 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.definitionsManager = void 0;
|
6
|
+
exports.definitionsManager = exports.SAMPLE_PLAN_NAME = void 0;
|
7
7
|
const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
|
8
8
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
9
9
|
const cacheManager_1 = require("./cacheManager");
|
10
|
+
const nodejs_api_client_1 = require("@kapeta/nodejs-api-client");
|
11
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
12
|
+
const utils_1 = require("./utils/utils");
|
13
|
+
const yaml_1 = __importDefault(require("yaml"));
|
14
|
+
const nodejs_registry_utils_1 = require("@kapeta/nodejs-registry-utils");
|
15
|
+
const progressListener_1 = require("./progressListener");
|
16
|
+
const path_1 = __importDefault(require("path"));
|
17
|
+
exports.SAMPLE_PLAN_NAME = 'kapeta/sample-nodejs-plan';
|
18
|
+
function applyHandleChange(definition, targetHandle) {
|
19
|
+
const originalUri = (0, nodejs_utils_1.parseKapetaUri)(definition.definition.metadata.name);
|
20
|
+
definition.definition.metadata.name = `${targetHandle}/${originalUri.name}`;
|
21
|
+
return definition;
|
22
|
+
}
|
23
|
+
function normalizeFilters(kindFilter) {
|
24
|
+
let resolvedFilters = [];
|
25
|
+
if (kindFilter) {
|
26
|
+
if (Array.isArray(kindFilter)) {
|
27
|
+
resolvedFilters = [...kindFilter];
|
28
|
+
}
|
29
|
+
else {
|
30
|
+
resolvedFilters = [kindFilter];
|
31
|
+
}
|
32
|
+
}
|
33
|
+
return resolvedFilters.map((k) => k.toLowerCase());
|
34
|
+
}
|
10
35
|
class DefinitionsManager {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
36
|
+
async resolveDefinitionsAndSamples() {
|
37
|
+
const definitions = local_cluster_config_1.default.getDefinitions();
|
38
|
+
const samplePlan = definitions.find((d) => d.version === 'local' && d.definition.metadata.name === exports.SAMPLE_PLAN_NAME);
|
39
|
+
if (!samplePlan) {
|
40
|
+
return definitions;
|
41
|
+
}
|
42
|
+
// We will only rewrite the sample plan once since we change the handle to be the users handle
|
43
|
+
const api = new nodejs_api_client_1.KapetaAPI();
|
44
|
+
if (!api.hasToken()) {
|
45
|
+
// Not logged in yet, so we can't rewrite the sample plan
|
46
|
+
return definitions;
|
47
|
+
}
|
48
|
+
const profile = await api.getCurrentIdentity();
|
49
|
+
if (!profile) {
|
50
|
+
// Not logged in yet, so we can't rewrite the sample plan
|
51
|
+
return definitions;
|
52
|
+
}
|
53
|
+
console.log('Rewriting sample plan to use handle %s', profile.handle);
|
54
|
+
applyHandleChange(samplePlan, profile.handle);
|
55
|
+
const planDef = samplePlan.definition;
|
56
|
+
const blockRefs = new Set();
|
57
|
+
planDef.spec.blocks.forEach((b) => {
|
58
|
+
const blockUri = (0, nodejs_utils_1.parseKapetaUri)(b.block.ref);
|
59
|
+
if (blockUri.version === 'local') {
|
60
|
+
blockRefs.add(blockUri.id);
|
61
|
+
b.block.ref = (0, utils_1.normalizeKapetaUri)(`${profile.handle}/${blockUri.name}:local`);
|
15
62
|
}
|
16
|
-
|
63
|
+
});
|
64
|
+
// Rewrite all blocks that are referenced by the sample plan
|
65
|
+
const rewrittenBlocks = Array.from(blockRefs)
|
66
|
+
.map((ref) => definitions.find((d) => (0, utils_1.normalizeKapetaUri)(d.definition.metadata.name + ':' + d.version) === (0, utils_1.normalizeKapetaUri)(ref)))
|
67
|
+
.filter((d) => d !== undefined)
|
68
|
+
.map((d) => applyHandleChange(d, profile.handle));
|
69
|
+
// Persist the rewritten assets
|
70
|
+
const progressListener = new progressListener_1.ProgressListener();
|
71
|
+
const rewrittenAssets = [samplePlan, ...rewrittenBlocks];
|
72
|
+
const originalRefs = [`${exports.SAMPLE_PLAN_NAME}:local`, ...Array.from(blockRefs)];
|
73
|
+
// Store the original paths on the assets - we'll need them later
|
74
|
+
for (const asset of rewrittenAssets) {
|
75
|
+
asset.path = await fs_extra_1.default.readlink(asset.path);
|
76
|
+
asset.ymlPath = path_1.default.join(asset.path, path_1.default.basename(asset.ymlPath));
|
77
|
+
}
|
78
|
+
// Uninstall the original assets
|
79
|
+
// This removes the symlinks
|
80
|
+
console.log('Uninstalling original assets', originalRefs);
|
81
|
+
try {
|
82
|
+
await nodejs_registry_utils_1.Actions.uninstall(progressListener, originalRefs);
|
83
|
+
}
|
84
|
+
catch (err) {
|
85
|
+
console.warn('Failed to uninstall original assets', err);
|
17
86
|
}
|
18
|
-
|
87
|
+
for (const asset of rewrittenAssets) {
|
88
|
+
console.log('Updating %s ', asset.ymlPath);
|
89
|
+
await fs_extra_1.default.writeFile(asset.ymlPath, yaml_1.default.stringify(asset.definition));
|
90
|
+
console.log('Linking %s ', asset.path);
|
91
|
+
await nodejs_registry_utils_1.Actions.link(progressListener, asset.path);
|
92
|
+
}
|
93
|
+
console.log('Rewrite done for sample plan');
|
94
|
+
// Return the rewritten definitions
|
95
|
+
return local_cluster_config_1.default.getDefinitions();
|
19
96
|
}
|
20
|
-
|
21
|
-
|
97
|
+
applyFilters(definitions, kindFilter) {
|
98
|
+
if (kindFilter.length === 0) {
|
99
|
+
return definitions;
|
100
|
+
}
|
101
|
+
return definitions.filter((d) => {
|
102
|
+
return kindFilter.includes(d.definition.kind.toLowerCase());
|
103
|
+
});
|
22
104
|
}
|
23
|
-
getDefinitions(kindFilter) {
|
24
|
-
|
25
|
-
|
105
|
+
async getDefinitions(kindFilter) {
|
106
|
+
kindFilter = normalizeFilters(kindFilter);
|
107
|
+
const definitions = await (0, cacheManager_1.doCached)('definitionsManager:all', () => this.resolveDefinitionsAndSamples());
|
108
|
+
return this.applyFilters(definitions, kindFilter);
|
26
109
|
}
|
27
|
-
exists(ref) {
|
28
|
-
return !!this.getDefinition(ref);
|
110
|
+
async exists(ref) {
|
111
|
+
return !!(await this.getDefinition(ref));
|
29
112
|
}
|
30
|
-
getProviderDefinitions() {
|
31
|
-
return (0, cacheManager_1.doCached)('providers', () => local_cluster_config_1.default.getProviderDefinitions());
|
113
|
+
async getProviderDefinitions() {
|
114
|
+
return (0, cacheManager_1.doCached)('definitionsManager:providers', () => local_cluster_config_1.default.getProviderDefinitions());
|
32
115
|
}
|
33
|
-
getDefinition(ref) {
|
116
|
+
async getDefinition(ref) {
|
34
117
|
const uri = (0, nodejs_utils_1.parseKapetaUri)(ref);
|
35
|
-
|
118
|
+
const definitions = await this.getDefinitions();
|
119
|
+
return definitions.find((d) => {
|
36
120
|
if (!uri.version) {
|
37
121
|
return d.definition.metadata.name === uri.fullName;
|
38
122
|
}
|
@@ -7,7 +7,7 @@ export declare class InstanceManager {
|
|
7
7
|
constructor();
|
8
8
|
private checkInstancesLater;
|
9
9
|
getInstances(): InstanceInfo[];
|
10
|
-
getInstancesForPlan(systemId: string): InstanceInfo[]
|
10
|
+
getInstancesForPlan(systemId: string): Promise<InstanceInfo[]>;
|
11
11
|
getInstance(systemId: string, instanceId: string): InstanceInfo | undefined;
|
12
12
|
private exclusive;
|
13
13
|
getLogs(systemId: string, instanceId: string): Promise<LogEntry[]>;
|
@@ -47,12 +47,12 @@ class InstanceManager {
|
|
47
47
|
}
|
48
48
|
return [...this._instances];
|
49
49
|
}
|
50
|
-
getInstancesForPlan(systemId) {
|
50
|
+
async getInstancesForPlan(systemId) {
|
51
51
|
if (!this._instances) {
|
52
52
|
return [];
|
53
53
|
}
|
54
54
|
systemId = (0, utils_1.normalizeKapetaUri)(systemId);
|
55
|
-
const planInfo = definitionsManager_1.definitionsManager.getDefinition(systemId);
|
55
|
+
const planInfo = await definitionsManager_1.definitionsManager.getDefinition(systemId);
|
56
56
|
if (!planInfo) {
|
57
57
|
return [];
|
58
58
|
}
|
@@ -362,9 +362,9 @@ class InstanceManager {
|
|
362
362
|
await this.saveInternalInstance(instance);
|
363
363
|
const blockSpec = blockAsset.data.spec;
|
364
364
|
if (blockSpec.consumers) {
|
365
|
-
const promises = blockSpec.consumers.map((consumer) => {
|
365
|
+
const promises = blockSpec.consumers.map(async (consumer) => {
|
366
366
|
const consumerUri = (0, nodejs_utils_1.parseKapetaUri)(consumer.kind);
|
367
|
-
const asset = definitionsManager_1.definitionsManager.getDefinition(consumer.kind);
|
367
|
+
const asset = await definitionsManager_1.definitionsManager.getDefinition(consumer.kind);
|
368
368
|
if (!asset) {
|
369
369
|
// Definition not found
|
370
370
|
return Promise.resolve();
|
@@ -422,11 +422,6 @@ class InstanceManager {
|
|
422
422
|
errorMessage: e.message ?? 'Failed to start - Check logs for details.',
|
423
423
|
});
|
424
424
|
socketManager_1.socketManager.emitInstanceLog(systemId, instanceId, logs[0]);
|
425
|
-
socketManager_1.socketManager.emitInstanceEvent(systemId, blockInstance.id, socketManager_1.EVENT_INSTANCE_EXITED, {
|
426
|
-
error: `Failed to start instance: ${e.message}`,
|
427
|
-
status: socketManager_1.EVENT_INSTANCE_EXITED,
|
428
|
-
instanceId: blockInstance.id,
|
429
|
-
});
|
430
425
|
return out;
|
431
426
|
}
|
432
427
|
}, {
|
@@ -486,6 +481,7 @@ class InstanceManager {
|
|
486
481
|
try {
|
487
482
|
const plan = await assetManager_1.assetManager.getAsset(instance.systemId, true, false);
|
488
483
|
if (!plan) {
|
484
|
+
console.log('Plan not found - reset to stop', instance.ref, instance.systemId);
|
489
485
|
instance.desiredStatus = types_1.DesiredInstanceStatus.STOP;
|
490
486
|
changed = true;
|
491
487
|
return;
|
@@ -493,12 +489,14 @@ class InstanceManager {
|
|
493
489
|
const planData = plan.data;
|
494
490
|
const planInstance = planData?.spec?.blocks?.find((b) => b.id === instance.instanceId);
|
495
491
|
if (!planInstance || !planInstance?.block?.ref) {
|
492
|
+
console.log('Plan instance not found - reset to stop', instance.ref, instance.systemId);
|
496
493
|
instance.desiredStatus = types_1.DesiredInstanceStatus.STOP;
|
497
494
|
changed = true;
|
498
495
|
return;
|
499
496
|
}
|
500
497
|
const blockDef = await assetManager_1.assetManager.getAsset(instance.ref, true, false);
|
501
498
|
if (!blockDef) {
|
499
|
+
console.log('Block definition not found - reset to stop', instance.ref, instance.systemId);
|
502
500
|
instance.desiredStatus = types_1.DesiredInstanceStatus.STOP;
|
503
501
|
changed = true;
|
504
502
|
return;
|
@@ -676,6 +674,3 @@ class InstanceManager {
|
|
676
674
|
}
|
677
675
|
exports.InstanceManager = InstanceManager;
|
678
676
|
exports.instanceManager = new InstanceManager();
|
679
|
-
process.on('exit', async () => {
|
680
|
-
await exports.instanceManager.stopAll();
|
681
|
-
});
|
@@ -23,8 +23,8 @@ router.get('/', (req, res) => {
|
|
23
23
|
/**
|
24
24
|
* Get all instances
|
25
25
|
*/
|
26
|
-
router.get('/:systemId/instances', (req, res) => {
|
27
|
-
res.send(instanceManager_1.instanceManager.getInstancesForPlan(req.params.systemId));
|
26
|
+
router.get('/:systemId/instances', async (req, res) => {
|
27
|
+
res.send(await instanceManager_1.instanceManager.getInstancesForPlan(req.params.systemId));
|
28
28
|
});
|
29
29
|
/**
|
30
30
|
* Get single instance in a plan
|
@@ -21,7 +21,7 @@ declare class OperatorManager {
|
|
21
21
|
* @param {string} version
|
22
22
|
* @return {Operator}
|
23
23
|
*/
|
24
|
-
getOperator(resourceType: string, version: string): Operator
|
24
|
+
getOperator(resourceType: string, version: string): Promise<Operator>;
|
25
25
|
/**
|
26
26
|
* Get information about a specific consumed resource
|
27
27
|
*/
|
@@ -17,6 +17,7 @@ const lodash_1 = __importDefault(require("lodash"));
|
|
17
17
|
const async_lock_1 = __importDefault(require("async-lock"));
|
18
18
|
const taskManager_1 = require("./taskManager");
|
19
19
|
exports.KIND_OPERATOR = 'core/resource-type-operator';
|
20
|
+
const KIND_PLAN = 'core/plan';
|
20
21
|
class Operator {
|
21
22
|
_data;
|
22
23
|
constructor(data) {
|
@@ -49,8 +50,8 @@ class OperatorManager {
|
|
49
50
|
* @param {string} version
|
50
51
|
* @return {Operator}
|
51
52
|
*/
|
52
|
-
getOperator(resourceType, version) {
|
53
|
-
const operators = definitionsManager_1.definitionsManager.getDefinitions(exports.KIND_OPERATOR);
|
53
|
+
async getOperator(resourceType, version) {
|
54
|
+
const operators = await definitionsManager_1.definitionsManager.getDefinitions(exports.KIND_OPERATOR);
|
54
55
|
const operator = operators.find((operator) => operator.definition &&
|
55
56
|
operator.definition.metadata &&
|
56
57
|
operator.definition.metadata.name &&
|
@@ -69,7 +70,7 @@ class OperatorManager {
|
|
69
70
|
*/
|
70
71
|
async getConsumerResourceInfo(systemId, fromServiceId, resourceType, portType, name, environment) {
|
71
72
|
systemId = (0, utils_1.normalizeKapetaUri)(systemId);
|
72
|
-
const plans = definitionsManager_1.definitionsManager.getDefinitions(
|
73
|
+
const plans = await definitionsManager_1.definitionsManager.getDefinitions(KIND_PLAN);
|
73
74
|
const planUri = (0, nodejs_utils_1.parseKapetaUri)(systemId);
|
74
75
|
const currentPlan = plans.find((plan) => plan.definition.metadata.name === planUri.fullName && plan.version === planUri.version);
|
75
76
|
if (!currentPlan) {
|
@@ -79,10 +80,7 @@ class OperatorManager {
|
|
79
80
|
if (!currentInstance) {
|
80
81
|
throw new Error(`Unknown instance: ${fromServiceId} in plan ${systemId}`);
|
81
82
|
}
|
82
|
-
const
|
83
|
-
const blockDefinition = definitionsManager_1.definitionsManager
|
84
|
-
.getDefinitions()
|
85
|
-
.find((definition) => definition.version === blockUri.version && definition.definition.metadata.name === blockUri.fullName);
|
83
|
+
const blockDefinition = await definitionsManager_1.definitionsManager.getDefinition(currentInstance.block.ref);
|
86
84
|
if (!blockDefinition) {
|
87
85
|
throw new Error(`Unknown block: ${currentInstance.block.ref} in plan ${systemId}`);
|
88
86
|
}
|
@@ -91,7 +89,7 @@ class OperatorManager {
|
|
91
89
|
throw new Error(`Unknown resource: ${name} in block ${currentInstance.block.ref} in plan ${systemId}`);
|
92
90
|
}
|
93
91
|
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(blockResource.kind);
|
94
|
-
const operator = this.getOperator(resourceType, kindUri.version);
|
92
|
+
const operator = await this.getOperator(resourceType, kindUri.version);
|
95
93
|
const credentials = operator.getCredentials();
|
96
94
|
const container = await this.ensureResource(systemId, resourceType, kindUri.version);
|
97
95
|
const portInfo = await container.getPort(portType);
|
@@ -122,7 +120,7 @@ class OperatorManager {
|
|
122
120
|
systemId = (0, utils_1.normalizeKapetaUri)(systemId);
|
123
121
|
const key = `${systemId}#${resourceType}:${version}`;
|
124
122
|
return await this.operatorLock.acquire(key, async () => {
|
125
|
-
const operator = this.getOperator(resourceType, version);
|
123
|
+
const operator = await this.getOperator(resourceType, version);
|
126
124
|
const operatorData = operator.getLocalData();
|
127
125
|
const portTypes = Object.keys(operatorData.ports);
|
128
126
|
portTypes.sort();
|
@@ -1,5 +1,6 @@
|
|
1
|
+
import { DefinitionInfo } from '@kapeta/local-cluster-config';
|
1
2
|
declare class ProviderManager {
|
2
|
-
getWebProviders():
|
3
|
+
getWebProviders(): Promise<DefinitionInfo[]>;
|
3
4
|
getProviderWebJS(handle: string, name: string, version: string, sourceMap?: boolean): Promise<unknown>;
|
4
5
|
}
|
5
6
|
export declare const providerManager: ProviderManager;
|
@@ -11,8 +11,9 @@ const cacheManager_1 = require("./cacheManager");
|
|
11
11
|
const request_1 = __importDefault(require("request"));
|
12
12
|
const PROVIDER_FILE_BASE = 'https://providers.kapeta.com/files';
|
13
13
|
class ProviderManager {
|
14
|
-
getWebProviders() {
|
15
|
-
|
14
|
+
async getWebProviders() {
|
15
|
+
const providers = await definitionsManager_1.definitionsManager.getProviderDefinitions();
|
16
|
+
return providers.filter((providerDefinition) => providerDefinition.hasWeb);
|
16
17
|
}
|
17
18
|
async getProviderWebJS(handle, name, version, sourceMap = false) {
|
18
19
|
const fullName = `${handle}/${name}`;
|
@@ -22,7 +23,8 @@ class ProviderManager {
|
|
22
23
|
if (file && (await fs_extra_1.default.pathExists(file))) {
|
23
24
|
return fs_extra_1.default.readFile(file, 'utf8');
|
24
25
|
}
|
25
|
-
const
|
26
|
+
const providers = await this.getWebProviders();
|
27
|
+
const installedProvider = providers.find((providerDefinition) => {
|
26
28
|
return providerDefinition.definition.metadata.name === fullName && providerDefinition.version === version;
|
27
29
|
});
|
28
30
|
if (installedProvider) {
|
@@ -57,16 +59,22 @@ class ProviderManager {
|
|
57
59
|
});
|
58
60
|
}
|
59
61
|
}
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
providerDefinitions.
|
64
|
-
console.log('
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
}
|
69
|
-
|
70
|
-
|
71
|
-
|
62
|
+
definitionsManager_1.definitionsManager
|
63
|
+
.getProviderDefinitions()
|
64
|
+
.then((providerDefinitions) => {
|
65
|
+
if (providerDefinitions.length > 0) {
|
66
|
+
console.log('## Loaded the following providers ##');
|
67
|
+
providerDefinitions.forEach((providerDefinition) => {
|
68
|
+
console.log(' - %s[%s:%s]', providerDefinition.definition.kind, providerDefinition.definition.metadata.name, providerDefinition.version);
|
69
|
+
console.log(' from %s', providerDefinition.path);
|
70
|
+
});
|
71
|
+
console.log('##');
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
console.log('## No providers found ##');
|
75
|
+
}
|
76
|
+
})
|
77
|
+
.catch((e) => {
|
78
|
+
console.error('Failed to load providers', e);
|
79
|
+
});
|
72
80
|
exports.providerManager = new ProviderManager();
|
@@ -12,8 +12,8 @@ declare class RepositoryManager {
|
|
12
12
|
*/
|
13
13
|
setSourceOfChangeFor(file: string, source: SourceOfChange): Promise<void>;
|
14
14
|
clearSourceOfChangeFor(file: string): Promise<void>;
|
15
|
-
ensureDefaultProviders(): void
|
16
|
-
private
|
15
|
+
ensureDefaultProviders(): Promise<void>;
|
16
|
+
private scheduleInstallation;
|
17
17
|
ensureAsset(handle: string, name: string, version: string, wait?: boolean): Promise<undefined | Task[]>;
|
18
18
|
}
|
19
19
|
export declare const repositoryManager: RepositoryManager;
|
@@ -53,18 +53,18 @@ class RepositoryManager {
|
|
53
53
|
clearSourceOfChangeFor(file) {
|
54
54
|
return this.watcher.clearSourceOfChangeFor(file);
|
55
55
|
}
|
56
|
-
ensureDefaultProviders() {
|
56
|
+
async ensureDefaultProviders() {
|
57
57
|
socketManager_1.socketManager.emitGlobal(EVENT_DEFAULT_PROVIDERS_START, { providers: DEFAULT_PROVIDERS });
|
58
|
-
const tasks = this.
|
58
|
+
const tasks = await this.scheduleInstallation(DEFAULT_PROVIDERS);
|
59
59
|
Promise.allSettled(tasks.map((t) => t.wait())).then(() => {
|
60
60
|
socketManager_1.socketManager.emitGlobal(EVENT_DEFAULT_PROVIDERS_END, {});
|
61
61
|
});
|
62
62
|
}
|
63
|
-
|
63
|
+
async scheduleInstallation(refs) {
|
64
64
|
//We make sure to only install one asset at a time - otherwise unexpected things might happen
|
65
65
|
const createInstaller = (ref) => {
|
66
66
|
return async () => {
|
67
|
-
if (definitionsManager_1.definitionsManager.exists(ref)) {
|
67
|
+
if (await definitionsManager_1.definitionsManager.exists(ref)) {
|
68
68
|
return;
|
69
69
|
}
|
70
70
|
//console.log(`Installing asset: ${ref}`);
|
@@ -89,7 +89,7 @@ class RepositoryManager {
|
|
89
89
|
continue;
|
90
90
|
}
|
91
91
|
ref = (0, utils_1.normalizeKapetaUri)(ref);
|
92
|
-
if (definitionsManager_1.definitionsManager.exists(ref)) {
|
92
|
+
if (await definitionsManager_1.definitionsManager.exists(ref)) {
|
93
93
|
continue;
|
94
94
|
}
|
95
95
|
const task = taskManager_1.taskManager.add(`asset:install:${ref}`, createInstaller(ref), {
|
@@ -107,8 +107,7 @@ class RepositoryManager {
|
|
107
107
|
//TODO: Get dependencies for local asset
|
108
108
|
return;
|
109
109
|
}
|
110
|
-
const
|
111
|
-
const installedAsset = definitions.find((d) => d.definition.metadata.name === fullName && d.version === version);
|
110
|
+
const installedAsset = await definitionsManager_1.definitionsManager.getDefinition(`${fullName}:${version}`);
|
112
111
|
let assetVersion;
|
113
112
|
try {
|
114
113
|
assetVersion = await this._registryService.getVersion(fullName, version);
|
@@ -125,13 +124,13 @@ class RepositoryManager {
|
|
125
124
|
}
|
126
125
|
let tasks = undefined;
|
127
126
|
if (!installedAsset) {
|
128
|
-
tasks = this.
|
127
|
+
tasks = await this.scheduleInstallation([ref]);
|
129
128
|
}
|
130
129
|
else {
|
131
130
|
//Ensure dependencies are installed
|
132
131
|
const refs = assetVersion.dependencies.map((dep) => dep.name);
|
133
132
|
if (refs.length > 0) {
|
134
|
-
tasks = this.
|
133
|
+
tasks = await this.scheduleInstallation(refs);
|
135
134
|
}
|
136
135
|
}
|
137
136
|
if (tasks && wait) {
|
@@ -19,10 +19,10 @@ export declare class SocketManager {
|
|
19
19
|
emitInstanceLog(systemId: string, instanceId: string, payload: LogEntry): void;
|
20
20
|
emitSystemLog(systemId: string, payload: LogEntry): void;
|
21
21
|
emitGlobalLog(payload: LogEntry): void;
|
22
|
-
emitInstanceEvent(systemId: string, instanceId: string, type: string, payload: any): void;
|
23
22
|
private _bindIO;
|
24
23
|
private _handleSocketCreated;
|
25
24
|
private _bindSocket;
|
26
|
-
private
|
25
|
+
private handleJoinRoom;
|
26
|
+
private handleLeaveRoom;
|
27
27
|
}
|
28
28
|
export declare const socketManager: SocketManager;
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.socketManager = exports.SocketManager = exports.EVENT_LOG = exports.EVENT_SYSTEM_LOG = exports.EVENT_INSTANCE_LOG = exports.EVENT_INSTANCE_EXITED = exports.EVENT_INSTANCE_CREATED = exports.EVENT_STATUS_CHANGED = void 0;
|
7
7
|
const lodash_1 = __importDefault(require("lodash"));
|
8
8
|
const utils_1 = require("./utils/utils");
|
9
|
+
const containerManager_1 = require("./containerManager");
|
9
10
|
exports.EVENT_STATUS_CHANGED = 'status-changed';
|
10
11
|
exports.EVENT_INSTANCE_CREATED = 'instance-created';
|
11
12
|
exports.EVENT_INSTANCE_EXITED = 'instance-exited';
|
@@ -48,30 +49,28 @@ class SocketManager {
|
|
48
49
|
emitSystemEvent(systemId, type, payload) {
|
49
50
|
systemId = (0, utils_1.normalizeKapetaUri)(systemId);
|
50
51
|
try {
|
51
|
-
|
52
|
+
const contextId = `system-events/${encodeURIComponent(systemId)}`;
|
53
|
+
this.emit(contextId, type, payload);
|
52
54
|
}
|
53
55
|
catch (e) {
|
54
56
|
console.warn('Failed to emit instance event: %s', e.message);
|
55
57
|
}
|
56
58
|
}
|
57
59
|
emitInstanceLog(systemId, instanceId, payload) {
|
58
|
-
this.emitInstanceEvent(systemId, instanceId, exports.EVENT_INSTANCE_LOG, payload);
|
59
|
-
}
|
60
|
-
emitSystemLog(systemId, payload) {
|
61
|
-
this.emitSystemEvent(systemId, exports.EVENT_SYSTEM_LOG, payload);
|
62
|
-
}
|
63
|
-
emitGlobalLog(payload) {
|
64
|
-
this.emitGlobal(exports.EVENT_LOG, payload);
|
65
|
-
}
|
66
|
-
emitInstanceEvent(systemId, instanceId, type, payload) {
|
67
60
|
systemId = (0, utils_1.normalizeKapetaUri)(systemId);
|
68
61
|
try {
|
69
|
-
|
62
|
+
this.emit(`instance-logs/${encodeURIComponent(systemId)}/${encodeURIComponent(instanceId)}`, exports.EVENT_INSTANCE_LOG, payload);
|
70
63
|
}
|
71
64
|
catch (e) {
|
72
65
|
console.warn('Failed to emit instance event: %s', e.message);
|
73
66
|
}
|
74
67
|
}
|
68
|
+
emitSystemLog(systemId, payload) {
|
69
|
+
this.emitSystemEvent(systemId, exports.EVENT_SYSTEM_LOG, payload);
|
70
|
+
}
|
71
|
+
emitGlobalLog(payload) {
|
72
|
+
this.emitGlobal(exports.EVENT_LOG, payload);
|
73
|
+
}
|
75
74
|
_bindIO() {
|
76
75
|
this.io.on('connection', (socket) => this._handleSocketCreated(socket));
|
77
76
|
}
|
@@ -80,16 +79,42 @@ class SocketManager {
|
|
80
79
|
this._sockets.push(socket);
|
81
80
|
}
|
82
81
|
_bindSocket(socket) {
|
83
|
-
socket.on('disconnect', () =>
|
82
|
+
socket.on('disconnect', () => {
|
83
|
+
lodash_1.default.pull(this._sockets, socket);
|
84
|
+
socket.rooms.forEach((roomId) => {
|
85
|
+
this.handleLeaveRoom(roomId);
|
86
|
+
});
|
87
|
+
});
|
84
88
|
socket.on('join', (id) => {
|
85
89
|
socket.join(id);
|
90
|
+
this.handleJoinRoom(id);
|
86
91
|
});
|
87
92
|
socket.on('leave', (id) => {
|
88
93
|
socket.leave(id);
|
94
|
+
this.handleLeaveRoom(id);
|
89
95
|
});
|
90
96
|
}
|
91
|
-
|
92
|
-
|
97
|
+
handleJoinRoom(id) {
|
98
|
+
if (id.startsWith('instance-logs/')) {
|
99
|
+
let [, systemId, instanceId] = id.split(/\//g);
|
100
|
+
systemId = decodeURIComponent(systemId);
|
101
|
+
instanceId = decodeURIComponent(instanceId);
|
102
|
+
console.log('Start listening for logs', systemId, instanceId);
|
103
|
+
containerManager_1.containerManager
|
104
|
+
.ensureLogListening(systemId, instanceId, (log) => {
|
105
|
+
this.emitInstanceLog(systemId, instanceId, log);
|
106
|
+
})
|
107
|
+
.catch((e) => { });
|
108
|
+
}
|
109
|
+
}
|
110
|
+
handleLeaveRoom(id) {
|
111
|
+
if (id.startsWith('instance-logs/')) {
|
112
|
+
let [, systemId, instanceId] = id.split(/\//g);
|
113
|
+
systemId = decodeURIComponent(systemId);
|
114
|
+
instanceId = decodeURIComponent(instanceId);
|
115
|
+
console.log('Stop listening for logs', systemId, instanceId);
|
116
|
+
containerManager_1.containerManager.stopLogListening(systemId, instanceId).catch((e) => { });
|
117
|
+
}
|
93
118
|
}
|
94
119
|
}
|
95
120
|
exports.SocketManager = SocketManager;
|
@@ -27,8 +27,9 @@ const DOCKER_ENV_VARS = [
|
|
27
27
|
`KAPETA_LOCAL_CLUSTER_HOST=host.docker.internal`,
|
28
28
|
`KAPETA_ENVIRONMENT_TYPE=docker`,
|
29
29
|
];
|
30
|
-
function getProvider(uri) {
|
31
|
-
|
30
|
+
async function getProvider(uri) {
|
31
|
+
const providers = await definitionsManager_1.definitionsManager.getProviderDefinitions();
|
32
|
+
return providers.find((provider) => {
|
32
33
|
const ref = `${provider.definition.metadata.name}:${provider.version}`;
|
33
34
|
return (0, nodejs_utils_1.parseKapetaUri)(ref).id === uri.id;
|
34
35
|
});
|
@@ -76,15 +77,12 @@ class BlockInstanceRunner {
|
|
76
77
|
if (!blockUri.version) {
|
77
78
|
blockUri.version = 'local';
|
78
79
|
}
|
79
|
-
const assetVersion = definitionsManager_1.definitionsManager.
|
80
|
-
const ref = `${definitions.definition.metadata.name}:${definitions.version}`;
|
81
|
-
return (0, nodejs_utils_1.parseKapetaUri)(ref).id === blockUri.id;
|
82
|
-
});
|
80
|
+
const assetVersion = await definitionsManager_1.definitionsManager.getDefinition(blockUri.id);
|
83
81
|
if (!assetVersion) {
|
84
82
|
throw new Error(`Block definition not found: ${blockUri.id}`);
|
85
83
|
}
|
86
84
|
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.kind);
|
87
|
-
const providerVersion = getProvider(kindUri);
|
85
|
+
const providerVersion = await getProvider(kindUri);
|
88
86
|
if (!providerVersion) {
|
89
87
|
throw new Error(`Kind not found: ${kindUri.id}`);
|
90
88
|
}
|
@@ -120,7 +118,7 @@ class BlockInstanceRunner {
|
|
120
118
|
throw new Error('Missing target kind in block definition');
|
121
119
|
}
|
122
120
|
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.spec?.target?.kind);
|
123
|
-
const targetVersion = getProvider(kindUri);
|
121
|
+
const targetVersion = await getProvider(kindUri);
|
124
122
|
if (!targetVersion) {
|
125
123
|
throw new Error(`Target not found: ${kindUri.id}`);
|
126
124
|
}
|
package/index.ts
CHANGED
@@ -23,6 +23,7 @@ import request from 'request';
|
|
23
23
|
import { repositoryManager } from './src/repositoryManager';
|
24
24
|
import { ensureCLI } from './src/utils/commandLineUtils';
|
25
25
|
import { defaultProviderInstaller } from './src/utils/DefaultProviderInstaller';
|
26
|
+
import { authManager } from './src/authManager';
|
26
27
|
|
27
28
|
export type LocalClusterService = HTTP.Server & { host?: string; port?: number };
|
28
29
|
|
@@ -147,6 +148,7 @@ export default {
|
|
147
148
|
}
|
148
149
|
|
149
150
|
await clusterService.init();
|
151
|
+
await authManager.listenForChanges();
|
150
152
|
|
151
153
|
currentServer = createServer();
|
152
154
|
|
@@ -177,7 +179,7 @@ export default {
|
|
177
179
|
|
178
180
|
const bindHost = getBindHost(host);
|
179
181
|
|
180
|
-
currentServer.listen(port, bindHost, () => {
|
182
|
+
currentServer.listen(port, bindHost, async () => {
|
181
183
|
try {
|
182
184
|
ensureCLI().catch((e: any) => console.error('Failed to install CLI.', e));
|
183
185
|
} catch (e: any) {
|
@@ -186,7 +188,7 @@ export default {
|
|
186
188
|
|
187
189
|
try {
|
188
190
|
// Start installation process for all default providers
|
189
|
-
repositoryManager.ensureDefaultProviders();
|
191
|
+
await repositoryManager.ensureDefaultProviders();
|
190
192
|
} catch (e: any) {
|
191
193
|
console.error('Failed to install default providers.', e);
|
192
194
|
}
|