@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.
Files changed (67) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/index.js +4 -2
  3. package/dist/cjs/src/assetManager.d.ts +2 -2
  4. package/dist/cjs/src/assetManager.js +16 -16
  5. package/dist/cjs/src/assets/routes.js +2 -2
  6. package/dist/cjs/src/authManager.d.ts +12 -0
  7. package/dist/cjs/src/authManager.js +60 -0
  8. package/dist/cjs/src/codeGeneratorManager.d.ts +1 -1
  9. package/dist/cjs/src/codeGeneratorManager.js +3 -3
  10. package/dist/cjs/src/configManager.js +2 -2
  11. package/dist/cjs/src/containerManager.d.ts +15 -0
  12. package/dist/cjs/src/containerManager.js +190 -37
  13. package/dist/cjs/src/definitionsManager.d.ts +7 -6
  14. package/dist/cjs/src/definitionsManager.js +102 -18
  15. package/dist/cjs/src/instanceManager.d.ts +1 -1
  16. package/dist/cjs/src/instanceManager.js +7 -12
  17. package/dist/cjs/src/instances/routes.js +2 -2
  18. package/dist/cjs/src/operatorManager.d.ts +1 -1
  19. package/dist/cjs/src/operatorManager.js +7 -9
  20. package/dist/cjs/src/providerManager.d.ts +2 -1
  21. package/dist/cjs/src/providerManager.js +23 -15
  22. package/dist/cjs/src/repositoryManager.d.ts +2 -2
  23. package/dist/cjs/src/repositoryManager.js +8 -9
  24. package/dist/cjs/src/socketManager.d.ts +2 -2
  25. package/dist/cjs/src/socketManager.js +39 -14
  26. package/dist/cjs/src/utils/BlockInstanceRunner.js +6 -8
  27. package/dist/esm/index.js +4 -2
  28. package/dist/esm/src/assetManager.d.ts +2 -2
  29. package/dist/esm/src/assetManager.js +16 -16
  30. package/dist/esm/src/assets/routes.js +2 -2
  31. package/dist/esm/src/authManager.d.ts +12 -0
  32. package/dist/esm/src/authManager.js +60 -0
  33. package/dist/esm/src/codeGeneratorManager.d.ts +1 -1
  34. package/dist/esm/src/codeGeneratorManager.js +3 -3
  35. package/dist/esm/src/configManager.js +2 -2
  36. package/dist/esm/src/containerManager.d.ts +15 -0
  37. package/dist/esm/src/containerManager.js +190 -37
  38. package/dist/esm/src/definitionsManager.d.ts +7 -6
  39. package/dist/esm/src/definitionsManager.js +102 -18
  40. package/dist/esm/src/instanceManager.d.ts +1 -1
  41. package/dist/esm/src/instanceManager.js +7 -12
  42. package/dist/esm/src/instances/routes.js +2 -2
  43. package/dist/esm/src/operatorManager.d.ts +1 -1
  44. package/dist/esm/src/operatorManager.js +7 -9
  45. package/dist/esm/src/providerManager.d.ts +2 -1
  46. package/dist/esm/src/providerManager.js +23 -15
  47. package/dist/esm/src/repositoryManager.d.ts +2 -2
  48. package/dist/esm/src/repositoryManager.js +8 -9
  49. package/dist/esm/src/socketManager.d.ts +2 -2
  50. package/dist/esm/src/socketManager.js +39 -14
  51. package/dist/esm/src/utils/BlockInstanceRunner.js +6 -8
  52. package/index.ts +4 -2
  53. package/package.json +1 -1
  54. package/src/assetManager.ts +18 -16
  55. package/src/assets/routes.ts +2 -2
  56. package/src/authManager.ts +62 -0
  57. package/src/codeGeneratorManager.ts +3 -3
  58. package/src/configManager.ts +2 -2
  59. package/src/containerManager.ts +210 -40
  60. package/src/definitionsManager.ts +132 -17
  61. package/src/instanceManager.ts +7 -14
  62. package/src/instances/routes.ts +2 -2
  63. package/src/operatorManager.ts +7 -12
  64. package/src/providerManager.ts +27 -19
  65. package/src/repositoryManager.ts +8 -11
  66. package/src/socketManager.ts +42 -15
  67. 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
- getHash(kindFilter) {
12
- if (kindFilter) {
13
- if (Array.isArray(kindFilter)) {
14
- return kindFilter.join(',');
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
- return kindFilter;
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
- return 'none';
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
- getFullKey(kindFilter) {
21
- return `definitionsManager:${this.getHash(kindFilter)}`;
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
- const key = this.getFullKey(kindFilter);
25
- return (0, cacheManager_1.doCached)(key, () => local_cluster_config_1.default.getDefinitions(kindFilter));
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
- return this.getDefinitions().find((d) => {
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('core/plan');
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 blockUri = (0, nodejs_utils_1.parseKapetaUri)(currentInstance.block.ref);
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(): import("@kapeta/local-cluster-config").DefinitionInfo[];
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
- return definitionsManager_1.definitionsManager.getProviderDefinitions().filter((providerDefinition) => providerDefinition.hasWeb);
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 installedProvider = this.getWebProviders().find((providerDefinition) => {
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
- const providerDefinitions = definitionsManager_1.definitionsManager.getProviderDefinitions();
61
- if (providerDefinitions.length > 0) {
62
- console.log('## Loaded the following providers ##');
63
- providerDefinitions.forEach((providerDefinition) => {
64
- console.log(' - %s[%s:%s]', providerDefinition.definition.kind, providerDefinition.definition.metadata.name, providerDefinition.version);
65
- console.log(' from %s', providerDefinition.path);
66
- });
67
- console.log('##');
68
- }
69
- else {
70
- console.log('## No providers found ##');
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 _install;
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._install(DEFAULT_PROVIDERS);
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
- _install(refs) {
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 definitions = definitionsManager_1.definitionsManager.getDefinitions();
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._install([ref]);
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._install(refs);
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 _handleSocketDestroyed;
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
- exports.socketManager.emit(`${systemId}/instances`, type, payload);
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
- exports.socketManager.emit(`${systemId}/instances/${instanceId}`, type, payload);
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', () => this._handleSocketDestroyed(socket));
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
- _handleSocketDestroyed(socket) {
92
- lodash_1.default.pull(this._sockets, socket);
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
- return definitionsManager_1.definitionsManager.getProviderDefinitions().find((provider) => {
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.getDefinitions().find((definitions) => {
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {