@kapeta/local-cluster-service 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/cjs/src/containerManager.d.ts +1 -1
- package/dist/cjs/src/containerManager.js +3 -14
- package/dist/cjs/src/instanceManager.js +8 -2
- package/dist/cjs/src/instances/routes.js +2 -0
- package/dist/cjs/src/operatorManager.js +1 -0
- package/dist/cjs/src/utils/BlockInstanceRunner.js +0 -1
- package/dist/esm/src/containerManager.d.ts +1 -1
- package/dist/esm/src/containerManager.js +3 -14
- package/dist/esm/src/instanceManager.js +8 -2
- package/dist/esm/src/instances/routes.js +2 -0
- package/dist/esm/src/operatorManager.js +1 -0
- package/dist/esm/src/utils/BlockInstanceRunner.js +0 -1
- package/package.json +1 -1
- package/src/containerManager.ts +4 -18
- package/src/instanceManager.ts +13 -3
- package/src/instances/routes.ts +2 -0
- package/src/operatorManager.ts +2 -0
- package/src/utils/BlockInstanceRunner.ts +0 -2
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## [0.12.1](https://github.com/kapetacom/local-cluster-service/compare/v0.12.0...v0.12.1) (2023-08-02)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* Adjustments to make starting plans locally smoother ([fc353ad](https://github.com/kapetacom/local-cluster-service/commit/fc353adde350b7e9d4c7eb9347c4cfa0c3a6aa58))
|
7
|
+
|
1
8
|
# [0.12.0](https://github.com/kapetacom/local-cluster-service/compare/v0.11.1...v0.12.0) (2023-07-31)
|
2
9
|
|
3
10
|
|
@@ -59,7 +59,7 @@ declare class ContainerManager {
|
|
59
59
|
ping(): Promise<void>;
|
60
60
|
docker(): Docker;
|
61
61
|
getContainerByName(containerName: string): Promise<ContainerInfo | undefined>;
|
62
|
-
pull(image: string
|
62
|
+
pull(image: string): Promise<boolean>;
|
63
63
|
toDockerMounts(mounts: StringMap): DockerMounts[];
|
64
64
|
toDockerHealth(health: Health): {
|
65
65
|
Test: string[];
|
@@ -22,8 +22,6 @@ exports.CONTAINER_LABEL_PORT_PREFIX = 'kapeta_port-';
|
|
22
22
|
const NANO_SECOND = 1000000;
|
23
23
|
const HEALTH_CHECK_INTERVAL = 3000;
|
24
24
|
const HEALTH_CHECK_MAX = 20;
|
25
|
-
const IMAGE_PULL_CACHE_TTL = 30 * 60 * 1000;
|
26
|
-
const IMAGE_PULL_CACHE = {};
|
27
25
|
exports.HEALTH_CHECK_TIMEOUT = HEALTH_CHECK_INTERVAL * HEALTH_CHECK_MAX * 2;
|
28
26
|
const promisifyStream = (stream, handler) => new Promise((resolve, reject) => {
|
29
27
|
stream.on('data', handler);
|
@@ -151,17 +149,11 @@ class ContainerManager {
|
|
151
149
|
}
|
152
150
|
return undefined;
|
153
151
|
}
|
154
|
-
async pull(image
|
152
|
+
async pull(image) {
|
155
153
|
let [imageName, tag] = image.split(/:/);
|
156
154
|
if (!tag) {
|
157
155
|
tag = 'latest';
|
158
156
|
}
|
159
|
-
if (IMAGE_PULL_CACHE[image]) {
|
160
|
-
const timeSince = Date.now() - IMAGE_PULL_CACHE[image];
|
161
|
-
if (timeSince < cacheForMS) {
|
162
|
-
return false;
|
163
|
-
}
|
164
|
-
}
|
165
157
|
const imageTagList = (await this.docker().image.list())
|
166
158
|
.map((image) => image.data)
|
167
159
|
.filter((imageData) => !!imageData.RepoTags)
|
@@ -171,7 +163,7 @@ class ContainerManager {
|
|
171
163
|
return false;
|
172
164
|
}
|
173
165
|
const timeStarted = Date.now();
|
174
|
-
socketManager_1.socketManager.emitGlobal(EVENT_IMAGE_PULL, { image, percent:
|
166
|
+
socketManager_1.socketManager.emitGlobal(EVENT_IMAGE_PULL, { image, percent: -1 });
|
175
167
|
const api = new nodejs_api_client_1.KapetaAPI();
|
176
168
|
const accessToken = await api.getAccessToken();
|
177
169
|
const auth = image.startsWith('docker.kapeta.com/')
|
@@ -283,7 +275,6 @@ class ContainerManager {
|
|
283
275
|
lastEmitted = Date.now();
|
284
276
|
//console.log('Pulling image %s: %s % [done: %s, total: %s]', image, Math.round(percent), totals.done, totals.total);
|
285
277
|
});
|
286
|
-
IMAGE_PULL_CACHE[image] = Date.now();
|
287
278
|
socketManager_1.socketManager.emitGlobal(EVENT_IMAGE_PULL, { image, percent: 100, timeTaken: Date.now() - timeStarted });
|
288
279
|
return true;
|
289
280
|
}
|
@@ -319,9 +310,7 @@ class ContainerManager {
|
|
319
310
|
dockerOpts.Labels.HASH = hash;
|
320
311
|
}
|
321
312
|
async ensureContainer(opts) {
|
322
|
-
|
323
|
-
await this.waitForReady(container);
|
324
|
-
return container;
|
313
|
+
return await this.createOrUpdateContainer(opts);
|
325
314
|
}
|
326
315
|
async createOrUpdateContainer(opts) {
|
327
316
|
let imagePulled = await this.pull(opts.Image);
|
@@ -55,7 +55,13 @@ class InstanceManager {
|
|
55
55
|
return [];
|
56
56
|
}
|
57
57
|
systemId = (0, utils_1.normalizeKapetaUri)(systemId);
|
58
|
-
|
58
|
+
const planInfo = definitionsManager_1.definitionsManager.getDefinition(systemId);
|
59
|
+
if (!planInfo) {
|
60
|
+
return [];
|
61
|
+
}
|
62
|
+
const plan = planInfo.definition;
|
63
|
+
const instanceIds = plan.spec.blocks.map((block) => block.id);
|
64
|
+
return this._instances.filter((instance) => instance.systemId === systemId && instanceIds.includes(instance.instanceId));
|
59
65
|
}
|
60
66
|
getInstance(systemId, instanceId) {
|
61
67
|
systemId = (0, utils_1.normalizeKapetaUri)(systemId);
|
@@ -393,7 +399,7 @@ class InstanceManager {
|
|
393
399
|
];
|
394
400
|
const out = await this.saveInternalInstance({
|
395
401
|
...instance,
|
396
|
-
type: types_1.InstanceType.
|
402
|
+
type: types_1.InstanceType.UNKNOWN,
|
397
403
|
pid: null,
|
398
404
|
health: null,
|
399
405
|
portType: DEFAULT_HEALTH_PORT_TYPE,
|
@@ -122,8 +122,10 @@ router.put('/', async (req, res) => {
|
|
122
122
|
const oldInstance = instanceManager_1.instanceManager.getInstance(req.kapeta.systemId, req.kapeta.instanceId);
|
123
123
|
if (oldInstance) {
|
124
124
|
instance.pid = oldInstance.pid;
|
125
|
+
instance.desiredStatus = oldInstance.desiredStatus;
|
125
126
|
}
|
126
127
|
instance.type = types_1.InstanceType.DOCKER;
|
128
|
+
instance.owner = types_1.InstanceOwner.INTERNAL;
|
127
129
|
}
|
128
130
|
else {
|
129
131
|
// Coming from user starting the instance outside of kapeta
|
@@ -324,7 +324,6 @@ class BlockInstanceRunner {
|
|
324
324
|
}
|
325
325
|
async ensureContainer(opts) {
|
326
326
|
const container = await containerManager_1.containerManager.ensureContainer(opts);
|
327
|
-
await containerManager_1.containerManager.waitForReady(container);
|
328
327
|
return this._handleContainer(container);
|
329
328
|
}
|
330
329
|
async _handleContainer(container) {
|
@@ -59,7 +59,7 @@ declare class ContainerManager {
|
|
59
59
|
ping(): Promise<void>;
|
60
60
|
docker(): Docker;
|
61
61
|
getContainerByName(containerName: string): Promise<ContainerInfo | undefined>;
|
62
|
-
pull(image: string
|
62
|
+
pull(image: string): Promise<boolean>;
|
63
63
|
toDockerMounts(mounts: StringMap): DockerMounts[];
|
64
64
|
toDockerHealth(health: Health): {
|
65
65
|
Test: string[];
|
@@ -16,8 +16,6 @@ export const CONTAINER_LABEL_PORT_PREFIX = 'kapeta_port-';
|
|
16
16
|
const NANO_SECOND = 1000000;
|
17
17
|
const HEALTH_CHECK_INTERVAL = 3000;
|
18
18
|
const HEALTH_CHECK_MAX = 20;
|
19
|
-
const IMAGE_PULL_CACHE_TTL = 30 * 60 * 1000;
|
20
|
-
const IMAGE_PULL_CACHE = {};
|
21
19
|
export const HEALTH_CHECK_TIMEOUT = HEALTH_CHECK_INTERVAL * HEALTH_CHECK_MAX * 2;
|
22
20
|
const promisifyStream = (stream, handler) => new Promise((resolve, reject) => {
|
23
21
|
stream.on('data', handler);
|
@@ -145,17 +143,11 @@ class ContainerManager {
|
|
145
143
|
}
|
146
144
|
return undefined;
|
147
145
|
}
|
148
|
-
async pull(image
|
146
|
+
async pull(image) {
|
149
147
|
let [imageName, tag] = image.split(/:/);
|
150
148
|
if (!tag) {
|
151
149
|
tag = 'latest';
|
152
150
|
}
|
153
|
-
if (IMAGE_PULL_CACHE[image]) {
|
154
|
-
const timeSince = Date.now() - IMAGE_PULL_CACHE[image];
|
155
|
-
if (timeSince < cacheForMS) {
|
156
|
-
return false;
|
157
|
-
}
|
158
|
-
}
|
159
151
|
const imageTagList = (await this.docker().image.list())
|
160
152
|
.map((image) => image.data)
|
161
153
|
.filter((imageData) => !!imageData.RepoTags)
|
@@ -165,7 +157,7 @@ class ContainerManager {
|
|
165
157
|
return false;
|
166
158
|
}
|
167
159
|
const timeStarted = Date.now();
|
168
|
-
socketManager.emitGlobal(EVENT_IMAGE_PULL, { image, percent:
|
160
|
+
socketManager.emitGlobal(EVENT_IMAGE_PULL, { image, percent: -1 });
|
169
161
|
const api = new KapetaAPI();
|
170
162
|
const accessToken = await api.getAccessToken();
|
171
163
|
const auth = image.startsWith('docker.kapeta.com/')
|
@@ -277,7 +269,6 @@ class ContainerManager {
|
|
277
269
|
lastEmitted = Date.now();
|
278
270
|
//console.log('Pulling image %s: %s % [done: %s, total: %s]', image, Math.round(percent), totals.done, totals.total);
|
279
271
|
});
|
280
|
-
IMAGE_PULL_CACHE[image] = Date.now();
|
281
272
|
socketManager.emitGlobal(EVENT_IMAGE_PULL, { image, percent: 100, timeTaken: Date.now() - timeStarted });
|
282
273
|
return true;
|
283
274
|
}
|
@@ -313,9 +304,7 @@ class ContainerManager {
|
|
313
304
|
dockerOpts.Labels.HASH = hash;
|
314
305
|
}
|
315
306
|
async ensureContainer(opts) {
|
316
|
-
|
317
|
-
await this.waitForReady(container);
|
318
|
-
return container;
|
307
|
+
return await this.createOrUpdateContainer(opts);
|
319
308
|
}
|
320
309
|
async createOrUpdateContainer(opts) {
|
321
310
|
let imagePulled = await this.pull(opts.Image);
|
@@ -49,7 +49,13 @@ export class InstanceManager {
|
|
49
49
|
return [];
|
50
50
|
}
|
51
51
|
systemId = normalizeKapetaUri(systemId);
|
52
|
-
|
52
|
+
const planInfo = definitionsManager.getDefinition(systemId);
|
53
|
+
if (!planInfo) {
|
54
|
+
return [];
|
55
|
+
}
|
56
|
+
const plan = planInfo.definition;
|
57
|
+
const instanceIds = plan.spec.blocks.map((block) => block.id);
|
58
|
+
return this._instances.filter((instance) => instance.systemId === systemId && instanceIds.includes(instance.instanceId));
|
53
59
|
}
|
54
60
|
getInstance(systemId, instanceId) {
|
55
61
|
systemId = normalizeKapetaUri(systemId);
|
@@ -387,7 +393,7 @@ export class InstanceManager {
|
|
387
393
|
];
|
388
394
|
const out = await this.saveInternalInstance({
|
389
395
|
...instance,
|
390
|
-
type: InstanceType.
|
396
|
+
type: InstanceType.UNKNOWN,
|
391
397
|
pid: null,
|
392
398
|
health: null,
|
393
399
|
portType: DEFAULT_HEALTH_PORT_TYPE,
|
@@ -117,8 +117,10 @@ router.put('/', async (req, res) => {
|
|
117
117
|
const oldInstance = instanceManager.getInstance(req.kapeta.systemId, req.kapeta.instanceId);
|
118
118
|
if (oldInstance) {
|
119
119
|
instance.pid = oldInstance.pid;
|
120
|
+
instance.desiredStatus = oldInstance.desiredStatus;
|
120
121
|
}
|
121
122
|
instance.type = InstanceType.DOCKER;
|
123
|
+
instance.owner = InstanceOwner.INTERNAL;
|
122
124
|
}
|
123
125
|
else {
|
124
126
|
// Coming from user starting the instance outside of kapeta
|
@@ -318,7 +318,6 @@ export class BlockInstanceRunner {
|
|
318
318
|
}
|
319
319
|
async ensureContainer(opts) {
|
320
320
|
const container = await containerManager.ensureContainer(opts);
|
321
|
-
await containerManager.waitForReady(container);
|
322
321
|
return this._handleContainer(container);
|
323
322
|
}
|
324
323
|
async _handleContainer(container) {
|
package/package.json
CHANGED
package/src/containerManager.ts
CHANGED
@@ -66,8 +66,7 @@ export const CONTAINER_LABEL_PORT_PREFIX = 'kapeta_port-';
|
|
66
66
|
const NANO_SECOND = 1000000;
|
67
67
|
const HEALTH_CHECK_INTERVAL = 3000;
|
68
68
|
const HEALTH_CHECK_MAX = 20;
|
69
|
-
|
70
|
-
const IMAGE_PULL_CACHE: { [key: string]: number } = {};
|
69
|
+
|
71
70
|
|
72
71
|
export const HEALTH_CHECK_TIMEOUT = HEALTH_CHECK_INTERVAL * HEALTH_CHECK_MAX * 2;
|
73
72
|
|
@@ -223,19 +222,12 @@ class ContainerManager {
|
|
223
222
|
return undefined;
|
224
223
|
}
|
225
224
|
|
226
|
-
async pull(image: string
|
225
|
+
async pull(image: string) {
|
227
226
|
let [imageName, tag] = image.split(/:/);
|
228
227
|
if (!tag) {
|
229
228
|
tag = 'latest';
|
230
229
|
}
|
231
230
|
|
232
|
-
if (IMAGE_PULL_CACHE[image]) {
|
233
|
-
const timeSince = Date.now() - IMAGE_PULL_CACHE[image];
|
234
|
-
if (timeSince < cacheForMS) {
|
235
|
-
return false;
|
236
|
-
}
|
237
|
-
}
|
238
|
-
|
239
231
|
const imageTagList = (await this.docker().image.list())
|
240
232
|
.map((image) => image.data as any)
|
241
233
|
.filter((imageData) => !!imageData.RepoTags)
|
@@ -247,7 +239,7 @@ class ContainerManager {
|
|
247
239
|
}
|
248
240
|
|
249
241
|
const timeStarted = Date.now();
|
250
|
-
socketManager.emitGlobal(EVENT_IMAGE_PULL, { image, percent:
|
242
|
+
socketManager.emitGlobal(EVENT_IMAGE_PULL, { image, percent: -1 });
|
251
243
|
|
252
244
|
const api = new KapetaAPI();
|
253
245
|
const accessToken = await api.getAccessToken();
|
@@ -390,8 +382,6 @@ class ContainerManager {
|
|
390
382
|
//console.log('Pulling image %s: %s % [done: %s, total: %s]', image, Math.round(percent), totals.done, totals.total);
|
391
383
|
});
|
392
384
|
|
393
|
-
IMAGE_PULL_CACHE[image] = Date.now();
|
394
|
-
|
395
385
|
socketManager.emitGlobal(EVENT_IMAGE_PULL, { image, percent: 100, timeTaken: Date.now() - timeStarted });
|
396
386
|
|
397
387
|
return true;
|
@@ -435,11 +425,7 @@ class ContainerManager {
|
|
435
425
|
}
|
436
426
|
|
437
427
|
public async ensureContainer(opts: any) {
|
438
|
-
|
439
|
-
|
440
|
-
await this.waitForReady(container);
|
441
|
-
|
442
|
-
return container;
|
428
|
+
return await this.createOrUpdateContainer(opts);
|
443
429
|
}
|
444
430
|
|
445
431
|
private async createOrUpdateContainer(opts: any) {
|
package/src/instanceManager.ts
CHANGED
@@ -9,7 +9,7 @@ import { assetManager } from './assetManager';
|
|
9
9
|
import { containerManager, HEALTH_CHECK_TIMEOUT } from './containerManager';
|
10
10
|
import { configManager } from './configManager';
|
11
11
|
import { DesiredInstanceStatus, InstanceInfo, InstanceOwner, InstanceStatus, InstanceType, LogEntry } from './types';
|
12
|
-
import {
|
12
|
+
import {BlockDefinitionSpec, BlockInstance, Plan} from '@kapeta/schemas';
|
13
13
|
import { getBlockInstanceContainerName, normalizeKapetaUri } from './utils/utils';
|
14
14
|
import { KIND_OPERATOR, operatorManager } from './operatorManager';
|
15
15
|
import { parseKapetaUri } from '@kapeta/nodejs-utils';
|
@@ -64,7 +64,17 @@ export class InstanceManager {
|
|
64
64
|
|
65
65
|
systemId = normalizeKapetaUri(systemId);
|
66
66
|
|
67
|
-
|
67
|
+
const planInfo = definitionsManager.getDefinition(systemId);
|
68
|
+
|
69
|
+
if (!planInfo) {
|
70
|
+
return [];
|
71
|
+
}
|
72
|
+
|
73
|
+
const plan = planInfo.definition as Plan;
|
74
|
+
|
75
|
+
const instanceIds = plan.spec.blocks.map((block) => block.id);
|
76
|
+
|
77
|
+
return this._instances.filter((instance) => instance.systemId === systemId && instanceIds.includes(instance.instanceId));
|
68
78
|
}
|
69
79
|
|
70
80
|
public getInstance(systemId: string, instanceId: string) {
|
@@ -482,7 +492,7 @@ export class InstanceManager {
|
|
482
492
|
|
483
493
|
const out = await this.saveInternalInstance({
|
484
494
|
...instance,
|
485
|
-
type: InstanceType.
|
495
|
+
type: InstanceType.UNKNOWN,
|
486
496
|
pid: null,
|
487
497
|
health: null,
|
488
498
|
portType: DEFAULT_HEALTH_PORT_TYPE,
|
package/src/instances/routes.ts
CHANGED
@@ -146,8 +146,10 @@ router.put('/', async (req: KapetaBodyRequest, res: Response) => {
|
|
146
146
|
const oldInstance = instanceManager.getInstance(req.kapeta!.systemId, req.kapeta!.instanceId);
|
147
147
|
if (oldInstance) {
|
148
148
|
instance.pid = oldInstance.pid;
|
149
|
+
instance.desiredStatus = oldInstance.desiredStatus;
|
149
150
|
}
|
150
151
|
instance.type = InstanceType.DOCKER;
|
152
|
+
instance.owner = InstanceOwner.INTERNAL;
|
151
153
|
} else {
|
152
154
|
// Coming from user starting the instance outside of kapeta
|
153
155
|
instance.type = InstanceType.LOCAL;
|
package/src/operatorManager.ts
CHANGED
@@ -415,8 +415,6 @@ export class BlockInstanceRunner {
|
|
415
415
|
private async ensureContainer(opts: any) {
|
416
416
|
const container = await containerManager.ensureContainer(opts);
|
417
417
|
|
418
|
-
await containerManager.waitForReady(container);
|
419
|
-
|
420
418
|
return this._handleContainer(container);
|
421
419
|
}
|
422
420
|
|