@kapeta/local-cluster-service 0.35.0 → 0.36.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 +14 -0
- package/dist/cjs/src/containerManager.js +3 -3
- package/dist/cjs/src/instanceManager.d.ts +7 -3
- package/dist/cjs/src/instanceManager.js +143 -63
- package/dist/cjs/src/operatorManager.d.ts +7 -7
- package/dist/cjs/src/operatorManager.js +19 -19
- package/dist/cjs/src/types.d.ts +1 -0
- package/dist/cjs/src/utils/BlockInstanceRunner.d.ts +4 -12
- package/dist/cjs/src/utils/BlockInstanceRunner.js +107 -89
- package/dist/cjs/src/utils/utils.d.ts +1 -1
- package/dist/cjs/src/utils/utils.js +25 -2
- package/dist/esm/src/containerManager.js +3 -3
- package/dist/esm/src/instanceManager.d.ts +7 -3
- package/dist/esm/src/instanceManager.js +143 -63
- package/dist/esm/src/operatorManager.d.ts +7 -7
- package/dist/esm/src/operatorManager.js +19 -19
- package/dist/esm/src/types.d.ts +1 -0
- package/dist/esm/src/utils/BlockInstanceRunner.d.ts +4 -12
- package/dist/esm/src/utils/BlockInstanceRunner.js +107 -89
- package/dist/esm/src/utils/utils.d.ts +1 -1
- package/dist/esm/src/utils/utils.js +25 -2
- package/package.json +1 -1
- package/src/containerManager.ts +3 -3
- package/src/instanceManager.ts +193 -77
- package/src/operatorManager.ts +21 -18
- package/src/types.ts +1 -0
- package/src/utils/BlockInstanceRunner.ts +132 -102
- package/src/utils/utils.ts +28 -2
@@ -5,7 +5,8 @@
|
|
5
5
|
import { DefinitionInfo } from '@kapeta/local-cluster-config';
|
6
6
|
import { ContainerInfo } from './containerManager';
|
7
7
|
import { EnvironmentType, LocalImageOptions, OperatorInfo } from './types';
|
8
|
-
export declare const
|
8
|
+
export declare const KIND_RESOURCE_OPERATOR = "core/resource-type-operator";
|
9
|
+
export declare const KIND_BLOCK_OPERATOR = "core/block-type-operator";
|
9
10
|
declare class Operator {
|
10
11
|
private readonly _data;
|
11
12
|
constructor(data: DefinitionInfo);
|
@@ -21,7 +22,7 @@ declare class OperatorManager {
|
|
21
22
|
/**
|
22
23
|
* Get operator definition for resource type
|
23
24
|
*/
|
24
|
-
getOperator(
|
25
|
+
getOperator(fullName: string, version: string): Promise<Operator>;
|
25
26
|
/**
|
26
27
|
* Get information about a specific consumed resource
|
27
28
|
*/
|
@@ -29,12 +30,11 @@ declare class OperatorManager {
|
|
29
30
|
/**
|
30
31
|
* Ensure we have a running operator of given type
|
31
32
|
*
|
32
|
-
* @param
|
33
|
-
* @param
|
34
|
-
* @param
|
35
|
-
* @return {Promise<ContainerInfo>}
|
33
|
+
* @param systemId the plan ref
|
34
|
+
* @param kind the full name - e.g. myhandle/rabbitmq
|
35
|
+
* @param version the version of the operator
|
36
36
|
*/
|
37
|
-
|
37
|
+
ensureOperator(systemId: string, kind: string, version: string): Promise<ContainerInfo>;
|
38
38
|
}
|
39
39
|
export declare const operatorManager: OperatorManager;
|
40
40
|
export {};
|
@@ -7,7 +7,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
8
8
|
};
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
10
|
-
exports.operatorManager = exports.
|
10
|
+
exports.operatorManager = exports.KIND_BLOCK_OPERATOR = exports.KIND_RESOURCE_OPERATOR = void 0;
|
11
11
|
const path_1 = __importDefault(require("path"));
|
12
12
|
const md5_1 = __importDefault(require("md5"));
|
13
13
|
const serviceManager_1 = require("./serviceManager");
|
@@ -20,7 +20,8 @@ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
|
20
20
|
const lodash_1 = __importDefault(require("lodash"));
|
21
21
|
const async_lock_1 = __importDefault(require("async-lock"));
|
22
22
|
const taskManager_1 = require("./taskManager");
|
23
|
-
exports.
|
23
|
+
exports.KIND_RESOURCE_OPERATOR = 'core/resource-type-operator';
|
24
|
+
exports.KIND_BLOCK_OPERATOR = 'core/block-type-operator';
|
24
25
|
const KIND_PLAN = 'core/plan';
|
25
26
|
class Operator {
|
26
27
|
_data;
|
@@ -50,18 +51,18 @@ class OperatorManager {
|
|
50
51
|
/**
|
51
52
|
* Get operator definition for resource type
|
52
53
|
*/
|
53
|
-
async getOperator(
|
54
|
-
const operators = await definitionsManager_1.definitionsManager.getDefinitions(exports.
|
54
|
+
async getOperator(fullName, version) {
|
55
|
+
const operators = await definitionsManager_1.definitionsManager.getDefinitions([exports.KIND_RESOURCE_OPERATOR, exports.KIND_BLOCK_OPERATOR]);
|
55
56
|
const operator = operators.find((operator) => operator.definition &&
|
56
57
|
operator.definition.metadata &&
|
57
58
|
operator.definition.metadata.name &&
|
58
|
-
operator.definition.metadata.name.toLowerCase() ===
|
59
|
+
operator.definition.metadata.name.toLowerCase() === fullName.toLowerCase() &&
|
59
60
|
operator.version === version);
|
60
61
|
if (!operator) {
|
61
|
-
throw new Error(`Unknown
|
62
|
+
throw new Error(`Unknown operator type: ${fullName}:${version}`);
|
62
63
|
}
|
63
64
|
if (!operator.definition.spec || !operator.definition.spec.local) {
|
64
|
-
throw new Error(`Operator missing local definition: ${
|
65
|
+
throw new Error(`Operator missing local definition: ${fullName}:${version}`);
|
65
66
|
}
|
66
67
|
return new Operator(operator);
|
67
68
|
}
|
@@ -96,7 +97,7 @@ class OperatorManager {
|
|
96
97
|
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(blockResource.kind);
|
97
98
|
const operator = await this.getOperator(resourceType, kindUri.version);
|
98
99
|
const credentials = operator.getCredentials();
|
99
|
-
const container = await this.
|
100
|
+
const container = await this.ensureOperator(systemId, resourceType, kindUri.version);
|
100
101
|
const portInfo = await container.getPort(portType);
|
101
102
|
if (!portInfo) {
|
102
103
|
throw new Error('Unknown resource port type : ' + resourceType + '#' + portType);
|
@@ -119,16 +120,15 @@ class OperatorManager {
|
|
119
120
|
/**
|
120
121
|
* Ensure we have a running operator of given type
|
121
122
|
*
|
122
|
-
* @param
|
123
|
-
* @param
|
124
|
-
* @param
|
125
|
-
* @return {Promise<ContainerInfo>}
|
123
|
+
* @param systemId the plan ref
|
124
|
+
* @param kind the full name - e.g. myhandle/rabbitmq
|
125
|
+
* @param version the version of the operator
|
126
126
|
*/
|
127
|
-
async
|
127
|
+
async ensureOperator(systemId, kind, version) {
|
128
128
|
systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
|
129
|
-
const key = `${systemId}#${
|
129
|
+
const key = `${systemId}#${kind}:${version}`;
|
130
130
|
return await this.operatorLock.acquire(key, async () => {
|
131
|
-
const operator = await this.getOperator(
|
131
|
+
const operator = await this.getOperator(kind, version);
|
132
132
|
const operatorData = operator.getLocalData();
|
133
133
|
const portTypes = Object.keys(operatorData.ports);
|
134
134
|
portTypes.sort();
|
@@ -136,7 +136,7 @@ class OperatorManager {
|
|
136
136
|
for (let i = 0; i < portTypes.length; i++) {
|
137
137
|
const portType = portTypes[i];
|
138
138
|
let containerPortInfo = operatorData.ports[portType];
|
139
|
-
const hostPort = await serviceManager_1.serviceManager.ensureServicePort(systemId,
|
139
|
+
const hostPort = await serviceManager_1.serviceManager.ensureServicePort(systemId, kind, portType);
|
140
140
|
const portInfo = (0, utils_1.toPortInfo)(containerPortInfo);
|
141
141
|
const portId = portInfo.port + '/' + portInfo.type;
|
142
142
|
ports[portId] = {
|
@@ -144,7 +144,7 @@ class OperatorManager {
|
|
144
144
|
hostPort,
|
145
145
|
};
|
146
146
|
}
|
147
|
-
const nameParts = [systemId,
|
147
|
+
const nameParts = [systemId, kind.toLowerCase(), version];
|
148
148
|
const containerName = `kapeta-resource-${(0, md5_1.default)(nameParts.join('_'))}`;
|
149
149
|
const PortBindings = {};
|
150
150
|
const Env = [];
|
@@ -152,7 +152,7 @@ class OperatorManager {
|
|
152
152
|
const Labels = {
|
153
153
|
kapeta: 'true',
|
154
154
|
[containerManager_1.COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
|
155
|
-
[containerManager_1.COMPOSE_LABEL_SERVICE]: [
|
155
|
+
[containerManager_1.COMPOSE_LABEL_SERVICE]: [kind, version].join('_').replace(/[^a-z0-9]/gi, '_'),
|
156
156
|
};
|
157
157
|
const operatorMetadata = operator.getDefinitionInfo().definition.metadata;
|
158
158
|
const bindHost = (0, utils_1.getBindHost)();
|
@@ -167,7 +167,7 @@ class OperatorManager {
|
|
167
167
|
];
|
168
168
|
Labels[containerManager_1.CONTAINER_LABEL_PORT_PREFIX + portInfo.hostPort] = portInfo.type;
|
169
169
|
});
|
170
|
-
const Mounts = await containerManager_1.containerManager.createVolumes(systemId,
|
170
|
+
const Mounts = await containerManager_1.containerManager.createVolumes(systemId, kind, operatorData.mounts);
|
171
171
|
lodash_1.default.forEach(operatorData.env, (value, name) => {
|
172
172
|
Env.push(name + '=' + value);
|
173
173
|
});
|
package/dist/esm/src/types.d.ts
CHANGED
@@ -2,9 +2,7 @@
|
|
2
2
|
* Copyright 2023 Kapeta Inc.
|
3
3
|
* SPDX-License-Identifier: BUSL-1.1
|
4
4
|
*/
|
5
|
-
import {
|
6
|
-
import { KapetaURI } from '@kapeta/nodejs-utils';
|
7
|
-
import { AnyMap, BlockProcessParams, ProcessInfo, StringMap } from '../types';
|
5
|
+
import { AnyMap, ProcessInfo } from '../types';
|
8
6
|
export declare function resolvePortType(portType: string): string;
|
9
7
|
export declare class BlockInstanceRunner {
|
10
8
|
private readonly _systemId;
|
@@ -20,17 +18,11 @@ export declare class BlockInstanceRunner {
|
|
20
18
|
*/
|
21
19
|
private _startLocalProcess;
|
22
20
|
private _startDockerProcess;
|
21
|
+
private _startOperatorProcess;
|
23
22
|
/**
|
24
|
-
*
|
25
|
-
* @param blockInstance
|
26
|
-
* @param blockUri
|
27
|
-
* @param providerDefinition
|
28
|
-
* @param {{[key:string]:string}} env
|
29
|
-
* @return {Promise<ProcessDetails>}
|
30
|
-
* @private
|
23
|
+
* Get the port bindings for a non-operator block
|
31
24
|
*/
|
32
|
-
|
33
|
-
private getDockerPortBindings;
|
25
|
+
private getServiceBlockPortBindings;
|
34
26
|
private ensureContainer;
|
35
27
|
private _handleContainer;
|
36
28
|
}
|
@@ -19,6 +19,7 @@ const clusterService_1 = require("../clusterService");
|
|
19
19
|
const types_1 = require("../types");
|
20
20
|
const definitionsManager_1 = require("../definitionsManager");
|
21
21
|
const node_os_1 = __importDefault(require("node:os"));
|
22
|
+
const taskManager_1 = require("../taskManager");
|
22
23
|
const KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
|
23
24
|
const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
|
24
25
|
const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
|
@@ -40,16 +41,23 @@ async function getProvider(uri) {
|
|
40
41
|
});
|
41
42
|
}
|
42
43
|
function resolvePortType(portType) {
|
43
|
-
if (serviceManager_1.HTTP_PORTS.includes(portType)) {
|
44
|
+
if (portType && serviceManager_1.HTTP_PORTS.includes(portType.toLowerCase())) {
|
44
45
|
return serviceManager_1.HTTP_PORT_TYPE;
|
45
46
|
}
|
46
47
|
return portType;
|
47
48
|
}
|
48
49
|
exports.resolvePortType = resolvePortType;
|
49
|
-
|
50
|
+
/**
|
51
|
+
* Get the port types for a non-operator block instance
|
52
|
+
*/
|
53
|
+
function getServiceProviderPorts(assetVersion, providerVersion) {
|
50
54
|
const out = assetVersion.definition?.spec?.providers
|
55
|
+
?.filter((provider) => {
|
56
|
+
// We only support HTTP provider ports for now. Need to figure out how to handle other types
|
57
|
+
return serviceManager_1.HTTP_PORTS.includes(provider.spec?.port?.type?.toLowerCase());
|
58
|
+
})
|
51
59
|
?.map((provider) => {
|
52
|
-
return resolvePortType(provider.spec?.port?.type);
|
60
|
+
return resolvePortType(provider.spec?.port?.type?.toLowerCase());
|
53
61
|
})
|
54
62
|
.filter((t) => !!t) ?? [];
|
55
63
|
if (out.length === 0) {
|
@@ -112,7 +120,7 @@ class BlockInstanceRunner {
|
|
112
120
|
}
|
113
121
|
else {
|
114
122
|
//We need a port type to know how to connect to the block consistently
|
115
|
-
const portTypes =
|
123
|
+
const portTypes = getServiceProviderPorts(assetVersion, providerVersion);
|
116
124
|
if (blockUri.version === 'local') {
|
117
125
|
processInfo = await this._startLocalProcess(blockInstance, blockUri, env, assetVersion);
|
118
126
|
}
|
@@ -155,7 +163,7 @@ class BlockInstanceRunner {
|
|
155
163
|
if (!dockerImage) {
|
156
164
|
throw new Error(`Missing docker image information: ${JSON.stringify(localContainer)}`);
|
157
165
|
}
|
158
|
-
const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
|
166
|
+
const containerName = await (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id, targetKindUri.id);
|
159
167
|
const startCmd = localContainer.handlers?.onCreate ? localContainer.handlers.onCreate : '';
|
160
168
|
const dockerOpts = localContainer.options ?? {};
|
161
169
|
const homeDir = localContainer.userHome ? localContainer.userHome : '/root';
|
@@ -168,7 +176,7 @@ class BlockInstanceRunner {
|
|
168
176
|
delete localContainer.HostConfig;
|
169
177
|
delete localContainer.Labels;
|
170
178
|
delete localContainer.Env;
|
171
|
-
const { PortBindings, ExposedPorts, addonEnv } = await this.
|
179
|
+
const { PortBindings, ExposedPorts, addonEnv } = await this.getServiceBlockPortBindings(blockInstance, assetVersion, providerVersion);
|
172
180
|
let HealthCheck = undefined;
|
173
181
|
if (localContainer.healthcheck) {
|
174
182
|
HealthCheck = containerManager_1.containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
|
@@ -240,8 +248,8 @@ class BlockInstanceRunner {
|
|
240
248
|
if (!providerVersion) {
|
241
249
|
throw new Error(`Block type not found: ${kindUri.id}`);
|
242
250
|
}
|
243
|
-
const { PortBindings, ExposedPorts, addonEnv } = await this.
|
244
|
-
const containerName = (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id);
|
251
|
+
const { PortBindings, ExposedPorts, addonEnv } = await this.getServiceBlockPortBindings(blockInstance, assetVersion, providerVersion);
|
252
|
+
const containerName = await (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id, kindUri.id);
|
245
253
|
// For windows we need to default to root
|
246
254
|
const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
|
247
255
|
const systemUri = (0, nodejs_utils_1.parseKapetaUri)(this._systemId);
|
@@ -268,15 +276,6 @@ class BlockInstanceRunner {
|
|
268
276
|
},
|
269
277
|
});
|
270
278
|
}
|
271
|
-
/**
|
272
|
-
*
|
273
|
-
* @param blockInstance
|
274
|
-
* @param blockUri
|
275
|
-
* @param providerDefinition
|
276
|
-
* @param {{[key:string]:string}} env
|
277
|
-
* @return {Promise<ProcessDetails>}
|
278
|
-
* @private
|
279
|
-
*/
|
280
279
|
async _startOperatorProcess(blockInstance, blockUri, providerDefinition, env) {
|
281
280
|
const { assetFile } = local_cluster_config_1.default.getRepositoryAssetInfoPath(blockUri.handle, blockUri.name, blockUri.version);
|
282
281
|
const kapetaYmlPath = assetFile;
|
@@ -290,88 +289,107 @@ class BlockInstanceRunner {
|
|
290
289
|
}
|
291
290
|
const local = spec.local;
|
292
291
|
const dockerImage = local.image;
|
293
|
-
|
294
|
-
const
|
295
|
-
const
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
const PortBindings = {};
|
300
|
-
let HealthCheck = undefined;
|
301
|
-
let Mounts = [];
|
302
|
-
const localPorts = local.ports ?? {};
|
303
|
-
const labels = {};
|
304
|
-
const promises = Object.entries(localPorts).map(async ([portType, value]) => {
|
305
|
-
const portInfo = (0, utils_1.toPortInfo)(value);
|
306
|
-
const dockerPort = `${portInfo.port}/${portInfo.type}`;
|
307
|
-
ExposedPorts[dockerPort] = {};
|
308
|
-
addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = `${portInfo.port}`;
|
309
|
-
const publicPort = await serviceManager_1.serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
|
310
|
-
PortBindings[dockerPort] = [
|
311
|
-
{
|
312
|
-
HostIp: bindHost,
|
313
|
-
HostPort: `${publicPort}`,
|
314
|
-
},
|
315
|
-
];
|
316
|
-
labels[containerManager_1.CONTAINER_LABEL_PORT_PREFIX + publicPort] = portType;
|
317
|
-
});
|
318
|
-
await Promise.all(promises);
|
319
|
-
if (local.env) {
|
320
|
-
Object.entries(local.env).forEach(([key, value]) => {
|
321
|
-
addonEnv[key] = value;
|
322
|
-
});
|
323
|
-
}
|
324
|
-
if (local.mounts) {
|
325
|
-
Mounts = await containerManager_1.containerManager.createVolumes(this._systemId, blockUri.id, local.mounts);
|
292
|
+
const operatorUri = local.singleton ? (0, nodejs_utils_1.parseKapetaUri)(providerRef) : blockUri;
|
293
|
+
const operatorId = local.singleton ? providerRef : blockInstance.id;
|
294
|
+
const operatorRef = local.singleton ? providerRef : blockInstance.ref;
|
295
|
+
if (local.singleton && env) {
|
296
|
+
env[KAPETA_BLOCK_REF] = operatorRef;
|
297
|
+
env[KAPETA_INSTANCE_ID] = operatorId;
|
326
298
|
}
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
299
|
+
const containerName = await (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id, providerRef);
|
300
|
+
const task = taskManager_1.taskManager.add(`container:start:${containerName}`, async () => {
|
301
|
+
const logs = new LogData_1.LogData();
|
302
|
+
const bindHost = (0, utils_1.getBindHost)();
|
303
|
+
const ExposedPorts = {};
|
304
|
+
const addonEnv = {};
|
305
|
+
const PortBindings = {};
|
306
|
+
let HealthCheck = undefined;
|
307
|
+
let Mounts = [];
|
308
|
+
const localPorts = local.ports ?? {};
|
309
|
+
const labels = {};
|
310
|
+
const promises = Object.entries(localPorts).map(async ([portType, value]) => {
|
311
|
+
const portInfo = (0, utils_1.toPortInfo)(value);
|
312
|
+
const dockerPort = `${portInfo.port}/${portInfo.type}`;
|
313
|
+
ExposedPorts[dockerPort] = {};
|
314
|
+
addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = `${portInfo.port}`;
|
315
|
+
const publicPort = await serviceManager_1.serviceManager.ensureServicePort(this._systemId, operatorId, portType);
|
316
|
+
PortBindings[dockerPort] = [
|
317
|
+
{
|
318
|
+
HostIp: bindHost,
|
319
|
+
HostPort: `${publicPort}`,
|
320
|
+
},
|
321
|
+
];
|
322
|
+
labels[containerManager_1.CONTAINER_LABEL_PORT_PREFIX + publicPort] = portType;
|
323
|
+
});
|
324
|
+
await Promise.all(promises);
|
325
|
+
if (local.env) {
|
326
|
+
Object.entries(local.env).forEach(([key, value]) => {
|
327
|
+
addonEnv[key] = value;
|
328
|
+
});
|
329
|
+
}
|
330
|
+
if (local.mounts) {
|
331
|
+
Mounts = await containerManager_1.containerManager.createVolumes(this._systemId, operatorUri.id, local.mounts);
|
332
|
+
}
|
333
|
+
if (local.health) {
|
334
|
+
HealthCheck = containerManager_1.containerManager.toDockerHealth(local.health);
|
335
|
+
}
|
336
|
+
// For windows we need to default to root
|
337
|
+
const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
|
338
|
+
const Binds = local.singleton
|
339
|
+
? [`${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`]
|
340
|
+
: [
|
341
341
|
`${(0, containerManager_1.toLocalBindVolume)(kapetaYmlPath)}:/kapeta.yml:ro`,
|
342
342
|
`${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`,
|
343
|
+
];
|
344
|
+
const systemUri = (0, nodejs_utils_1.parseKapetaUri)(this._systemId);
|
345
|
+
console.log(`Ensuring container for operator block: ${containerName} [singleton: ${!!local.singleton}]`);
|
346
|
+
logs.addLog(`Ensuring container for operator block: ${containerName}`);
|
347
|
+
const out = await this.ensureContainer({
|
348
|
+
Image: dockerImage,
|
349
|
+
name: containerName,
|
350
|
+
ExposedPorts,
|
351
|
+
HealthCheck,
|
352
|
+
HostConfig: {
|
353
|
+
Binds,
|
354
|
+
PortBindings,
|
355
|
+
Mounts,
|
356
|
+
},
|
357
|
+
Labels: {
|
358
|
+
...labels,
|
359
|
+
instance: operatorId,
|
360
|
+
[containerManager_1.COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
|
361
|
+
[containerManager_1.COMPOSE_LABEL_SERVICE]: operatorUri.id.replace(/[^a-z0-9]/gi, '_'),
|
362
|
+
},
|
363
|
+
Env: [
|
364
|
+
`KAPETA_INSTANCE_NAME=${operatorRef}`,
|
365
|
+
`KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
|
366
|
+
...DOCKER_ENV_VARS,
|
367
|
+
...Object.entries({
|
368
|
+
...env,
|
369
|
+
...addonEnv,
|
370
|
+
}).map(([key, value]) => `${key}=${value}`),
|
343
371
|
],
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
Env: [
|
354
|
-
`KAPETA_INSTANCE_NAME=${blockInstance.ref}`,
|
355
|
-
`KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
|
356
|
-
...DOCKER_ENV_VARS,
|
357
|
-
...Object.entries({
|
358
|
-
...env,
|
359
|
-
...addonEnv,
|
360
|
-
}).map(([key, value]) => `${key}=${value}`),
|
361
|
-
],
|
372
|
+
});
|
373
|
+
const portTypes = local.ports ? Object.keys(local.ports) : [];
|
374
|
+
if (portTypes.length > 0) {
|
375
|
+
out.portType = portTypes[0];
|
376
|
+
}
|
377
|
+
return out;
|
378
|
+
}, {
|
379
|
+
name: `Starting container for ${providerRef}`,
|
380
|
+
systemId: this._systemId,
|
362
381
|
});
|
363
|
-
|
364
|
-
if (portTypes.length > 0) {
|
365
|
-
out.portType = portTypes[0];
|
366
|
-
}
|
367
|
-
return out;
|
382
|
+
return task.wait();
|
368
383
|
}
|
369
|
-
|
384
|
+
/**
|
385
|
+
* Get the port bindings for a non-operator block
|
386
|
+
*/
|
387
|
+
async getServiceBlockPortBindings(blockInstance, assetVersion, providerVersion) {
|
370
388
|
const bindHost = (0, utils_1.getBindHost)();
|
371
389
|
const ExposedPorts = {};
|
372
390
|
const addonEnv = {};
|
373
391
|
const PortBindings = {};
|
374
|
-
const portTypes =
|
392
|
+
const portTypes = getServiceProviderPorts(assetVersion, providerVersion);
|
375
393
|
let port = 80;
|
376
394
|
const promises = portTypes.map(async (portType) => {
|
377
395
|
const publicPort = await serviceManager_1.serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
|
@@ -4,7 +4,7 @@
|
|
4
4
|
*/
|
5
5
|
import { EntityList } from '@kapeta/schemas';
|
6
6
|
import { AnyMap, PortInfo } from '../types';
|
7
|
-
export declare function getBlockInstanceContainerName(systemId: string, instanceId: string): string
|
7
|
+
export declare function getBlockInstanceContainerName(systemId: string, instanceId: string, blockType?: string): Promise<string>;
|
8
8
|
export declare function toPortInfo(port: PortInfo): {
|
9
9
|
port: number;
|
10
10
|
type: string;
|
@@ -13,8 +13,31 @@ const yaml_1 = __importDefault(require("yaml"));
|
|
13
13
|
const md5_1 = __importDefault(require("md5"));
|
14
14
|
const lodash_1 = __importDefault(require("lodash"));
|
15
15
|
const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
|
16
|
-
|
17
|
-
|
16
|
+
const definitionsManager_1 = require("../definitionsManager");
|
17
|
+
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
18
|
+
const operatorManager_1 = require("../operatorManager");
|
19
|
+
const assetManager_1 = require("../assetManager");
|
20
|
+
async function getBlockInstanceContainerName(systemId, instanceId, blockType) {
|
21
|
+
if (!blockType) {
|
22
|
+
const instance = await assetManager_1.assetManager.getBlockInstance(systemId, instanceId);
|
23
|
+
if (!instance) {
|
24
|
+
throw new Error(`Instance ${instanceId} not found in plan ${systemId}`);
|
25
|
+
}
|
26
|
+
const block = await assetManager_1.assetManager.getAsset(instance.block.ref);
|
27
|
+
if (!block) {
|
28
|
+
throw new Error(`Block ${instance.block.ref} not found`);
|
29
|
+
}
|
30
|
+
blockType = block.data.kind;
|
31
|
+
}
|
32
|
+
const typeDefinition = await definitionsManager_1.definitionsManager.getDefinition(blockType);
|
33
|
+
if (!typeDefinition) {
|
34
|
+
throw new Error(`Block type ${blockType} not found`);
|
35
|
+
}
|
36
|
+
if ((0, nodejs_utils_1.parseKapetaUri)(typeDefinition.definition.kind).fullName === operatorManager_1.KIND_BLOCK_OPERATOR &&
|
37
|
+
typeDefinition.definition.spec?.local?.singleton) {
|
38
|
+
return `kapeta-instance-operator-${(0, md5_1.default)((0, nodejs_utils_1.normalizeKapetaUri)(systemId) + (0, nodejs_utils_1.normalizeKapetaUri)(blockType))}`;
|
39
|
+
}
|
40
|
+
return `kapeta-block-instance-${(0, md5_1.default)((0, nodejs_utils_1.normalizeKapetaUri)(systemId) + instanceId)}`;
|
18
41
|
}
|
19
42
|
exports.getBlockInstanceContainerName = getBlockInstanceContainerName;
|
20
43
|
function toPortInfo(port) {
|
package/package.json
CHANGED
package/src/containerManager.ts
CHANGED
@@ -694,7 +694,7 @@ class ContainerManager {
|
|
694
694
|
}
|
695
695
|
|
696
696
|
async getLogs(instance: InstanceInfo): Promise<LogEntry[]> {
|
697
|
-
const containerName = getBlockInstanceContainerName(instance.systemId, instance.instanceId);
|
697
|
+
const containerName = await getBlockInstanceContainerName(instance.systemId, instance.instanceId);
|
698
698
|
const containerInfo = await this.getContainerByName(containerName);
|
699
699
|
if (!containerInfo) {
|
700
700
|
return [
|
@@ -711,7 +711,7 @@ class ContainerManager {
|
|
711
711
|
}
|
712
712
|
|
713
713
|
async stopLogListening(systemId: string, instanceId: string) {
|
714
|
-
const containerName = getBlockInstanceContainerName(systemId, instanceId);
|
714
|
+
const containerName = await getBlockInstanceContainerName(systemId, instanceId);
|
715
715
|
if (this.logStreams[containerName]) {
|
716
716
|
if (this.logStreams[containerName]?.timer) {
|
717
717
|
clearTimeout(this.logStreams[containerName].timer);
|
@@ -729,7 +729,7 @@ class ContainerManager {
|
|
729
729
|
}
|
730
730
|
|
731
731
|
async ensureLogListening(systemId: string, instanceId: string, handler: (log: LogEntry) => void) {
|
732
|
-
const containerName = getBlockInstanceContainerName(systemId, instanceId);
|
732
|
+
const containerName = await getBlockInstanceContainerName(systemId, instanceId);
|
733
733
|
try {
|
734
734
|
if (this.logStreams[containerName]?.stream) {
|
735
735
|
// Already listening - will shut itself down
|