@kapeta/local-cluster-service 0.10.1 → 0.11.1

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 (38) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/src/containerManager.d.ts +6 -4
  3. package/dist/cjs/src/containerManager.js +100 -45
  4. package/dist/cjs/src/definitionsManager.d.ts +1 -0
  5. package/dist/cjs/src/definitionsManager.js +7 -0
  6. package/dist/cjs/src/instanceManager.d.ts +6 -2
  7. package/dist/cjs/src/instanceManager.js +240 -233
  8. package/dist/cjs/src/instances/routes.js +10 -4
  9. package/dist/cjs/src/operatorManager.js +8 -6
  10. package/dist/cjs/src/repositoryManager.js +4 -4
  11. package/dist/cjs/src/types.d.ts +0 -9
  12. package/dist/cjs/src/utils/BlockInstanceRunner.js +9 -64
  13. package/dist/cjs/src/utils/utils.d.ts +1 -1
  14. package/dist/cjs/src/utils/utils.js +3 -2
  15. package/dist/esm/src/containerManager.d.ts +6 -4
  16. package/dist/esm/src/containerManager.js +100 -45
  17. package/dist/esm/src/definitionsManager.d.ts +1 -0
  18. package/dist/esm/src/definitionsManager.js +7 -0
  19. package/dist/esm/src/instanceManager.d.ts +6 -2
  20. package/dist/esm/src/instanceManager.js +240 -233
  21. package/dist/esm/src/instances/routes.js +10 -4
  22. package/dist/esm/src/operatorManager.js +8 -6
  23. package/dist/esm/src/repositoryManager.js +4 -4
  24. package/dist/esm/src/types.d.ts +0 -9
  25. package/dist/esm/src/utils/BlockInstanceRunner.js +9 -64
  26. package/dist/esm/src/utils/utils.d.ts +1 -1
  27. package/dist/esm/src/utils/utils.js +3 -2
  28. package/package.json +3 -1
  29. package/src/containerManager.ts +126 -49
  30. package/src/definitionsManager.ts +8 -0
  31. package/src/instanceManager.ts +270 -255
  32. package/src/instances/routes.ts +9 -4
  33. package/src/operatorManager.ts +9 -8
  34. package/src/repositoryManager.ts +5 -5
  35. package/src/types.ts +0 -7
  36. package/src/utils/BlockInstanceRunner.ts +10 -66
  37. package/src/utils/LogData.ts +1 -0
  38. package/src/utils/utils.ts +3 -2
@@ -113,9 +113,11 @@ class RepositoryManager {
113
113
  this._installQueue.push(async () => {
114
114
  try {
115
115
  const normalizedRefs = refs.map((ref) => (0, nodejs_utils_1.parseKapetaUri)(ref).id);
116
- const filteredRefs = normalizedRefs.filter((ref) => !INSTALL_ATTEMPTED[ref]);
117
- console.log(filteredRefs);
116
+ const filteredRefs = normalizedRefs
117
+ .filter((ref) => !INSTALL_ATTEMPTED[ref])
118
+ .filter((ref) => !definitionsManager_1.definitionsManager.exists(ref));
118
119
  if (filteredRefs.length > 0) {
120
+ console.log(`Auto-installing dependencies: ${filteredRefs.join(', ')}`);
119
121
  filteredRefs.forEach((ref) => (INSTALL_ATTEMPTED[ref] = true));
120
122
  //Auto-install missing asset
121
123
  try {
@@ -206,14 +208,12 @@ class RepositoryManager {
206
208
  }
207
209
  this._cache[ref] = true;
208
210
  if (!installedAsset) {
209
- console.log(`Auto-installing missing asset: ${ref}`);
210
211
  await this._install([ref]);
211
212
  }
212
213
  else {
213
214
  //Ensure dependencies are installed
214
215
  const refs = assetVersion.dependencies.map((dep) => dep.name);
215
216
  if (refs.length > 0) {
216
- console.log(`Auto-installing dependencies: ${refs.join(', ')}`);
217
217
  await this._install(refs);
218
218
  }
219
219
  }
@@ -1,5 +1,3 @@
1
- /// <reference types="node" />
2
- import EventEmitter from 'events';
3
1
  import express from 'express';
4
2
  import { Resource } from '@kapeta/schemas';
5
3
  import { StringBodyRequest } from './middleware/stringBody';
@@ -50,10 +48,7 @@ export declare enum DesiredInstanceStatus {
50
48
  export type ProcessInfo = {
51
49
  type: InstanceType;
52
50
  pid?: number | string | null;
53
- output: EventEmitter;
54
51
  portType?: string;
55
- logs: () => LogEntry[];
56
- stop: () => Promise<void> | void;
57
52
  };
58
53
  export type InstanceInfo = {
59
54
  systemId: string;
@@ -69,10 +64,6 @@ export type InstanceInfo = {
69
64
  health?: string | null;
70
65
  pid?: number | string | null;
71
66
  portType?: string;
72
- internal?: {
73
- output: EventEmitter;
74
- logs: () => LogEntry[];
75
- };
76
67
  };
77
68
  interface ResourceRef {
78
69
  blockId: string;
@@ -11,7 +11,6 @@ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
11
11
  const serviceManager_1 = require("../serviceManager");
12
12
  const containerManager_1 = require("../containerManager");
13
13
  const LogData_1 = require("./LogData");
14
- const events_1 = __importDefault(require("events"));
15
14
  const clusterService_1 = require("../clusterService");
16
15
  const types_1 = require("../types");
17
16
  const definitionsManager_1 = require("../definitionsManager");
@@ -133,7 +132,7 @@ class BlockInstanceRunner {
133
132
  if (!dockerImage) {
134
133
  throw new Error(`Missing docker image information: ${JSON.stringify(localContainer)}`);
135
134
  }
136
- const containerName = (0, utils_1.getBlockInstanceContainerName)(blockInstance.id);
135
+ const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
137
136
  const startCmd = localContainer.handlers?.onCreate ? localContainer.handlers.onCreate : '';
138
137
  const dockerOpts = localContainer.options ?? {};
139
138
  const homeDir = localContainer.userHome ? localContainer.userHome : '/root';
@@ -186,7 +185,7 @@ class BlockInstanceRunner {
186
185
  throw new Error(`Missing docker image information: ${JSON.stringify(versionInfo?.artifact?.details)}`);
187
186
  }
188
187
  const { PortBindings, ExposedPorts, addonEnv } = await this.getDockerPortBindings(blockInstance, assetVersion);
189
- const containerName = (0, utils_1.getBlockInstanceContainerName)(blockInstance.id);
188
+ const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
190
189
  // For windows we need to default to root
191
190
  const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
192
191
  return this.ensureContainer({
@@ -231,7 +230,8 @@ class BlockInstanceRunner {
231
230
  throw new Error(`Provider did not have local image: ${providerRef}`);
232
231
  }
233
232
  const dockerImage = spec?.local?.image;
234
- const containerName = (0, utils_1.getBlockInstanceContainerName)(blockInstance.id);
233
+ //We only want 1 operator per operator type - across all local systems
234
+ const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
235
235
  const logs = new LogData_1.LogData();
236
236
  const bindHost = (0, utils_1.getBindHost)();
237
237
  const ExposedPorts = {};
@@ -258,7 +258,7 @@ class BlockInstanceRunner {
258
258
  });
259
259
  }
260
260
  if (spec.local?.mounts) {
261
- const mounts = containerManager_1.containerManager.createMounts(blockUri.id, spec.local.mounts);
261
+ const mounts = await containerManager_1.containerManager.createMounts(this._systemId, blockUri.id, spec.local.mounts);
262
262
  Mounts = containerManager_1.containerManager.toDockerMounts(mounts);
263
263
  }
264
264
  if (spec.local?.health) {
@@ -323,69 +323,14 @@ class BlockInstanceRunner {
323
323
  return { PortBindings, ExposedPorts, addonEnv };
324
324
  }
325
325
  async ensureContainer(opts) {
326
- const logs = new LogData_1.LogData();
327
326
  const container = await containerManager_1.containerManager.ensureContainer(opts);
328
- try {
329
- if (opts.HealthCheck) {
330
- await containerManager_1.containerManager.waitForHealthy(container);
331
- }
332
- else {
333
- await containerManager_1.containerManager.waitForReady(container);
334
- }
335
- }
336
- catch (e) {
337
- logs.addLog(e.message, 'ERROR');
338
- }
339
- return this._handleContainer(container, logs);
327
+ await containerManager_1.containerManager.waitForReady(container);
328
+ return this._handleContainer(container);
340
329
  }
341
- async _handleContainer(container, logs, deleteOnExit = false) {
342
- let localContainer = container;
343
- const logStream = (await container.logs({
344
- follow: true,
345
- stdout: true,
346
- stderr: true,
347
- tail: LogData_1.LogData.MAX_LINES,
348
- }));
349
- const outputEvents = new events_1.default();
350
- logStream.on('data', (data) => {
351
- logs.addLog(data.toString());
352
- outputEvents.emit('data', data);
353
- });
354
- logStream.on('error', (data) => {
355
- logs.addLog(data.toString());
356
- outputEvents.emit('data', data);
357
- });
358
- logStream.on('close', async () => {
359
- const status = await container.status();
360
- const data = status.data;
361
- if (deleteOnExit) {
362
- try {
363
- await containerManager_1.containerManager.remove(container);
364
- }
365
- catch (e) { }
366
- }
367
- outputEvents.emit('exit', data?.State?.ExitCode ?? 0);
368
- });
330
+ async _handleContainer(container) {
369
331
  return {
370
332
  type: types_1.InstanceType.DOCKER,
371
- pid: container.id,
372
- output: outputEvents,
373
- stop: async () => {
374
- if (!localContainer) {
375
- return;
376
- }
377
- try {
378
- await localContainer.stop();
379
- if (deleteOnExit) {
380
- await containerManager_1.containerManager.remove(localContainer);
381
- }
382
- }
383
- catch (e) { }
384
- localContainer = null;
385
- },
386
- logs: () => {
387
- return logs.getLogs();
388
- },
333
+ pid: container.id
389
334
  };
390
335
  }
391
336
  }
@@ -1,4 +1,4 @@
1
- export declare function getBlockInstanceContainerName(instanceId: string): string;
1
+ export declare function getBlockInstanceContainerName(systemId: string, instanceId: string): string;
2
2
  export declare function normalizeKapetaUri(uri: string): string;
3
3
  export declare function readYML(path: string): any;
4
4
  export declare function isWindows(): boolean;
@@ -7,8 +7,9 @@ exports.getBindHost = exports.isLinux = exports.isMac = exports.isWindows = expo
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const yaml_1 = __importDefault(require("yaml"));
9
9
  const nodejs_utils_1 = require("@kapeta/nodejs-utils");
10
- function getBlockInstanceContainerName(instanceId) {
11
- return `kapeta-block-instance-${instanceId}`;
10
+ const md5_1 = __importDefault(require("md5"));
11
+ function getBlockInstanceContainerName(systemId, instanceId) {
12
+ return `kapeta-block-instance-${(0, md5_1.default)(systemId + instanceId)}`;
12
13
  }
13
14
  exports.getBlockInstanceContainerName = getBlockInstanceContainerName;
14
15
  function normalizeKapetaUri(uri) {
@@ -1,5 +1,6 @@
1
1
  import { Docker } from 'node-docker-api';
2
2
  import { Container } from 'node-docker-api/lib/container';
3
+ import { InstanceInfo, LogEntry } from "./types";
3
4
  type StringMap = {
4
5
  [key: string]: string;
5
6
  };
@@ -52,8 +53,8 @@ declare class ContainerManager {
52
53
  initialize(): Promise<void>;
53
54
  checkAlive(): Promise<boolean>;
54
55
  isAlive(): boolean;
55
- getMountPoint(kind: string, mountName: string): string;
56
- createMounts(kind: string, mountOpts: StringMap): StringMap;
56
+ getMountPoint(systemId: string, ref: string, mountName: string): string;
57
+ createMounts(systemId: string, kind: string, mountOpts: StringMap | null | undefined): Promise<StringMap>;
57
58
  ping(): Promise<void>;
58
59
  docker(): Docker;
59
60
  getContainerByName(containerName: string): Promise<ContainerInfo | undefined>;
@@ -67,11 +68,10 @@ declare class ContainerManager {
67
68
  };
68
69
  private applyHash;
69
70
  ensureContainer(opts: any): Promise<Container>;
71
+ private createOrUpdateContainer;
70
72
  startContainer(opts: any): Promise<Container>;
71
73
  waitForReady(container: Container, attempt?: number): Promise<void>;
72
- waitForHealthy(container: Container, attempt?: number): Promise<void>;
73
74
  _isReady(container: Container): Promise<any>;
74
- _isHealthy(container: Container): Promise<boolean>;
75
75
  remove(container: Container, opts?: {
76
76
  force?: boolean;
77
77
  }): Promise<void>;
@@ -81,6 +81,7 @@ declare class ContainerManager {
81
81
  * @return {Promise<ContainerInfo>}
82
82
  */
83
83
  get(name: string): Promise<ContainerInfo | null>;
84
+ getLogs(instance: InstanceInfo): Promise<LogEntry[]>;
84
85
  }
85
86
  export declare class ContainerInfo {
86
87
  private readonly _container;
@@ -105,6 +106,7 @@ export declare class ContainerInfo {
105
106
  inspect(): Promise<any>;
106
107
  status(): Promise<DockerState>;
107
108
  getPorts(): Promise<PortMap | false>;
109
+ getLogs(): Promise<LogEntry[]>;
108
110
  }
109
111
  export declare function getExtraHosts(dockerVersion: string): string[] | undefined;
110
112
  /**
@@ -8,6 +8,7 @@ import { parseKapetaUri } from '@kapeta/nodejs-utils';
8
8
  import ClusterConfiguration from '@kapeta/local-cluster-config';
9
9
  import uuid from 'node-uuid';
10
10
  import md5 from 'md5';
11
+ import { getBlockInstanceContainerName } from "./utils/utils";
11
12
  export const CONTAINER_LABEL_PORT_PREFIX = 'kapeta_port-';
12
13
  const NANO_SECOND = 1000000;
13
14
  const HEALTH_CHECK_INTERVAL = 3000;
@@ -15,8 +16,8 @@ const HEALTH_CHECK_MAX = 20;
15
16
  const IMAGE_PULL_CACHE_TTL = 30 * 60 * 1000;
16
17
  const IMAGE_PULL_CACHE = {};
17
18
  export const HEALTH_CHECK_TIMEOUT = HEALTH_CHECK_INTERVAL * HEALTH_CHECK_MAX * 2;
18
- const promisifyStream = (stream) => new Promise((resolve, reject) => {
19
- stream.on('data', (d) => console.log(d.toString()));
19
+ const promisifyStream = (stream, handler) => new Promise((resolve, reject) => {
20
+ stream.on('data', handler);
20
21
  stream.on('end', resolve);
21
22
  stream.on('error', reject);
22
23
  });
@@ -95,17 +96,21 @@ class ContainerManager {
95
96
  isAlive() {
96
97
  return this._alive;
97
98
  }
98
- getMountPoint(kind, mountName) {
99
- const kindUri = parseKapetaUri(kind);
100
- return Path.join(this._mountDir, kindUri.handle, kindUri.name, mountName);
99
+ getMountPoint(systemId, ref, mountName) {
100
+ const kindUri = parseKapetaUri(ref);
101
+ const systemUri = parseKapetaUri(systemId);
102
+ return Path.join(this._mountDir, systemUri.handle, systemUri.name, systemUri.version, kindUri.handle, kindUri.name, kindUri.version, mountName);
101
103
  }
102
- createMounts(kind, mountOpts) {
104
+ async createMounts(systemId, kind, mountOpts) {
103
105
  const mounts = {};
104
- _.forEach(mountOpts, (containerPath, mountName) => {
105
- const hostPath = this.getMountPoint(kind, mountName);
106
- FSExtra.mkdirpSync(hostPath);
107
- mounts[containerPath] = hostPath;
108
- });
106
+ if (mountOpts) {
107
+ const mountOptList = Object.entries(mountOpts);
108
+ for (const [mountName, containerPath] of mountOptList) {
109
+ const hostPath = this.getMountPoint(systemId, kind, mountName);
110
+ await FSExtra.mkdirp(hostPath);
111
+ mounts[containerPath] = hostPath;
112
+ }
113
+ }
109
114
  return mounts;
110
115
  }
111
116
  async ping() {
@@ -156,12 +161,14 @@ class ContainerManager {
156
161
  return false;
157
162
  }
158
163
  console.log('Pulling image: %s', image);
159
- await this.docker()
164
+ const stream = await this.docker()
160
165
  .image.create({}, {
161
166
  fromImage: imageName,
162
167
  tag: tag,
163
- })
164
- .then((stream) => promisifyStream(stream));
168
+ });
169
+ await promisifyStream(stream, (chunk) => {
170
+ console.log('Data from docker: "%s"', chunk.toString());
171
+ });
165
172
  IMAGE_PULL_CACHE[image] = Date.now();
166
173
  console.log('Image pulled: %s', image);
167
174
  return true;
@@ -198,6 +205,11 @@ class ContainerManager {
198
205
  dockerOpts.Labels.HASH = hash;
199
206
  }
200
207
  async ensureContainer(opts) {
208
+ const container = await this.createOrUpdateContainer(opts);
209
+ await this.waitForReady(container);
210
+ return container;
211
+ }
212
+ async createOrUpdateContainer(opts) {
201
213
  let imagePulled = false;
202
214
  try {
203
215
  imagePulled = await this.pull(opts.Image);
@@ -277,28 +289,6 @@ class ContainerManager {
277
289
  }, HEALTH_CHECK_INTERVAL);
278
290
  });
279
291
  }
280
- async waitForHealthy(container, attempt) {
281
- if (!attempt) {
282
- attempt = 0;
283
- }
284
- if (attempt >= HEALTH_CHECK_MAX) {
285
- throw new Error('Container did not become healthy within the timeout');
286
- }
287
- if (await this._isHealthy(container)) {
288
- return;
289
- }
290
- return new Promise((resolve, reject) => {
291
- setTimeout(async () => {
292
- try {
293
- await this.waitForHealthy(container, (attempt ?? 0) + 1);
294
- resolve();
295
- }
296
- catch (err) {
297
- reject(err);
298
- }
299
- }, HEALTH_CHECK_INTERVAL);
300
- });
301
- }
302
292
  async _isReady(container) {
303
293
  let info;
304
294
  try {
@@ -312,16 +302,12 @@ class ContainerManager {
312
302
  if (state?.Status === 'exited' || state?.Status === 'removing' || state?.Status === 'dead') {
313
303
  throw new Error('Container exited unexpectedly');
314
304
  }
315
- return infoData?.State?.Running ?? false;
316
- }
317
- async _isHealthy(container) {
318
- try {
319
- const info = await container.status();
320
- const infoData = info?.data;
321
- return infoData?.State?.Health?.Status === 'healthy';
305
+ if (infoData?.State?.Health) {
306
+ // If container has health info - wait for it to become healthy
307
+ return infoData.State.Health.Status === 'healthy';
322
308
  }
323
- catch (err) {
324
- return false;
309
+ else {
310
+ return infoData?.State?.Running ?? false;
325
311
  }
326
312
  }
327
313
  async remove(container, opts) {
@@ -351,6 +337,19 @@ class ContainerManager {
351
337
  }
352
338
  return new ContainerInfo(dockerContainer);
353
339
  }
340
+ async getLogs(instance) {
341
+ const containerName = getBlockInstanceContainerName(instance.systemId, instance.instanceId);
342
+ const containerInfo = await this.getContainerByName(containerName);
343
+ if (!containerInfo) {
344
+ return [{
345
+ source: "stdout",
346
+ level: "ERROR",
347
+ time: Date.now(),
348
+ message: "Container not found"
349
+ }];
350
+ }
351
+ return containerInfo.getLogs();
352
+ }
354
353
  }
355
354
  export class ContainerInfo {
356
355
  _container;
@@ -434,6 +433,62 @@ export class ContainerInfo {
434
433
  });
435
434
  return ports;
436
435
  }
436
+ async getLogs() {
437
+ const logStream = await this.native.logs({
438
+ stdout: true,
439
+ stderr: true,
440
+ follow: false,
441
+ tail: 100,
442
+ timestamps: true,
443
+ });
444
+ const out = [];
445
+ await promisifyStream(logStream, (data) => {
446
+ const buf = data;
447
+ let offset = 0;
448
+ while (offset < buf.length) {
449
+ try {
450
+ // Read the docker log format - explained here:
451
+ // https://docs.docker.com/engine/api/v1.41/#operation/ContainerAttach
452
+ // or here : https://ahmet.im/blog/docker-logs-api-binary-format-explained/
453
+ // First byte is stream type
454
+ const streamTypeInt = buf.readInt8(offset);
455
+ const streamType = streamTypeInt === 1 ? 'stdout' : 'stderr';
456
+ // Bytes 4-8 is frame size
457
+ const messageLength = buf.readInt32BE(offset + 4);
458
+ // After that is the message - with the message length
459
+ const dataWithoutStreamType = buf.subarray(offset + 8, offset + 8 + messageLength);
460
+ const raw = dataWithoutStreamType.toString();
461
+ // Split the message into date and message
462
+ const firstSpaceIx = raw.indexOf(' ');
463
+ const dateString = raw.substring(0, firstSpaceIx);
464
+ const line = raw.substring(firstSpaceIx + 1);
465
+ offset = offset + messageLength + 8;
466
+ if (!dateString) {
467
+ continue;
468
+ }
469
+ out.push({
470
+ time: new Date(dateString).getTime(),
471
+ message: line,
472
+ level: 'INFO',
473
+ source: streamType,
474
+ });
475
+ }
476
+ catch (err) {
477
+ console.error('Error parsing log entry', err);
478
+ offset = buf.length;
479
+ }
480
+ }
481
+ });
482
+ if (out.length === 0) {
483
+ out.push({
484
+ time: Date.now(),
485
+ message: 'No logs found for container',
486
+ level: 'INFO',
487
+ source: 'stdout',
488
+ });
489
+ }
490
+ return out;
491
+ }
437
492
  }
438
493
  export function getExtraHosts(dockerVersion) {
439
494
  if (process.platform !== 'darwin' && process.platform !== 'win32') {
@@ -5,6 +5,7 @@ declare class DefinitionsManager {
5
5
  clearCache(): void;
6
6
  private doCached;
7
7
  getDefinitions(kindFilter?: string | string[]): DefinitionInfo[];
8
+ exists(ref: string): boolean;
8
9
  getProviderDefinitions(): DefinitionInfo[];
9
10
  }
10
11
  export declare const definitionsManager: DefinitionsManager;
@@ -1,4 +1,5 @@
1
1
  import ClusterConfiguration from '@kapeta/local-cluster-config';
2
+ import { parseKapetaUri } from "@kapeta/nodejs-utils";
2
3
  const CACHE_TTL = 60 * 1000; // 1 min
3
4
  class DefinitionsManager {
4
5
  cache = {};
@@ -31,6 +32,12 @@ class DefinitionsManager {
31
32
  const key = this.getKey(kindFilter);
32
33
  return this.doCached(key, () => ClusterConfiguration.getDefinitions(kindFilter));
33
34
  }
35
+ exists(ref) {
36
+ const uri = parseKapetaUri(ref);
37
+ return !!this.getDefinitions().find((d) => {
38
+ return parseKapetaUri(`${d.definition.metadata.name}:${d.version}`).id === uri.id;
39
+ });
40
+ }
34
41
  getProviderDefinitions() {
35
42
  return this.doCached('providers', () => ClusterConfiguration.getProviderDefinitions());
36
43
  }
@@ -1,12 +1,15 @@
1
- import { InstanceInfo } from './types';
1
+ import { InstanceInfo, LogEntry } from './types';
2
2
  export declare class InstanceManager {
3
3
  private _interval;
4
4
  private readonly _instances;
5
+ private readonly instanceLocks;
5
6
  constructor();
6
7
  private checkInstancesLater;
7
8
  getInstances(): InstanceInfo[];
8
9
  getInstancesForPlan(systemId: string): InstanceInfo[];
9
10
  getInstance(systemId: string, instanceId: string): InstanceInfo | undefined;
11
+ private exclusive;
12
+ getLogs(systemId: string, instanceId: string): Promise<LogEntry[]>;
10
13
  saveInternalInstance(instance: InstanceInfo): Promise<InstanceInfo>;
11
14
  /**
12
15
  * Method is called when instance is started from the Kapeta SDKs (e.g. NodeJS SDK)
@@ -14,9 +17,10 @@ export declare class InstanceManager {
14
17
  */
15
18
  registerInstanceFromSDK(systemId: string, instanceId: string, info: Omit<InstanceInfo, 'systemId' | 'instanceId'>): Promise<InstanceInfo | undefined>;
16
19
  private getHealthUrl;
17
- markAsStopped(systemId: string, instanceId: string): void;
20
+ markAsStopped(systemId: string, instanceId: string): Promise<void>;
18
21
  startAllForPlan(systemId: string): Promise<InstanceInfo[]>;
19
22
  stop(systemId: string, instanceId: string): Promise<void>;
23
+ private stopInner;
20
24
  stopAllForPlan(systemId: string): Promise<void>;
21
25
  start(systemId: string, instanceId: string): Promise<InstanceInfo>;
22
26
  restart(systemId: string, instanceId: string): Promise<InstanceInfo>;