@kapeta/local-cluster-service 0.7.3 → 0.7.5

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.7.5](https://github.com/kapetacom/local-cluster-service/compare/v0.7.4...v0.7.5) (2023-07-17)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Handle homedir on windows ([913fdd4](https://github.com/kapetacom/local-cluster-service/commit/913fdd4f853e4f79848c06afe2aaed72792e9ec5))
7
+
8
+ ## [0.7.4](https://github.com/kapetacom/local-cluster-service/compare/v0.7.3...v0.7.4) (2023-07-17)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Add host.docker.internal on Linux ([#43](https://github.com/kapetacom/local-cluster-service/issues/43)) ([f76eab1](https://github.com/kapetacom/local-cluster-service/commit/f76eab13059bc920026769303b49cf065d48f5ca))
14
+
1
15
  ## [0.7.3](https://github.com/kapetacom/local-cluster-service/compare/v0.7.2...v0.7.3) (2023-07-17)
2
16
 
3
17
 
@@ -27,6 +27,7 @@ declare class ContainerManager {
27
27
  private _docker;
28
28
  private _alive;
29
29
  private _mountDir;
30
+ private _version;
30
31
  constructor();
31
32
  initialize(): Promise<void>;
32
33
  isAlive(): boolean;
@@ -85,6 +86,7 @@ export declare class ContainerInfo {
85
86
  getStatus(): Promise<any>;
86
87
  getPorts(): Promise<PortMap | false>;
87
88
  }
89
+ export declare function getExtraHosts(dockerVersion: string): string[] | undefined;
88
90
  /**
89
91
  * Ensure that the volume is in the correct format for the docker daemon on the host
90
92
  *
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.containerManager = exports.toLocalBindVolume = exports.ContainerInfo = void 0;
6
+ exports.containerManager = exports.toLocalBindVolume = exports.getExtraHosts = exports.ContainerInfo = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const storageService_1 = require("./storageService");
9
9
  const os_1 = __importDefault(require("os"));
@@ -27,9 +27,11 @@ class ContainerManager {
27
27
  _docker;
28
28
  _alive;
29
29
  _mountDir;
30
+ _version;
30
31
  constructor() {
31
32
  this._docker = null;
32
33
  this._alive = false;
34
+ this._version = '';
33
35
  this._mountDir = path_1.default.join(storageService_1.storageService.getKapetaBasedir(), 'mounts');
34
36
  fs_extra_1.default.mkdirpSync(this._mountDir);
35
37
  }
@@ -58,7 +60,10 @@ class ContainerManager {
58
60
  const client = new node_docker_api_1.Docker(opts);
59
61
  await client.ping();
60
62
  this._docker = client;
63
+ const versionInfo = await client.version();
64
+ this._version = versionInfo.Server?.Version;
61
65
  this._alive = true;
66
+ console.log('Connected to docker daemon with version: %s', this._version);
62
67
  return;
63
68
  }
64
69
  catch (err) {
@@ -205,6 +210,16 @@ class ContainerManager {
205
210
  return new ContainerInfo(dockerContainer);
206
211
  }
207
212
  async startContainer(opts) {
213
+ const extraHosts = getExtraHosts(this._version);
214
+ if (extraHosts && extraHosts.length > 0) {
215
+ if (!opts.HostConfig) {
216
+ opts.HostConfig = {};
217
+ }
218
+ if (!opts.HostConfig.ExtraHosts) {
219
+ opts.HostConfig.ExtraHosts = [];
220
+ }
221
+ opts.HostConfig.ExtraHosts = opts.HostConfig.ExtraHosts.concat(extraHosts);
222
+ }
208
223
  const dockerContainer = await this.docker().container.create(opts);
209
224
  await dockerContainer.start();
210
225
  return dockerContainer;
@@ -362,6 +377,20 @@ class ContainerInfo {
362
377
  }
363
378
  }
364
379
  exports.ContainerInfo = ContainerInfo;
380
+ function getExtraHosts(dockerVersion) {
381
+ if (process.platform !== 'darwin' && process.platform !== 'win32') {
382
+ const [major, minor] = dockerVersion.split('.');
383
+ if (parseInt(major) >= 20 && parseInt(minor) >= 10) {
384
+ // Docker 20.10+ on Linux supports adding host.docker.internal to point to host-gateway
385
+ return ['host.docker.internal:host-gateway'];
386
+ }
387
+ // Docker versions lower than 20.10 needs an actual IP address. We use the default network bridge which
388
+ // is always 172.17.0.1
389
+ return ['host.docker.internal:172.17.0.1'];
390
+ }
391
+ return undefined;
392
+ }
393
+ exports.getExtraHosts = getExtraHosts;
365
394
  /**
366
395
  * Ensure that the volume is in the correct format for the docker daemon on the host
367
396
  *
@@ -18,7 +18,6 @@ const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
18
18
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
19
19
  const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
20
20
  const KAPETA_INSTANCE_ID = 'KAPETA_INSTANCE_ID';
21
- const KAPETA_LOCAL_CLUSTER_PORT = 'KAPETA_LOCAL_CLUSTER_PORT';
22
21
  /**
23
22
  * Needed when running local docker containers as part of plan
24
23
  * @type {string[]}
@@ -205,7 +204,7 @@ class BlockInstanceRunner {
205
204
  HostConfig: {
206
205
  Binds: [
207
206
  `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${homeDir}/.kapeta`,
208
- `${(0, containerManager_1.toLocalBindVolume)(baseDir)}:${workingDir}`, //We mount
207
+ `${(0, containerManager_1.toLocalBindVolume)(baseDir)}:${workingDir}`,
209
208
  ],
210
209
  PortBindings,
211
210
  },
@@ -291,6 +290,8 @@ class BlockInstanceRunner {
291
290
  const containerName = `kapeta-block-instance-${blockInstance.id}`;
292
291
  const logs = new LogData_1.LogData();
293
292
  let container = await containerManager_1.containerManager.getContainerByName(containerName);
293
+ // For windows we need to default to root
294
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
294
295
  if (container) {
295
296
  const containerData = container.data;
296
297
  if (containerData.State === 'running') {
@@ -316,7 +317,7 @@ class BlockInstanceRunner {
316
317
  ],
317
318
  HostConfig: {
318
319
  Binds: [
319
- `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${local_cluster_config_1.default.getKapetaBasedir()}`,
320
+ `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`,
320
321
  ],
321
322
  },
322
323
  });
@@ -420,6 +421,8 @@ class BlockInstanceRunner {
420
421
  if (spec.local?.health) {
421
422
  HealthCheck = containerManager_1.containerManager.toDockerHealth(spec.local?.health);
422
423
  }
424
+ // For windows we need to default to root
425
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
423
426
  logs.addLog(`Creating new container for block: ${containerName}`);
424
427
  container = await containerManager_1.containerManager.startContainer({
425
428
  Image: dockerImage,
@@ -429,7 +432,7 @@ class BlockInstanceRunner {
429
432
  HostConfig: {
430
433
  Binds: [
431
434
  `${(0, containerManager_1.toLocalBindVolume)(kapetaYmlPath)}:/kapeta.yml:ro`,
432
- `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${local_cluster_config_1.default.getKapetaBasedir()}`,
435
+ `${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`,
433
436
  ],
434
437
  PortBindings,
435
438
  Mounts,
@@ -27,6 +27,7 @@ declare class ContainerManager {
27
27
  private _docker;
28
28
  private _alive;
29
29
  private _mountDir;
30
+ private _version;
30
31
  constructor();
31
32
  initialize(): Promise<void>;
32
33
  isAlive(): boolean;
@@ -85,6 +86,7 @@ export declare class ContainerInfo {
85
86
  getStatus(): Promise<any>;
86
87
  getPorts(): Promise<PortMap | false>;
87
88
  }
89
+ export declare function getExtraHosts(dockerVersion: string): string[] | undefined;
88
90
  /**
89
91
  * Ensure that the volume is in the correct format for the docker daemon on the host
90
92
  *
@@ -21,9 +21,11 @@ class ContainerManager {
21
21
  _docker;
22
22
  _alive;
23
23
  _mountDir;
24
+ _version;
24
25
  constructor() {
25
26
  this._docker = null;
26
27
  this._alive = false;
28
+ this._version = '';
27
29
  this._mountDir = Path.join(storageService.getKapetaBasedir(), 'mounts');
28
30
  FSExtra.mkdirpSync(this._mountDir);
29
31
  }
@@ -52,7 +54,10 @@ class ContainerManager {
52
54
  const client = new Docker(opts);
53
55
  await client.ping();
54
56
  this._docker = client;
57
+ const versionInfo = await client.version();
58
+ this._version = versionInfo.Server?.Version;
55
59
  this._alive = true;
60
+ console.log('Connected to docker daemon with version: %s', this._version);
56
61
  return;
57
62
  }
58
63
  catch (err) {
@@ -199,6 +204,16 @@ class ContainerManager {
199
204
  return new ContainerInfo(dockerContainer);
200
205
  }
201
206
  async startContainer(opts) {
207
+ const extraHosts = getExtraHosts(this._version);
208
+ if (extraHosts && extraHosts.length > 0) {
209
+ if (!opts.HostConfig) {
210
+ opts.HostConfig = {};
211
+ }
212
+ if (!opts.HostConfig.ExtraHosts) {
213
+ opts.HostConfig.ExtraHosts = [];
214
+ }
215
+ opts.HostConfig.ExtraHosts = opts.HostConfig.ExtraHosts.concat(extraHosts);
216
+ }
202
217
  const dockerContainer = await this.docker().container.create(opts);
203
218
  await dockerContainer.start();
204
219
  return dockerContainer;
@@ -355,6 +370,19 @@ export class ContainerInfo {
355
370
  return ports;
356
371
  }
357
372
  }
373
+ export function getExtraHosts(dockerVersion) {
374
+ if (process.platform !== 'darwin' && process.platform !== 'win32') {
375
+ const [major, minor] = dockerVersion.split('.');
376
+ if (parseInt(major) >= 20 && parseInt(minor) >= 10) {
377
+ // Docker 20.10+ on Linux supports adding host.docker.internal to point to host-gateway
378
+ return ['host.docker.internal:host-gateway'];
379
+ }
380
+ // Docker versions lower than 20.10 needs an actual IP address. We use the default network bridge which
381
+ // is always 172.17.0.1
382
+ return ['host.docker.internal:172.17.0.1'];
383
+ }
384
+ return undefined;
385
+ }
358
386
  /**
359
387
  * Ensure that the volume is in the correct format for the docker daemon on the host
360
388
  *
@@ -12,7 +12,6 @@ const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
12
12
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
13
13
  const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
14
14
  const KAPETA_INSTANCE_ID = 'KAPETA_INSTANCE_ID';
15
- const KAPETA_LOCAL_CLUSTER_PORT = 'KAPETA_LOCAL_CLUSTER_PORT';
16
15
  /**
17
16
  * Needed when running local docker containers as part of plan
18
17
  * @type {string[]}
@@ -199,7 +198,7 @@ export class BlockInstanceRunner {
199
198
  HostConfig: {
200
199
  Binds: [
201
200
  `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${homeDir}/.kapeta`,
202
- `${toLocalBindVolume(baseDir)}:${workingDir}`, //We mount
201
+ `${toLocalBindVolume(baseDir)}:${workingDir}`,
203
202
  ],
204
203
  PortBindings,
205
204
  },
@@ -285,6 +284,8 @@ export class BlockInstanceRunner {
285
284
  const containerName = `kapeta-block-instance-${blockInstance.id}`;
286
285
  const logs = new LogData();
287
286
  let container = await containerManager.getContainerByName(containerName);
287
+ // For windows we need to default to root
288
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
288
289
  if (container) {
289
290
  const containerData = container.data;
290
291
  if (containerData.State === 'running') {
@@ -310,7 +311,7 @@ export class BlockInstanceRunner {
310
311
  ],
311
312
  HostConfig: {
312
313
  Binds: [
313
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${ClusterConfig.getKapetaBasedir()}`,
314
+ `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`,
314
315
  ],
315
316
  },
316
317
  });
@@ -414,6 +415,8 @@ export class BlockInstanceRunner {
414
415
  if (spec.local?.health) {
415
416
  HealthCheck = containerManager.toDockerHealth(spec.local?.health);
416
417
  }
418
+ // For windows we need to default to root
419
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
417
420
  logs.addLog(`Creating new container for block: ${containerName}`);
418
421
  container = await containerManager.startContainer({
419
422
  Image: dockerImage,
@@ -423,7 +426,7 @@ export class BlockInstanceRunner {
423
426
  HostConfig: {
424
427
  Binds: [
425
428
  `${toLocalBindVolume(kapetaYmlPath)}:/kapeta.yml:ro`,
426
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${ClusterConfig.getKapetaBasedir()}`,
429
+ `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`,
427
430
  ],
428
431
  PortBindings,
429
432
  Mounts,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kapeta/local-cluster-service",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "Manages configuration, ports and service discovery for locally running Kapeta systems",
5
5
  "type": "commonjs",
6
6
  "exports": {
@@ -51,10 +51,12 @@ class ContainerManager {
51
51
  private _docker: Docker | null;
52
52
  private _alive: boolean;
53
53
  private _mountDir: string;
54
+ private _version: string;
54
55
 
55
56
  constructor() {
56
57
  this._docker = null;
57
58
  this._alive = false;
59
+ this._version = '';
58
60
  this._mountDir = Path.join(storageService.getKapetaBasedir(), 'mounts');
59
61
  FSExtra.mkdirpSync(this._mountDir);
60
62
  }
@@ -85,7 +87,10 @@ class ContainerManager {
85
87
  const client = new Docker(opts);
86
88
  await client.ping();
87
89
  this._docker = client;
90
+ const versionInfo: any = await client.version();
91
+ this._version = versionInfo.Server?.Version;
88
92
  this._alive = true;
93
+ console.log('Connected to docker daemon with version: %s', this._version);
89
94
  return;
90
95
  } catch (err) {
91
96
  // silently ignore bad configs
@@ -269,6 +274,20 @@ class ContainerManager {
269
274
  }
270
275
 
271
276
  async startContainer(opts: any) {
277
+ const extraHosts = getExtraHosts(this._version);
278
+
279
+ if (extraHosts && extraHosts.length > 0) {
280
+ if (!opts.HostConfig) {
281
+ opts.HostConfig = {};
282
+ }
283
+
284
+ if (!opts.HostConfig.ExtraHosts) {
285
+ opts.HostConfig.ExtraHosts = [];
286
+ }
287
+
288
+ opts.HostConfig.ExtraHosts = opts.HostConfig.ExtraHosts.concat(extraHosts);
289
+ }
290
+
272
291
  const dockerContainer = await this.docker().container.create(opts);
273
292
  await dockerContainer.start();
274
293
  return dockerContainer;
@@ -462,6 +481,21 @@ export class ContainerInfo {
462
481
  }
463
482
  }
464
483
 
484
+ export function getExtraHosts(dockerVersion: string): string[] | undefined {
485
+ if (process.platform !== 'darwin' && process.platform !== 'win32') {
486
+ const [major, minor] = dockerVersion.split('.');
487
+ if (parseInt(major) >= 20 && parseInt(minor) >= 10) {
488
+ // Docker 20.10+ on Linux supports adding host.docker.internal to point to host-gateway
489
+ return ['host.docker.internal:host-gateway'];
490
+ }
491
+ // Docker versions lower than 20.10 needs an actual IP address. We use the default network bridge which
492
+ // is always 172.17.0.1
493
+ return ['host.docker.internal:172.17.0.1'];
494
+ }
495
+
496
+ return undefined;
497
+ }
498
+
465
499
  /**
466
500
  * Ensure that the volume is in the correct format for the docker daemon on the host
467
501
  *
@@ -15,7 +15,7 @@ const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
15
15
  const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
16
16
  const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
17
17
  const KAPETA_INSTANCE_ID = 'KAPETA_INSTANCE_ID';
18
- const KAPETA_LOCAL_CLUSTER_PORT = 'KAPETA_LOCAL_CLUSTER_PORT';
18
+
19
19
  /**
20
20
  * Needed when running local docker containers as part of plan
21
21
  * @type {string[]}
@@ -248,7 +248,7 @@ export class BlockInstanceRunner {
248
248
  HostConfig: {
249
249
  Binds: [
250
250
  `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${homeDir}/.kapeta`,
251
- `${toLocalBindVolume(baseDir)}:${workingDir}`, //We mount
251
+ `${toLocalBindVolume(baseDir)}:${workingDir}`,
252
252
  ],
253
253
  PortBindings,
254
254
  },
@@ -352,6 +352,9 @@ export class BlockInstanceRunner {
352
352
  const logs = new LogData();
353
353
  let container = await containerManager.getContainerByName(containerName);
354
354
 
355
+ // For windows we need to default to root
356
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
357
+
355
358
  if (container) {
356
359
  const containerData = container.data as any;
357
360
  if (containerData.State === 'running') {
@@ -362,6 +365,7 @@ export class BlockInstanceRunner {
362
365
  }
363
366
  } else {
364
367
  logs.addLog(`Creating new container for block: ${containerName}`);
368
+
365
369
  container = await containerManager.startContainer({
366
370
  Image: dockerImage,
367
371
  name: containerName,
@@ -375,7 +379,7 @@ export class BlockInstanceRunner {
375
379
  ],
376
380
  HostConfig: {
377
381
  Binds: [
378
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${ClusterConfig.getKapetaBasedir()}`,
382
+ `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`,
379
383
  ],
380
384
  },
381
385
  });
@@ -502,6 +506,9 @@ export class BlockInstanceRunner {
502
506
  HealthCheck = containerManager.toDockerHealth(spec.local?.health);
503
507
  }
504
508
 
509
+ // For windows we need to default to root
510
+ const innerHome = process.platform === 'win32' ? '/root/.kapeta' : ClusterConfig.getKapetaBasedir();
511
+
505
512
  logs.addLog(`Creating new container for block: ${containerName}`);
506
513
  container = await containerManager.startContainer({
507
514
  Image: dockerImage,
@@ -511,7 +518,7 @@ export class BlockInstanceRunner {
511
518
  HostConfig: {
512
519
  Binds: [
513
520
  `${toLocalBindVolume(kapetaYmlPath)}:/kapeta.yml:ro`,
514
- `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${ClusterConfig.getKapetaBasedir()}`,
521
+ `${toLocalBindVolume(ClusterConfig.getKapetaBasedir())}:${innerHome}`,
515
522
  ],
516
523
  PortBindings,
517
524
  Mounts,