@kapeta/local-cluster-service 0.15.1 → 0.15.3
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 +14 -0
- package/dist/cjs/src/assetManager.js +2 -2
- package/dist/cjs/src/containerManager.js +0 -1
- package/dist/cjs/src/identities/routes.js +2 -1
- package/dist/cjs/src/instanceManager.d.ts +0 -2
- package/dist/cjs/src/instanceManager.js +12 -34
- package/dist/cjs/src/progressListener.d.ts +5 -6
- package/dist/cjs/src/progressListener.js +54 -36
- package/dist/cjs/src/repositoryManager.js +9 -3
- package/dist/cjs/src/socketManager.d.ts +18 -6
- package/dist/cjs/src/socketManager.js +35 -1
- package/dist/esm/src/assetManager.js +3 -3
- package/dist/esm/src/containerManager.js +0 -1
- package/dist/esm/src/identities/routes.js +2 -1
- package/dist/esm/src/instanceManager.d.ts +0 -2
- package/dist/esm/src/instanceManager.js +12 -34
- package/dist/esm/src/progressListener.d.ts +5 -6
- package/dist/esm/src/progressListener.js +53 -36
- package/dist/esm/src/repositoryManager.js +9 -3
- package/dist/esm/src/socketManager.d.ts +18 -6
- package/dist/esm/src/socketManager.js +34 -0
- package/package.json +1 -1
- package/src/assetManager.ts +4 -4
- package/src/containerManager.ts +0 -5
- package/src/identities/routes.ts +3 -1
- package/src/instanceManager.ts +18 -34
- package/src/progressListener.ts +59 -39
- package/src/repositoryManager.ts +10 -3
- package/src/socketManager.ts +44 -5
package/src/progressListener.ts
CHANGED
@@ -1,19 +1,38 @@
|
|
1
1
|
import { spawn } from '@kapeta/nodejs-process';
|
2
|
-
import {
|
3
|
-
|
4
|
-
|
2
|
+
import { socketManager } from './socketManager';
|
3
|
+
import { LogEntry } from './types';
|
4
|
+
import { format } from 'node:util';
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
export class ProgressListener {
|
7
|
+
private readonly systemId: string | undefined;
|
8
|
+
private readonly instanceId: string | undefined;
|
9
|
+
|
10
|
+
constructor(systemId?: string, instanceId?: string) {
|
11
|
+
this.systemId = systemId;
|
12
|
+
this.instanceId = instanceId;
|
8
13
|
}
|
9
14
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
private emitLog(payload: Omit<LogEntry, 'time' | 'source'>) {
|
16
|
+
const logEntry: LogEntry = {
|
17
|
+
...payload,
|
18
|
+
source: 'stdout',
|
19
|
+
time: Date.now(),
|
20
|
+
};
|
21
|
+
if (this.systemId && this.instanceId) {
|
22
|
+
socketManager.emitInstanceLog(this.systemId, this.instanceId, logEntry);
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
|
26
|
+
if (this.systemId) {
|
27
|
+
socketManager.emitSystemLog(this.systemId, logEntry);
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
|
31
|
+
socketManager.emitGlobalLog(logEntry);
|
32
|
+
}
|
15
33
|
|
16
|
-
|
34
|
+
run(command: string, directory?: string): Promise<{ exit: number; signal: NodeJS.Signals | null; output: string }> {
|
35
|
+
this.info(`Running command "${command}"`);
|
17
36
|
|
18
37
|
return new Promise(async (resolve, reject) => {
|
19
38
|
try {
|
@@ -25,7 +44,10 @@ class ProgressListener {
|
|
25
44
|
});
|
26
45
|
|
27
46
|
child.onData((data) => {
|
28
|
-
this.
|
47
|
+
this.emitLog({
|
48
|
+
level: data.type === 'stdout' ? 'INFO' : 'WARN',
|
49
|
+
message: data.line,
|
50
|
+
});
|
29
51
|
});
|
30
52
|
|
31
53
|
if (child.process.stdout) {
|
@@ -36,25 +58,16 @@ class ProgressListener {
|
|
36
58
|
|
37
59
|
child.process.on('exit', (exit, signal) => {
|
38
60
|
if (exit !== 0) {
|
39
|
-
this.
|
40
|
-
type: 'info',
|
41
|
-
message: `"${command}" failed: "${exit}"`,
|
42
|
-
});
|
61
|
+
this.warn(`Command "${command}" failed: ${exit}`);
|
43
62
|
reject(new Error(`Command "${command}" exited with code ${exit}`));
|
44
63
|
} else {
|
45
|
-
this.
|
46
|
-
type: 'info',
|
47
|
-
message: `Command OK: "${command}"`,
|
48
|
-
});
|
64
|
+
this.info(`Command OK: "${command}"`);
|
49
65
|
resolve({ exit, signal, output: Buffer.concat(chunks).toString() });
|
50
66
|
}
|
51
67
|
});
|
52
68
|
|
53
69
|
child.process.on('error', (err) => {
|
54
|
-
this.
|
55
|
-
type: 'info',
|
56
|
-
message: `"${command}" failed: "${err.message}"`,
|
57
|
-
});
|
70
|
+
this.warn(`"${command}" failed: "${err.message}"`);
|
58
71
|
reject(err);
|
59
72
|
});
|
60
73
|
|
@@ -66,48 +79,55 @@ class ProgressListener {
|
|
66
79
|
}
|
67
80
|
|
68
81
|
async progress(label: string, callback: () => void | Promise<void>) {
|
69
|
-
this.
|
82
|
+
this.info(`${label}: started`);
|
70
83
|
try {
|
71
84
|
const result = await callback();
|
72
|
-
this.
|
85
|
+
this.info(`${label}: done`);
|
73
86
|
return result;
|
74
87
|
} catch (e: any) {
|
75
|
-
this.
|
76
|
-
type: 'info',
|
77
|
-
message: `${label}: failed. ${e.message}`,
|
78
|
-
});
|
88
|
+
this.warn(`${label}: failed. ${e.message}`);
|
79
89
|
throw e;
|
80
90
|
}
|
81
91
|
}
|
82
92
|
|
83
93
|
async check(message: string, ok: boolean | Promise<boolean> | (() => Promise<boolean>)) {
|
84
94
|
const wasOk = await ok;
|
85
|
-
this.
|
95
|
+
this.info(`${message}: ${wasOk}`);
|
86
96
|
}
|
87
97
|
|
88
98
|
start(label: string) {
|
89
|
-
this.
|
99
|
+
this.info(label);
|
90
100
|
}
|
91
101
|
|
92
102
|
showValue(label: string, value: any) {
|
93
|
-
this.
|
103
|
+
this.info(`${label}: ${value}`);
|
94
104
|
}
|
95
105
|
|
96
106
|
error(msg: string, ...args: any[]) {
|
97
|
-
this.
|
107
|
+
this.emitLog({
|
108
|
+
message: format(msg, args),
|
109
|
+
level: 'ERROR',
|
110
|
+
});
|
98
111
|
}
|
99
112
|
|
100
113
|
warn(msg: string, ...args: any[]) {
|
101
|
-
this.
|
114
|
+
this.emitLog({
|
115
|
+
message: format(msg, args),
|
116
|
+
level: 'WARN',
|
117
|
+
});
|
102
118
|
}
|
103
119
|
|
104
120
|
info(msg: string, ...args: any[]) {
|
105
|
-
this.
|
121
|
+
this.emitLog({
|
122
|
+
message: format(msg, args),
|
123
|
+
level: 'INFO',
|
124
|
+
});
|
106
125
|
}
|
107
126
|
|
108
127
|
debug(msg: string, ...args: any[]) {
|
109
|
-
this.
|
128
|
+
this.emitLog({
|
129
|
+
message: format(msg, args),
|
130
|
+
level: 'DEBUG',
|
131
|
+
});
|
110
132
|
}
|
111
133
|
}
|
112
|
-
|
113
|
-
export const progressListener = new ProgressListener(socketManager);
|
package/src/repositoryManager.ts
CHANGED
@@ -6,13 +6,16 @@ import FSExtra from 'fs-extra';
|
|
6
6
|
import ClusterConfiguration from '@kapeta/local-cluster-config';
|
7
7
|
import { parseKapetaUri } from '@kapeta/nodejs-utils';
|
8
8
|
import { socketManager } from './socketManager';
|
9
|
-
import { progressListener } from './progressListener';
|
10
9
|
import { Dependency } from '@kapeta/schemas';
|
11
10
|
import { Actions, Config, RegistryService } from '@kapeta/nodejs-registry-utils';
|
12
11
|
import { definitionsManager } from './definitionsManager';
|
13
12
|
import { Task, taskManager } from './taskManager';
|
14
13
|
import { normalizeKapetaUri } from './utils/utils';
|
15
14
|
import { assetManager } from './assetManager';
|
15
|
+
import { ProgressListener } from './progressListener';
|
16
|
+
|
17
|
+
const EVENT_DEFAULT_PROVIDERS_START = 'default-providers-start';
|
18
|
+
const EVENT_DEFAULT_PROVIDERS_END = 'default-providers-end';
|
16
19
|
|
17
20
|
const DEFAULT_PROVIDERS = [
|
18
21
|
'kapeta/block-type-service',
|
@@ -130,7 +133,11 @@ class RepositoryManager {
|
|
130
133
|
}
|
131
134
|
|
132
135
|
public ensureDefaultProviders(): void {
|
133
|
-
|
136
|
+
socketManager.emitGlobal(EVENT_DEFAULT_PROVIDERS_START, { providers: DEFAULT_PROVIDERS });
|
137
|
+
const tasks = this._install(DEFAULT_PROVIDERS);
|
138
|
+
Promise.allSettled(tasks.map((t) => t.wait())).then(() => {
|
139
|
+
socketManager.emitGlobal(EVENT_DEFAULT_PROVIDERS_END, {});
|
140
|
+
});
|
134
141
|
}
|
135
142
|
|
136
143
|
private _install(refs: string[]): Task[] {
|
@@ -152,7 +159,7 @@ class RepositoryManager {
|
|
152
159
|
process.chdir(os.tmpdir());
|
153
160
|
//Disable change events while installing
|
154
161
|
this.setChangeEventsEnabled(false);
|
155
|
-
await Actions.install(
|
162
|
+
await Actions.install(new ProgressListener(), [ref], {});
|
156
163
|
} catch (e) {
|
157
164
|
console.error(`Failed to install asset: ${ref}`, e);
|
158
165
|
throw e;
|
package/src/socketManager.ts
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
import _ from 'lodash';
|
2
2
|
import { Socket, Server } from 'socket.io';
|
3
|
+
import { normalizeKapetaUri } from './utils/utils';
|
4
|
+
import { LogEntry } from './types';
|
5
|
+
export const EVENT_STATUS_CHANGED = 'status-changed';
|
6
|
+
export const EVENT_INSTANCE_CREATED = 'instance-created';
|
7
|
+
export const EVENT_INSTANCE_EXITED = 'instance-exited';
|
8
|
+
export const EVENT_INSTANCE_LOG = 'instance-log';
|
9
|
+
|
10
|
+
export const EVENT_SYSTEM_LOG = 'system-log';
|
11
|
+
export const EVENT_LOG = 'log';
|
3
12
|
|
4
13
|
export class SocketManager {
|
5
14
|
private _io: Server | null;
|
6
|
-
private _sockets: Socket[];
|
15
|
+
private readonly _sockets: Socket[];
|
7
16
|
|
8
17
|
constructor() {
|
9
18
|
this._io = null;
|
@@ -35,16 +44,46 @@ export class SocketManager {
|
|
35
44
|
this.io.emit(type, payload);
|
36
45
|
}
|
37
46
|
|
38
|
-
|
47
|
+
emitSystemEvent(systemId: string, type: string, payload: any) {
|
48
|
+
systemId = normalizeKapetaUri(systemId);
|
49
|
+
try {
|
50
|
+
socketManager.emit(`${systemId}/instances`, type, payload);
|
51
|
+
} catch (e: any) {
|
52
|
+
console.warn('Failed to emit instance event: %s', e.message);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
emitInstanceLog(systemId: string, instanceId: string, payload: LogEntry) {
|
57
|
+
this.emitInstanceEvent(systemId, instanceId, EVENT_INSTANCE_LOG, payload);
|
58
|
+
}
|
59
|
+
|
60
|
+
emitSystemLog(systemId: string, payload: LogEntry) {
|
61
|
+
this.emitSystemEvent(systemId, EVENT_SYSTEM_LOG, payload);
|
62
|
+
}
|
63
|
+
|
64
|
+
emitGlobalLog(payload: LogEntry) {
|
65
|
+
this.emitGlobal(EVENT_LOG, payload);
|
66
|
+
}
|
67
|
+
|
68
|
+
emitInstanceEvent(systemId: string, instanceId: string, type: string, payload: any) {
|
69
|
+
systemId = normalizeKapetaUri(systemId);
|
70
|
+
try {
|
71
|
+
socketManager.emit(`${systemId}/instances/${instanceId}`, type, payload);
|
72
|
+
} catch (e: any) {
|
73
|
+
console.warn('Failed to emit instance event: %s', e.message);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
private _bindIO() {
|
39
78
|
this.io.on('connection', (socket) => this._handleSocketCreated(socket));
|
40
79
|
}
|
41
80
|
|
42
|
-
_handleSocketCreated(socket: Socket) {
|
81
|
+
private _handleSocketCreated(socket: Socket) {
|
43
82
|
this._bindSocket(socket);
|
44
83
|
this._sockets.push(socket);
|
45
84
|
}
|
46
85
|
|
47
|
-
_bindSocket(socket: Socket) {
|
86
|
+
private _bindSocket(socket: Socket) {
|
48
87
|
socket.on('disconnect', () => this._handleSocketDestroyed(socket));
|
49
88
|
socket.on('join', (id) => {
|
50
89
|
socket.join(id);
|
@@ -54,7 +93,7 @@ export class SocketManager {
|
|
54
93
|
});
|
55
94
|
}
|
56
95
|
|
57
|
-
_handleSocketDestroyed(socket: Socket) {
|
96
|
+
private _handleSocketDestroyed(socket: Socket) {
|
58
97
|
_.pull(this._sockets, socket);
|
59
98
|
}
|
60
99
|
}
|