@kapeta/local-cluster-service 0.40.6 → 0.41.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## [0.41.1](https://github.com/kapetacom/local-cluster-service/compare/v0.41.0...v0.41.1) (2024-04-16)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * better missing file handling [CORE-2685] ([1baf002](https://github.com/kapetacom/local-cluster-service/commit/1baf002c18c6acc92a4f6ca1bff37cda9270e487))
7
+ * bump local-cluster-config w/ improved error handling ([f9a945f](https://github.com/kapetacom/local-cluster-service/commit/f9a945f7761e472e45bc55839b40e563c5298719))
8
+
9
+ # [0.41.0](https://github.com/kapetacom/local-cluster-service/compare/v0.40.6...v0.41.0) (2024-04-12)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * review comments ([c0b75a0](https://github.com/kapetacom/local-cluster-service/commit/c0b75a08994c0505f4598327547ccd2199efa94a))
15
+
16
+
17
+ ### Features
18
+
19
+ * append connected block operator specific env to blocks ([a003c4f](https://github.com/kapetacom/local-cluster-service/commit/a003c4fdb98706aebbc6bc8ae28cf9cc6e7ba9cf))
20
+
1
21
  ## [0.40.6](https://github.com/kapetacom/local-cluster-service/compare/v0.40.5...v0.40.6) (2024-04-11)
2
22
 
3
23
 
@@ -25,10 +25,17 @@ const node_os_1 = __importDefault(require("node:os"));
25
25
  const CACHE_TTL = 60 * 60 * 1000; // 1 hour
26
26
  const UPGRADE_CHECK_INTERVAL = 10 * 60 * 1000; // 10 minutes
27
27
  const toKey = (ref) => `assetManager:asset:${ref}`;
28
- function filterExists(asset) {
29
- return fs_extra_1.default.existsSync(asset.path) && fs_extra_1.default.existsSync(asset.ymlPath);
30
- }
31
28
  function enrichAsset(asset) {
29
+ let exists = true;
30
+ let path = asset.path;
31
+ let ymlPath = asset.ymlPath;
32
+ try {
33
+ path = fs_extra_1.default.realpathSync(path);
34
+ ymlPath = fs_extra_1.default.realpathSync(ymlPath);
35
+ }
36
+ catch (e) {
37
+ exists = false;
38
+ }
32
39
  return {
33
40
  ref: `kapeta://${asset.definition.metadata.name}:${asset.version}`,
34
41
  editable: asset.version === 'local', //Only local versions are editable
@@ -36,8 +43,8 @@ function enrichAsset(asset) {
36
43
  version: asset.version,
37
44
  kind: asset.definition.kind,
38
45
  data: asset.definition,
39
- path: fs_extra_1.default.realpathSync(asset.path),
40
- ymlPath: fs_extra_1.default.realpathSync(asset.ymlPath),
46
+ path,
47
+ ymlPath,
41
48
  };
42
49
  }
43
50
  function compareRefs(a, b) {
@@ -86,7 +93,7 @@ class AssetManager {
86
93
  assetKinds.push('core/plan');
87
94
  }
88
95
  const assets = await definitionsManager_1.definitionsManager.getDefinitions(assetKinds);
89
- return assets.filter(filterExists).map(enrichAsset);
96
+ return assets.map(enrichAsset).filter((a) => a.exists);
90
97
  }
91
98
  async getPlans() {
92
99
  return this.getAssets(['core/plan']);
@@ -124,9 +131,14 @@ class AssetManager {
124
131
  throw new Error('Asset not found: ' + ref);
125
132
  }
126
133
  if (definitionInfo) {
127
- const asset = enrichAsset(definitionInfo);
128
- cacheManager_1.cacheManager.set(cacheKey, asset, CACHE_TTL);
129
- return asset;
134
+ try {
135
+ const asset = enrichAsset(definitionInfo);
136
+ cacheManager_1.cacheManager.set(cacheKey, asset, CACHE_TTL);
137
+ return asset;
138
+ }
139
+ catch (e) {
140
+ console.error('Failed to enrich asset', e);
141
+ }
130
142
  }
131
143
  return undefined;
132
144
  }
@@ -26,4 +26,5 @@ export declare class BlockInstanceRunner {
26
26
  private ensureContainer;
27
27
  private _handleContainer;
28
28
  private getFileHash;
29
+ private appendConnectedBlockOperatorEnv;
29
30
  }
@@ -114,7 +114,8 @@ class BlockInstanceRunner {
114
114
  const realBaseDir = await fs_extra_1.default.realpath(baseDir);
115
115
  const internalConfigProvider = await (0, InternalConfigProvider_1.createInternalConfigProvider)(this._systemId, blockInstance.id, assetVersion);
116
116
  // Resolve the environment variables
117
- const variables = await (0, config_mapper_1.resolveKapetaVariables)(realBaseDir, internalConfigProvider);
117
+ const blockVariables = await (0, config_mapper_1.resolveKapetaVariables)(realBaseDir, internalConfigProvider);
118
+ const variables = await this.appendConnectedBlockOperatorEnv(internalConfigProvider, blockInstance, blockVariables);
118
119
  // Write out the config templates if they exist
119
120
  await (0, config_mapper_1.writeConfigTemplates)(variables, realBaseDir);
120
121
  const env = await (0, config_mapper_1.getEnvironmentVariables)(variables);
@@ -409,6 +410,7 @@ class BlockInstanceRunner {
409
410
  PortBindings,
410
411
  Mounts,
411
412
  },
413
+ Cmd: local.cmd,
412
414
  Labels: {
413
415
  ...labels,
414
416
  instance: operatorId,
@@ -480,5 +482,39 @@ class BlockInstanceRunner {
480
482
  //Creating the hash in the required format
481
483
  return data.digest('hex');
482
484
  }
485
+ async appendConnectedBlockOperatorEnv(internalConfigProvider, blockInstance, variables) {
486
+ const plan = await internalConfigProvider.getPlan();
487
+ const connectedBlockIds = [
488
+ ...new Set(plan.spec.connections
489
+ .filter((connection) => connection.provider.blockId == blockInstance.id || connection.consumer.blockId == blockInstance.id)
490
+ .flatMap((connection) => [connection.provider.blockId, connection.consumer.blockId])
491
+ .filter((blockId) => blockId !== blockInstance.id)),
492
+ ];
493
+ for (const connectedBlockId of connectedBlockIds) {
494
+ const connectedBlockInstance = plan.spec.blocks.find((blockInstance) => blockInstance.id == connectedBlockId);
495
+ if (!connectedBlockInstance) {
496
+ continue;
497
+ }
498
+ const connectedBlockDefinition = await internalConfigProvider.getBlock(connectedBlockInstance?.block.ref);
499
+ const connectedBlockDefinitionInfo = await getProvider((0, nodejs_utils_1.parseKapetaUri)(connectedBlockDefinition.kind));
500
+ const local = connectedBlockDefinitionInfo?.definition.spec.local;
501
+ if (!local || !local.addEnv) {
502
+ continue;
503
+ }
504
+ const connectedBlockInstanceOperator = await internalConfigProvider.getInstanceOperator(connectedBlockId);
505
+ for (const addEnv of local.addEnv) {
506
+ var result;
507
+ try {
508
+ result = eval(addEnv)(connectedBlockInstanceOperator);
509
+ }
510
+ catch (error) {
511
+ result = addEnv;
512
+ }
513
+ const parts = result.split('=');
514
+ variables[parts[0]] = { type: config_mapper_1.VariableType.ENV, value: parts[1], json: false };
515
+ }
516
+ }
517
+ return variables;
518
+ }
483
519
  }
484
520
  exports.BlockInstanceRunner = BlockInstanceRunner;
@@ -25,10 +25,17 @@ const node_os_1 = __importDefault(require("node:os"));
25
25
  const CACHE_TTL = 60 * 60 * 1000; // 1 hour
26
26
  const UPGRADE_CHECK_INTERVAL = 10 * 60 * 1000; // 10 minutes
27
27
  const toKey = (ref) => `assetManager:asset:${ref}`;
28
- function filterExists(asset) {
29
- return fs_extra_1.default.existsSync(asset.path) && fs_extra_1.default.existsSync(asset.ymlPath);
30
- }
31
28
  function enrichAsset(asset) {
29
+ let exists = true;
30
+ let path = asset.path;
31
+ let ymlPath = asset.ymlPath;
32
+ try {
33
+ path = fs_extra_1.default.realpathSync(path);
34
+ ymlPath = fs_extra_1.default.realpathSync(ymlPath);
35
+ }
36
+ catch (e) {
37
+ exists = false;
38
+ }
32
39
  return {
33
40
  ref: `kapeta://${asset.definition.metadata.name}:${asset.version}`,
34
41
  editable: asset.version === 'local', //Only local versions are editable
@@ -36,8 +43,8 @@ function enrichAsset(asset) {
36
43
  version: asset.version,
37
44
  kind: asset.definition.kind,
38
45
  data: asset.definition,
39
- path: fs_extra_1.default.realpathSync(asset.path),
40
- ymlPath: fs_extra_1.default.realpathSync(asset.ymlPath),
46
+ path,
47
+ ymlPath,
41
48
  };
42
49
  }
43
50
  function compareRefs(a, b) {
@@ -86,7 +93,7 @@ class AssetManager {
86
93
  assetKinds.push('core/plan');
87
94
  }
88
95
  const assets = await definitionsManager_1.definitionsManager.getDefinitions(assetKinds);
89
- return assets.filter(filterExists).map(enrichAsset);
96
+ return assets.map(enrichAsset).filter((a) => a.exists);
90
97
  }
91
98
  async getPlans() {
92
99
  return this.getAssets(['core/plan']);
@@ -124,9 +131,14 @@ class AssetManager {
124
131
  throw new Error('Asset not found: ' + ref);
125
132
  }
126
133
  if (definitionInfo) {
127
- const asset = enrichAsset(definitionInfo);
128
- cacheManager_1.cacheManager.set(cacheKey, asset, CACHE_TTL);
129
- return asset;
134
+ try {
135
+ const asset = enrichAsset(definitionInfo);
136
+ cacheManager_1.cacheManager.set(cacheKey, asset, CACHE_TTL);
137
+ return asset;
138
+ }
139
+ catch (e) {
140
+ console.error('Failed to enrich asset', e);
141
+ }
130
142
  }
131
143
  return undefined;
132
144
  }
@@ -26,4 +26,5 @@ export declare class BlockInstanceRunner {
26
26
  private ensureContainer;
27
27
  private _handleContainer;
28
28
  private getFileHash;
29
+ private appendConnectedBlockOperatorEnv;
29
30
  }
@@ -114,7 +114,8 @@ class BlockInstanceRunner {
114
114
  const realBaseDir = await fs_extra_1.default.realpath(baseDir);
115
115
  const internalConfigProvider = await (0, InternalConfigProvider_1.createInternalConfigProvider)(this._systemId, blockInstance.id, assetVersion);
116
116
  // Resolve the environment variables
117
- const variables = await (0, config_mapper_1.resolveKapetaVariables)(realBaseDir, internalConfigProvider);
117
+ const blockVariables = await (0, config_mapper_1.resolveKapetaVariables)(realBaseDir, internalConfigProvider);
118
+ const variables = await this.appendConnectedBlockOperatorEnv(internalConfigProvider, blockInstance, blockVariables);
118
119
  // Write out the config templates if they exist
119
120
  await (0, config_mapper_1.writeConfigTemplates)(variables, realBaseDir);
120
121
  const env = await (0, config_mapper_1.getEnvironmentVariables)(variables);
@@ -409,6 +410,7 @@ class BlockInstanceRunner {
409
410
  PortBindings,
410
411
  Mounts,
411
412
  },
413
+ Cmd: local.cmd,
412
414
  Labels: {
413
415
  ...labels,
414
416
  instance: operatorId,
@@ -480,5 +482,39 @@ class BlockInstanceRunner {
480
482
  //Creating the hash in the required format
481
483
  return data.digest('hex');
482
484
  }
485
+ async appendConnectedBlockOperatorEnv(internalConfigProvider, blockInstance, variables) {
486
+ const plan = await internalConfigProvider.getPlan();
487
+ const connectedBlockIds = [
488
+ ...new Set(plan.spec.connections
489
+ .filter((connection) => connection.provider.blockId == blockInstance.id || connection.consumer.blockId == blockInstance.id)
490
+ .flatMap((connection) => [connection.provider.blockId, connection.consumer.blockId])
491
+ .filter((blockId) => blockId !== blockInstance.id)),
492
+ ];
493
+ for (const connectedBlockId of connectedBlockIds) {
494
+ const connectedBlockInstance = plan.spec.blocks.find((blockInstance) => blockInstance.id == connectedBlockId);
495
+ if (!connectedBlockInstance) {
496
+ continue;
497
+ }
498
+ const connectedBlockDefinition = await internalConfigProvider.getBlock(connectedBlockInstance?.block.ref);
499
+ const connectedBlockDefinitionInfo = await getProvider((0, nodejs_utils_1.parseKapetaUri)(connectedBlockDefinition.kind));
500
+ const local = connectedBlockDefinitionInfo?.definition.spec.local;
501
+ if (!local || !local.addEnv) {
502
+ continue;
503
+ }
504
+ const connectedBlockInstanceOperator = await internalConfigProvider.getInstanceOperator(connectedBlockId);
505
+ for (const addEnv of local.addEnv) {
506
+ var result;
507
+ try {
508
+ result = eval(addEnv)(connectedBlockInstanceOperator);
509
+ }
510
+ catch (error) {
511
+ result = addEnv;
512
+ }
513
+ const parts = result.split('=');
514
+ variables[parts[0]] = { type: config_mapper_1.VariableType.ENV, value: parts[1], json: false };
515
+ }
516
+ }
517
+ return variables;
518
+ }
483
519
  }
484
520
  exports.BlockInstanceRunner = BlockInstanceRunner;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.40.6",
3
+ "version": "0.41.1",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {
@@ -50,7 +50,7 @@
50
50
  "dependencies": {
51
51
  "@kapeta/codegen": "^1.3.0",
52
52
  "@kapeta/config-mapper": "^1.2.0",
53
- "@kapeta/local-cluster-config": "^0.4.1",
53
+ "@kapeta/local-cluster-config": "^0.4.2",
54
54
  "@kapeta/nodejs-api-client": ">=0.2.0 <2",
55
55
  "@kapeta/nodejs-process": "^1.2.0",
56
56
  "@kapeta/nodejs-registry-utils": ">=0.11.1 <2",
@@ -36,11 +36,16 @@ export interface EnrichedAsset {
36
36
  ymlPath: string;
37
37
  }
38
38
 
39
- function filterExists(asset: DefinitionInfo): boolean {
40
- return FS.existsSync(asset.path) && FS.existsSync(asset.ymlPath);
41
- }
42
-
43
39
  function enrichAsset(asset: DefinitionInfo): EnrichedAsset {
40
+ let exists = true;
41
+ let path = asset.path;
42
+ let ymlPath = asset.ymlPath;
43
+ try {
44
+ path = FS.realpathSync(path);
45
+ ymlPath = FS.realpathSync(ymlPath);
46
+ } catch (e) {
47
+ exists = false;
48
+ }
44
49
  return {
45
50
  ref: `kapeta://${asset.definition.metadata.name}:${asset.version}`,
46
51
  editable: asset.version === 'local', //Only local versions are editable
@@ -48,8 +53,8 @@ function enrichAsset(asset: DefinitionInfo): EnrichedAsset {
48
53
  version: asset.version,
49
54
  kind: asset.definition.kind,
50
55
  data: asset.definition,
51
- path: FS.realpathSync(asset.path),
52
- ymlPath: FS.realpathSync(asset.ymlPath),
56
+ path,
57
+ ymlPath,
53
58
  };
54
59
  }
55
60
 
@@ -106,7 +111,7 @@ class AssetManager {
106
111
 
107
112
  const assets = await definitionsManager.getDefinitions(assetKinds);
108
113
 
109
- return assets.filter(filterExists).map(enrichAsset);
114
+ return assets.map(enrichAsset).filter((a) => a.exists);
110
115
  }
111
116
 
112
117
  async getPlans(): Promise<EnrichedAsset[]> {
@@ -159,9 +164,13 @@ class AssetManager {
159
164
  }
160
165
 
161
166
  if (definitionInfo) {
162
- const asset = enrichAsset(definitionInfo);
163
- cacheManager.set(cacheKey, asset, CACHE_TTL);
164
- return asset;
167
+ try {
168
+ const asset = enrichAsset(definitionInfo);
169
+ cacheManager.set(cacheKey, asset, CACHE_TTL);
170
+ return asset;
171
+ } catch (e) {
172
+ console.error('Failed to enrich asset', e);
173
+ }
165
174
  }
166
175
 
167
176
  return undefined;
@@ -33,13 +33,15 @@ import OS from 'node:os';
33
33
  import Path from 'node:path';
34
34
  import { taskManager } from '../taskManager';
35
35
  import { LocalDevContainer, LocalInstance } from '@kapeta/schemas';
36
- import { createInternalConfigProvider } from './InternalConfigProvider';
36
+ import { createInternalConfigProvider, InternalConfigProvider } from './InternalConfigProvider';
37
37
  import {
38
38
  getConfigFilePath,
39
39
  getEnvironmentVariables,
40
40
  KAPETA_CONFIG_ENV_VAR,
41
41
  KAPETA_ENV_CONFIG_FILE,
42
42
  resolveKapetaVariables,
43
+ Variables,
44
+ VariableType,
43
45
  writeConfigTemplates,
44
46
  writeEnvConfigFile,
45
47
  } from '@kapeta/config-mapper';
@@ -157,7 +159,12 @@ export class BlockInstanceRunner {
157
159
  );
158
160
 
159
161
  // Resolve the environment variables
160
- const variables = await resolveKapetaVariables(realBaseDir, internalConfigProvider);
162
+ const blockVariables = await resolveKapetaVariables(realBaseDir, internalConfigProvider);
163
+ const variables = await this.appendConnectedBlockOperatorEnv(
164
+ internalConfigProvider,
165
+ blockInstance,
166
+ blockVariables
167
+ );
161
168
 
162
169
  // Write out the config templates if they exist
163
170
  await writeConfigTemplates(variables, realBaseDir);
@@ -556,6 +563,7 @@ export class BlockInstanceRunner {
556
563
  PortBindings,
557
564
  Mounts,
558
565
  },
566
+ Cmd: local.cmd,
559
567
  Labels: {
560
568
  ...labels,
561
569
  instance: operatorId,
@@ -645,4 +653,52 @@ export class BlockInstanceRunner {
645
653
  //Creating the hash in the required format
646
654
  return data.digest('hex');
647
655
  }
656
+
657
+ private async appendConnectedBlockOperatorEnv(
658
+ internalConfigProvider: InternalConfigProvider,
659
+ blockInstance: BlockProcessParams,
660
+ variables: Variables
661
+ ): Promise<Variables> {
662
+ const plan = await internalConfigProvider.getPlan();
663
+
664
+ const connectedBlockIds = [
665
+ ...new Set(
666
+ plan.spec.connections
667
+ .filter((connection) => connection.provider.blockId == blockInstance.id || connection.consumer.blockId == blockInstance.id)
668
+ .flatMap((connection) => [connection.provider.blockId, connection.consumer.blockId])
669
+ .filter((blockId) => blockId !== blockInstance.id)
670
+ ),
671
+ ];
672
+
673
+ for (const connectedBlockId of connectedBlockIds) {
674
+ const connectedBlockInstance = plan.spec.blocks.find((blockInstance) => blockInstance.id == connectedBlockId);
675
+ if (!connectedBlockInstance) {
676
+ continue;
677
+ }
678
+
679
+ const connectedBlockDefinition = await internalConfigProvider.getBlock(connectedBlockInstance?.block.ref);
680
+ const connectedBlockDefinitionInfo = await getProvider(parseKapetaUri(connectedBlockDefinition.kind));
681
+
682
+ const local = connectedBlockDefinitionInfo?.definition.spec.local;
683
+
684
+ if (!local || !local.addEnv) {
685
+ continue;
686
+ }
687
+
688
+ const connectedBlockInstanceOperator = await internalConfigProvider.getInstanceOperator(connectedBlockId);
689
+
690
+ for (const addEnv of local.addEnv) {
691
+ var result: string;
692
+ try {
693
+ result = eval(addEnv)(connectedBlockInstanceOperator) as string;
694
+ } catch (error) {
695
+ result = addEnv;
696
+ }
697
+ const parts = result.split('=');
698
+ variables[parts[0]] = { type: VariableType.ENV, value: parts[1], json: false };
699
+ }
700
+ }
701
+
702
+ return variables;
703
+ }
648
704
  }