@kapeta/local-cluster-service 0.32.0 → 0.32.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/RepositoryWatcher.js +30 -6
- package/dist/cjs/src/assetManager.js +5 -2
- package/dist/cjs/src/definitionsManager.js +2 -2
- package/dist/cjs/src/instanceManager.js +2 -2
- package/dist/cjs/src/repositoryManager.js +1 -1
- package/dist/esm/src/RepositoryWatcher.js +30 -6
- package/dist/esm/src/assetManager.js +5 -2
- package/dist/esm/src/definitionsManager.js +2 -2
- package/dist/esm/src/instanceManager.js +2 -2
- package/dist/esm/src/repositoryManager.js +1 -1
- package/package.json +1 -1
- package/src/RepositoryWatcher.ts +34 -6
- package/src/assetManager.ts +5 -1
- package/src/definitionsManager.ts +2 -2
- package/src/instanceManager.ts +2 -2
- package/src/repositoryManager.ts +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## [0.32.1](https://github.com/kapetacom/local-cluster-service/compare/v0.32.0...v0.32.1) (2023-12-23)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* Several smaller fixes ([4036345](https://github.com/kapetacom/local-cluster-service/commit/40363457597d36c97481e94e646a6b45d113bb09))
|
7
|
+
|
1
8
|
# [0.32.0](https://github.com/kapetacom/local-cluster-service/compare/v0.31.0...v0.32.0) (2023-12-20)
|
2
9
|
|
3
10
|
|
@@ -20,6 +20,24 @@ const cacheManager_1 = require("./cacheManager");
|
|
20
20
|
const node_events_1 = require("node:events");
|
21
21
|
const assetManager_1 = require("./assetManager");
|
22
22
|
const KAPETA_YML_RX = /^kapeta.ya?ml$/;
|
23
|
+
let definitions;
|
24
|
+
let definitionTimeout;
|
25
|
+
function getDefinitionsDebounced() {
|
26
|
+
if (definitionTimeout) {
|
27
|
+
clearTimeout(definitionTimeout);
|
28
|
+
definitionTimeout = undefined;
|
29
|
+
}
|
30
|
+
if (!definitions) {
|
31
|
+
definitions = local_cluster_config_1.default.getDefinitions();
|
32
|
+
}
|
33
|
+
else {
|
34
|
+
definitionTimeout = setTimeout(() => {
|
35
|
+
definitionTimeout = undefined;
|
36
|
+
definitions = undefined;
|
37
|
+
}, 500);
|
38
|
+
}
|
39
|
+
return definitions;
|
40
|
+
}
|
23
41
|
class RepositoryWatcher extends node_events_1.EventEmitter {
|
24
42
|
watcher;
|
25
43
|
disabled = false;
|
@@ -186,7 +204,7 @@ class RepositoryWatcher extends node_events_1.EventEmitter {
|
|
186
204
|
}
|
187
205
|
async checkForChange(assetIdentity, sourceOfChange) {
|
188
206
|
const ymlPath = node_path_1.default.join(this.getRepositoryPath(assetIdentity), 'kapeta.yml');
|
189
|
-
const newDefinitions =
|
207
|
+
const newDefinitions = getDefinitionsDebounced();
|
190
208
|
const newDefinition = newDefinitions.find((d) => d.ymlPath === ymlPath);
|
191
209
|
let currentDefinition = this.allDefinitions.find((d) => d.ymlPath === ymlPath);
|
192
210
|
const ymlExists = await this.exists(ymlPath);
|
@@ -265,11 +283,17 @@ class RepositoryWatcher extends node_events_1.EventEmitter {
|
|
265
283
|
}
|
266
284
|
catch (e) { }
|
267
285
|
if (symbolicLink) {
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
286
|
+
try {
|
287
|
+
const realPath = node_path_1.default.join(await fs_extra_1.default.realpath(path), 'kapeta.yml');
|
288
|
+
if (await this.exists(realPath)) {
|
289
|
+
//console.log('Watching symlink target %s => %s', path, realPath);
|
290
|
+
this.watcher?.add(realPath);
|
291
|
+
this.symbolicLinks[path] = realPath;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
catch (e) {
|
295
|
+
// Remove the symlink - it's broken
|
296
|
+
await fs_extra_1.default.remove(path);
|
273
297
|
}
|
274
298
|
}
|
275
299
|
}
|
@@ -24,10 +24,13 @@ const node_os_1 = __importDefault(require("node:os"));
|
|
24
24
|
const CACHE_TTL = 60 * 60 * 1000; // 1 hour
|
25
25
|
const UPGRADE_CHECK_INTERVAL = 10 * 60 * 1000; // 10 minutes
|
26
26
|
const toKey = (ref) => `assetManager:asset:${ref}`;
|
27
|
+
function filterExists(asset) {
|
28
|
+
return fs_extra_1.default.existsSync(asset.path);
|
29
|
+
}
|
27
30
|
function enrichAsset(asset) {
|
28
31
|
return {
|
29
32
|
ref: `kapeta://${asset.definition.metadata.name}:${asset.version}`,
|
30
|
-
editable: asset.version === 'local',
|
33
|
+
editable: asset.version === 'local', //Only local versions are editable
|
31
34
|
exists: true,
|
32
35
|
version: asset.version,
|
33
36
|
kind: asset.definition.kind,
|
@@ -81,7 +84,7 @@ class AssetManager {
|
|
81
84
|
assetKinds.push('core/plan');
|
82
85
|
}
|
83
86
|
const assets = await definitionsManager_1.definitionsManager.getDefinitions(assetKinds);
|
84
|
-
return assets.map(enrichAsset);
|
87
|
+
return assets.filter(filterExists).map(enrichAsset);
|
85
88
|
}
|
86
89
|
async getPlans() {
|
87
90
|
return this.getAssets(['core/plan']);
|
@@ -131,9 +131,9 @@ class DefinitionsManager {
|
|
131
131
|
const definitions = await this.getDefinitions();
|
132
132
|
return definitions.find((d) => {
|
133
133
|
if (!uri.version) {
|
134
|
-
return d.definition.metadata.name === uri.fullName;
|
134
|
+
return d.definition.metadata.name.toLowerCase() === uri.fullName.toLowerCase();
|
135
135
|
}
|
136
|
-
return (0, nodejs_utils_1.parseKapetaUri)(`${d.definition.metadata.name}:${d.version}`).
|
136
|
+
return (0, nodejs_utils_1.parseKapetaUri)(`${d.definition.metadata.name}:${d.version}`).equals(uri);
|
137
137
|
});
|
138
138
|
}
|
139
139
|
async getLatestDefinition(name) {
|
@@ -25,7 +25,7 @@ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
|
25
25
|
const definitionsManager_1 = require("./definitionsManager");
|
26
26
|
const taskManager_1 = require("./taskManager");
|
27
27
|
const CHECK_INTERVAL = 5000;
|
28
|
-
const DEFAULT_HEALTH_PORT_TYPE = '
|
28
|
+
const DEFAULT_HEALTH_PORT_TYPE = 'http';
|
29
29
|
const MIN_TIME_RUNNING = 30000; //If something didnt run for more than 30 secs - it failed
|
30
30
|
class InstanceManager {
|
31
31
|
_interval = undefined;
|
@@ -198,7 +198,7 @@ class InstanceManager {
|
|
198
198
|
}
|
199
199
|
getHealthUrl(info, address) {
|
200
200
|
let healthUrl = null;
|
201
|
-
let health = info.health;
|
201
|
+
let health = info.health ?? '/.kapeta/health';
|
202
202
|
if (health) {
|
203
203
|
if (health.startsWith('/')) {
|
204
204
|
health = health.substring(1);
|
@@ -183,7 +183,7 @@ class RepositoryManager extends node_events_1.EventEmitter {
|
|
183
183
|
if (await definitionsManager_1.definitionsManager.exists(ref)) {
|
184
184
|
return;
|
185
185
|
}
|
186
|
-
throw new Error(`Failed to
|
186
|
+
throw new Error(`Failed to find asset after installation: ${ref}. Please try again`);
|
187
187
|
};
|
188
188
|
};
|
189
189
|
const tasks = [];
|
@@ -20,6 +20,24 @@ const cacheManager_1 = require("./cacheManager");
|
|
20
20
|
const node_events_1 = require("node:events");
|
21
21
|
const assetManager_1 = require("./assetManager");
|
22
22
|
const KAPETA_YML_RX = /^kapeta.ya?ml$/;
|
23
|
+
let definitions;
|
24
|
+
let definitionTimeout;
|
25
|
+
function getDefinitionsDebounced() {
|
26
|
+
if (definitionTimeout) {
|
27
|
+
clearTimeout(definitionTimeout);
|
28
|
+
definitionTimeout = undefined;
|
29
|
+
}
|
30
|
+
if (!definitions) {
|
31
|
+
definitions = local_cluster_config_1.default.getDefinitions();
|
32
|
+
}
|
33
|
+
else {
|
34
|
+
definitionTimeout = setTimeout(() => {
|
35
|
+
definitionTimeout = undefined;
|
36
|
+
definitions = undefined;
|
37
|
+
}, 500);
|
38
|
+
}
|
39
|
+
return definitions;
|
40
|
+
}
|
23
41
|
class RepositoryWatcher extends node_events_1.EventEmitter {
|
24
42
|
watcher;
|
25
43
|
disabled = false;
|
@@ -186,7 +204,7 @@ class RepositoryWatcher extends node_events_1.EventEmitter {
|
|
186
204
|
}
|
187
205
|
async checkForChange(assetIdentity, sourceOfChange) {
|
188
206
|
const ymlPath = node_path_1.default.join(this.getRepositoryPath(assetIdentity), 'kapeta.yml');
|
189
|
-
const newDefinitions =
|
207
|
+
const newDefinitions = getDefinitionsDebounced();
|
190
208
|
const newDefinition = newDefinitions.find((d) => d.ymlPath === ymlPath);
|
191
209
|
let currentDefinition = this.allDefinitions.find((d) => d.ymlPath === ymlPath);
|
192
210
|
const ymlExists = await this.exists(ymlPath);
|
@@ -265,11 +283,17 @@ class RepositoryWatcher extends node_events_1.EventEmitter {
|
|
265
283
|
}
|
266
284
|
catch (e) { }
|
267
285
|
if (symbolicLink) {
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
286
|
+
try {
|
287
|
+
const realPath = node_path_1.default.join(await fs_extra_1.default.realpath(path), 'kapeta.yml');
|
288
|
+
if (await this.exists(realPath)) {
|
289
|
+
//console.log('Watching symlink target %s => %s', path, realPath);
|
290
|
+
this.watcher?.add(realPath);
|
291
|
+
this.symbolicLinks[path] = realPath;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
catch (e) {
|
295
|
+
// Remove the symlink - it's broken
|
296
|
+
await fs_extra_1.default.remove(path);
|
273
297
|
}
|
274
298
|
}
|
275
299
|
}
|
@@ -24,10 +24,13 @@ const node_os_1 = __importDefault(require("node:os"));
|
|
24
24
|
const CACHE_TTL = 60 * 60 * 1000; // 1 hour
|
25
25
|
const UPGRADE_CHECK_INTERVAL = 10 * 60 * 1000; // 10 minutes
|
26
26
|
const toKey = (ref) => `assetManager:asset:${ref}`;
|
27
|
+
function filterExists(asset) {
|
28
|
+
return fs_extra_1.default.existsSync(asset.path);
|
29
|
+
}
|
27
30
|
function enrichAsset(asset) {
|
28
31
|
return {
|
29
32
|
ref: `kapeta://${asset.definition.metadata.name}:${asset.version}`,
|
30
|
-
editable: asset.version === 'local',
|
33
|
+
editable: asset.version === 'local', //Only local versions are editable
|
31
34
|
exists: true,
|
32
35
|
version: asset.version,
|
33
36
|
kind: asset.definition.kind,
|
@@ -81,7 +84,7 @@ class AssetManager {
|
|
81
84
|
assetKinds.push('core/plan');
|
82
85
|
}
|
83
86
|
const assets = await definitionsManager_1.definitionsManager.getDefinitions(assetKinds);
|
84
|
-
return assets.map(enrichAsset);
|
87
|
+
return assets.filter(filterExists).map(enrichAsset);
|
85
88
|
}
|
86
89
|
async getPlans() {
|
87
90
|
return this.getAssets(['core/plan']);
|
@@ -131,9 +131,9 @@ class DefinitionsManager {
|
|
131
131
|
const definitions = await this.getDefinitions();
|
132
132
|
return definitions.find((d) => {
|
133
133
|
if (!uri.version) {
|
134
|
-
return d.definition.metadata.name === uri.fullName;
|
134
|
+
return d.definition.metadata.name.toLowerCase() === uri.fullName.toLowerCase();
|
135
135
|
}
|
136
|
-
return (0, nodejs_utils_1.parseKapetaUri)(`${d.definition.metadata.name}:${d.version}`).
|
136
|
+
return (0, nodejs_utils_1.parseKapetaUri)(`${d.definition.metadata.name}:${d.version}`).equals(uri);
|
137
137
|
});
|
138
138
|
}
|
139
139
|
async getLatestDefinition(name) {
|
@@ -25,7 +25,7 @@ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
|
25
25
|
const definitionsManager_1 = require("./definitionsManager");
|
26
26
|
const taskManager_1 = require("./taskManager");
|
27
27
|
const CHECK_INTERVAL = 5000;
|
28
|
-
const DEFAULT_HEALTH_PORT_TYPE = '
|
28
|
+
const DEFAULT_HEALTH_PORT_TYPE = 'http';
|
29
29
|
const MIN_TIME_RUNNING = 30000; //If something didnt run for more than 30 secs - it failed
|
30
30
|
class InstanceManager {
|
31
31
|
_interval = undefined;
|
@@ -198,7 +198,7 @@ class InstanceManager {
|
|
198
198
|
}
|
199
199
|
getHealthUrl(info, address) {
|
200
200
|
let healthUrl = null;
|
201
|
-
let health = info.health;
|
201
|
+
let health = info.health ?? '/.kapeta/health';
|
202
202
|
if (health) {
|
203
203
|
if (health.startsWith('/')) {
|
204
204
|
health = health.substring(1);
|
@@ -183,7 +183,7 @@ class RepositoryManager extends node_events_1.EventEmitter {
|
|
183
183
|
if (await definitionsManager_1.definitionsManager.exists(ref)) {
|
184
184
|
return;
|
185
185
|
}
|
186
|
-
throw new Error(`Failed to
|
186
|
+
throw new Error(`Failed to find asset after installation: ${ref}. Please try again`);
|
187
187
|
};
|
188
188
|
};
|
189
189
|
const tasks = [];
|
package/package.json
CHANGED
package/src/RepositoryWatcher.ts
CHANGED
@@ -15,6 +15,7 @@ import { SourceOfChange, WatchEventName } from './types';
|
|
15
15
|
import { cacheManager } from './cacheManager';
|
16
16
|
import { EventEmitter } from 'node:events';
|
17
17
|
import { assetManager } from './assetManager';
|
18
|
+
import { definitionsManager } from './definitionsManager';
|
18
19
|
|
19
20
|
interface AssetIdentity {
|
20
21
|
handle: string;
|
@@ -22,6 +23,27 @@ interface AssetIdentity {
|
|
22
23
|
version: string;
|
23
24
|
}
|
24
25
|
const KAPETA_YML_RX = /^kapeta.ya?ml$/;
|
26
|
+
|
27
|
+
let definitions: DefinitionInfo[] | undefined;
|
28
|
+
let definitionTimeout: NodeJS.Timeout | undefined;
|
29
|
+
|
30
|
+
function getDefinitionsDebounced() {
|
31
|
+
if (definitionTimeout) {
|
32
|
+
clearTimeout(definitionTimeout);
|
33
|
+
definitionTimeout = undefined;
|
34
|
+
}
|
35
|
+
if (!definitions) {
|
36
|
+
definitions = ClusterConfiguration.getDefinitions();
|
37
|
+
} else {
|
38
|
+
definitionTimeout = setTimeout(() => {
|
39
|
+
definitionTimeout = undefined;
|
40
|
+
definitions = undefined;
|
41
|
+
}, 500);
|
42
|
+
}
|
43
|
+
|
44
|
+
return definitions;
|
45
|
+
}
|
46
|
+
|
25
47
|
export class RepositoryWatcher extends EventEmitter {
|
26
48
|
private watcher?: FSWatcher;
|
27
49
|
private disabled: boolean = false;
|
@@ -208,7 +230,8 @@ export class RepositoryWatcher extends EventEmitter {
|
|
208
230
|
|
209
231
|
private async checkForChange(assetIdentity: AssetIdentity, sourceOfChange: SourceOfChange) {
|
210
232
|
const ymlPath = Path.join(this.getRepositoryPath(assetIdentity), 'kapeta.yml');
|
211
|
-
const newDefinitions =
|
233
|
+
const newDefinitions = getDefinitionsDebounced();
|
234
|
+
|
212
235
|
const newDefinition = newDefinitions.find((d) => d.ymlPath === ymlPath);
|
213
236
|
let currentDefinition = this.allDefinitions.find((d) => d.ymlPath === ymlPath);
|
214
237
|
const ymlExists = await this.exists(ymlPath);
|
@@ -290,11 +313,16 @@ export class RepositoryWatcher extends EventEmitter {
|
|
290
313
|
} catch (e) {}
|
291
314
|
|
292
315
|
if (symbolicLink) {
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
316
|
+
try {
|
317
|
+
const realPath = Path.join(await FS.realpath(path), 'kapeta.yml');
|
318
|
+
if (await this.exists(realPath)) {
|
319
|
+
//console.log('Watching symlink target %s => %s', path, realPath);
|
320
|
+
this.watcher?.add(realPath);
|
321
|
+
this.symbolicLinks[path] = realPath;
|
322
|
+
}
|
323
|
+
} catch (e) {
|
324
|
+
// Remove the symlink - it's broken
|
325
|
+
await FS.remove(path);
|
298
326
|
}
|
299
327
|
}
|
300
328
|
} catch (e) {
|
package/src/assetManager.ts
CHANGED
@@ -36,6 +36,10 @@ export interface EnrichedAsset {
|
|
36
36
|
ymlPath: string;
|
37
37
|
}
|
38
38
|
|
39
|
+
function filterExists(asset: DefinitionInfo): boolean {
|
40
|
+
return FS.existsSync(asset.path);
|
41
|
+
}
|
42
|
+
|
39
43
|
function enrichAsset(asset: DefinitionInfo): EnrichedAsset {
|
40
44
|
return {
|
41
45
|
ref: `kapeta://${asset.definition.metadata.name}:${asset.version}`,
|
@@ -101,7 +105,7 @@ class AssetManager {
|
|
101
105
|
|
102
106
|
const assets = await definitionsManager.getDefinitions(assetKinds);
|
103
107
|
|
104
|
-
return assets.map(enrichAsset);
|
108
|
+
return assets.filter(filterExists).map(enrichAsset);
|
105
109
|
}
|
106
110
|
|
107
111
|
async getPlans(): Promise<EnrichedAsset[]> {
|
@@ -164,9 +164,9 @@ class DefinitionsManager {
|
|
164
164
|
const definitions = await this.getDefinitions();
|
165
165
|
return definitions.find((d) => {
|
166
166
|
if (!uri.version) {
|
167
|
-
return d.definition.metadata.name === uri.fullName;
|
167
|
+
return d.definition.metadata.name.toLowerCase() === uri.fullName.toLowerCase();
|
168
168
|
}
|
169
|
-
return parseKapetaUri(`${d.definition.metadata.name}:${d.version}`).
|
169
|
+
return parseKapetaUri(`${d.definition.metadata.name}:${d.version}`).equals(uri);
|
170
170
|
});
|
171
171
|
}
|
172
172
|
|
package/src/instanceManager.ts
CHANGED
@@ -27,7 +27,7 @@ import { definitionsManager } from './definitionsManager';
|
|
27
27
|
import { Task, taskManager } from './taskManager';
|
28
28
|
|
29
29
|
const CHECK_INTERVAL = 5000;
|
30
|
-
const DEFAULT_HEALTH_PORT_TYPE = '
|
30
|
+
const DEFAULT_HEALTH_PORT_TYPE = 'http';
|
31
31
|
|
32
32
|
const MIN_TIME_RUNNING = 30000; //If something didnt run for more than 30 secs - it failed
|
33
33
|
|
@@ -264,7 +264,7 @@ export class InstanceManager {
|
|
264
264
|
|
265
265
|
private getHealthUrl(info: Omit<InstanceInfo, 'systemId' | 'instanceId'>, address: string) {
|
266
266
|
let healthUrl = null;
|
267
|
-
let health = info.health;
|
267
|
+
let health = info.health ?? '/.kapeta/health';
|
268
268
|
if (health) {
|
269
269
|
if (health.startsWith('/')) {
|
270
270
|
health = health.substring(1);
|
package/src/repositoryManager.ts
CHANGED
@@ -209,7 +209,7 @@ class RepositoryManager extends EventEmitter {
|
|
209
209
|
if (await definitionsManager.exists(ref)) {
|
210
210
|
return;
|
211
211
|
}
|
212
|
-
throw new Error(`Failed to
|
212
|
+
throw new Error(`Failed to find asset after installation: ${ref}. Please try again`);
|
213
213
|
};
|
214
214
|
};
|
215
215
|
|