@kapeta/local-cluster-service 0.8.2 → 0.9.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 (80) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/definitions.d.ts +1 -1
  3. package/dist/cjs/index.js +3 -3
  4. package/dist/cjs/src/assetManager.js +7 -4
  5. package/dist/cjs/src/attachments/routes.js +4 -4
  6. package/dist/cjs/src/clusterService.js +2 -0
  7. package/dist/cjs/src/codeGeneratorManager.js +3 -3
  8. package/dist/cjs/src/config/routes.js +1 -1
  9. package/dist/cjs/src/configManager.js +13 -1
  10. package/dist/cjs/src/containerManager.d.ts +22 -2
  11. package/dist/cjs/src/containerManager.js +42 -15
  12. package/dist/cjs/src/definitionsManager.d.ts +11 -0
  13. package/dist/cjs/src/definitionsManager.js +44 -0
  14. package/dist/cjs/src/filesystemManager.js +0 -2
  15. package/dist/cjs/src/instanceManager.d.ts +23 -47
  16. package/dist/cjs/src/instanceManager.js +416 -235
  17. package/dist/cjs/src/instances/routes.js +23 -14
  18. package/dist/cjs/src/middleware/kapeta.js +7 -0
  19. package/dist/cjs/src/networkManager.js +6 -0
  20. package/dist/cjs/src/operatorManager.js +8 -4
  21. package/dist/cjs/src/providerManager.js +3 -3
  22. package/dist/cjs/src/repositoryManager.js +7 -3
  23. package/dist/cjs/src/serviceManager.js +5 -0
  24. package/dist/cjs/src/types.d.ts +39 -13
  25. package/dist/cjs/src/types.js +28 -0
  26. package/dist/cjs/src/utils/BlockInstanceRunner.d.ts +3 -3
  27. package/dist/cjs/src/utils/BlockInstanceRunner.js +28 -29
  28. package/dist/cjs/src/utils/utils.d.ts +2 -0
  29. package/dist/cjs/src/utils/utils.js +18 -2
  30. package/dist/esm/index.js +4 -4
  31. package/dist/esm/src/assetManager.js +7 -4
  32. package/dist/esm/src/attachments/routes.js +5 -5
  33. package/dist/esm/src/clusterService.js +2 -0
  34. package/dist/esm/src/codeGeneratorManager.js +3 -3
  35. package/dist/esm/src/config/routes.js +1 -1
  36. package/dist/esm/src/configManager.js +13 -1
  37. package/dist/esm/src/containerManager.d.ts +22 -2
  38. package/dist/esm/src/containerManager.js +41 -14
  39. package/dist/esm/src/definitionsManager.d.ts +11 -0
  40. package/dist/esm/src/definitionsManager.js +38 -0
  41. package/dist/esm/src/filesystemManager.js +0 -2
  42. package/dist/esm/src/instanceManager.d.ts +23 -47
  43. package/dist/esm/src/instanceManager.js +416 -236
  44. package/dist/esm/src/instances/routes.js +23 -14
  45. package/dist/esm/src/middleware/kapeta.js +7 -0
  46. package/dist/esm/src/networkManager.js +6 -0
  47. package/dist/esm/src/operatorManager.js +8 -4
  48. package/dist/esm/src/providerManager.js +3 -3
  49. package/dist/esm/src/repositoryManager.js +7 -3
  50. package/dist/esm/src/serviceManager.js +5 -0
  51. package/dist/esm/src/types.d.ts +39 -13
  52. package/dist/esm/src/types.js +27 -1
  53. package/dist/esm/src/utils/BlockInstanceRunner.d.ts +3 -3
  54. package/dist/esm/src/utils/BlockInstanceRunner.js +29 -30
  55. package/dist/esm/src/utils/utils.d.ts +2 -0
  56. package/dist/esm/src/utils/utils.js +15 -1
  57. package/index.ts +10 -8
  58. package/package.json +2 -1
  59. package/src/assetManager.ts +7 -4
  60. package/src/attachments/routes.ts +8 -8
  61. package/src/clusterService.ts +3 -0
  62. package/src/codeGeneratorManager.ts +3 -2
  63. package/src/config/routes.ts +1 -1
  64. package/src/configManager.ts +13 -1
  65. package/src/containerManager.ts +63 -16
  66. package/src/definitionsManager.ts +54 -0
  67. package/src/filesystemManager.ts +0 -2
  68. package/src/identities/routes.ts +2 -3
  69. package/src/instanceManager.ts +495 -266
  70. package/src/instances/routes.ts +23 -17
  71. package/src/middleware/kapeta.ts +10 -0
  72. package/src/networkManager.ts +6 -0
  73. package/src/operatorManager.ts +11 -6
  74. package/src/providerManager.ts +3 -2
  75. package/src/repositoryManager.ts +14 -10
  76. package/src/serviceManager.ts +6 -0
  77. package/src/storageService.ts +1 -1
  78. package/src/types.ts +44 -14
  79. package/src/utils/BlockInstanceRunner.ts +34 -34
  80. package/src/utils/utils.ts +20 -2
@@ -4,6 +4,7 @@ import { serviceManager } from '../serviceManager';
4
4
  import { corsHandler } from '../middleware/cors';
5
5
  import { kapetaHeaders } from '../middleware/kapeta';
6
6
  import { stringBody } from '../middleware/stringBody';
7
+ import { DesiredInstanceStatus, InstanceOwner, InstanceType } from '../types';
7
8
  const router = Router();
8
9
  router.use('/', corsHandler);
9
10
  router.use('/', kapetaHeaders);
@@ -23,10 +24,10 @@ router.get('/:systemId/instances', (req, res) => {
23
24
  * Start all instances in a plan
24
25
  */
25
26
  router.post('/:systemId/start', async (req, res) => {
26
- const processes = await instanceManager.createProcessesForPlan(req.params.systemId);
27
+ const instances = await instanceManager.startAllForPlan(req.params.systemId);
27
28
  res.status(202).send({
28
29
  ok: true,
29
- processes: processes.map((p) => {
30
+ processes: instances.map((p) => {
30
31
  return { pid: p.pid, type: p.type };
31
32
  }),
32
33
  });
@@ -44,7 +45,7 @@ router.post('/:systemId/stop', async (req, res) => {
44
45
  * Start single instance in a plan
45
46
  */
46
47
  router.post('/:systemId/:instanceId/start', async (req, res) => {
47
- const process = await instanceManager.createProcess(req.params.systemId, req.params.instanceId);
48
+ const process = await instanceManager.start(req.params.systemId, req.params.instanceId);
48
49
  res.status(202).send({
49
50
  ok: true,
50
51
  pid: process.pid,
@@ -55,20 +56,20 @@ router.post('/:systemId/:instanceId/start', async (req, res) => {
55
56
  * Stop single instance in a plan
56
57
  */
57
58
  router.post('/:systemId/:instanceId/stop', async (req, res) => {
58
- await instanceManager.stopProcess(req.params.systemId, req.params.instanceId);
59
+ await instanceManager.stop(req.params.systemId, req.params.instanceId);
59
60
  res.status(202).send({ ok: true });
60
61
  });
61
62
  /**
62
63
  * Get logs for instance in a plan
63
64
  */
64
65
  router.get('/:systemId/:instanceId/logs', (req, res) => {
65
- const processInfo = instanceManager.getProcessForInstance(req.params.systemId, req.params.instanceId);
66
- if (!processInfo) {
66
+ const instanceInfo = instanceManager.getInstance(req.params.systemId, req.params.instanceId);
67
+ if (!instanceInfo) {
67
68
  res.status(404).send({ ok: false });
68
69
  return;
69
70
  }
70
71
  res.status(202).send({
71
- logs: processInfo.logs(),
72
+ logs: instanceInfo.internal?.logs() ?? [],
72
73
  });
73
74
  });
74
75
  /**
@@ -101,7 +102,7 @@ router.use('/', (req, res, next) => {
101
102
  next();
102
103
  });
103
104
  /**
104
- * Updates the full configuration for a given service.
105
+ * Updates the full configuration for a given instance.
105
106
  */
106
107
  router.put('/', async (req, res) => {
107
108
  let instance = req.stringBody ? JSON.parse(req.stringBody) : null;
@@ -111,19 +112,27 @@ router.put('/', async (req, res) => {
111
112
  if (oldInstance) {
112
113
  instance.pid = oldInstance.pid;
113
114
  }
114
- instance.type = 'docker';
115
+ instance.type = InstanceType.DOCKER;
115
116
  }
116
- else if (req.kapeta.environment === 'process') {
117
- instance.type = 'process';
117
+ else {
118
+ // Coming from user starting the instance outside of kapeta
119
+ instance.type = InstanceType.LOCAL;
120
+ instance.owner = InstanceOwner.EXTERNAL;
121
+ instance.desiredStatus = DesiredInstanceStatus.EXTERNAL;
122
+ }
123
+ try {
124
+ await instanceManager.registerInstanceFromSDK(req.kapeta.systemId, req.kapeta.instanceId, instance);
125
+ res.status(202).send({ ok: true });
126
+ }
127
+ catch (e) {
128
+ res.status(400).send({ error: e.message });
118
129
  }
119
- await instanceManager.registerInstance(req.kapeta.systemId, req.kapeta.instanceId, instance);
120
- res.status(202).send({ ok: true });
121
130
  });
122
131
  /**
123
132
  * Delete instance
124
133
  */
125
134
  router.delete('/', async (req, res) => {
126
- await instanceManager.setInstanceAsStopped(req.kapeta.systemId, req.kapeta.instanceId);
135
+ await instanceManager.markAsStopped(req.kapeta.systemId, req.kapeta.instanceId);
127
136
  res.status(202).send({ ok: true });
128
137
  });
129
138
  export default router;
@@ -1,8 +1,15 @@
1
+ import { normalizeKapetaUri } from '../utils/utils';
1
2
  export function kapetaHeaders(req, res, next) {
2
3
  let blockRef = req.headers['x-kapeta-block'];
3
4
  let systemId = req.headers['x-kapeta-system'];
4
5
  let instanceId = req.headers['x-kapeta-instance'];
5
6
  let environment = req.headers['x-kapeta-environment'];
7
+ if (blockRef) {
8
+ blockRef = normalizeKapetaUri(blockRef);
9
+ }
10
+ if (systemId) {
11
+ systemId = normalizeKapetaUri(systemId);
12
+ }
6
13
  req.kapeta = {
7
14
  blockRef,
8
15
  instanceId,
@@ -1,4 +1,5 @@
1
1
  import uuid from 'node-uuid';
2
+ import { normalizeKapetaUri } from './utils/utils';
2
3
  class NetworkManager {
3
4
  _connections;
4
5
  _sources;
@@ -17,6 +18,7 @@ class NetworkManager {
17
18
  this._targets = {};
18
19
  }
19
20
  _ensureSystem(systemId) {
21
+ systemId = normalizeKapetaUri(systemId);
20
22
  if (!this._connections[systemId]) {
21
23
  this._connections[systemId] = {};
22
24
  }
@@ -28,6 +30,7 @@ class NetworkManager {
28
30
  }
29
31
  }
30
32
  _ensureConnection(systemId, connectionId) {
33
+ systemId = normalizeKapetaUri(systemId);
31
34
  this._ensureSystem(systemId);
32
35
  if (!this._connections[systemId][connectionId]) {
33
36
  this._connections[systemId][connectionId] = [];
@@ -35,6 +38,7 @@ class NetworkManager {
35
38
  return this._connections[systemId][connectionId];
36
39
  }
37
40
  _ensureSource(systemId, sourceBlockInstanceId) {
41
+ systemId = normalizeKapetaUri(systemId);
38
42
  this._ensureSystem(systemId);
39
43
  if (!this._sources[systemId][sourceBlockInstanceId]) {
40
44
  this._sources[systemId][sourceBlockInstanceId] = [];
@@ -42,6 +46,7 @@ class NetworkManager {
42
46
  return this._sources[systemId][sourceBlockInstanceId];
43
47
  }
44
48
  _ensureTarget(systemId, targetBlockInstanceId) {
49
+ systemId = normalizeKapetaUri(systemId);
45
50
  this._ensureSystem(systemId);
46
51
  if (!this._targets[systemId][targetBlockInstanceId]) {
47
52
  this._targets[systemId][targetBlockInstanceId] = [];
@@ -49,6 +54,7 @@ class NetworkManager {
49
54
  return this._targets[systemId][targetBlockInstanceId];
50
55
  }
51
56
  addRequest(systemId, connection, request, consumerMethodId, providerMethodId) {
57
+ systemId = normalizeKapetaUri(systemId);
52
58
  const traffic = new Traffic(connection, request, consumerMethodId, providerMethodId);
53
59
  this._ensureConnection(systemId, traffic.connectionId).push(traffic);
54
60
  this._ensureSource(systemId, connection.provider.blockId).push(traffic);
@@ -1,4 +1,3 @@
1
- import ClusterConfiguration from '@kapeta/local-cluster-config';
2
1
  import Path from 'path';
3
2
  import md5 from 'md5';
4
3
  import { parseKapetaUri } from '@kapeta/nodejs-utils';
@@ -6,6 +5,8 @@ import { serviceManager } from './serviceManager';
6
5
  import { storageService } from './storageService';
7
6
  import { containerManager } from './containerManager';
8
7
  import FSExtra from 'fs-extra';
8
+ import { definitionsManager } from './definitionsManager';
9
+ import { normalizeKapetaUri } from './utils/utils';
9
10
  const KIND_OPERATOR = 'core/resource-type-operator';
10
11
  class Operator {
11
12
  _data;
@@ -36,7 +37,7 @@ class OperatorManager {
36
37
  * @return {Operator}
37
38
  */
38
39
  getOperator(resourceType, version) {
39
- const operators = ClusterConfiguration.getDefinitions(KIND_OPERATOR);
40
+ const operators = definitionsManager.getDefinitions(KIND_OPERATOR);
40
41
  const operator = operators.find((operator) => operator.definition &&
41
42
  operator.definition.metadata &&
42
43
  operator.definition.metadata.name &&
@@ -54,7 +55,8 @@ class OperatorManager {
54
55
  * Get information about a specific consumed resource
55
56
  */
56
57
  async getConsumerResourceInfo(systemId, fromServiceId, resourceType, portType, name, environment) {
57
- const plans = ClusterConfiguration.getDefinitions('core/plan');
58
+ systemId = normalizeKapetaUri(systemId);
59
+ const plans = definitionsManager.getDefinitions('core/plan');
58
60
  const planUri = parseKapetaUri(systemId);
59
61
  const currentPlan = plans.find((plan) => plan.definition.metadata.name === planUri.fullName && plan.version === planUri.version);
60
62
  if (!currentPlan) {
@@ -65,7 +67,9 @@ class OperatorManager {
65
67
  throw new Error(`Unknown instance: ${fromServiceId} in plan ${systemId}`);
66
68
  }
67
69
  const blockUri = parseKapetaUri(currentInstance.block.ref);
68
- const blockDefinition = ClusterConfiguration.getDefinitions().find((definition) => definition.version === blockUri.version && definition.definition.metadata.name === blockUri.fullName);
70
+ const blockDefinition = definitionsManager
71
+ .getDefinitions()
72
+ .find((definition) => definition.version === blockUri.version && definition.definition.metadata.name === blockUri.fullName);
69
73
  if (!blockDefinition) {
70
74
  throw new Error(`Unknown block: ${currentInstance.block.ref} in plan ${systemId}`);
71
75
  }
@@ -1,14 +1,14 @@
1
1
  import Path from 'path';
2
2
  import FSExtra from 'fs-extra';
3
3
  import { repositoryManager } from './repositoryManager';
4
- import ClusterConfiguration from '@kapeta/local-cluster-config';
4
+ import { definitionsManager } from './definitionsManager';
5
5
  class ProviderManager {
6
6
  _webAssetCache;
7
7
  constructor() {
8
8
  this._webAssetCache = {};
9
9
  }
10
10
  getWebProviders() {
11
- return ClusterConfiguration.getProviderDefinitions().filter((providerDefinition) => providerDefinition.hasWeb);
11
+ return definitionsManager.getProviderDefinitions().filter((providerDefinition) => providerDefinition.hasWeb);
12
12
  }
13
13
  async getAsset(handle, name, version, sourceMap = false) {
14
14
  const fullName = `${handle}/${name}`;
@@ -31,7 +31,7 @@ class ProviderManager {
31
31
  return null;
32
32
  }
33
33
  }
34
- const providerDefinitions = ClusterConfiguration.getProviderDefinitions();
34
+ const providerDefinitions = definitionsManager.getProviderDefinitions();
35
35
  if (providerDefinitions.length > 0) {
36
36
  console.log('## Loaded the following providers ##');
37
37
  providerDefinitions.forEach((providerDefinition) => {
@@ -8,6 +8,7 @@ import { parseKapetaUri } from '@kapeta/nodejs-utils';
8
8
  import { socketManager } from './socketManager';
9
9
  import { progressListener } from './progressListener';
10
10
  import { Actions, Config, RegistryService } from '@kapeta/nodejs-registry-utils';
11
+ import { definitionsManager } from './definitionsManager';
11
12
  const INSTALL_ATTEMPTED = {};
12
13
  class RepositoryManager {
13
14
  changeEventsEnabled;
@@ -83,6 +84,7 @@ class RepositoryManager {
83
84
  };
84
85
  allDefinitions = newDefinitions;
85
86
  socketManager.emit(`assets`, 'changed', payload);
87
+ definitionsManager.clearCache();
86
88
  });
87
89
  }
88
90
  catch (e) {
@@ -173,7 +175,7 @@ class RepositoryManager {
173
175
  //TODO: Get dependencies for local asset
174
176
  return;
175
177
  }
176
- const definitions = ClusterConfiguration.getDefinitions();
178
+ const definitions = definitionsManager.getDefinitions();
177
179
  const installedAsset = definitions.find((d) => d.definition.metadata.name === fullName && d.version === version);
178
180
  if (installedAsset && this._cache[ref] === true) {
179
181
  return;
@@ -204,8 +206,10 @@ class RepositoryManager {
204
206
  else {
205
207
  //Ensure dependencies are installed
206
208
  const refs = assetVersion.dependencies.map((dep) => dep.name);
207
- console.log(`Auto-installing dependencies: ${refs.join(', ')}`);
208
- await this._install(refs);
209
+ if (refs.length > 0) {
210
+ console.log(`Auto-installing dependencies: ${refs.join(', ')}`);
211
+ await this._install(refs);
212
+ }
209
213
  }
210
214
  }
211
215
  }
@@ -1,6 +1,7 @@
1
1
  import _ from 'lodash';
2
2
  import { clusterService } from './clusterService';
3
3
  import { storageService } from './storageService';
4
+ import { normalizeKapetaUri } from './utils/utils';
4
5
  const DEFAULT_PORT_TYPE = 'rest';
5
6
  class ServiceManager {
6
7
  _systems;
@@ -35,6 +36,7 @@ class ServiceManager {
35
36
  return `http://${host}:${port}/${path}`;
36
37
  }
37
38
  _ensureSystem(systemId) {
39
+ systemId = normalizeKapetaUri(systemId);
38
40
  if (!this._systems[systemId]) {
39
41
  this._systems[systemId] = {};
40
42
  }
@@ -48,6 +50,7 @@ class ServiceManager {
48
50
  return system[serviceId];
49
51
  }
50
52
  async ensureServicePort(systemId, blockInstanceId, portType = DEFAULT_PORT_TYPE) {
53
+ systemId = normalizeKapetaUri(systemId);
51
54
  if (!portType) {
52
55
  portType = DEFAULT_PORT_TYPE;
53
56
  }
@@ -70,6 +73,7 @@ class ServiceManager {
70
73
  *
71
74
  */
72
75
  getConsumerAddress(systemId, consumerInstanceId, consumerResourceName, portType, environmentType) {
76
+ systemId = normalizeKapetaUri(systemId);
73
77
  const port = clusterService.getClusterServicePort();
74
78
  const path = clusterService.getProxyPath(systemId, consumerInstanceId, consumerResourceName, portType);
75
79
  return this._forLocal(port, path, environmentType);
@@ -83,6 +87,7 @@ class ServiceManager {
83
87
  *
84
88
  */
85
89
  async getProviderAddress(systemId, providerInstanceId, portType) {
90
+ systemId = normalizeKapetaUri(systemId);
86
91
  const port = await this.ensureServicePort(systemId, providerInstanceId, portType);
87
92
  return this._forLocal(port);
88
93
  }
@@ -24,29 +24,55 @@ export interface BlockProcessParams {
24
24
  ref: string;
25
25
  configuration?: AnyMap;
26
26
  }
27
- export type ProcessType = 'docker' | 'local';
28
- export interface ProcessDetails {
29
- pid: number | string;
30
- type: ProcessType;
31
- portType?: string;
27
+ export declare enum InstanceType {
28
+ DOCKER = "docker",
29
+ LOCAL = "local",
30
+ UNKNOWN = "unknown"
31
+ }
32
+ export declare enum InstanceOwner {
33
+ INTERNAL = "internal",
34
+ EXTERNAL = "external"
35
+ }
36
+ export declare enum InstanceStatus {
37
+ STOPPED = "stopped",
38
+ STARTING = "starting",
39
+ BUSY = "busy",
40
+ READY = "ready",
41
+ STOPPING = "stopping",
42
+ UNHEALTHY = "unhealthy",
43
+ FAILED = "failed"
44
+ }
45
+ export declare enum DesiredInstanceStatus {
46
+ STOP = "stop",
47
+ RUN = "run",
48
+ EXTERNAL = "external"
49
+ }
50
+ export type ProcessInfo = {
51
+ type: InstanceType;
52
+ pid?: number | string | null;
32
53
  output: EventEmitter;
54
+ portType?: string;
33
55
  logs: () => LogEntry[];
34
56
  stop: () => Promise<void> | void;
35
- }
36
- export interface ProcessInfo extends ProcessDetails {
37
- id: string;
38
- ref: string;
39
- name: string;
40
- }
57
+ };
41
58
  export type InstanceInfo = {
42
59
  systemId: string;
43
60
  instanceId: string;
61
+ ref: string;
62
+ name: string;
63
+ type: InstanceType;
64
+ owner: InstanceOwner;
65
+ status: InstanceStatus;
66
+ desiredStatus: DesiredInstanceStatus;
44
67
  address?: string;
68
+ startedAt?: number;
45
69
  health?: string | null;
46
- status: string;
47
70
  pid?: number | string | null;
48
- type: ProcessType;
49
71
  portType?: string;
72
+ internal?: {
73
+ output: EventEmitter;
74
+ logs: () => LogEntry[];
75
+ };
50
76
  };
51
77
  interface ResourceRef {
52
78
  blockId: string;
@@ -1 +1,27 @@
1
- export {};
1
+ export var InstanceType;
2
+ (function (InstanceType) {
3
+ InstanceType["DOCKER"] = "docker";
4
+ InstanceType["LOCAL"] = "local";
5
+ InstanceType["UNKNOWN"] = "unknown";
6
+ })(InstanceType || (InstanceType = {}));
7
+ export var InstanceOwner;
8
+ (function (InstanceOwner) {
9
+ InstanceOwner["INTERNAL"] = "internal";
10
+ InstanceOwner["EXTERNAL"] = "external";
11
+ })(InstanceOwner || (InstanceOwner = {}));
12
+ export var InstanceStatus;
13
+ (function (InstanceStatus) {
14
+ InstanceStatus["STOPPED"] = "stopped";
15
+ InstanceStatus["STARTING"] = "starting";
16
+ InstanceStatus["BUSY"] = "busy";
17
+ InstanceStatus["READY"] = "ready";
18
+ InstanceStatus["STOPPING"] = "stopping";
19
+ InstanceStatus["UNHEALTHY"] = "unhealthy";
20
+ InstanceStatus["FAILED"] = "failed";
21
+ })(InstanceStatus || (InstanceStatus = {}));
22
+ export var DesiredInstanceStatus;
23
+ (function (DesiredInstanceStatus) {
24
+ DesiredInstanceStatus["STOP"] = "stop";
25
+ DesiredInstanceStatus["RUN"] = "run";
26
+ DesiredInstanceStatus["EXTERNAL"] = "external";
27
+ })(DesiredInstanceStatus || (DesiredInstanceStatus = {}));
@@ -1,9 +1,9 @@
1
1
  import { DefinitionInfo } from '@kapeta/local-cluster-config';
2
2
  import { KapetaURI } from '@kapeta/nodejs-utils';
3
- import { AnyMap, BlockProcessParams, ProcessDetails, ProcessInfo, StringMap } from '../types';
3
+ import { AnyMap, BlockProcessParams, ProcessInfo, StringMap } from '../types';
4
4
  export declare class BlockInstanceRunner {
5
5
  private readonly _systemId;
6
- constructor(planReference: string);
6
+ constructor(systemId: string);
7
7
  /**
8
8
  * Start a block
9
9
  *
@@ -25,5 +25,5 @@ export declare class BlockInstanceRunner {
25
25
  * @return {Promise<ProcessDetails>}
26
26
  * @private
27
27
  */
28
- _startOperatorProcess(blockInstance: BlockProcessParams, blockUri: KapetaURI, providerDefinition: DefinitionInfo, env: StringMap): Promise<ProcessDetails>;
28
+ _startOperatorProcess(blockInstance: BlockProcessParams, blockUri: KapetaURI, providerDefinition: DefinitionInfo, env: StringMap): Promise<ProcessInfo>;
29
29
  }
@@ -1,13 +1,14 @@
1
1
  import FS from 'node:fs';
2
2
  import ClusterConfig from '@kapeta/local-cluster-config';
3
- import { getBindHost, readYML } from './utils';
3
+ import { getBindHost, getBlockInstanceContainerName, normalizeKapetaUri, readYML } from './utils';
4
4
  import { parseKapetaUri } from '@kapeta/nodejs-utils';
5
5
  import { serviceManager } from '../serviceManager';
6
6
  import { containerManager, toLocalBindVolume } from '../containerManager';
7
7
  import { LogData } from './LogData';
8
8
  import EventEmitter from 'events';
9
- import md5 from 'md5';
10
9
  import { clusterService } from '../clusterService';
10
+ import { InstanceType } from '../types';
11
+ import { definitionsManager } from '../definitionsManager';
11
12
  const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
12
13
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
13
14
  const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
@@ -22,7 +23,7 @@ const DOCKER_ENV_VARS = [
22
23
  `KAPETA_ENVIRONMENT_TYPE=docker`,
23
24
  ];
24
25
  function getProvider(uri) {
25
- return ClusterConfig.getProviderDefinitions().find((provider) => {
26
+ return definitionsManager.getProviderDefinitions().find((provider) => {
26
27
  const ref = `${provider.definition.metadata.name}:${provider.version}`;
27
28
  return parseKapetaUri(ref).id === uri.id;
28
29
  });
@@ -36,13 +37,13 @@ function getProviderPorts(assetVersion) {
36
37
  }
37
38
  export class BlockInstanceRunner {
38
39
  _systemId;
39
- constructor(planReference) {
40
+ constructor(systemId) {
40
41
  /**
41
42
  *
42
43
  * @type {string}
43
44
  * @private
44
45
  */
45
- this._systemId = planReference ?? '';
46
+ this._systemId = normalizeKapetaUri(systemId);
46
47
  }
47
48
  /**
48
49
  * Start a block
@@ -70,7 +71,7 @@ export class BlockInstanceRunner {
70
71
  if (!blockUri.version) {
71
72
  blockUri.version = 'local';
72
73
  }
73
- const assetVersion = ClusterConfig.getDefinitions().find((definitions) => {
74
+ const assetVersion = definitionsManager.getDefinitions().find((definitions) => {
74
75
  const ref = `${definitions.definition.metadata.name}:${definitions.version}`;
75
76
  return parseKapetaUri(ref).id === blockUri.id;
76
77
  });
@@ -82,28 +83,24 @@ export class BlockInstanceRunner {
82
83
  if (!providerVersion) {
83
84
  throw new Error(`Kind not found: ${kindUri.id}`);
84
85
  }
85
- let processDetails;
86
+ let processInfo;
86
87
  if (providerVersion.definition.kind === KIND_BLOCK_TYPE_OPERATOR) {
87
- processDetails = await this._startOperatorProcess(blockInstance, blockUri, providerVersion, env);
88
+ processInfo = await this._startOperatorProcess(blockInstance, blockUri, providerVersion, env);
88
89
  }
89
90
  else {
90
91
  //We need a port type to know how to connect to the block consistently
91
92
  const portTypes = getProviderPorts(assetVersion);
92
93
  if (blockUri.version === 'local') {
93
- processDetails = await this._startLocalProcess(blockInstance, blockUri, env, assetVersion);
94
+ processInfo = await this._startLocalProcess(blockInstance, blockUri, env, assetVersion);
94
95
  }
95
96
  else {
96
- processDetails = await this._startDockerProcess(blockInstance, blockUri, env);
97
+ processInfo = await this._startDockerProcess(blockInstance, blockUri, env);
97
98
  }
98
99
  if (portTypes.length > 0) {
99
- processDetails.portType = portTypes[0];
100
+ processInfo.portType = portTypes[0];
100
101
  }
101
102
  }
102
- return {
103
- name: blockUri.id,
104
- ...blockInstance,
105
- ...processDetails,
106
- };
103
+ return processInfo;
107
104
  }
108
105
  /**
109
106
  * Starts local process
@@ -130,13 +127,14 @@ export class BlockInstanceRunner {
130
127
  if (!dockerImage) {
131
128
  throw new Error(`Missing docker image information: ${JSON.stringify(localContainer)}`);
132
129
  }
133
- const containerName = `kapeta-block-instance-${blockInstance.id}`;
130
+ const containerName = getBlockInstanceContainerName(blockInstance.id);
134
131
  const logs = new LogData();
135
132
  logs.addLog(`Starting block ${blockInstance.ref}`);
136
- let container = (await containerManager.getContainerByName(containerName)) ?? null;
133
+ const containerInfo = await containerManager.getContainerByName(containerName);
134
+ let container = containerInfo?.native;
137
135
  console.log('Starting dev container', containerName);
138
136
  if (container) {
139
- console.log(`Container already exists. Deleting...`);
137
+ console.log(`Dev container already exists. Deleting...`);
140
138
  try {
141
139
  await container.delete({
142
140
  force: true,
@@ -145,7 +143,7 @@ export class BlockInstanceRunner {
145
143
  catch (e) {
146
144
  throw new Error('Failed to delete existing container: ' + e.message);
147
145
  }
148
- container = null;
146
+ container = undefined;
149
147
  }
150
148
  logs.addLog(`Creating new container for block: ${containerName}`);
151
149
  console.log('Creating new dev container', containerName, dockerImage);
@@ -178,6 +176,7 @@ export class BlockInstanceRunner {
178
176
  if (localContainer.healthcheck) {
179
177
  HealthCheck = containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
180
178
  }
179
+ console.log('Starting dev container', containerName, dockerImage);
181
180
  container = await containerManager.startContainer({
182
181
  Image: dockerImage,
183
182
  name: containerName,
@@ -247,7 +246,7 @@ export class BlockInstanceRunner {
247
246
  outputEvents.emit('exit', data?.State?.ExitCode ?? 0);
248
247
  });
249
248
  return {
250
- type: 'docker',
249
+ type: InstanceType.DOCKER,
251
250
  pid: container.id,
252
251
  output: outputEvents,
253
252
  stop: async () => {
@@ -282,9 +281,10 @@ export class BlockInstanceRunner {
282
281
  if (!dockerImage) {
283
282
  throw new Error(`Missing docker image information: ${JSON.stringify(versionInfo?.artifact?.details)}`);
284
283
  }
285
- const containerName = `kapeta-block-instance-${blockInstance.id}`;
284
+ const containerName = getBlockInstanceContainerName(blockInstance.id);
286
285
  const logs = new LogData();
287
- let container = await containerManager.getContainerByName(containerName);
286
+ const containerInfo = await containerManager.getContainerByName(containerName);
287
+ let container = containerInfo?.native;
288
288
  // For windows we need to default to root
289
289
  const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
290
290
  if (container) {
@@ -311,9 +311,7 @@ export class BlockInstanceRunner {
311
311
  ...Object.entries(env).map(([key, value]) => `${key}=${value}`),
312
312
  ],
313
313
  HostConfig: {
314
- Binds: [
315
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`,
316
- ],
314
+ Binds: [`${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`],
317
315
  },
318
316
  });
319
317
  try {
@@ -352,9 +350,10 @@ export class BlockInstanceRunner {
352
350
  catch (e) {
353
351
  console.warn('Failed to pull image. Continuing...', e);
354
352
  }
355
- const containerName = `kapeta-block-instance-${md5(blockInstance.id)}`;
353
+ const containerName = getBlockInstanceContainerName(blockInstance.id);
356
354
  const logs = new LogData();
357
- let container = (await containerManager.getContainerByName(containerName)) ?? null;
355
+ const containerInfo = await containerManager.getContainerByName(containerName);
356
+ let container = containerInfo?.native;
358
357
  if (container) {
359
358
  const containerData = container.data;
360
359
  if (containerData.State === 'running') {
@@ -367,7 +366,7 @@ export class BlockInstanceRunner {
367
366
  await container.delete();
368
367
  }
369
368
  catch (e) { }
370
- container = null;
369
+ container = undefined;
371
370
  }
372
371
  else {
373
372
  logs.addLog(`Found existing container for block: ${containerName}. Starting now`);
@@ -380,7 +379,7 @@ export class BlockInstanceRunner {
380
379
  await container.delete();
381
380
  }
382
381
  catch (e) { }
383
- container = null;
382
+ container = undefined;
384
383
  }
385
384
  }
386
385
  }
@@ -1,3 +1,5 @@
1
+ export declare function getBlockInstanceContainerName(instanceId: string): string;
2
+ export declare function normalizeKapetaUri(uri: string): string;
1
3
  export declare function readYML(path: string): any;
2
4
  export declare function isWindows(): boolean;
3
5
  export declare function isMac(): boolean;
@@ -1,5 +1,19 @@
1
1
  import FS from 'node:fs';
2
2
  import YAML from 'yaml';
3
+ import { parseKapetaUri } from '@kapeta/nodejs-utils';
4
+ export function getBlockInstanceContainerName(instanceId) {
5
+ return `kapeta-block-instance-${instanceId}`;
6
+ }
7
+ export function normalizeKapetaUri(uri) {
8
+ if (!uri) {
9
+ return '';
10
+ }
11
+ const uriObj = parseKapetaUri(uri);
12
+ if (!uriObj.version) {
13
+ return `kapeta://${parseKapetaUri(uri).fullName}`;
14
+ }
15
+ return `kapeta://${parseKapetaUri(uri).id}`;
16
+ }
3
17
  export function readYML(path) {
4
18
  const rawYaml = FS.readFileSync(path);
5
19
  try {
@@ -19,7 +33,7 @@ export function isLinux() {
19
33
  return !isWindows() && !isMac();
20
34
  }
21
35
  export function getBindHost(preferredHost = '127.0.0.1') {
22
- // On Linux we need to bind to 0.0.0.0 to be able to connect to it from docker containers.
36
+ // On Linux we need to bind to 0.0.0.0 to be able to connect to it from docker containers.
23
37
  // TODO: This might pose a security risk - so we should authenticate all requests using a shared secret/nonce that we pass around.
24
38
  return isLinux() ? '0.0.0.0' : preferredHost;
25
39
  }