@kapeta/local-cluster-service 0.21.4 → 0.22.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [0.22.0](https://github.com/kapetacom/local-cluster-service/compare/v0.21.5...v0.22.0) (2023-10-17)
2
+
3
+
4
+ ### Features
5
+
6
+ * Allow local containers to add Binds ([#85](https://github.com/kapetacom/local-cluster-service/issues/85)) ([c7b46e9](https://github.com/kapetacom/local-cluster-service/commit/c7b46e94412da1eec82503f7d30957fc665e71e6))
7
+
8
+ ## [0.21.5](https://github.com/kapetacom/local-cluster-service/compare/v0.21.4...v0.21.5) (2023-09-26)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * handle bad token in current identity API ([#84](https://github.com/kapetacom/local-cluster-service/issues/84)) ([60ca70d](https://github.com/kapetacom/local-cluster-service/commit/60ca70d9f6aa5747d89110b03f56fae70f1c7f24))
14
+
1
15
  ## [0.21.4](https://github.com/kapetacom/local-cluster-service/compare/v0.21.3...v0.21.4) (2023-09-21)
2
16
 
3
17
 
package/dist/cjs/index.js CHANGED
@@ -57,11 +57,22 @@ function createServer() {
57
57
  });
58
58
  app.use('/', (req, res) => {
59
59
  console.error('Invalid request: %s %s', req.method, req.originalUrl);
60
- res.status(400).send({
60
+ res.status(400).json({
61
61
  ok: false,
62
62
  error: 'Unknown',
63
63
  });
64
64
  });
65
+ /**
66
+ * Central error handler, allows us to return a consistent JSON response wrapper with the error.
67
+ */
68
+ app.use((err, req, res, next) => {
69
+ console.error('Error handling request: %s %s', req.method, req.originalUrl, err);
70
+ res.status(err.status || 500).json({
71
+ ok: false,
72
+ error: err.message || 'Unknown error',
73
+ stack: process.env.NODE_ENV !== 'production' ? err.stack : undefined,
74
+ });
75
+ });
65
76
  const server = http_1.default.createServer(app);
66
77
  //socket
67
78
  const io = new socket_io_1.Server(server, {
@@ -9,31 +9,25 @@ const cors_1 = require("../middleware/cors");
9
9
  const router = (0, express_promise_router_1.default)();
10
10
  router.use('/', cors_1.corsHandler);
11
11
  router.get('/current', async (req, res) => {
12
- try {
13
- const api = new nodejs_api_client_1.KapetaAPI();
14
- if (api.hasToken()) {
15
- res.send(await api.getCurrentIdentity());
12
+ const api = new nodejs_api_client_1.KapetaAPI();
13
+ if (api.hasToken()) {
14
+ try {
15
+ res.json(await api.getCurrentIdentity());
16
+ return;
16
17
  }
17
- else {
18
- res.status(404).send();
18
+ catch (e) {
19
+ console.error(e);
19
20
  }
20
21
  }
21
- catch (e) {
22
- res.status(e.status ?? 500).send(e);
23
- }
22
+ res.status(200).json(null);
24
23
  });
25
24
  router.get('/:identityId/memberships', async (req, res) => {
26
- try {
27
- const api = new nodejs_api_client_1.KapetaAPI();
28
- if (api.hasToken()) {
29
- res.send(await api.getMemberships(req.params.identityId));
30
- }
31
- else {
32
- res.send([]);
33
- }
25
+ const api = new nodejs_api_client_1.KapetaAPI();
26
+ if (api.hasToken()) {
27
+ res.send(await api.getMemberships(req.params.identityId));
34
28
  }
35
- catch (e) {
36
- res.status(e.status ?? 500).send(e);
29
+ else {
30
+ res.send([]);
37
31
  }
38
32
  });
39
33
  exports.default = router;
@@ -14,6 +14,7 @@ const LogData_1 = require("./LogData");
14
14
  const clusterService_1 = require("../clusterService");
15
15
  const types_1 = require("../types");
16
16
  const definitionsManager_1 = require("../definitionsManager");
17
+ const node_os_1 = __importDefault(require("node:os"));
17
18
  const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
18
19
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
19
20
  const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
@@ -46,7 +47,8 @@ function getProviderPorts(assetVersion, providerVersion) {
46
47
  }
47
48
  return [serviceManager_1.DEFAULT_PORT_TYPE];
48
49
  }
49
- return out;
50
+ // Duplicated port types are not allowed
51
+ return Array.from(new Set(out));
50
52
  }
51
53
  class BlockInstanceRunner {
52
54
  _systemId;
@@ -148,6 +150,8 @@ class BlockInstanceRunner {
148
150
  const homeDir = localContainer.userHome ? localContainer.userHome : '/root';
149
151
  const workingDir = localContainer.workingDir ? localContainer.workingDir : '/workspace';
150
152
  const customHostConfigs = localContainer.HostConfig ?? {};
153
+ const Binds = customHostConfigs.Binds ?? [];
154
+ delete customHostConfigs.Binds;
151
155
  const customLabels = localContainer.Labels ?? {};
152
156
  const customEnvs = localContainer.Env ?? [];
153
157
  delete localContainer.HostConfig;
@@ -160,7 +164,7 @@ class BlockInstanceRunner {
160
164
  }
161
165
  const realLocalPath = node_fs_1.default.realpathSync(baseDir);
162
166
  const Mounts = containerManager_1.containerManager.toDockerMounts({
163
- [workingDir]: (0, containerManager_1.toLocalBindVolume)(realLocalPath)
167
+ [workingDir]: (0, containerManager_1.toLocalBindVolume)(realLocalPath),
164
168
  });
165
169
  const systemUri = (0, nodejs_utils_1.parseKapetaUri)(this._systemId);
166
170
  return this.ensureContainer({
@@ -189,10 +193,20 @@ class BlockInstanceRunner {
189
193
  HostConfig: {
190
194
  ...customHostConfigs,
191
195
  Binds: [
192
- `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${homeDir}/.kapeta`
196
+ `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${homeDir}/.kapeta`,
197
+ ...Binds.map((bind) => {
198
+ let [host, container] = bind.split(':');
199
+ if (host.startsWith('~')) {
200
+ host = node_os_1.default.homedir() + host.substring(1);
201
+ }
202
+ if (container.startsWith('~')) {
203
+ container = homeDir + container.substring(1);
204
+ }
205
+ return `${(0, containerManager_1.toLocalBindVolume)(host)}:${container}`;
206
+ }),
193
207
  ],
194
208
  PortBindings,
195
- Mounts
209
+ Mounts,
196
210
  },
197
211
  });
198
212
  }
package/dist/esm/index.js CHANGED
@@ -57,11 +57,22 @@ function createServer() {
57
57
  });
58
58
  app.use('/', (req, res) => {
59
59
  console.error('Invalid request: %s %s', req.method, req.originalUrl);
60
- res.status(400).send({
60
+ res.status(400).json({
61
61
  ok: false,
62
62
  error: 'Unknown',
63
63
  });
64
64
  });
65
+ /**
66
+ * Central error handler, allows us to return a consistent JSON response wrapper with the error.
67
+ */
68
+ app.use((err, req, res, next) => {
69
+ console.error('Error handling request: %s %s', req.method, req.originalUrl, err);
70
+ res.status(err.status || 500).json({
71
+ ok: false,
72
+ error: err.message || 'Unknown error',
73
+ stack: process.env.NODE_ENV !== 'production' ? err.stack : undefined,
74
+ });
75
+ });
65
76
  const server = http_1.default.createServer(app);
66
77
  //socket
67
78
  const io = new socket_io_1.Server(server, {
@@ -9,31 +9,25 @@ const cors_1 = require("../middleware/cors");
9
9
  const router = (0, express_promise_router_1.default)();
10
10
  router.use('/', cors_1.corsHandler);
11
11
  router.get('/current', async (req, res) => {
12
- try {
13
- const api = new nodejs_api_client_1.KapetaAPI();
14
- if (api.hasToken()) {
15
- res.send(await api.getCurrentIdentity());
12
+ const api = new nodejs_api_client_1.KapetaAPI();
13
+ if (api.hasToken()) {
14
+ try {
15
+ res.json(await api.getCurrentIdentity());
16
+ return;
16
17
  }
17
- else {
18
- res.status(404).send();
18
+ catch (e) {
19
+ console.error(e);
19
20
  }
20
21
  }
21
- catch (e) {
22
- res.status(e.status ?? 500).send(e);
23
- }
22
+ res.status(200).json(null);
24
23
  });
25
24
  router.get('/:identityId/memberships', async (req, res) => {
26
- try {
27
- const api = new nodejs_api_client_1.KapetaAPI();
28
- if (api.hasToken()) {
29
- res.send(await api.getMemberships(req.params.identityId));
30
- }
31
- else {
32
- res.send([]);
33
- }
25
+ const api = new nodejs_api_client_1.KapetaAPI();
26
+ if (api.hasToken()) {
27
+ res.send(await api.getMemberships(req.params.identityId));
34
28
  }
35
- catch (e) {
36
- res.status(e.status ?? 500).send(e);
29
+ else {
30
+ res.send([]);
37
31
  }
38
32
  });
39
33
  exports.default = router;
@@ -14,6 +14,7 @@ const LogData_1 = require("./LogData");
14
14
  const clusterService_1 = require("../clusterService");
15
15
  const types_1 = require("../types");
16
16
  const definitionsManager_1 = require("../definitionsManager");
17
+ const node_os_1 = __importDefault(require("node:os"));
17
18
  const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
18
19
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
19
20
  const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
@@ -46,7 +47,8 @@ function getProviderPorts(assetVersion, providerVersion) {
46
47
  }
47
48
  return [serviceManager_1.DEFAULT_PORT_TYPE];
48
49
  }
49
- return out;
50
+ // Duplicated port types are not allowed
51
+ return Array.from(new Set(out));
50
52
  }
51
53
  class BlockInstanceRunner {
52
54
  _systemId;
@@ -148,6 +150,8 @@ class BlockInstanceRunner {
148
150
  const homeDir = localContainer.userHome ? localContainer.userHome : '/root';
149
151
  const workingDir = localContainer.workingDir ? localContainer.workingDir : '/workspace';
150
152
  const customHostConfigs = localContainer.HostConfig ?? {};
153
+ const Binds = customHostConfigs.Binds ?? [];
154
+ delete customHostConfigs.Binds;
151
155
  const customLabels = localContainer.Labels ?? {};
152
156
  const customEnvs = localContainer.Env ?? [];
153
157
  delete localContainer.HostConfig;
@@ -160,7 +164,7 @@ class BlockInstanceRunner {
160
164
  }
161
165
  const realLocalPath = node_fs_1.default.realpathSync(baseDir);
162
166
  const Mounts = containerManager_1.containerManager.toDockerMounts({
163
- [workingDir]: (0, containerManager_1.toLocalBindVolume)(realLocalPath)
167
+ [workingDir]: (0, containerManager_1.toLocalBindVolume)(realLocalPath),
164
168
  });
165
169
  const systemUri = (0, nodejs_utils_1.parseKapetaUri)(this._systemId);
166
170
  return this.ensureContainer({
@@ -189,10 +193,20 @@ class BlockInstanceRunner {
189
193
  HostConfig: {
190
194
  ...customHostConfigs,
191
195
  Binds: [
192
- `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${homeDir}/.kapeta`
196
+ `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${homeDir}/.kapeta`,
197
+ ...Binds.map((bind) => {
198
+ let [host, container] = bind.split(':');
199
+ if (host.startsWith('~')) {
200
+ host = node_os_1.default.homedir() + host.substring(1);
201
+ }
202
+ if (container.startsWith('~')) {
203
+ container = homeDir + container.substring(1);
204
+ }
205
+ return `${(0, containerManager_1.toLocalBindVolume)(host)}:${container}`;
206
+ }),
193
207
  ],
194
208
  PortBindings,
195
- Mounts
209
+ Mounts,
196
210
  },
197
211
  });
198
212
  }
package/index.ts CHANGED
@@ -62,12 +62,24 @@ function createServer() {
62
62
 
63
63
  app.use('/', (req: express.Request, res: express.Response) => {
64
64
  console.error('Invalid request: %s %s', req.method, req.originalUrl);
65
- res.status(400).send({
65
+ res.status(400).json({
66
66
  ok: false,
67
67
  error: 'Unknown',
68
68
  });
69
69
  });
70
70
 
71
+ /**
72
+ * Central error handler, allows us to return a consistent JSON response wrapper with the error.
73
+ */
74
+ app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
75
+ console.error('Error handling request: %s %s', req.method, req.originalUrl, err);
76
+ res.status(err.status || 500).json({
77
+ ok: false,
78
+ error: err.message || 'Unknown error',
79
+ stack: process.env.NODE_ENV !== 'production' ? err.stack : undefined,
80
+ });
81
+ });
82
+
71
83
  const server = HTTP.createServer(app);
72
84
 
73
85
  //socket
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.21.4",
3
+ "version": "0.22.0",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {
@@ -45,7 +45,7 @@
45
45
  "dependencies": {
46
46
  "@kapeta/codegen": "<2",
47
47
  "@kapeta/local-cluster-config": ">= 0.2.3 <2",
48
- "@kapeta/nodejs-api-client": "<2",
48
+ "@kapeta/nodejs-api-client": ">=0.1.3 <2",
49
49
  "@kapeta/nodejs-process": "<2",
50
50
  "@kapeta/nodejs-registry-utils": "<2",
51
51
  "@kapeta/nodejs-utils": "<2",
@@ -9,28 +9,24 @@ const router = Router();
9
9
  router.use('/', corsHandler);
10
10
 
11
11
  router.get('/current', async (req: Request, res: Response) => {
12
- try {
13
- const api = new KapetaAPI();
14
- if (api.hasToken()) {
15
- res.send(await api.getCurrentIdentity());
16
- } else {
17
- res.status(404).send();
12
+ const api = new KapetaAPI();
13
+ if (api.hasToken()) {
14
+ try {
15
+ res.json(await api.getCurrentIdentity());
16
+ return;
17
+ } catch (e) {
18
+ console.error(e);
18
19
  }
19
- } catch (e: any) {
20
- res.status(e.status ?? 500).send(e);
21
20
  }
21
+ res.status(200).json(null);
22
22
  });
23
23
 
24
24
  router.get('/:identityId/memberships', async (req: Request, res: Response) => {
25
- try {
26
- const api = new KapetaAPI();
27
- if (api.hasToken()) {
28
- res.send(await api.getMemberships(req.params.identityId));
29
- } else {
30
- res.send([]);
31
- }
32
- } catch (e: any) {
33
- res.status(e.status ?? 500).send(e);
25
+ const api = new KapetaAPI();
26
+ if (api.hasToken()) {
27
+ res.send(await api.getMemberships(req.params.identityId));
28
+ } else {
29
+ res.send([]);
34
30
  }
35
31
  });
36
32
 
@@ -15,6 +15,7 @@ import { clusterService } from '../clusterService';
15
15
  import { AnyMap, BlockProcessParams, InstanceType, ProcessInfo, StringMap } from '../types';
16
16
  import { definitionsManager } from '../definitionsManager';
17
17
  import Docker from 'dockerode';
18
+ import OS from 'node:os';
18
19
 
19
20
  const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
20
21
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
@@ -53,8 +54,8 @@ function getProviderPorts(assetVersion: DefinitionInfo, providerVersion: Definit
53
54
  }
54
55
  return [DEFAULT_PORT_TYPE];
55
56
  }
56
-
57
- return out;
57
+ // Duplicated port types are not allowed
58
+ return Array.from(new Set<string>(out));
58
59
  }
59
60
 
60
61
  export class BlockInstanceRunner {
@@ -194,6 +195,8 @@ export class BlockInstanceRunner {
194
195
  const workingDir = localContainer.workingDir ? localContainer.workingDir : '/workspace';
195
196
 
196
197
  const customHostConfigs = localContainer.HostConfig ?? {};
198
+ const Binds = customHostConfigs.Binds ?? [];
199
+ delete customHostConfigs.Binds;
197
200
  const customLabels = localContainer.Labels ?? {};
198
201
  const customEnvs = localContainer.Env ?? [];
199
202
  delete localContainer.HostConfig;
@@ -214,7 +217,7 @@ export class BlockInstanceRunner {
214
217
  const realLocalPath = FS.realpathSync(baseDir);
215
218
 
216
219
  const Mounts = containerManager.toDockerMounts({
217
- [workingDir]: toLocalBindVolume(realLocalPath)
220
+ [workingDir]: toLocalBindVolume(realLocalPath),
218
221
  });
219
222
 
220
223
  const systemUri = parseKapetaUri(this._systemId);
@@ -245,10 +248,22 @@ export class BlockInstanceRunner {
245
248
  HostConfig: {
246
249
  ...customHostConfigs,
247
250
  Binds: [
248
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${homeDir}/.kapeta`
251
+ `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${homeDir}/.kapeta`,
252
+ ...Binds.map((bind: string) => {
253
+ let [host, container] = bind.split(':');
254
+ if (host.startsWith('~')) {
255
+ host = OS.homedir() + host.substring(1);
256
+ }
257
+
258
+ if (container.startsWith('~')) {
259
+ container = homeDir + container.substring(1);
260
+ }
261
+
262
+ return `${toLocalBindVolume(host)}:${container}`;
263
+ }),
249
264
  ],
250
265
  PortBindings,
251
- Mounts
266
+ Mounts,
252
267
  },
253
268
  });
254
269
  }