@kapeta/local-cluster-service 0.19.6 → 0.19.7

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.
@@ -6,7 +6,12 @@ import { storageService } from './storageService';
6
6
  import { EVENT_INSTANCE_CREATED, EVENT_INSTANCE_EXITED, EVENT_STATUS_CHANGED, socketManager } from './socketManager';
7
7
  import { serviceManager } from './serviceManager';
8
8
  import { assetManager } from './assetManager';
9
- import { containerManager, HEALTH_CHECK_TIMEOUT } from './containerManager';
9
+ import {
10
+ containerManager,
11
+ DockerContainerHealth,
12
+ DockerContainerStatus,
13
+ HEALTH_CHECK_TIMEOUT,
14
+ } from './containerManager';
10
15
  import { configManager } from './configManager';
11
16
  import { DesiredInstanceStatus, InstanceInfo, InstanceOwner, InstanceStatus, InstanceType, LogEntry } from './types';
12
17
  import { BlockDefinitionSpec, BlockInstance, Plan } from '@kapeta/schemas';
@@ -336,6 +341,10 @@ export class InstanceManager {
336
341
  return;
337
342
  }
338
343
 
344
+ if (instance.status === InstanceStatus.STOPPING) {
345
+ return;
346
+ }
347
+
339
348
  if (changeDesired && instance.desiredStatus !== DesiredInstanceStatus.EXTERNAL) {
340
349
  instance.desiredStatus = DesiredInstanceStatus.STOP;
341
350
  }
@@ -496,7 +505,7 @@ export class InstanceManager {
496
505
  try {
497
506
  const processInfo = await runner.start(blockRef, instanceId, instanceConfig);
498
507
 
499
- instance.status = InstanceStatus.READY;
508
+ instance.status = InstanceStatus.STARTING;
500
509
 
501
510
  return this.saveInternalInstance({
502
511
  ...instance,
@@ -504,10 +513,10 @@ export class InstanceManager {
504
513
  pid: processInfo.pid ?? -1,
505
514
  health: null,
506
515
  portType: processInfo.portType,
507
- status: InstanceStatus.READY,
516
+ status: InstanceStatus.STARTING,
508
517
  });
509
518
  } catch (e: any) {
510
- console.warn('Failed to start instance: ', systemId, instanceId, blockRef, e.message);
519
+ console.warn('Failed to start instance: ', systemId, instanceId, blockRef, e);
511
520
  const logs: LogEntry[] = [
512
521
  {
513
522
  source: 'stdout',
@@ -686,7 +695,12 @@ export class InstanceManager {
686
695
  try {
687
696
  await this.start(instance.systemId, instance.instanceId);
688
697
  } catch (e: any) {
689
- console.warn('Failed to start instance', instance.systemId, instance.instanceId, e);
698
+ console.warn(
699
+ 'Failed to start previously stopped instance',
700
+ instance.systemId,
701
+ instance.instanceId,
702
+ e
703
+ );
690
704
  }
691
705
  return;
692
706
  }
@@ -738,37 +752,47 @@ export class InstanceManager {
738
752
  return InstanceStatus.STOPPED;
739
753
  }
740
754
  const state = await container.status();
755
+ if (!state) {
756
+ return InstanceStatus.STOPPED;
757
+ }
741
758
 
742
- if (state.Status === 'running') {
743
- if (state.Health?.Status === 'healthy') {
744
- return InstanceStatus.READY;
745
- }
746
- if (state.Health?.Status === 'starting') {
747
- return InstanceStatus.STARTING;
748
- }
749
- if (state.Health?.Status === 'unhealthy') {
750
- return InstanceStatus.UNHEALTHY;
751
- }
759
+ const statusType = state.Status as DockerContainerStatus;
752
760
 
761
+ if (statusType === 'running') {
762
+ if (state.Health?.Status) {
763
+ const healthStatusType = state.Health.Status as DockerContainerHealth;
764
+ if (healthStatusType === 'healthy' || healthStatusType === 'none') {
765
+ return InstanceStatus.READY;
766
+ }
767
+
768
+ if (healthStatusType === 'starting') {
769
+ return InstanceStatus.STARTING;
770
+ }
771
+
772
+ if (healthStatusType === 'unhealthy') {
773
+ return InstanceStatus.UNHEALTHY;
774
+ }
775
+ }
753
776
  return InstanceStatus.READY;
754
777
  }
755
- if (state.Status === 'created') {
778
+
779
+ if (statusType === 'created') {
756
780
  return InstanceStatus.STARTING;
757
781
  }
758
782
 
759
- if (state.Status === 'exited' || state.Status === 'dead') {
783
+ if (statusType === 'exited' || statusType === 'dead') {
760
784
  return InstanceStatus.STOPPED;
761
785
  }
762
786
 
763
- if (state.Status === 'removing') {
787
+ if (statusType === 'removing') {
764
788
  return InstanceStatus.BUSY;
765
789
  }
766
790
 
767
- if (state.Status === 'restarting') {
791
+ if (statusType === 'restarting') {
768
792
  return InstanceStatus.BUSY;
769
793
  }
770
794
 
771
- if (state.Status === 'paused') {
795
+ if (statusType === 'paused') {
772
796
  return InstanceStatus.BUSY;
773
797
  }
774
798
 
@@ -4,7 +4,13 @@ import md5 from 'md5';
4
4
  import { parseKapetaUri } from '@kapeta/nodejs-utils';
5
5
  import { serviceManager } from './serviceManager';
6
6
  import { storageService } from './storageService';
7
- import { CONTAINER_LABEL_PORT_PREFIX, ContainerInfo, containerManager } from './containerManager';
7
+ import {
8
+ COMPOSE_LABEL_PROJECT,
9
+ COMPOSE_LABEL_SERVICE,
10
+ CONTAINER_LABEL_PORT_PREFIX,
11
+ ContainerInfo,
12
+ containerManager,
13
+ } from './containerManager';
8
14
  import FSExtra from 'fs-extra';
9
15
  import { AnyMap, EnvironmentType, OperatorInfo, StringMap } from './types';
10
16
  import { BlockInstance, Resource } from '@kapeta/schemas';
@@ -199,8 +205,12 @@ class OperatorManager {
199
205
  const PortBindings: { [key: string]: any } = {};
200
206
  const Env: string[] = [];
201
207
 
208
+ const systemUri = parseKapetaUri(systemId);
209
+
202
210
  const Labels: StringMap = {
203
211
  kapeta: 'true',
212
+ [COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
213
+ [COMPOSE_LABEL_SERVICE]: [resourceType, version].join('_').replace(/[^a-z0-9]/gi, '_'),
204
214
  };
205
215
 
206
216
  const operatorMetadata = operator.getDefinitionInfo().definition.metadata;
@@ -139,7 +139,9 @@ class TaskManager {
139
139
 
140
140
  socketManager.emitGlobal(EVENT_TASK_ADDED, task.toData());
141
141
 
142
- this.invokeTask(task).catch(() => {});
142
+ this.invokeTask(task).catch((err) => {
143
+ console.warn(`Task ${task.id} failed`, err);
144
+ });
143
145
 
144
146
  return task;
145
147
  }
@@ -205,6 +207,7 @@ class TaskManager {
205
207
  task.future.resolve(result);
206
208
  task.emitUpdate();
207
209
  } catch (e: any) {
210
+ console.warn(`Task ${task.id} failed while waiting for it to resolve`, e);
208
211
  task.errorMessage = e.message;
209
212
  task.status = TaskStatus.FAILED;
210
213
  task.future.reject(e);
@@ -3,12 +3,18 @@ import ClusterConfig, { DefinitionInfo } from '@kapeta/local-cluster-config';
3
3
  import { getBindHost, getBlockInstanceContainerName, normalizeKapetaUri, readYML } from './utils';
4
4
  import { KapetaURI, parseKapetaUri } from '@kapeta/nodejs-utils';
5
5
  import { serviceManager } from '../serviceManager';
6
- import { containerManager, DockerMounts, toLocalBindVolume } from '../containerManager';
6
+ import {
7
+ COMPOSE_LABEL_PROJECT,
8
+ COMPOSE_LABEL_SERVICE,
9
+ containerManager,
10
+ DockerMounts,
11
+ toLocalBindVolume,
12
+ } from '../containerManager';
7
13
  import { LogData } from './LogData';
8
14
  import { clusterService } from '../clusterService';
9
15
  import { AnyMap, BlockProcessParams, InstanceType, ProcessInfo, StringMap } from '../types';
10
- import { Container } from 'node-docker-api/lib/container';
11
16
  import { definitionsManager } from '../definitionsManager';
17
+ import Docker from 'dockerode';
12
18
 
13
19
  const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
14
20
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
@@ -185,6 +191,8 @@ export class BlockInstanceRunner {
185
191
  HealthCheck = containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
186
192
  }
187
193
 
194
+ const systemUri = parseKapetaUri(this._systemId);
195
+
188
196
  return this.ensureContainer({
189
197
  ...dockerOpts,
190
198
  Image: dockerImage,
@@ -193,6 +201,8 @@ export class BlockInstanceRunner {
193
201
  Labels: {
194
202
  ...customLabels,
195
203
  instance: blockInstance.id,
204
+ [COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
205
+ [COMPOSE_LABEL_SERVICE]: blockInfo.id.replace(/[^a-z0-9]/gi, '_'),
196
206
  },
197
207
  HealthCheck,
198
208
  ExposedPorts,
@@ -250,6 +260,7 @@ export class BlockInstanceRunner {
250
260
 
251
261
  // For windows we need to default to root
252
262
  const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
263
+ const systemUri = parseKapetaUri(this._systemId);
253
264
 
254
265
  return this.ensureContainer({
255
266
  Image: dockerImage,
@@ -257,6 +268,8 @@ export class BlockInstanceRunner {
257
268
  ExposedPorts,
258
269
  Labels: {
259
270
  instance: blockInstance.id,
271
+ [COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
272
+ [COMPOSE_LABEL_SERVICE]: blockInfo.id.replace(/[^a-z0-9]/gi, '_'),
260
273
  },
261
274
  Env: [
262
275
  ...DOCKER_ENV_VARS,
@@ -354,6 +367,7 @@ export class BlockInstanceRunner {
354
367
  // For windows we need to default to root
355
368
  const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
356
369
 
370
+ const systemUri = parseKapetaUri(this._systemId);
357
371
  logs.addLog(`Creating new container for block: ${containerName}`);
358
372
  const out = await this.ensureContainer({
359
373
  Image: dockerImage,
@@ -370,6 +384,8 @@ export class BlockInstanceRunner {
370
384
  },
371
385
  Labels: {
372
386
  instance: blockInstance.id,
387
+ [COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
388
+ [COMPOSE_LABEL_SERVICE]: blockUri.id.replace(/[^a-z0-9]/gi, '_'),
373
389
  },
374
390
  Env: [
375
391
  `KAPETA_INSTANCE_NAME=${blockInstance.ref}`,
@@ -424,7 +440,7 @@ export class BlockInstanceRunner {
424
440
  return this._handleContainer(container);
425
441
  }
426
442
 
427
- private async _handleContainer(container: Container): Promise<ProcessInfo> {
443
+ private async _handleContainer(container: Docker.Container): Promise<ProcessInfo> {
428
444
  return {
429
445
  type: InstanceType.DOCKER,
430
446
  pid: container.id,