@kapeta/local-cluster-service 0.6.1 → 0.7.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 (192) hide show
  1. package/.eslintrc.cjs +17 -0
  2. package/.github/workflows/main.yml +22 -22
  3. package/.prettierignore +4 -0
  4. package/.vscode/launch.json +2 -4
  5. package/CHANGELOG.md +14 -0
  6. package/definitions.d.ts +17 -35
  7. package/dist/cjs/index.d.ts +27 -0
  8. package/dist/cjs/index.js +126 -0
  9. package/dist/cjs/package.json +1 -0
  10. package/dist/cjs/src/assetManager.d.ts +31 -0
  11. package/dist/cjs/src/assetManager.js +153 -0
  12. package/dist/cjs/src/assets/routes.d.ts +3 -0
  13. package/dist/cjs/src/assets/routes.js +117 -0
  14. package/dist/cjs/src/clusterService.d.ts +40 -0
  15. package/dist/cjs/src/clusterService.js +114 -0
  16. package/dist/cjs/src/codeGeneratorManager.d.ts +8 -0
  17. package/dist/cjs/src/codeGeneratorManager.js +53 -0
  18. package/dist/cjs/src/config/routes.d.ts +3 -0
  19. package/dist/cjs/src/config/routes.js +126 -0
  20. package/dist/cjs/src/configManager.d.ts +36 -0
  21. package/dist/cjs/src/configManager.js +110 -0
  22. package/dist/cjs/src/containerManager.d.ts +89 -0
  23. package/dist/cjs/src/containerManager.js +365 -0
  24. package/dist/cjs/src/filesystem/routes.d.ts +3 -0
  25. package/dist/cjs/src/filesystem/routes.js +69 -0
  26. package/dist/cjs/src/filesystemManager.d.ts +15 -0
  27. package/dist/cjs/src/filesystemManager.js +87 -0
  28. package/dist/cjs/src/identities/routes.d.ts +3 -0
  29. package/dist/cjs/src/identities/routes.js +18 -0
  30. package/dist/cjs/src/instanceManager.d.ts +56 -0
  31. package/dist/cjs/src/instanceManager.js +424 -0
  32. package/dist/cjs/src/instances/routes.d.ts +3 -0
  33. package/dist/cjs/src/instances/routes.js +134 -0
  34. package/dist/cjs/src/middleware/cors.d.ts +2 -0
  35. package/dist/cjs/src/middleware/cors.js +10 -0
  36. package/dist/cjs/src/middleware/kapeta.d.ts +11 -0
  37. package/dist/cjs/src/middleware/kapeta.js +17 -0
  38. package/dist/cjs/src/middleware/stringBody.d.ts +5 -0
  39. package/dist/cjs/src/middleware/stringBody.js +14 -0
  40. package/dist/cjs/src/networkManager.d.ts +32 -0
  41. package/dist/cjs/src/networkManager.js +109 -0
  42. package/dist/cjs/src/operatorManager.d.ts +36 -0
  43. package/dist/cjs/src/operatorManager.js +165 -0
  44. package/dist/cjs/src/progressListener.d.ts +20 -0
  45. package/dist/cjs/src/progressListener.js +91 -0
  46. package/dist/cjs/src/providerManager.d.ts +9 -0
  47. package/dist/cjs/src/providerManager.js +51 -0
  48. package/dist/cjs/src/providers/routes.d.ts +3 -0
  49. package/dist/cjs/src/providers/routes.js +42 -0
  50. package/dist/cjs/src/proxy/routes.d.ts +3 -0
  51. package/dist/cjs/src/proxy/routes.js +111 -0
  52. package/dist/cjs/src/proxy/types/rest.d.ts +4 -0
  53. package/dist/cjs/src/proxy/types/rest.js +114 -0
  54. package/dist/cjs/src/proxy/types/web.d.ts +4 -0
  55. package/dist/cjs/src/proxy/types/web.js +53 -0
  56. package/dist/cjs/src/repositoryManager.d.ts +17 -0
  57. package/dist/cjs/src/repositoryManager.js +218 -0
  58. package/dist/cjs/src/serviceManager.d.ts +29 -0
  59. package/dist/cjs/src/serviceManager.js +99 -0
  60. package/dist/cjs/src/socketManager.d.ts +14 -0
  61. package/dist/cjs/src/socketManager.js +53 -0
  62. package/dist/cjs/src/storageService.d.ts +17 -0
  63. package/dist/cjs/src/storageService.js +74 -0
  64. package/dist/cjs/src/traffic/routes.d.ts +3 -0
  65. package/dist/cjs/src/traffic/routes.js +18 -0
  66. package/dist/cjs/src/types.d.ts +88 -0
  67. package/dist/cjs/src/types.js +2 -0
  68. package/dist/cjs/src/utils/BlockInstanceRunner.d.ts +29 -0
  69. package/dist/cjs/src/utils/BlockInstanceRunner.js +468 -0
  70. package/dist/cjs/src/utils/LogData.d.ts +19 -0
  71. package/dist/cjs/src/utils/LogData.js +43 -0
  72. package/dist/cjs/src/utils/pathTemplateParser.d.ts +26 -0
  73. package/dist/cjs/src/utils/pathTemplateParser.js +121 -0
  74. package/dist/cjs/src/utils/utils.d.ts +1 -0
  75. package/dist/cjs/src/utils/utils.js +18 -0
  76. package/dist/cjs/start.d.ts +1 -0
  77. package/dist/cjs/start.js +12 -0
  78. package/dist/esm/index.d.ts +27 -0
  79. package/dist/esm/index.js +121 -0
  80. package/dist/esm/package.json +1 -0
  81. package/dist/esm/src/assetManager.d.ts +31 -0
  82. package/{src → dist/esm/src}/assetManager.js +22 -60
  83. package/dist/esm/src/assets/routes.d.ts +3 -0
  84. package/{src → dist/esm/src}/assets/routes.js +21 -36
  85. package/dist/esm/src/clusterService.d.ts +40 -0
  86. package/{src → dist/esm/src}/clusterService.js +14 -37
  87. package/dist/esm/src/codeGeneratorManager.d.ts +8 -0
  88. package/{src → dist/esm/src}/codeGeneratorManager.js +15 -24
  89. package/dist/esm/src/config/routes.d.ts +3 -0
  90. package/{src → dist/esm/src}/config/routes.js +40 -89
  91. package/dist/esm/src/configManager.d.ts +36 -0
  92. package/{src → dist/esm/src}/configManager.js +11 -40
  93. package/dist/esm/src/containerManager.d.ts +89 -0
  94. package/{src → dist/esm/src}/containerManager.js +81 -182
  95. package/dist/esm/src/filesystem/routes.d.ts +3 -0
  96. package/dist/esm/src/filesystem/routes.js +64 -0
  97. package/dist/esm/src/filesystemManager.d.ts +15 -0
  98. package/{src → dist/esm/src}/filesystemManager.js +20 -28
  99. package/dist/esm/src/identities/routes.d.ts +3 -0
  100. package/dist/esm/src/identities/routes.js +13 -0
  101. package/dist/esm/src/instanceManager.d.ts +56 -0
  102. package/{src → dist/esm/src}/instanceManager.js +88 -179
  103. package/dist/esm/src/instances/routes.d.ts +3 -0
  104. package/{src → dist/esm/src}/instances/routes.js +31 -70
  105. package/dist/esm/src/middleware/cors.d.ts +2 -0
  106. package/{src → dist/esm/src}/middleware/cors.js +2 -3
  107. package/dist/esm/src/middleware/kapeta.d.ts +11 -0
  108. package/{src → dist/esm/src}/middleware/kapeta.js +3 -7
  109. package/dist/esm/src/middleware/stringBody.d.ts +5 -0
  110. package/{src → dist/esm/src}/middleware/stringBody.js +2 -3
  111. package/dist/esm/src/networkManager.d.ts +32 -0
  112. package/{src → dist/esm/src}/networkManager.js +16 -33
  113. package/dist/esm/src/operatorManager.d.ts +36 -0
  114. package/{src → dist/esm/src}/operatorManager.js +35 -91
  115. package/dist/esm/src/progressListener.d.ts +20 -0
  116. package/dist/esm/src/progressListener.js +88 -0
  117. package/dist/esm/src/providerManager.d.ts +9 -0
  118. package/dist/esm/src/providerManager.js +45 -0
  119. package/dist/esm/src/providers/routes.d.ts +3 -0
  120. package/{src → dist/esm/src}/providers/routes.js +10 -16
  121. package/dist/esm/src/proxy/routes.d.ts +3 -0
  122. package/dist/esm/src/proxy/routes.js +106 -0
  123. package/dist/esm/src/proxy/types/rest.d.ts +4 -0
  124. package/dist/esm/src/proxy/types/rest.js +107 -0
  125. package/dist/esm/src/proxy/types/web.d.ts +4 -0
  126. package/{src → dist/esm/src}/proxy/types/web.js +13 -35
  127. package/dist/esm/src/repositoryManager.d.ts +17 -0
  128. package/dist/esm/src/repositoryManager.js +212 -0
  129. package/dist/esm/src/serviceManager.d.ts +29 -0
  130. package/{src → dist/esm/src}/serviceManager.js +12 -42
  131. package/dist/esm/src/socketManager.d.ts +14 -0
  132. package/{src → dist/esm/src}/socketManager.js +19 -23
  133. package/dist/esm/src/storageService.d.ts +17 -0
  134. package/{src → dist/esm/src}/storageService.js +8 -27
  135. package/dist/esm/src/traffic/routes.d.ts +3 -0
  136. package/{src → dist/esm/src}/traffic/routes.js +4 -9
  137. package/dist/esm/src/types.d.ts +88 -0
  138. package/dist/esm/src/types.js +1 -0
  139. package/dist/esm/src/utils/BlockInstanceRunner.d.ts +29 -0
  140. package/{src → dist/esm/src}/utils/BlockInstanceRunner.js +137 -256
  141. package/dist/esm/src/utils/LogData.d.ts +19 -0
  142. package/{src → dist/esm/src}/utils/LogData.js +11 -22
  143. package/dist/esm/src/utils/pathTemplateParser.d.ts +26 -0
  144. package/{src → dist/esm/src}/utils/pathTemplateParser.js +21 -40
  145. package/dist/esm/src/utils/utils.d.ts +1 -0
  146. package/dist/esm/src/utils/utils.js +11 -0
  147. package/dist/esm/start.d.ts +1 -0
  148. package/dist/esm/start.js +7 -0
  149. package/index.ts +147 -0
  150. package/package.json +106 -74
  151. package/src/assetManager.ts +191 -0
  152. package/src/assets/routes.ts +132 -0
  153. package/src/clusterService.ts +134 -0
  154. package/src/codeGeneratorManager.ts +57 -0
  155. package/src/config/routes.ts +159 -0
  156. package/src/configManager.ts +148 -0
  157. package/src/containerManager.ts +466 -0
  158. package/src/filesystem/routes.ts +74 -0
  159. package/src/filesystemManager.ts +93 -0
  160. package/src/identities/routes.ts +20 -0
  161. package/src/instanceManager.ts +503 -0
  162. package/src/instances/routes.ts +164 -0
  163. package/src/middleware/cors.ts +9 -0
  164. package/src/middleware/kapeta.ts +27 -0
  165. package/src/middleware/stringBody.ts +16 -0
  166. package/src/networkManager.ts +137 -0
  167. package/src/operatorManager.ts +221 -0
  168. package/src/progressListener.ts +102 -0
  169. package/src/{providerManager.js → providerManager.ts} +15 -31
  170. package/src/providers/routes.ts +46 -0
  171. package/src/proxy/routes.ts +148 -0
  172. package/src/proxy/types/{rest.js → rest.ts} +30 -30
  173. package/src/proxy/types/web.ts +60 -0
  174. package/src/{repositoryManager.js → repositoryManager.ts} +49 -73
  175. package/src/serviceManager.ts +120 -0
  176. package/src/socketManager.ts +57 -0
  177. package/src/storageService.ts +88 -0
  178. package/src/traffic/routes.ts +18 -0
  179. package/src/types.ts +97 -0
  180. package/src/utils/BlockInstanceRunner.ts +555 -0
  181. package/src/utils/LogData.ts +47 -0
  182. package/src/utils/pathTemplateParser.ts +138 -0
  183. package/src/utils/utils.ts +12 -0
  184. package/start.ts +8 -0
  185. package/tsconfig.json +13 -0
  186. package/index.js +0 -127
  187. package/src/filesystem/routes.js +0 -74
  188. package/src/identities/routes.js +0 -19
  189. package/src/progressListener.js +0 -82
  190. package/src/proxy/routes.js +0 -126
  191. package/src/utils/utils.js +0 -13
  192. package/start.js +0 -7
@@ -1,23 +1,18 @@
1
- const {spawn} = require('node:child_process');
2
- const FS = require('node:fs');
3
- const Path = require('node:path');
4
- const {Docker} = require('node-docker-api');
5
- const ClusterConfig = require("@kapeta/local-cluster-config").default;
6
- const {readYML} = require("./utils");
7
- const {parseKapetaUri} = require("@kapeta/nodejs-utils");
8
- const serviceManager = require("../serviceManager");
9
- const containerManager = require("../containerManager");
10
- const LogData = require("./LogData");
11
- const EventEmitter = require("events");
12
- const md5 = require('md5');
13
- const {execSync} = require("child_process");
14
- const clusterService = require("../clusterService");
15
-
1
+ import FS from 'node:fs';
2
+ import ClusterConfig from '@kapeta/local-cluster-config';
3
+ import { readYML } from './utils';
4
+ import { parseKapetaUri } from '@kapeta/nodejs-utils';
5
+ import { serviceManager } from '../serviceManager';
6
+ import { containerManager } from '../containerManager';
7
+ import { LogData } from './LogData';
8
+ import EventEmitter from 'events';
9
+ import md5 from 'md5';
10
+ import { clusterService } from '../clusterService';
16
11
  const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
17
- const KAPETA_SYSTEM_ID = "KAPETA_SYSTEM_ID";
18
- const KAPETA_BLOCK_REF = "KAPETA_BLOCK_REF";
19
- const KAPETA_INSTANCE_ID = "KAPETA_INSTANCE_ID";
20
- const KAPETA_LOCAL_CLUSTER_PORT = "KAPETA_LOCAL_CLUSTER_PORT";
12
+ const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
13
+ const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
14
+ const KAPETA_INSTANCE_ID = 'KAPETA_INSTANCE_ID';
15
+ const KAPETA_LOCAL_CLUSTER_PORT = 'KAPETA_LOCAL_CLUSTER_PORT';
21
16
  /**
22
17
  * Needed when running local docker containers as part of plan
23
18
  * @type {string[]}
@@ -26,27 +21,22 @@ const DOCKER_ENV_VARS = [
26
21
  `KAPETA_LOCAL_SERVER=0.0.0.0`,
27
22
  `KAPETA_LOCAL_CLUSTER_HOST=host.docker.internal`,
28
23
  `KAPETA_ENVIRONMENT_TYPE=docker`,
29
- ]
30
-
31
-
24
+ ];
32
25
  function getProvider(uri) {
33
- return ClusterConfig.getProviderDefinitions().find(provider => {
34
- const ref = `${provider.definition.metadata.name}:${provider.version}`
26
+ return ClusterConfig.getProviderDefinitions().find((provider) => {
27
+ const ref = `${provider.definition.metadata.name}:${provider.version}`;
35
28
  return parseKapetaUri(ref).id === uri.id;
36
29
  });
37
30
  }
38
-
39
31
  function getProviderPorts(assetVersion) {
40
- return assetVersion.definition?.spec?.providers?.map(provider => {
41
- return provider.spec?.port?.type
42
- }).filter(t => !!t) ?? [];
32
+ return (assetVersion.definition?.spec?.providers
33
+ ?.map((provider) => {
34
+ return provider.spec?.port?.type;
35
+ })
36
+ .filter((t) => !!t) ?? []);
43
37
  }
44
-
45
- class BlockInstanceRunner {
46
- /**
47
- * @param {string} [planReference]
48
- * @param {BlockInstanceInfo[]} [instances]
49
- */
38
+ export class BlockInstanceRunner {
39
+ _systemId;
50
40
  constructor(planReference) {
51
41
  /**
52
42
  *
@@ -55,206 +45,145 @@ class BlockInstanceRunner {
55
45
  */
56
46
  this._systemId = planReference ?? '';
57
47
  }
58
-
59
-
60
-
61
48
  /**
62
49
  * Start a block
63
50
  *
64
- * @param {string} blockRef
65
- * @param {string} instanceId
66
- * @param {any} configuration
67
- * @returns {Promise<ProcessInfo>}
68
51
  */
69
52
  async start(blockRef, instanceId, configuration) {
70
53
  return this._execute({
71
54
  ref: blockRef,
72
55
  id: instanceId,
73
- configuration
56
+ configuration,
74
57
  });
75
58
  }
76
-
77
- /**
78
- *
79
- * @param {BlockInstanceInfo} blockInstance
80
- * @return {Promise<ProcessInfo>}
81
- * @private
82
- */
83
59
  async _execute(blockInstance) {
84
60
  const env = {};
85
-
86
61
  if (this._systemId) {
87
62
  env[KAPETA_SYSTEM_ID] = this._systemId;
88
63
  }
89
-
90
64
  if (blockInstance.ref) {
91
65
  env[KAPETA_BLOCK_REF] = blockInstance.ref;
92
66
  }
93
-
94
67
  if (blockInstance.id) {
95
68
  env[KAPETA_INSTANCE_ID] = blockInstance.id;
96
69
  }
97
-
98
70
  const blockUri = parseKapetaUri(blockInstance.ref);
99
-
100
71
  if (!blockUri.version) {
101
72
  blockUri.version = 'local';
102
73
  }
103
-
104
- const assetVersion = ClusterConfig.getDefinitions().find(definitions => {
105
- const ref = `${definitions.definition.metadata.name}:${definitions.version}`
74
+ const assetVersion = ClusterConfig.getDefinitions().find((definitions) => {
75
+ const ref = `${definitions.definition.metadata.name}:${definitions.version}`;
106
76
  return parseKapetaUri(ref).id === blockUri.id;
107
77
  });
108
-
109
78
  if (!assetVersion) {
110
79
  throw new Error(`Block definition not found: ${blockUri.id}`);
111
80
  }
112
-
113
81
  const kindUri = parseKapetaUri(assetVersion.definition.kind);
114
-
115
82
  const providerVersion = getProvider(kindUri);
116
-
117
83
  if (!providerVersion) {
118
84
  throw new Error(`Kind not found: ${kindUri.id}`);
119
85
  }
120
-
121
- /**
122
- * @type {ProcessDetails}
123
- */
124
86
  let processDetails;
125
-
126
87
  if (providerVersion.definition.kind === KIND_BLOCK_TYPE_OPERATOR) {
127
88
  processDetails = await this._startOperatorProcess(blockInstance, blockUri, providerVersion, env);
128
- } else {
89
+ }
90
+ else {
129
91
  //We need a port type to know how to connect to the block consistently
130
92
  const portTypes = getProviderPorts(assetVersion);
131
-
132
93
  if (blockUri.version === 'local') {
133
94
  processDetails = await this._startLocalProcess(blockInstance, blockUri, env, assetVersion);
134
- } else {
95
+ }
96
+ else {
135
97
  processDetails = await this._startDockerProcess(blockInstance, blockUri, env);
136
98
  }
137
-
138
99
  if (portTypes.length > 0) {
139
100
  processDetails.portType = portTypes[0];
140
101
  }
141
102
  }
142
-
143
103
  return {
104
+ name: blockUri.id,
144
105
  ...blockInstance,
145
- ...processDetails
106
+ ...processDetails,
146
107
  };
147
108
  }
148
-
149
-
150
109
  /**
151
110
  * Starts local process
152
- * @param {BlockInstanceInfo} blockInstance
153
- * @param {BlockInfo} blockInfo
154
- * @param {EnvironmentVariables} env
155
- * @param assetVersion
156
- * @return {ProcessDetails}
157
- * @private
158
111
  */
159
112
  async _startLocalProcess(blockInstance, blockInfo, env, assetVersion) {
160
- const baseDir = ClusterConfig.getRepositoryAssetPath(
161
- blockInfo.handle,
162
- blockInfo.name,
163
- blockInfo.version
164
- );
165
-
113
+ const baseDir = ClusterConfig.getRepositoryAssetPath(blockInfo.handle, blockInfo.name, blockInfo.version);
166
114
  if (!FS.existsSync(baseDir)) {
167
- throw new Error(
168
- `Local block not registered correctly - expected symlink here: ${baseDir}.\n` +
169
- `Make sure you've run "blockctl registry link" in your local directory to connect it to Kapeta`
170
- );
115
+ throw new Error(`Local block not registered correctly - expected symlink here: ${baseDir}.\n` +
116
+ `Make sure you've run "blockctl registry link" in your local directory to connect it to Kapeta`);
171
117
  }
172
-
173
118
  if (!assetVersion.definition.spec?.target?.kind) {
174
119
  throw new Error('Missing target kind in block definition');
175
120
  }
176
-
177
121
  const kindUri = parseKapetaUri(assetVersion.definition.spec?.target?.kind);
178
-
179
122
  const targetVersion = getProvider(kindUri);
180
-
181
123
  if (!targetVersion) {
182
124
  throw new Error(`Target not found: ${kindUri.id}`);
183
125
  }
184
-
185
126
  const localContainer = targetVersion.definition.spec.local;
186
-
187
127
  if (!localContainer) {
188
128
  throw new Error(`Missing local container information from target: ${kindUri.id}`);
189
129
  }
190
-
191
130
  const dockerImage = localContainer.image;
192
131
  if (!dockerImage) {
193
132
  throw new Error(`Missing docker image information: ${JSON.stringify(localContainer)}`);
194
133
  }
195
-
196
134
  const containerName = `kapeta-block-instance-${blockInstance.id}`;
197
135
  const logs = new LogData();
198
136
  logs.addLog(`Starting block ${blockInstance.ref}`);
199
- let container = await containerManager.getContainerByName(containerName);
137
+ let container = (await containerManager.getContainerByName(containerName)) ?? null;
200
138
  console.log('Starting dev container', containerName);
201
-
202
139
  if (container) {
203
140
  console.log(`Container already exists. Deleting...`);
204
141
  try {
205
142
  await container.delete({
206
- force: true
207
- })
208
- } catch (e) {
143
+ force: true,
144
+ });
145
+ }
146
+ catch (e) {
209
147
  throw new Error('Failed to delete existing container: ' + e.message);
210
148
  }
211
149
  container = null;
212
150
  }
213
-
214
151
  logs.addLog(`Creating new container for block: ${containerName}`);
215
152
  console.log('Creating new dev container', containerName, dockerImage);
216
153
  await containerManager.pull(dockerImage);
217
-
218
154
  const startCmd = localContainer.handlers?.onCreate ? localContainer.handlers.onCreate : '';
219
155
  const dockerOpts = localContainer.options ?? {};
220
156
  const homeDir = localContainer.userHome ? localContainer.userHome : '/root';
221
157
  const workingDir = localContainer.workingDir ? localContainer.workingDir : '/workspace';
222
-
223
158
  const ExposedPorts = {};
224
159
  const addonEnv = {};
225
160
  const PortBindings = {};
226
-
227
161
  const portTypes = getProviderPorts(assetVersion);
228
162
  let port = 80;
229
- const promises = portTypes
230
- .map(async (portType) => {
231
- const publicPort = await serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
232
- const thisPort = port++; //TODO: Not sure how we should handle multiple ports or non-HTTP ports
233
- const dockerPort = `${thisPort}/tcp`;
234
- ExposedPorts[dockerPort] = {};
235
- addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = thisPort;
236
-
237
- PortBindings[dockerPort] = [
238
- {
239
- HostIp: "127.0.0.1", //No public
240
- HostPort: `${publicPort}`
241
- }
242
- ];
243
- });
244
-
163
+ const promises = portTypes.map(async (portType) => {
164
+ const publicPort = await serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
165
+ const thisPort = port++; //TODO: Not sure how we should handle multiple ports or non-HTTP ports
166
+ const dockerPort = `${thisPort}/tcp`;
167
+ ExposedPorts[dockerPort] = {};
168
+ addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = '' + thisPort;
169
+ PortBindings[dockerPort] = [
170
+ {
171
+ HostIp: '127.0.0.1',
172
+ HostPort: `${publicPort}`,
173
+ },
174
+ ];
175
+ });
245
176
  await Promise.all(promises);
246
-
247
177
  let HealthCheck = undefined;
248
178
  if (localContainer.healthcheck) {
249
- HealthCheck = containerManager.toDockerHealth({cmd: localContainer.healthcheck});
179
+ HealthCheck = containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
250
180
  }
251
-
252
181
  container = await containerManager.startContainer({
253
182
  Image: dockerImage,
254
183
  name: containerName,
255
184
  WorkingDir: workingDir,
256
185
  Labels: {
257
- 'instance': blockInstance.id
186
+ instance: blockInstance.id,
258
187
  },
259
188
  HealthCheck,
260
189
  ExposedPorts,
@@ -264,118 +193,88 @@ class BlockInstanceRunner {
264
193
  `KAPETA_LOCAL_CLUSTER_PORT=${clusterService.getClusterServicePort()}`,
265
194
  ...Object.entries({
266
195
  ...env,
267
- ...addonEnv
268
- }).map(([key, value]) => `${key}=${value}`)
196
+ ...addonEnv,
197
+ }).map(([key, value]) => `${key}=${value}`),
269
198
  ],
270
199
  HostConfig: {
271
200
  Binds: [
272
201
  `${ClusterConfig.getKapetaBasedir()}:${homeDir}/.kapeta`,
273
- `${baseDir}:${workingDir}` //We mount
202
+ `${baseDir}:${workingDir}`, //We mount
274
203
  ],
275
- PortBindings
204
+ PortBindings,
276
205
  },
277
- ...dockerOpts
206
+ ...dockerOpts,
278
207
  });
279
-
280
208
  try {
281
209
  if (HealthCheck) {
282
210
  await containerManager.waitForHealthy(container);
283
- } else {
211
+ }
212
+ else {
284
213
  await containerManager.waitForReady(container);
285
214
  }
286
- } catch (e) {
215
+ }
216
+ catch (e) {
287
217
  logs.addLog(e.message, 'ERROR');
288
218
  }
289
-
290
219
  return this._handleContainer(container, logs);
291
220
  }
292
-
293
- /**
294
- *
295
- * @param container
296
- * @param logs
297
- * @param deleteOnExit
298
- * @return {Promise<ProcessDetails>}
299
- * @private
300
- */
301
- async _handleContainer(container, logs , deleteOnExit = false) {
302
- const logStream = await container.logs({
221
+ async _handleContainer(container, logs, deleteOnExit = false) {
222
+ let localContainer = container;
223
+ const logStream = (await container.logs({
303
224
  follow: true,
304
225
  stdout: true,
305
226
  stderr: true,
306
- tail: LogData.MAX_LINES
307
- })
308
-
227
+ tail: LogData.MAX_LINES,
228
+ }));
309
229
  const outputEvents = new EventEmitter();
310
230
  logStream.on('data', (data) => {
311
231
  logs.addLog(data.toString());
312
232
  outputEvents.emit('data', data);
313
233
  });
314
-
315
234
  logStream.on('error', (data) => {
316
235
  logs.addLog(data.toString());
317
236
  outputEvents.emit('data', data);
318
237
  });
319
-
320
238
  logStream.on('close', async () => {
321
239
  const status = await container.status();
240
+ const data = status.data;
322
241
  if (deleteOnExit) {
323
242
  try {
324
- await container.delete()
325
- } catch (e) {}
243
+ await container.delete();
244
+ }
245
+ catch (e) { }
326
246
  }
327
- outputEvents.emit('exit', status.data?.State?.ExitCode ?? 0);
247
+ outputEvents.emit('exit', data?.State?.ExitCode ?? 0);
328
248
  });
329
- /**
330
- *
331
- * @type {ProcessDetails}
332
- */
333
249
  return {
334
250
  type: 'docker',
335
251
  pid: container.id,
336
252
  output: outputEvents,
337
253
  stop: async () => {
338
- if (!container) {
254
+ if (!localContainer) {
339
255
  return;
340
256
  }
341
-
342
257
  try {
343
- await container.stop();
258
+ await localContainer.stop();
344
259
  if (deleteOnExit) {
345
- await container.delete();
260
+ await localContainer.delete();
346
261
  }
347
- } catch (e) {}
348
- container = null;
262
+ }
263
+ catch (e) { }
264
+ localContainer = null;
349
265
  },
350
266
  logs: () => {
351
267
  return logs.getLogs();
352
- }
268
+ },
353
269
  };
354
270
  }
355
-
356
-
357
- /**
358
- * Starts local process using docker
359
- * @param {BlockInstanceInfo} blockInstance
360
- * @param {BlockInfo} blockInfo
361
- * @param {EnvironmentVariables} env
362
- * @return {Promise<ProcessDetails>}
363
- * @private
364
- */
365
271
  async _startDockerProcess(blockInstance, blockInfo, env) {
366
- const {versionFile} = ClusterConfig.getRepositoryAssetInfoPath(
367
- blockInfo.handle,
368
- blockInfo.name,
369
- blockInfo.version
370
- );
371
-
272
+ const { versionFile } = ClusterConfig.getRepositoryAssetInfoPath(blockInfo.handle, blockInfo.name, blockInfo.version);
372
273
  const versionYml = versionFile;
373
274
  if (!FS.existsSync(versionYml)) {
374
275
  throw new Error(`Did not find version info at the expected path: ${versionYml}`);
375
276
  }
376
-
377
277
  const versionInfo = readYML(versionYml);
378
-
379
278
  if (versionInfo?.artifact?.type !== 'docker') {
380
279
  throw new Error(`Unsupported artifact type: ${versionInfo?.artifact?.type}`);
381
280
  }
@@ -383,49 +282,45 @@ class BlockInstanceRunner {
383
282
  if (!dockerImage) {
384
283
  throw new Error(`Missing docker image information: ${JSON.stringify(versionInfo?.artifact?.details)}`);
385
284
  }
386
-
387
285
  const containerName = `kapeta-block-instance-${blockInstance.id}`;
388
286
  const logs = new LogData();
389
287
  let container = await containerManager.getContainerByName(containerName);
390
-
391
288
  if (container) {
392
- if (container.data.State === 'running') {
289
+ const containerData = container.data;
290
+ if (containerData.State === 'running') {
393
291
  logs.addLog(`Found existing running container for block: ${containerName}`);
394
- } else {
292
+ }
293
+ else {
395
294
  logs.addLog(`Found existing container for block: ${containerName}. Starting now`);
396
295
  await container.start();
397
296
  }
398
- } else {
297
+ }
298
+ else {
399
299
  logs.addLog(`Creating new container for block: ${containerName}`);
400
300
  container = await containerManager.startContainer({
401
301
  Image: dockerImage,
402
302
  name: containerName,
403
303
  Labels: {
404
- 'instance': blockInstance.id
304
+ instance: blockInstance.id,
405
305
  },
406
306
  Env: [
407
307
  ...DOCKER_ENV_VARS,
408
308
  `KAPETA_LOCAL_CLUSTER_PORT=${clusterService.getClusterServicePort()}`,
409
- ...Object.entries(env).map(([key, value]) => `${key}=${value}`)
309
+ ...Object.entries(env).map(([key, value]) => `${key}=${value}`),
410
310
  ],
411
311
  HostConfig: {
412
- Binds: [
413
- `${ClusterConfig.getKapetaBasedir()}:${ClusterConfig.getKapetaBasedir()}`
414
- ],
415
-
416
- }
312
+ Binds: [`${ClusterConfig.getKapetaBasedir()}:${ClusterConfig.getKapetaBasedir()}`],
313
+ },
417
314
  });
418
-
419
315
  try {
420
316
  await containerManager.waitForReady(container);
421
- } catch (e) {
317
+ }
318
+ catch (e) {
422
319
  logs.addLog(e.message, 'ERROR');
423
320
  }
424
321
  }
425
-
426
322
  return this._handleContainer(container, logs);
427
323
  }
428
-
429
324
  /**
430
325
  *
431
326
  * @param blockInstance
@@ -436,98 +331,87 @@ class BlockInstanceRunner {
436
331
  * @private
437
332
  */
438
333
  async _startOperatorProcess(blockInstance, blockUri, providerDefinition, env) {
439
- const {assetFile} = ClusterConfig.getRepositoryAssetInfoPath(
440
- blockUri.handle,
441
- blockUri.name,
442
- blockUri.version
443
- );
444
-
334
+ const { assetFile } = ClusterConfig.getRepositoryAssetInfoPath(blockUri.handle, blockUri.name, blockUri.version);
445
335
  const kapetaYmlPath = assetFile;
446
336
  if (!FS.existsSync(kapetaYmlPath)) {
447
337
  throw new Error(`Did not find kapeta.yml at the expected path: ${kapetaYmlPath}`);
448
338
  }
449
-
450
339
  const spec = providerDefinition.definition.spec;
451
340
  const providerRef = `${providerDefinition.definition.metadata.name}:${providerDefinition.version}`;
452
-
453
341
  if (!spec?.local?.image) {
454
342
  throw new Error(`Provider did not have local image: ${providerRef}`);
455
343
  }
456
-
457
344
  const dockerImage = spec?.local?.image;
458
-
459
345
  try {
460
346
  await containerManager.pull(dockerImage);
461
- } catch (e) {
347
+ }
348
+ catch (e) {
462
349
  console.warn('Failed to pull image. Continuing...', e);
463
350
  }
464
-
465
351
  const containerName = `kapeta-block-instance-${md5(blockInstance.id)}`;
466
352
  const logs = new LogData();
467
- let container = await containerManager.getContainerByName(containerName);
468
-
353
+ let container = (await containerManager.getContainerByName(containerName)) ?? null;
469
354
  if (container) {
470
- if (container.data.State === 'running') {
355
+ const containerData = container.data;
356
+ if (containerData.State === 'running') {
471
357
  logs.addLog(`Found existing running container for block: ${containerName}`);
472
- } else {
473
- if (container.data.State?.ExitCode > 0) {
474
- logs.addLog(`Container exited with code: ${container.data.State.ExitCode}. Deleting...`);
358
+ }
359
+ else {
360
+ if (containerData.State?.ExitCode > 0) {
361
+ logs.addLog(`Container exited with code: ${containerData.State.ExitCode}. Deleting...`);
475
362
  try {
476
- await container.delete()
477
- } catch (e) {}
363
+ await container.delete();
364
+ }
365
+ catch (e) { }
478
366
  container = null;
479
- } else {
367
+ }
368
+ else {
480
369
  logs.addLog(`Found existing container for block: ${containerName}. Starting now`);
481
370
  try {
482
371
  await container.start();
483
- } catch (e) {
372
+ }
373
+ catch (e) {
484
374
  console.warn('Failed to start container. Deleting...', e);
485
375
  try {
486
- await container.delete()
487
- } catch (e) {}
376
+ await container.delete();
377
+ }
378
+ catch (e) { }
488
379
  container = null;
489
380
  }
490
381
  }
491
382
  }
492
383
  }
493
-
494
384
  if (!container) {
495
385
  const ExposedPorts = {};
496
386
  const addonEnv = {};
497
387
  const PortBindings = {};
498
388
  let HealthCheck = undefined;
499
389
  let Mounts = [];
500
- const promises = Object.entries(spec.local.ports)
501
- .map(async ([portType, value]) => {
502
- const dockerPort = `${value.port}/${value.type}`;
503
- ExposedPorts[dockerPort] = {};
504
- addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = value.port;
505
- const publicPort = await serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
506
- PortBindings[dockerPort] = [
507
- {
508
- HostIp: "127.0.0.1", //No public
509
- HostPort: `${publicPort}`
510
- }
511
- ];
512
- });
513
-
390
+ const promises = Object.entries(spec.local.ports).map(async ([portType, value]) => {
391
+ const dockerPort = `${value.port}/${value.type}`;
392
+ ExposedPorts[dockerPort] = {};
393
+ addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = value.port;
394
+ const publicPort = await serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
395
+ PortBindings[dockerPort] = [
396
+ {
397
+ HostIp: '127.0.0.1',
398
+ HostPort: `${publicPort}`,
399
+ },
400
+ ];
401
+ });
514
402
  await Promise.all(promises);
515
-
516
403
  if (spec.local?.env) {
517
404
  Object.entries(spec.local.env).forEach(([key, value]) => {
518
405
  addonEnv[key] = value;
519
406
  });
520
407
  }
521
-
522
408
  if (spec.local?.mounts) {
523
409
  const mounts = containerManager.createMounts(blockUri.id, spec.local.mounts);
524
410
  Mounts = containerManager.toDockerMounts(mounts);
525
411
  }
526
-
527
412
  if (spec.local?.health) {
528
413
  HealthCheck = containerManager.toDockerHealth(spec.local?.health);
529
414
  }
530
-
531
415
  logs.addLog(`Creating new container for block: ${containerName}`);
532
416
  container = await containerManager.startContainer({
533
417
  Image: dockerImage,
@@ -537,13 +421,13 @@ class BlockInstanceRunner {
537
421
  HostConfig: {
538
422
  Binds: [
539
423
  `${kapetaYmlPath}:/kapeta.yml:ro`,
540
- `${ClusterConfig.getKapetaBasedir()}:${ClusterConfig.getKapetaBasedir()}`
424
+ `${ClusterConfig.getKapetaBasedir()}:${ClusterConfig.getKapetaBasedir()}`,
541
425
  ],
542
426
  PortBindings,
543
- Mounts
427
+ Mounts,
544
428
  },
545
429
  Labels: {
546
- 'instance': blockInstance.id
430
+ instance: blockInstance.id,
547
431
  },
548
432
  Env: [
549
433
  `KAPETA_INSTANCE_NAME=${blockInstance.ref}`,
@@ -551,30 +435,27 @@ class BlockInstanceRunner {
551
435
  ...DOCKER_ENV_VARS,
552
436
  ...Object.entries({
553
437
  ...env,
554
- ...addonEnv
555
- }).map(([key, value]) => `${key}=${value}`)
556
- ]
438
+ ...addonEnv,
439
+ }).map(([key, value]) => `${key}=${value}`),
440
+ ],
557
441
  });
558
-
559
442
  try {
560
443
  if (HealthCheck) {
561
444
  await containerManager.waitForHealthy(container);
562
- } else {
445
+ }
446
+ else {
563
447
  await containerManager.waitForReady(container);
564
448
  }
565
- } catch (e) {
449
+ }
450
+ catch (e) {
566
451
  logs.addLog(e.message, 'ERROR');
567
452
  }
568
453
  }
569
-
570
454
  const out = await this._handleContainer(container, logs, true);
571
455
  const portTypes = spec.local.ports ? Object.keys(spec.local.ports) : [];
572
456
  if (portTypes.length > 0) {
573
457
  out.portType = portTypes[0];
574
458
  }
575
-
576
459
  return out;
577
460
  }
578
461
  }
579
-
580
- module.exports = BlockInstanceRunner;