@kapeta/local-cluster-service 0.34.2 → 0.36.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 (39) hide show
  1. package/.github/workflows/check-license.yml +0 -1
  2. package/CHANGELOG.md +14 -0
  3. package/dist/cjs/src/config/routes.js +9 -0
  4. package/dist/cjs/src/containerManager.d.ts +2 -8
  5. package/dist/cjs/src/containerManager.js +7 -7
  6. package/dist/cjs/src/instanceManager.d.ts +8 -3
  7. package/dist/cjs/src/instanceManager.js +147 -25
  8. package/dist/cjs/src/operatorManager.d.ts +9 -9
  9. package/dist/cjs/src/operatorManager.js +21 -26
  10. package/dist/cjs/src/serviceManager.d.ts +1 -0
  11. package/dist/cjs/src/serviceManager.js +9 -9
  12. package/dist/cjs/src/types.d.ts +40 -0
  13. package/dist/cjs/src/utils/BlockInstanceRunner.d.ts +2 -13
  14. package/dist/cjs/src/utils/BlockInstanceRunner.js +91 -79
  15. package/dist/cjs/src/utils/utils.d.ts +6 -2
  16. package/dist/cjs/src/utils/utils.js +35 -2
  17. package/dist/esm/src/config/routes.js +9 -0
  18. package/dist/esm/src/containerManager.d.ts +2 -8
  19. package/dist/esm/src/containerManager.js +7 -7
  20. package/dist/esm/src/instanceManager.d.ts +8 -3
  21. package/dist/esm/src/instanceManager.js +147 -25
  22. package/dist/esm/src/operatorManager.d.ts +9 -9
  23. package/dist/esm/src/operatorManager.js +21 -26
  24. package/dist/esm/src/serviceManager.d.ts +1 -0
  25. package/dist/esm/src/serviceManager.js +9 -9
  26. package/dist/esm/src/types.d.ts +40 -0
  27. package/dist/esm/src/utils/BlockInstanceRunner.d.ts +2 -13
  28. package/dist/esm/src/utils/BlockInstanceRunner.js +91 -79
  29. package/dist/esm/src/utils/utils.d.ts +6 -2
  30. package/dist/esm/src/utils/utils.js +35 -2
  31. package/package.json +1 -1
  32. package/src/config/routes.ts +15 -0
  33. package/src/containerManager.ts +8 -15
  34. package/src/instanceManager.ts +218 -34
  35. package/src/operatorManager.ts +26 -31
  36. package/src/serviceManager.ts +11 -8
  37. package/src/types.ts +36 -0
  38. package/src/utils/BlockInstanceRunner.ts +119 -92
  39. package/src/utils/utils.ts +40 -3
@@ -256,10 +256,79 @@ class InstanceManager {
256
256
  name: `Starting plan ${systemId}`,
257
257
  });
258
258
  }
259
+ stopAllForPlan(systemId) {
260
+ systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
261
+ const instancesForPlan = this._instances.filter((instance) => instance.systemId === systemId);
262
+ return taskManager_1.taskManager.add(`plan:stop:${systemId}`, async () => {
263
+ return this.stopInstances(instancesForPlan);
264
+ }, {
265
+ name: `Stopping plan ${systemId}`,
266
+ });
267
+ }
268
+ async getInstanceOperator(systemId, instanceId, environment) {
269
+ const blockInstance = await assetManager_1.assetManager.getBlockInstance(systemId, instanceId);
270
+ if (!blockInstance) {
271
+ throw new Error(`Instance not found: ${systemId}/${instanceId}`);
272
+ }
273
+ const blockRef = (0, nodejs_utils_1.normalizeKapetaUri)(blockInstance.block.ref);
274
+ const block = await assetManager_1.assetManager.getAsset(blockRef, true);
275
+ if (!block) {
276
+ throw new Error(`Block not found: ${blockRef}`);
277
+ }
278
+ const operatorDefinition = await definitionsManager_1.definitionsManager.getDefinition(block.kind);
279
+ if (!operatorDefinition?.definition.spec.local) {
280
+ throw new Error(`Operator block has no local definition: ${blockRef}`);
281
+ }
282
+ const localConfig = operatorDefinition.definition.spec.local;
283
+ let instance = await this.start(systemId, instanceId);
284
+ if (instance instanceof taskManager_1.Task) {
285
+ instance = await instance.wait();
286
+ }
287
+ const container = await containerManager_1.containerManager.get(instance.pid);
288
+ if (!container) {
289
+ throw new Error(`Container not found: ${instance.pid}`);
290
+ }
291
+ const portInfo = await container.getPorts();
292
+ if (!portInfo) {
293
+ throw new Error(`No ports found for instance: ${instanceId}`);
294
+ }
295
+ const hostname = serviceManager_1.serviceManager.getLocalHost(environment);
296
+ const ports = {};
297
+ Object.entries(portInfo).forEach(([key, value]) => {
298
+ ports[key] = {
299
+ protocol: value.protocol,
300
+ port: parseInt(value.hostPort),
301
+ };
302
+ });
303
+ return {
304
+ hostname,
305
+ ports,
306
+ credentials: localConfig.credentials,
307
+ options: localConfig.options,
308
+ };
309
+ }
259
310
  async stop(systemId, instanceId) {
260
311
  return this.stopInner(systemId, instanceId, true);
261
312
  }
262
- async stopInner(systemId, instanceId, changeDesired = false) {
313
+ async stopInner(systemId, instanceId, changeDesired = false, checkForSingleton = true) {
314
+ if (checkForSingleton) {
315
+ const blockInstance = await assetManager_1.assetManager.getBlockInstance(systemId, instanceId);
316
+ const blockRef = (0, nodejs_utils_1.normalizeKapetaUri)(blockInstance.block.ref);
317
+ const blockAsset = await assetManager_1.assetManager.getAsset(blockRef, true);
318
+ if (!blockAsset) {
319
+ throw new Error('Block not found: ' + blockRef);
320
+ }
321
+ if (await this.isSingletonOperator(blockAsset)) {
322
+ const instances = await this.getAllInstancesForKind(systemId, blockAsset.data.kind);
323
+ if (instances.length > 1) {
324
+ const promises = instances.map((id) => {
325
+ return this.stopInner(systemId, id, changeDesired, false);
326
+ });
327
+ await Promise.all(promises);
328
+ return;
329
+ }
330
+ }
331
+ }
263
332
  return this.exclusive(systemId, instanceId, async () => {
264
333
  systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
265
334
  const instance = this.getInstance(systemId, instanceId);
@@ -277,11 +346,11 @@ class InstanceManager {
277
346
  }
278
347
  instance.status = types_1.InstanceStatus.STOPPING;
279
348
  socketManager_1.socketManager.emitSystemEvent(systemId, socketManager_1.EVENT_STATUS_CHANGED, instance);
280
- console.log('Stopping instance: %s::%s [desired: %s]', systemId, instanceId, instance.desiredStatus);
349
+ console.log('Stopping instance: %s::%s [desired: %s] [intentional: %s]', systemId, instanceId, instance.desiredStatus, changeDesired);
281
350
  this.save();
282
351
  try {
283
352
  if (instance.type === 'docker') {
284
- const containerName = (0, utils_1.getBlockInstanceContainerName)(instance.systemId, instance.instanceId);
353
+ const containerName = await (0, utils_1.getBlockInstanceContainerName)(instance.systemId, instance.instanceId);
285
354
  const container = await containerManager_1.containerManager.getContainerByName(containerName);
286
355
  if (container) {
287
356
  try {
@@ -314,26 +383,34 @@ class InstanceManager {
314
383
  }
315
384
  });
316
385
  }
317
- stopAllForPlan(systemId) {
386
+ async start(systemId, instanceId, checkForSingleton = true) {
318
387
  systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
319
- const instancesForPlan = this._instances.filter((instance) => instance.systemId === systemId);
320
- return taskManager_1.taskManager.add(`plan:stop:${systemId}`, async () => {
321
- return this.stopInstances(instancesForPlan);
322
- }, {
323
- name: `Stopping plan ${systemId}`,
324
- });
325
- }
326
- async start(systemId, instanceId) {
388
+ const blockInstance = await assetManager_1.assetManager.getBlockInstance(systemId, instanceId);
389
+ const blockRef = (0, nodejs_utils_1.normalizeKapetaUri)(blockInstance.block.ref);
390
+ const blockAsset = await assetManager_1.assetManager.getAsset(blockRef, true);
391
+ if (!blockAsset) {
392
+ throw new Error('Block not found: ' + blockRef);
393
+ }
394
+ if (checkForSingleton && (await this.isSingletonOperator(blockAsset))) {
395
+ const instances = await this.getAllInstancesForKind(systemId, blockAsset.data.kind);
396
+ if (instances.length > 1) {
397
+ const promises = instances.map((id) => {
398
+ return this.start(systemId, id, false);
399
+ });
400
+ await Promise.all(promises);
401
+ return promises[0];
402
+ }
403
+ }
327
404
  return this.exclusive(systemId, instanceId, async () => {
328
- systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
329
- const blockInstance = await assetManager_1.assetManager.getBlockInstance(systemId, instanceId);
330
- const blockRef = (0, nodejs_utils_1.normalizeKapetaUri)(blockInstance.block.ref);
331
- const blockAsset = await assetManager_1.assetManager.getAsset(blockRef, true);
332
- if (!blockAsset) {
333
- throw new Error('Block not found: ' + blockRef);
405
+ let existingInstance = this.getInstance(systemId, instanceId);
406
+ if (existingInstance && existingInstance.pid) {
407
+ const container = await containerManager_1.containerManager.get(existingInstance.pid);
408
+ if (!container) {
409
+ // The container is not running
410
+ existingInstance = undefined;
411
+ }
334
412
  }
335
- const existingInstance = this.getInstance(systemId, instanceId);
336
- if (existingInstance) {
413
+ if (existingInstance?.pid) {
337
414
  if (existingInstance.status === types_1.InstanceStatus.READY) {
338
415
  // Instance is already running
339
416
  return existingInstance;
@@ -372,7 +449,7 @@ class InstanceManager {
372
449
  // Definition not found
373
450
  return Promise.resolve();
374
451
  }
375
- if (operatorManager_1.KIND_OPERATOR.toLowerCase() !== asset.definition.kind.toLowerCase()) {
452
+ if (operatorManager_1.KIND_RESOURCE_OPERATOR.toLowerCase() !== asset.definition.kind.toLowerCase()) {
376
453
  // Not an operator
377
454
  return Promise.resolve();
378
455
  }
@@ -382,7 +459,7 @@ class InstanceManager {
382
459
  return Promise.resolve();
383
460
  }
384
461
  console.log('Ensuring resource: %s in %s', consumerUri.id, systemId);
385
- return operatorManager_1.operatorManager.ensureResource(systemId, consumerUri.fullName, consumerUri.version);
462
+ return operatorManager_1.operatorManager.ensureOperator(systemId, consumerUri.fullName, consumerUri.version);
386
463
  });
387
464
  await Promise.all(promises);
388
465
  }
@@ -449,6 +526,7 @@ class InstanceManager {
449
526
  */
450
527
  async prepareForRestart(systemId, instanceId) {
451
528
  systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
529
+ console.log('Stopping instance during restart...', systemId, instanceId);
452
530
  await this.stopInner(systemId, instanceId);
453
531
  }
454
532
  async stopAll() {
@@ -476,8 +554,13 @@ class InstanceManager {
476
554
  while (all.length > 0) {
477
555
  // Check a few instances at a time - docker doesn't like too many concurrent requests
478
556
  const chunk = all.splice(0, 30);
479
- const promises = chunk.map(async (instance) => {
480
- if (!instance.systemId) {
557
+ const promises = chunk.map(async (oldInstance) => {
558
+ if (!oldInstance.systemId) {
559
+ return;
560
+ }
561
+ // Grab the latest here
562
+ const instance = this.getInstance(oldInstance.systemId, oldInstance.instanceId);
563
+ if (!instance) {
481
564
  return;
482
565
  }
483
566
  instance.systemId = (0, nodejs_utils_1.normalizeKapetaUri)(instance.systemId);
@@ -567,6 +650,7 @@ class InstanceManager {
567
650
  [types_1.InstanceStatus.READY, types_1.InstanceStatus.STARTING, types_1.InstanceStatus.UNHEALTHY].includes(newStatus)) {
568
651
  //If the instance is running but we want it to stop, stop it
569
652
  try {
653
+ console.log('Stopping instance since it is its desired state', instance.systemId, instance.instanceId);
570
654
  await this.stopInner(instance.systemId, instance.instanceId);
571
655
  }
572
656
  catch (e) {
@@ -596,7 +680,7 @@ class InstanceManager {
596
680
  }
597
681
  async getExternalStatus(instance) {
598
682
  if (instance.type === types_1.InstanceType.DOCKER) {
599
- const containerName = (0, utils_1.getBlockInstanceContainerName)(instance.systemId, instance.instanceId);
683
+ const containerName = await (0, utils_1.getBlockInstanceContainerName)(instance.systemId, instance.instanceId);
600
684
  const container = await containerManager_1.containerManager.getContainerByName(containerName);
601
685
  if (!container) {
602
686
  // If the container doesn't exist, we consider the instance stopped
@@ -687,6 +771,44 @@ class InstanceManager {
687
771
  });
688
772
  });
689
773
  }
774
+ async isSingletonOperator(blockAsset) {
775
+ const provider = await assetManager_1.assetManager.getAsset(blockAsset.data.kind);
776
+ if (!provider) {
777
+ return false;
778
+ }
779
+ if ((0, nodejs_utils_1.parseKapetaUri)(provider.kind).fullName === operatorManager_1.KIND_BLOCK_OPERATOR) {
780
+ const localConfig = provider.data.spec.local;
781
+ return localConfig.singleton ?? false;
782
+ }
783
+ return false;
784
+ }
785
+ async getKindForAssetRef(assetRef) {
786
+ const block = await assetManager_1.assetManager.getAsset(assetRef);
787
+ if (!block) {
788
+ return null;
789
+ }
790
+ return block.data.kind;
791
+ }
792
+ async isUsingKind(ref, kind) {
793
+ const assetKind = await this.getKindForAssetRef(ref);
794
+ if (!assetKind) {
795
+ return false;
796
+ }
797
+ return (0, nodejs_utils_1.parseKapetaUri)(assetKind).fullName === (0, nodejs_utils_1.parseKapetaUri)(kind).fullName;
798
+ }
799
+ async getAllInstancesForKind(systemId, kind) {
800
+ const plan = await assetManager_1.assetManager.getPlan(systemId);
801
+ if (!plan?.spec?.blocks) {
802
+ return [];
803
+ }
804
+ const out = [];
805
+ for (const block of plan.spec.blocks) {
806
+ if (await this.isUsingKind(block.block.ref, kind)) {
807
+ out.push(block.id);
808
+ }
809
+ }
810
+ return out;
811
+ }
690
812
  }
691
813
  exports.InstanceManager = InstanceManager;
692
814
  exports.instanceManager = new InstanceManager();
@@ -4,12 +4,13 @@
4
4
  */
5
5
  import { DefinitionInfo } from '@kapeta/local-cluster-config';
6
6
  import { ContainerInfo } from './containerManager';
7
- import { EnvironmentType, OperatorInfo } from './types';
8
- export declare const KIND_OPERATOR = "core/resource-type-operator";
7
+ import { EnvironmentType, LocalImageOptions, OperatorInfo } from './types';
8
+ export declare const KIND_RESOURCE_OPERATOR = "core/resource-type-operator";
9
+ export declare const KIND_BLOCK_OPERATOR = "core/block-type-operator";
9
10
  declare class Operator {
10
11
  private readonly _data;
11
12
  constructor(data: DefinitionInfo);
12
- getLocalData(): any;
13
+ getLocalData(): LocalImageOptions;
13
14
  getDefinitionInfo(): DefinitionInfo;
14
15
  getCredentials(): any;
15
16
  }
@@ -21,7 +22,7 @@ declare class OperatorManager {
21
22
  /**
22
23
  * Get operator definition for resource type
23
24
  */
24
- getOperator(resourceType: string, version: string): Promise<Operator>;
25
+ getOperator(fullName: string, version: string): Promise<Operator>;
25
26
  /**
26
27
  * Get information about a specific consumed resource
27
28
  */
@@ -29,12 +30,11 @@ declare class OperatorManager {
29
30
  /**
30
31
  * Ensure we have a running operator of given type
31
32
  *
32
- * @param {string} systemId
33
- * @param {string} resourceType
34
- * @param {string} version
35
- * @return {Promise<ContainerInfo>}
33
+ * @param systemId the plan ref
34
+ * @param kind the full name - e.g. myhandle/rabbitmq
35
+ * @param version the version of the operator
36
36
  */
37
- ensureResource(systemId: string, resourceType: string, version: string): Promise<ContainerInfo>;
37
+ ensureOperator(systemId: string, kind: string, version: string): Promise<ContainerInfo>;
38
38
  }
39
39
  export declare const operatorManager: OperatorManager;
40
40
  export {};
@@ -7,7 +7,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
7
7
  return (mod && mod.__esModule) ? mod : { "default": mod };
8
8
  };
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.operatorManager = exports.KIND_OPERATOR = void 0;
10
+ exports.operatorManager = exports.KIND_BLOCK_OPERATOR = exports.KIND_RESOURCE_OPERATOR = void 0;
11
11
  const path_1 = __importDefault(require("path"));
12
12
  const md5_1 = __importDefault(require("md5"));
13
13
  const serviceManager_1 = require("./serviceManager");
@@ -20,7 +20,8 @@ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
20
20
  const lodash_1 = __importDefault(require("lodash"));
21
21
  const async_lock_1 = __importDefault(require("async-lock"));
22
22
  const taskManager_1 = require("./taskManager");
23
- exports.KIND_OPERATOR = 'core/resource-type-operator';
23
+ exports.KIND_RESOURCE_OPERATOR = 'core/resource-type-operator';
24
+ exports.KIND_BLOCK_OPERATOR = 'core/block-type-operator';
24
25
  const KIND_PLAN = 'core/plan';
25
26
  class Operator {
26
27
  _data;
@@ -50,18 +51,18 @@ class OperatorManager {
50
51
  /**
51
52
  * Get operator definition for resource type
52
53
  */
53
- async getOperator(resourceType, version) {
54
- const operators = await definitionsManager_1.definitionsManager.getDefinitions(exports.KIND_OPERATOR);
54
+ async getOperator(fullName, version) {
55
+ const operators = await definitionsManager_1.definitionsManager.getDefinitions([exports.KIND_RESOURCE_OPERATOR, exports.KIND_BLOCK_OPERATOR]);
55
56
  const operator = operators.find((operator) => operator.definition &&
56
57
  operator.definition.metadata &&
57
58
  operator.definition.metadata.name &&
58
- operator.definition.metadata.name.toLowerCase() === resourceType.toLowerCase() &&
59
+ operator.definition.metadata.name.toLowerCase() === fullName.toLowerCase() &&
59
60
  operator.version === version);
60
61
  if (!operator) {
61
- throw new Error(`Unknown resource type: ${resourceType}:${version}`);
62
+ throw new Error(`Unknown operator type: ${fullName}:${version}`);
62
63
  }
63
64
  if (!operator.definition.spec || !operator.definition.spec.local) {
64
- throw new Error(`Operator missing local definition: ${resourceType}:${version}`);
65
+ throw new Error(`Operator missing local definition: ${fullName}:${version}`);
65
66
  }
66
67
  return new Operator(operator);
67
68
  }
@@ -96,7 +97,7 @@ class OperatorManager {
96
97
  const kindUri = (0, nodejs_utils_1.parseKapetaUri)(blockResource.kind);
97
98
  const operator = await this.getOperator(resourceType, kindUri.version);
98
99
  const credentials = operator.getCredentials();
99
- const container = await this.ensureResource(systemId, resourceType, kindUri.version);
100
+ const container = await this.ensureOperator(systemId, resourceType, kindUri.version);
100
101
  const portInfo = await container.getPort(portType);
101
102
  if (!portInfo) {
102
103
  throw new Error('Unknown resource port type : ' + resourceType + '#' + portType);
@@ -119,16 +120,15 @@ class OperatorManager {
119
120
  /**
120
121
  * Ensure we have a running operator of given type
121
122
  *
122
- * @param {string} systemId
123
- * @param {string} resourceType
124
- * @param {string} version
125
- * @return {Promise<ContainerInfo>}
123
+ * @param systemId the plan ref
124
+ * @param kind the full name - e.g. myhandle/rabbitmq
125
+ * @param version the version of the operator
126
126
  */
127
- async ensureResource(systemId, resourceType, version) {
127
+ async ensureOperator(systemId, kind, version) {
128
128
  systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
129
- const key = `${systemId}#${resourceType}:${version}`;
129
+ const key = `${systemId}#${kind}:${version}`;
130
130
  return await this.operatorLock.acquire(key, async () => {
131
- const operator = await this.getOperator(resourceType, version);
131
+ const operator = await this.getOperator(kind, version);
132
132
  const operatorData = operator.getLocalData();
133
133
  const portTypes = Object.keys(operatorData.ports);
134
134
  portTypes.sort();
@@ -136,20 +136,15 @@ class OperatorManager {
136
136
  for (let i = 0; i < portTypes.length; i++) {
137
137
  const portType = portTypes[i];
138
138
  let containerPortInfo = operatorData.ports[portType];
139
- const hostPort = await serviceManager_1.serviceManager.ensureServicePort(systemId, resourceType, portType);
140
- if (typeof containerPortInfo === 'number' || typeof containerPortInfo === 'string') {
141
- containerPortInfo = { port: containerPortInfo, type: 'tcp' };
142
- }
143
- if (!containerPortInfo.type) {
144
- containerPortInfo.type = 'tcp';
145
- }
146
- const portId = containerPortInfo.port + '/' + containerPortInfo.type;
139
+ const hostPort = await serviceManager_1.serviceManager.ensureServicePort(systemId, kind, portType);
140
+ const portInfo = (0, utils_1.toPortInfo)(containerPortInfo);
141
+ const portId = portInfo.port + '/' + portInfo.type;
147
142
  ports[portId] = {
148
143
  type: portType,
149
144
  hostPort,
150
145
  };
151
146
  }
152
- const nameParts = [systemId, resourceType.toLowerCase(), version];
147
+ const nameParts = [systemId, kind.toLowerCase(), version];
153
148
  const containerName = `kapeta-resource-${(0, md5_1.default)(nameParts.join('_'))}`;
154
149
  const PortBindings = {};
155
150
  const Env = [];
@@ -157,7 +152,7 @@ class OperatorManager {
157
152
  const Labels = {
158
153
  kapeta: 'true',
159
154
  [containerManager_1.COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
160
- [containerManager_1.COMPOSE_LABEL_SERVICE]: [resourceType, version].join('_').replace(/[^a-z0-9]/gi, '_'),
155
+ [containerManager_1.COMPOSE_LABEL_SERVICE]: [kind, version].join('_').replace(/[^a-z0-9]/gi, '_'),
161
156
  };
162
157
  const operatorMetadata = operator.getDefinitionInfo().definition.metadata;
163
158
  const bindHost = (0, utils_1.getBindHost)();
@@ -172,7 +167,7 @@ class OperatorManager {
172
167
  ];
173
168
  Labels[containerManager_1.CONTAINER_LABEL_PORT_PREFIX + portInfo.hostPort] = portInfo.type;
174
169
  });
175
- const Mounts = await containerManager_1.containerManager.createVolumes(systemId, resourceType, operatorData.mounts);
170
+ const Mounts = await containerManager_1.containerManager.createVolumes(systemId, kind, operatorData.mounts);
176
171
  lodash_1.default.forEach(operatorData.env, (value, name) => {
177
172
  Env.push(name + '=' + value);
178
173
  });
@@ -9,6 +9,7 @@ export declare const HTTP_PORTS: string[];
9
9
  declare class ServiceManager {
10
10
  private _systems;
11
11
  constructor();
12
+ getLocalHost(environmentType?: EnvironmentType): string;
12
13
  _forLocal(port: string | number, path?: string, environmentType?: EnvironmentType): string;
13
14
  _ensureSystem(systemId: string): any;
14
15
  _ensureService(systemId: string, serviceId: string): any;
@@ -31,22 +31,22 @@ class ServiceManager {
31
31
  });
32
32
  });
33
33
  }
34
- _forLocal(port, path, environmentType) {
35
- if (!path) {
36
- path = '';
37
- }
38
- let host;
34
+ getLocalHost(environmentType) {
39
35
  if (environmentType === 'docker') {
40
36
  //We're inside a docker container, so we can use this special host name to access the host machine
41
- host = 'host.docker.internal';
37
+ return 'host.docker.internal';
42
38
  }
43
- else {
44
- host = clusterService_1.clusterService.getClusterServiceHost();
39
+ return clusterService_1.clusterService.getClusterServiceHost();
40
+ }
41
+ _forLocal(port, path, environmentType) {
42
+ if (!path) {
43
+ path = '';
45
44
  }
45
+ const hostname = this.getLocalHost(environmentType);
46
46
  if (path.startsWith('/')) {
47
47
  path = path.substring(1);
48
48
  }
49
- return `http://${host}:${port}/${path}`;
49
+ return `http://${hostname}:${port}/${path}`;
50
50
  }
51
51
  _ensureSystem(systemId) {
52
52
  systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
@@ -56,6 +56,31 @@ export type ProcessInfo = {
56
56
  pid?: number | string | null;
57
57
  portType?: string;
58
58
  };
59
+ export interface Health {
60
+ cmd: string;
61
+ interval?: number;
62
+ timeout?: number;
63
+ retries?: number;
64
+ }
65
+ export type PortInfo = {
66
+ port: number;
67
+ type: 'tcp' | 'udp';
68
+ } | number | string;
69
+ export type LocalImageOptions<Credentials = AnyMap, Options = AnyMap> = {
70
+ image: string;
71
+ ports: {
72
+ [key: string]: PortInfo;
73
+ };
74
+ credentials?: Credentials;
75
+ options?: Options;
76
+ cmd?: string;
77
+ env?: AnyMap;
78
+ health?: Health;
79
+ singleton?: boolean;
80
+ mounts?: {
81
+ [key: string]: string;
82
+ };
83
+ };
59
84
  export type InstanceInfo = {
60
85
  systemId: string;
61
86
  instanceId: string;
@@ -73,6 +98,21 @@ export type InstanceInfo = {
73
98
  portType?: string;
74
99
  };
75
100
  export type ProxyRequestHandler = (req: StringBodyRequest, res: express.Response, info: ProxyRequestInfo) => void;
101
+ export interface OperatorInstancePort {
102
+ protocol: string;
103
+ port: number;
104
+ }
105
+ export interface OperatorInstanceInfo {
106
+ hostname: string;
107
+ ports: {
108
+ [portType: string]: OperatorInstancePort;
109
+ };
110
+ path?: string;
111
+ query?: string;
112
+ hash?: string;
113
+ options?: AnyMap;
114
+ credentials?: AnyMap;
115
+ }
76
116
  export interface OperatorInfo {
77
117
  host: string;
78
118
  port: string;
@@ -2,9 +2,7 @@
2
2
  * Copyright 2023 Kapeta Inc.
3
3
  * SPDX-License-Identifier: BUSL-1.1
4
4
  */
5
- import { DefinitionInfo } from '@kapeta/local-cluster-config';
6
- import { KapetaURI } from '@kapeta/nodejs-utils';
7
- import { AnyMap, BlockProcessParams, ProcessInfo, StringMap } from '../types';
5
+ import { AnyMap, ProcessInfo } from '../types';
8
6
  export declare function resolvePortType(portType: string): string;
9
7
  export declare class BlockInstanceRunner {
10
8
  private readonly _systemId;
@@ -20,16 +18,7 @@ export declare class BlockInstanceRunner {
20
18
  */
21
19
  private _startLocalProcess;
22
20
  private _startDockerProcess;
23
- /**
24
- *
25
- * @param blockInstance
26
- * @param blockUri
27
- * @param providerDefinition
28
- * @param {{[key:string]:string}} env
29
- * @return {Promise<ProcessDetails>}
30
- * @private
31
- */
32
- _startOperatorProcess(blockInstance: BlockProcessParams, blockUri: KapetaURI, providerDefinition: DefinitionInfo, env: StringMap): Promise<ProcessInfo>;
21
+ private _startOperatorProcess;
33
22
  private getDockerPortBindings;
34
23
  private ensureContainer;
35
24
  private _handleContainer;