@kapeta/local-cluster-service 0.16.8 → 0.17.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 (56) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/index.js +2 -0
  3. package/dist/cjs/src/socketManager.js +6 -0
  4. package/dist/cjs/src/utils/DefaultProviderInstaller.d.ts +11 -0
  5. package/dist/cjs/src/utils/DefaultProviderInstaller.js +129 -0
  6. package/dist/esm/index.js +64 -57
  7. package/dist/esm/src/RepositoryWatcher.js +40 -33
  8. package/dist/esm/src/api.js +14 -9
  9. package/dist/esm/src/assetManager.js +62 -56
  10. package/dist/esm/src/assets/routes.js +22 -17
  11. package/dist/esm/src/attachments/routes.js +14 -9
  12. package/dist/esm/src/cacheManager.js +13 -5
  13. package/dist/esm/src/clusterService.js +6 -3
  14. package/dist/esm/src/codeGeneratorManager.js +19 -13
  15. package/dist/esm/src/config/routes.js +30 -25
  16. package/dist/esm/src/configManager.js +29 -26
  17. package/dist/esm/src/containerManager.js +48 -39
  18. package/dist/esm/src/definitionsManager.js +15 -9
  19. package/dist/esm/src/filesystem/routes.js +21 -16
  20. package/dist/esm/src/filesystemManager.js +23 -17
  21. package/dist/esm/src/identities/routes.js +13 -8
  22. package/dist/esm/src/instanceManager.js +163 -156
  23. package/dist/esm/src/instances/routes.js +38 -33
  24. package/dist/esm/src/middleware/cors.js +5 -1
  25. package/dist/esm/src/middleware/kapeta.js +8 -4
  26. package/dist/esm/src/middleware/stringBody.js +5 -1
  27. package/dist/esm/src/networkManager.js +15 -9
  28. package/dist/esm/src/operatorManager.js +45 -39
  29. package/dist/esm/src/progressListener.js +16 -12
  30. package/dist/esm/src/providerManager.js +22 -16
  31. package/dist/esm/src/providers/routes.js +14 -9
  32. package/dist/esm/src/proxy/routes.js +26 -21
  33. package/dist/esm/src/proxy/types/rest.js +29 -22
  34. package/dist/esm/src/proxy/types/web.js +18 -11
  35. package/dist/esm/src/repositoryManager.js +28 -22
  36. package/dist/esm/src/serviceManager.js +25 -19
  37. package/dist/esm/src/socketManager.js +31 -18
  38. package/dist/esm/src/storageService.js +18 -12
  39. package/dist/esm/src/taskManager.js +12 -8
  40. package/dist/esm/src/tasks/routes.js +14 -9
  41. package/dist/esm/src/traffic/routes.js +12 -7
  42. package/dist/esm/src/types.js +11 -8
  43. package/dist/esm/src/utils/BlockInstanceRunner.js +57 -50
  44. package/dist/esm/src/utils/DefaultProviderInstaller.d.ts +11 -0
  45. package/dist/esm/src/utils/DefaultProviderInstaller.js +129 -0
  46. package/dist/esm/src/utils/LogData.js +5 -1
  47. package/dist/esm/src/utils/commandLineUtils.js +12 -7
  48. package/dist/esm/src/utils/pathTemplateParser.js +7 -2
  49. package/dist/esm/src/utils/utils.js +30 -17
  50. package/dist/esm/start.js +7 -2
  51. package/index.ts +3 -0
  52. package/package.json +10 -4
  53. package/src/instanceManager.ts +1 -1
  54. package/src/socketManager.ts +6 -0
  55. package/src/utils/DefaultProviderInstaller.ts +141 -0
  56. package/tsconfig.json +3 -2
@@ -1,8 +1,14 @@
1
- import _ from 'lodash';
2
- import FS from 'fs';
3
- import FSExtra from 'fs-extra';
4
- import YAML from 'yaml';
5
- import ClusterConfiguration from '@kapeta/local-cluster-config';
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.storageService = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const yaml_1 = __importDefault(require("yaml"));
11
+ const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
6
12
  /**
7
13
  * Class that handles reading and writing from local configuration file.
8
14
  */
@@ -12,15 +18,15 @@ class StorageService {
12
18
  this._data = this._readConfig();
13
19
  }
14
20
  getKapetaBasedir() {
15
- return ClusterConfiguration.getKapetaBasedir();
21
+ return local_cluster_config_1.default.getKapetaBasedir();
16
22
  }
17
23
  _readConfig() {
18
- return ClusterConfiguration.getClusterConfig();
24
+ return local_cluster_config_1.default.getClusterConfig();
19
25
  }
20
26
  _writeConfig() {
21
- const configFile = ClusterConfiguration.getClusterConfigFile();
22
- FSExtra.mkdirsSync(this.getKapetaBasedir());
23
- FS.writeFileSync(configFile, YAML.stringify(this._data));
27
+ const configFile = local_cluster_config_1.default.getClusterConfigFile();
28
+ fs_extra_1.default.mkdirsSync(this.getKapetaBasedir());
29
+ fs_1.default.writeFileSync(configFile, yaml_1.default.stringify(this._data));
24
30
  }
25
31
  section(section, defaultValue) {
26
32
  if (!defaultValue) {
@@ -33,7 +39,7 @@ class StorageService {
33
39
  return this._data[section];
34
40
  }
35
41
  put(section, property, value) {
36
- if (!_.isString(property)) {
42
+ if (!lodash_1.default.isString(property)) {
37
43
  this._data[section] = property;
38
44
  this._writeConfig();
39
45
  return;
@@ -68,4 +74,4 @@ class StorageService {
68
74
  return out;
69
75
  }
70
76
  }
71
- export const storageService = new StorageService();
77
+ exports.storageService = new StorageService();
@@ -1,18 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.taskManager = exports.Task = exports.TaskStatus = void 0;
1
4
  /**
2
5
  * Class that handles processing background tasks.
3
6
  */
4
- import { socketManager } from './socketManager';
7
+ const socketManager_1 = require("./socketManager");
5
8
  const EVENT_TASK_UPDATED = 'task-updated';
6
9
  const EVENT_TASK_ADDED = 'task-added';
7
10
  const EVENT_TASK_REMOVED = 'task-removed';
8
- export var TaskStatus;
11
+ var TaskStatus;
9
12
  (function (TaskStatus) {
10
13
  TaskStatus["PENDING"] = "PENDING";
11
14
  TaskStatus["RUNNING"] = "RUNNING";
12
15
  TaskStatus["COMPLETED"] = "COMPLETED";
13
16
  TaskStatus["FAILED"] = "FAILED";
14
- })(TaskStatus || (TaskStatus = {}));
15
- export class Task {
17
+ })(TaskStatus || (exports.TaskStatus = TaskStatus = {}));
18
+ class Task {
16
19
  data;
17
20
  constructor(task) {
18
21
  this.data = task;
@@ -45,7 +48,7 @@ export class Task {
45
48
  this.data.metadata = metadata;
46
49
  }
47
50
  emitUpdate() {
48
- socketManager.emitGlobal(EVENT_TASK_UPDATED, this.toData());
51
+ socketManager_1.socketManager.emitGlobal(EVENT_TASK_UPDATED, this.toData());
49
52
  }
50
53
  async wait() {
51
54
  return this.future.promise;
@@ -54,6 +57,7 @@ export class Task {
54
57
  return { ...this.data };
55
58
  }
56
59
  }
60
+ exports.Task = Task;
57
61
  function createFuture() {
58
62
  let resolve = () => { };
59
63
  let reject = () => { };
@@ -85,7 +89,7 @@ class TaskManager {
85
89
  run: runner,
86
90
  });
87
91
  this._tasks.push(task);
88
- socketManager.emitGlobal(EVENT_TASK_ADDED, task.toData());
92
+ socketManager_1.socketManager.emitGlobal(EVENT_TASK_ADDED, task.toData());
89
93
  this.invokeTask(task).catch(() => { });
90
94
  return task;
91
95
  }
@@ -119,7 +123,7 @@ class TaskManager {
119
123
  throw new Error('Cannot remove a running task');
120
124
  }
121
125
  this._tasks = this._tasks.filter((t) => t.id !== taskId);
122
- socketManager.emitGlobal(EVENT_TASK_REMOVED, task.toData());
126
+ socketManager_1.socketManager.emitGlobal(EVENT_TASK_REMOVED, task.toData());
123
127
  }
124
128
  list() {
125
129
  return this._tasks.map((t) => t.toData());
@@ -158,4 +162,4 @@ class TaskManager {
158
162
  }
159
163
  }
160
164
  }
161
- export const taskManager = new TaskManager();
165
+ exports.taskManager = new TaskManager();
@@ -1,16 +1,21 @@
1
- import Router from 'express-promise-router';
2
- import { corsHandler } from '../middleware/cors';
3
- import { taskManager } from '../taskManager';
4
- const router = Router();
5
- router.use('/', corsHandler);
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const express_promise_router_1 = __importDefault(require("express-promise-router"));
7
+ const cors_1 = require("../middleware/cors");
8
+ const taskManager_1 = require("../taskManager");
9
+ const router = (0, express_promise_router_1.default)();
10
+ router.use('/', cors_1.corsHandler);
6
11
  /**
7
12
  * Get all current tasks
8
13
  */
9
14
  router.get('/', (req, res) => {
10
- res.send(taskManager.list());
15
+ res.send(taskManager_1.taskManager.list());
11
16
  });
12
17
  router.get('/:taskId', (req, res) => {
13
- const task = taskManager.get(req.params.taskId);
18
+ const task = taskManager_1.taskManager.get(req.params.taskId);
14
19
  if (!task) {
15
20
  res.status(404).send({ error: 'Task not found' });
16
21
  return;
@@ -19,7 +24,7 @@ router.get('/:taskId', (req, res) => {
19
24
  });
20
25
  router.delete('/:taskId', (req, res) => {
21
26
  try {
22
- taskManager.remove(req.params.taskId);
27
+ taskManager_1.taskManager.remove(req.params.taskId);
23
28
  res.send({ ok: true });
24
29
  }
25
30
  catch (e) {
@@ -27,4 +32,4 @@ router.delete('/:taskId', (req, res) => {
27
32
  return;
28
33
  }
29
34
  });
30
- export default router;
35
+ exports.default = router;
@@ -1,13 +1,18 @@
1
- import Router from 'express-promise-router';
2
- import { networkManager } from '../networkManager';
3
- const router = Router();
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const express_promise_router_1 = __importDefault(require("express-promise-router"));
7
+ const networkManager_1 = require("../networkManager");
8
+ const router = (0, express_promise_router_1.default)();
4
9
  router.get('/:systemId/target/:connectionId/', (req, res) => {
5
- res.send(networkManager.getTrafficForConnection(req.params.systemId, req.params.connectionId));
10
+ res.send(networkManager_1.networkManager.getTrafficForConnection(req.params.systemId, req.params.connectionId));
6
11
  });
7
12
  router.get('/:systemId/source/:blockInstanceId/', (req, res) => {
8
- res.send(networkManager.getTrafficForSource(req.params.systemId, req.params.blockInstanceId));
13
+ res.send(networkManager_1.networkManager.getTrafficForSource(req.params.systemId, req.params.blockInstanceId));
9
14
  });
10
15
  router.get('/:systemId/target/:blockInstanceId/', (req, res) => {
11
- res.send(networkManager.getTrafficForTarget(req.params.systemId, req.params.blockInstanceId));
16
+ res.send(networkManager_1.networkManager.getTrafficForTarget(req.params.systemId, req.params.blockInstanceId));
12
17
  });
13
- export default router;
18
+ exports.default = router;
@@ -1,15 +1,18 @@
1
- export var InstanceType;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DesiredInstanceStatus = exports.InstanceStatus = exports.InstanceOwner = exports.InstanceType = void 0;
4
+ var InstanceType;
2
5
  (function (InstanceType) {
3
6
  InstanceType["DOCKER"] = "docker";
4
7
  InstanceType["LOCAL"] = "local";
5
8
  InstanceType["UNKNOWN"] = "unknown";
6
- })(InstanceType || (InstanceType = {}));
7
- export var InstanceOwner;
9
+ })(InstanceType || (exports.InstanceType = InstanceType = {}));
10
+ var InstanceOwner;
8
11
  (function (InstanceOwner) {
9
12
  InstanceOwner["INTERNAL"] = "internal";
10
13
  InstanceOwner["EXTERNAL"] = "external";
11
- })(InstanceOwner || (InstanceOwner = {}));
12
- export var InstanceStatus;
14
+ })(InstanceOwner || (exports.InstanceOwner = InstanceOwner = {}));
15
+ var InstanceStatus;
13
16
  (function (InstanceStatus) {
14
17
  InstanceStatus["STOPPED"] = "stopped";
15
18
  InstanceStatus["STARTING"] = "starting";
@@ -18,10 +21,10 @@ export var InstanceStatus;
18
21
  InstanceStatus["STOPPING"] = "stopping";
19
22
  InstanceStatus["UNHEALTHY"] = "unhealthy";
20
23
  InstanceStatus["FAILED"] = "failed";
21
- })(InstanceStatus || (InstanceStatus = {}));
22
- export var DesiredInstanceStatus;
24
+ })(InstanceStatus || (exports.InstanceStatus = InstanceStatus = {}));
25
+ var DesiredInstanceStatus;
23
26
  (function (DesiredInstanceStatus) {
24
27
  DesiredInstanceStatus["STOP"] = "stop";
25
28
  DesiredInstanceStatus["RUN"] = "run";
26
29
  DesiredInstanceStatus["EXTERNAL"] = "external";
27
- })(DesiredInstanceStatus || (DesiredInstanceStatus = {}));
30
+ })(DesiredInstanceStatus || (exports.DesiredInstanceStatus = DesiredInstanceStatus = {}));
@@ -1,13 +1,19 @@
1
- import FS from 'node:fs';
2
- import ClusterConfig from '@kapeta/local-cluster-config';
3
- import { getBindHost, getBlockInstanceContainerName, normalizeKapetaUri, readYML } from './utils';
4
- import { parseKapetaUri } from '@kapeta/nodejs-utils';
5
- import { serviceManager } from '../serviceManager';
6
- import { containerManager, toLocalBindVolume } from '../containerManager';
7
- import { LogData } from './LogData';
8
- import { clusterService } from '../clusterService';
9
- import { InstanceType } from '../types';
10
- import { definitionsManager } from '../definitionsManager';
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BlockInstanceRunner = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
9
+ const utils_1 = require("./utils");
10
+ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
11
+ const serviceManager_1 = require("../serviceManager");
12
+ const containerManager_1 = require("../containerManager");
13
+ const LogData_1 = require("./LogData");
14
+ const clusterService_1 = require("../clusterService");
15
+ const types_1 = require("../types");
16
+ const definitionsManager_1 = require("../definitionsManager");
11
17
  const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
12
18
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
13
19
  const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
@@ -22,9 +28,9 @@ const DOCKER_ENV_VARS = [
22
28
  `KAPETA_ENVIRONMENT_TYPE=docker`,
23
29
  ];
24
30
  function getProvider(uri) {
25
- return definitionsManager.getProviderDefinitions().find((provider) => {
31
+ return definitionsManager_1.definitionsManager.getProviderDefinitions().find((provider) => {
26
32
  const ref = `${provider.definition.metadata.name}:${provider.version}`;
27
- return parseKapetaUri(ref).id === uri.id;
33
+ return (0, nodejs_utils_1.parseKapetaUri)(ref).id === uri.id;
28
34
  });
29
35
  }
30
36
  function getProviderPorts(assetVersion) {
@@ -34,7 +40,7 @@ function getProviderPorts(assetVersion) {
34
40
  })
35
41
  .filter((t) => !!t) ?? []);
36
42
  }
37
- export class BlockInstanceRunner {
43
+ class BlockInstanceRunner {
38
44
  _systemId;
39
45
  constructor(systemId) {
40
46
  /**
@@ -42,7 +48,7 @@ export class BlockInstanceRunner {
42
48
  * @type {string}
43
49
  * @private
44
50
  */
45
- this._systemId = normalizeKapetaUri(systemId);
51
+ this._systemId = (0, utils_1.normalizeKapetaUri)(systemId);
46
52
  }
47
53
  /**
48
54
  * Start a block
@@ -66,18 +72,18 @@ export class BlockInstanceRunner {
66
72
  if (blockInstance.id) {
67
73
  env[KAPETA_INSTANCE_ID] = blockInstance.id;
68
74
  }
69
- const blockUri = parseKapetaUri(blockInstance.ref);
75
+ const blockUri = (0, nodejs_utils_1.parseKapetaUri)(blockInstance.ref);
70
76
  if (!blockUri.version) {
71
77
  blockUri.version = 'local';
72
78
  }
73
- const assetVersion = definitionsManager.getDefinitions().find((definitions) => {
79
+ const assetVersion = definitionsManager_1.definitionsManager.getDefinitions().find((definitions) => {
74
80
  const ref = `${definitions.definition.metadata.name}:${definitions.version}`;
75
- return parseKapetaUri(ref).id === blockUri.id;
81
+ return (0, nodejs_utils_1.parseKapetaUri)(ref).id === blockUri.id;
76
82
  });
77
83
  if (!assetVersion) {
78
84
  throw new Error(`Block definition not found: ${blockUri.id}`);
79
85
  }
80
- const kindUri = parseKapetaUri(assetVersion.definition.kind);
86
+ const kindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.kind);
81
87
  const providerVersion = getProvider(kindUri);
82
88
  if (!providerVersion) {
83
89
  throw new Error(`Kind not found: ${kindUri.id}`);
@@ -105,15 +111,15 @@ export class BlockInstanceRunner {
105
111
  * Starts local process
106
112
  */
107
113
  async _startLocalProcess(blockInstance, blockInfo, env, assetVersion) {
108
- const baseDir = ClusterConfig.getRepositoryAssetPath(blockInfo.handle, blockInfo.name, blockInfo.version);
109
- if (!FS.existsSync(baseDir)) {
114
+ const baseDir = local_cluster_config_1.default.getRepositoryAssetPath(blockInfo.handle, blockInfo.name, blockInfo.version);
115
+ if (!node_fs_1.default.existsSync(baseDir)) {
110
116
  throw new Error(`Local block not registered correctly - expected symlink here: ${baseDir}.\n` +
111
117
  `Make sure you've run "blockctl registry link" in your local directory to connect it to Kapeta`);
112
118
  }
113
119
  if (!assetVersion.definition.spec?.target?.kind) {
114
120
  throw new Error('Missing target kind in block definition');
115
121
  }
116
- const kindUri = parseKapetaUri(assetVersion.definition.spec?.target?.kind);
122
+ const kindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.spec?.target?.kind);
117
123
  const targetVersion = getProvider(kindUri);
118
124
  if (!targetVersion) {
119
125
  throw new Error(`Target not found: ${kindUri.id}`);
@@ -126,7 +132,7 @@ export class BlockInstanceRunner {
126
132
  if (!dockerImage) {
127
133
  throw new Error(`Missing docker image information: ${JSON.stringify(localContainer)}`);
128
134
  }
129
- const containerName = getBlockInstanceContainerName(this._systemId, blockInstance.id);
135
+ const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
130
136
  const startCmd = localContainer.handlers?.onCreate ? localContainer.handlers.onCreate : '';
131
137
  const dockerOpts = localContainer.options ?? {};
132
138
  const homeDir = localContainer.userHome ? localContainer.userHome : '/root';
@@ -134,7 +140,7 @@ export class BlockInstanceRunner {
134
140
  const { PortBindings, ExposedPorts, addonEnv } = await this.getDockerPortBindings(blockInstance, assetVersion);
135
141
  let HealthCheck = undefined;
136
142
  if (localContainer.healthcheck) {
137
- HealthCheck = containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
143
+ HealthCheck = containerManager_1.containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
138
144
  }
139
145
  return this.ensureContainer({
140
146
  Image: dockerImage,
@@ -148,7 +154,7 @@ export class BlockInstanceRunner {
148
154
  Cmd: startCmd ? startCmd.split(/\s+/g) : [],
149
155
  Env: [
150
156
  ...DOCKER_ENV_VARS,
151
- `KAPETA_LOCAL_CLUSTER_PORT=${clusterService.getClusterServicePort()}`,
157
+ `KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
152
158
  ...Object.entries({
153
159
  ...env,
154
160
  ...addonEnv,
@@ -156,8 +162,8 @@ export class BlockInstanceRunner {
156
162
  ],
157
163
  HostConfig: {
158
164
  Binds: [
159
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${homeDir}/.kapeta`,
160
- `${toLocalBindVolume(baseDir)}:${workingDir}`,
165
+ `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${homeDir}/.kapeta`,
166
+ `${(0, containerManager_1.toLocalBindVolume)(baseDir)}:${workingDir}`,
161
167
  ],
162
168
  PortBindings,
163
169
  },
@@ -165,12 +171,12 @@ export class BlockInstanceRunner {
165
171
  });
166
172
  }
167
173
  async _startDockerProcess(blockInstance, blockInfo, env, assetVersion) {
168
- const { versionFile } = ClusterConfig.getRepositoryAssetInfoPath(blockInfo.handle, blockInfo.name, blockInfo.version);
174
+ const { versionFile } = local_cluster_config_1.default.getRepositoryAssetInfoPath(blockInfo.handle, blockInfo.name, blockInfo.version);
169
175
  const versionYml = versionFile;
170
- if (!FS.existsSync(versionYml)) {
176
+ if (!node_fs_1.default.existsSync(versionYml)) {
171
177
  throw new Error(`Did not find version info at the expected path: ${versionYml}`);
172
178
  }
173
- const versionInfo = readYML(versionYml);
179
+ const versionInfo = (0, utils_1.readYML)(versionYml);
174
180
  if (versionInfo?.artifact?.type !== 'docker') {
175
181
  throw new Error(`Unsupported artifact type: ${versionInfo?.artifact?.type}`);
176
182
  }
@@ -179,9 +185,9 @@ export class BlockInstanceRunner {
179
185
  throw new Error(`Missing docker image information: ${JSON.stringify(versionInfo?.artifact?.details)}`);
180
186
  }
181
187
  const { PortBindings, ExposedPorts, addonEnv } = await this.getDockerPortBindings(blockInstance, assetVersion);
182
- const containerName = getBlockInstanceContainerName(this._systemId, blockInstance.id);
188
+ const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
183
189
  // For windows we need to default to root
184
- const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
190
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
185
191
  return this.ensureContainer({
186
192
  Image: dockerImage,
187
193
  name: containerName,
@@ -191,14 +197,14 @@ export class BlockInstanceRunner {
191
197
  },
192
198
  Env: [
193
199
  ...DOCKER_ENV_VARS,
194
- `KAPETA_LOCAL_CLUSTER_PORT=${clusterService.getClusterServicePort()}`,
200
+ `KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
195
201
  ...Object.entries({
196
202
  ...env,
197
203
  ...addonEnv,
198
204
  }).map(([key, value]) => `${key}=${value}`),
199
205
  ],
200
206
  HostConfig: {
201
- Binds: [`${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`],
207
+ Binds: [`${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`],
202
208
  PortBindings,
203
209
  },
204
210
  });
@@ -213,9 +219,9 @@ export class BlockInstanceRunner {
213
219
  * @private
214
220
  */
215
221
  async _startOperatorProcess(blockInstance, blockUri, providerDefinition, env) {
216
- const { assetFile } = ClusterConfig.getRepositoryAssetInfoPath(blockUri.handle, blockUri.name, blockUri.version);
222
+ const { assetFile } = local_cluster_config_1.default.getRepositoryAssetInfoPath(blockUri.handle, blockUri.name, blockUri.version);
217
223
  const kapetaYmlPath = assetFile;
218
- if (!FS.existsSync(kapetaYmlPath)) {
224
+ if (!node_fs_1.default.existsSync(kapetaYmlPath)) {
219
225
  throw new Error(`Did not find kapeta.yml at the expected path: ${kapetaYmlPath}`);
220
226
  }
221
227
  const spec = providerDefinition.definition.spec;
@@ -225,9 +231,9 @@ export class BlockInstanceRunner {
225
231
  }
226
232
  const dockerImage = spec?.local?.image;
227
233
  //We only want 1 operator per operator type - across all local systems
228
- const containerName = getBlockInstanceContainerName(this._systemId, blockInstance.id);
229
- const logs = new LogData();
230
- const bindHost = getBindHost();
234
+ const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
235
+ const logs = new LogData_1.LogData();
236
+ const bindHost = (0, utils_1.getBindHost)();
231
237
  const ExposedPorts = {};
232
238
  const addonEnv = {};
233
239
  const PortBindings = {};
@@ -237,7 +243,7 @@ export class BlockInstanceRunner {
237
243
  const dockerPort = `${value.port}/${value.type}`;
238
244
  ExposedPorts[dockerPort] = {};
239
245
  addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = value.port;
240
- const publicPort = await serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
246
+ const publicPort = await serviceManager_1.serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
241
247
  PortBindings[dockerPort] = [
242
248
  {
243
249
  HostIp: bindHost,
@@ -252,14 +258,14 @@ export class BlockInstanceRunner {
252
258
  });
253
259
  }
254
260
  if (spec.local?.mounts) {
255
- const mounts = await containerManager.createMounts(this._systemId, blockUri.id, spec.local.mounts);
256
- Mounts = containerManager.toDockerMounts(mounts);
261
+ const mounts = await containerManager_1.containerManager.createMounts(this._systemId, blockUri.id, spec.local.mounts);
262
+ Mounts = containerManager_1.containerManager.toDockerMounts(mounts);
257
263
  }
258
264
  if (spec.local?.health) {
259
- HealthCheck = containerManager.toDockerHealth(spec.local?.health);
265
+ HealthCheck = containerManager_1.containerManager.toDockerHealth(spec.local?.health);
260
266
  }
261
267
  // For windows we need to default to root
262
- const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
268
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
263
269
  logs.addLog(`Creating new container for block: ${containerName}`);
264
270
  const out = await this.ensureContainer({
265
271
  Image: dockerImage,
@@ -268,8 +274,8 @@ export class BlockInstanceRunner {
268
274
  HealthCheck,
269
275
  HostConfig: {
270
276
  Binds: [
271
- `${toLocalBindVolume(kapetaYmlPath)}:/kapeta.yml:ro`,
272
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`,
277
+ `${(0, containerManager_1.toLocalBindVolume)(kapetaYmlPath)}:/kapeta.yml:ro`,
278
+ `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`,
273
279
  ],
274
280
  PortBindings,
275
281
  Mounts,
@@ -279,7 +285,7 @@ export class BlockInstanceRunner {
279
285
  },
280
286
  Env: [
281
287
  `KAPETA_INSTANCE_NAME=${blockInstance.ref}`,
282
- `KAPETA_LOCAL_CLUSTER_PORT=${clusterService.getClusterServicePort()}`,
288
+ `KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
283
289
  ...DOCKER_ENV_VARS,
284
290
  ...Object.entries({
285
291
  ...env,
@@ -294,14 +300,14 @@ export class BlockInstanceRunner {
294
300
  return out;
295
301
  }
296
302
  async getDockerPortBindings(blockInstance, assetVersion) {
297
- const bindHost = getBindHost();
303
+ const bindHost = (0, utils_1.getBindHost)();
298
304
  const ExposedPorts = {};
299
305
  const addonEnv = {};
300
306
  const PortBindings = {};
301
307
  const portTypes = getProviderPorts(assetVersion);
302
308
  let port = 80;
303
309
  const promises = portTypes.map(async (portType) => {
304
- const publicPort = await serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
310
+ const publicPort = await serviceManager_1.serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
305
311
  const thisPort = port++; //TODO: Not sure how we should handle multiple ports or non-HTTP ports
306
312
  const dockerPort = `${thisPort}/tcp`;
307
313
  ExposedPorts[dockerPort] = {};
@@ -317,13 +323,14 @@ export class BlockInstanceRunner {
317
323
  return { PortBindings, ExposedPorts, addonEnv };
318
324
  }
319
325
  async ensureContainer(opts) {
320
- const container = await containerManager.ensureContainer(opts);
326
+ const container = await containerManager_1.containerManager.ensureContainer(opts);
321
327
  return this._handleContainer(container);
322
328
  }
323
329
  async _handleContainer(container) {
324
330
  return {
325
- type: InstanceType.DOCKER,
331
+ type: types_1.InstanceType.DOCKER,
326
332
  pid: container.id,
327
333
  };
328
334
  }
329
335
  }
336
+ exports.BlockInstanceRunner = BlockInstanceRunner;
@@ -0,0 +1,11 @@
1
+ declare class DefaultProviderInstaller {
2
+ private readonly progressListener;
3
+ checkForDefault(): Promise<void>;
4
+ private install;
5
+ private linkLocal;
6
+ private scanProjectBase;
7
+ private ensureDefaultProjectHome;
8
+ private download;
9
+ }
10
+ export declare const defaultProviderInstaller: DefaultProviderInstaller;
11
+ export {};
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.defaultProviderInstaller = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const node_os_1 = __importDefault(require("node:os"));
9
+ const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
10
+ const fs_extra_1 = __importDefault(require("fs-extra"));
11
+ const request_1 = __importDefault(require("request"));
12
+ const tar_stream_1 = require("tar-stream");
13
+ const gunzip_maybe_1 = __importDefault(require("gunzip-maybe"));
14
+ const filesystemManager_1 = require("../filesystemManager");
15
+ const nodejs_registry_utils_1 = require("@kapeta/nodejs-registry-utils");
16
+ const progressListener_1 = require("../progressListener");
17
+ const glob_1 = require("glob");
18
+ const DEFAULT_PROVIDERS_URL = 'https://storage.googleapis.com/kapeta-production-cdn/archives/default-providers.tar.gz';
19
+ const DEFAULT_PROJECT_HOME_DIR = 'KapetaProjects';
20
+ const ARCHIVE_LOCAL_PREFIX = 'local';
21
+ class DefaultProviderInstaller {
22
+ progressListener = new progressListener_1.ProgressListener();
23
+ async checkForDefault() {
24
+ const definitions = local_cluster_config_1.default.getDefinitions();
25
+ if (definitions.length < 1) {
26
+ console.log('Installing default providers');
27
+ try {
28
+ await this.install();
29
+ }
30
+ catch (e) {
31
+ console.warn('Failed to install defaults', e);
32
+ }
33
+ }
34
+ }
35
+ async install() {
36
+ await this.download();
37
+ await this.linkLocal();
38
+ }
39
+ async linkLocal() {
40
+ const projectBase = await this.ensureDefaultProjectHome();
41
+ const folders = this.scanProjectBase(projectBase);
42
+ for (let folder of folders) {
43
+ console.log('Linking %s', folder);
44
+ await nodejs_registry_utils_1.Actions.link(this.progressListener, folder);
45
+ }
46
+ }
47
+ scanProjectBase(projectBase) {
48
+ const assetFiles = glob_1.glob.sync('*/**/kapeta.yml', { cwd: projectBase });
49
+ return assetFiles.map((assetFile) => {
50
+ return node_path_1.default.dirname(node_path_1.default.join(projectBase, assetFile));
51
+ });
52
+ }
53
+ async ensureDefaultProjectHome() {
54
+ const defaultProjectHome = node_path_1.default.join(node_os_1.default.homedir(), DEFAULT_PROJECT_HOME_DIR);
55
+ let projectBase = filesystemManager_1.filesystemManager.getProjectRootFolder();
56
+ if (!projectBase) {
57
+ filesystemManager_1.filesystemManager.setProjectRootFolder(defaultProjectHome);
58
+ projectBase = defaultProjectHome;
59
+ if (!(await fs_extra_1.default.pathExists(projectBase))) {
60
+ await fs_extra_1.default.mkdirp(projectBase);
61
+ }
62
+ }
63
+ return projectBase;
64
+ }
65
+ async download() {
66
+ const projectBase = await this.ensureDefaultProjectHome();
67
+ const repoBase = local_cluster_config_1.default.getRepositoryBasedir();
68
+ return new Promise((resolve, reject) => {
69
+ const extractor = (0, tar_stream_1.extract)();
70
+ const dirCache = new Set();
71
+ extractor.on('entry', async function (header, stream, next) {
72
+ if (header.type !== 'file') {
73
+ stream.on('end', function () {
74
+ next(); // ready for next entry
75
+ });
76
+ stream.resume(); // just auto drain the stream
77
+ return;
78
+ }
79
+ // Local (editable) assets should be stored in the project folder
80
+ // - installed assets goes into the repository folder
81
+ const baseDir = header.name.startsWith(ARCHIVE_LOCAL_PREFIX) ? projectBase : repoBase;
82
+ const parts = header.name.split(/\//g);
83
+ parts.shift();
84
+ const filename = parts.join(node_path_1.default.sep);
85
+ try {
86
+ const dirname = node_path_1.default.join(baseDir, node_path_1.default.dirname(filename));
87
+ if (!dirCache.has(dirname)) {
88
+ let dirExists = false;
89
+ try {
90
+ await fs_extra_1.default.stat(dirname);
91
+ dirExists = true;
92
+ }
93
+ catch (e) { }
94
+ if (!dirExists) {
95
+ await fs_extra_1.default.mkdirp(dirname);
96
+ }
97
+ dirCache.add(dirname);
98
+ }
99
+ const fileTarget = node_path_1.default.join(baseDir, filename);
100
+ stream.on('error', (err) => {
101
+ reject(err);
102
+ });
103
+ stream.on('end', next);
104
+ stream.pipe(fs_extra_1.default.createWriteStream(fileTarget, {
105
+ mode: header.mode,
106
+ }));
107
+ }
108
+ catch (e) {
109
+ reject(e);
110
+ }
111
+ });
112
+ extractor.on('finish', function () {
113
+ // all entries done - lets finalize it
114
+ console.log('Default providers installed');
115
+ resolve();
116
+ });
117
+ extractor.on('error', function (err) {
118
+ reject(err);
119
+ });
120
+ console.log('Downloading default providers from %s', DEFAULT_PROVIDERS_URL);
121
+ const response = (0, request_1.default)(DEFAULT_PROVIDERS_URL);
122
+ response.on('error', function (err) {
123
+ reject(err);
124
+ });
125
+ response.pipe((0, gunzip_maybe_1.default)()).pipe(extractor);
126
+ });
127
+ }
128
+ }
129
+ exports.defaultProviderInstaller = new DefaultProviderInstaller();