@kapeta/local-cluster-service 0.0.0-96f91ef
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/.eslintrc.cjs +25 -0
- package/.github/workflows/check-license.yml +17 -0
- package/.github/workflows/main.yml +26 -0
- package/.prettierignore +4 -0
- package/.vscode/launch.json +19 -0
- package/CHANGELOG.md +920 -0
- package/LICENSE +38 -0
- package/README.md +36 -0
- package/definitions.d.ts +35 -0
- package/dist/cjs/index.d.ts +34 -0
- package/dist/cjs/index.js +263 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/src/RepositoryWatcher.d.ts +30 -0
- package/dist/cjs/src/RepositoryWatcher.js +332 -0
- package/dist/cjs/src/ai/aiClient.d.ts +20 -0
- package/dist/cjs/src/ai/aiClient.js +74 -0
- package/dist/cjs/src/ai/routes.d.ts +7 -0
- package/dist/cjs/src/ai/routes.js +37 -0
- package/dist/cjs/src/ai/transform.d.ts +11 -0
- package/dist/cjs/src/ai/transform.js +239 -0
- package/dist/cjs/src/ai/types.d.ts +40 -0
- package/dist/cjs/src/ai/types.js +2 -0
- package/dist/cjs/src/api.d.ts +7 -0
- package/dist/cjs/src/api.js +29 -0
- package/dist/cjs/src/assetManager.d.ts +41 -0
- package/dist/cjs/src/assetManager.js +274 -0
- package/dist/cjs/src/assets/routes.d.ts +7 -0
- package/dist/cjs/src/assets/routes.js +165 -0
- package/dist/cjs/src/attachments/routes.d.ts +7 -0
- package/dist/cjs/src/attachments/routes.js +72 -0
- package/dist/cjs/src/authManager.d.ts +16 -0
- package/dist/cjs/src/authManager.js +64 -0
- package/dist/cjs/src/cacheManager.d.ts +20 -0
- package/dist/cjs/src/cacheManager.js +51 -0
- package/dist/cjs/src/clusterService.d.ts +44 -0
- package/dist/cjs/src/clusterService.js +120 -0
- package/dist/cjs/src/codeGeneratorManager.d.ts +14 -0
- package/dist/cjs/src/codeGeneratorManager.js +93 -0
- package/dist/cjs/src/config/routes.d.ts +7 -0
- package/dist/cjs/src/config/routes.js +160 -0
- package/dist/cjs/src/configManager.d.ts +42 -0
- package/dist/cjs/src/configManager.js +136 -0
- package/dist/cjs/src/containerManager.d.ts +148 -0
- package/dist/cjs/src/containerManager.js +958 -0
- package/dist/cjs/src/definitionsManager.d.ts +20 -0
- package/dist/cjs/src/definitionsManager.js +171 -0
- package/dist/cjs/src/filesystem/routes.d.ts +7 -0
- package/dist/cjs/src/filesystem/routes.js +105 -0
- package/dist/cjs/src/filesystemManager.d.ts +27 -0
- package/dist/cjs/src/filesystemManager.js +118 -0
- package/dist/cjs/src/identities/routes.d.ts +7 -0
- package/dist/cjs/src/identities/routes.js +37 -0
- package/dist/cjs/src/instanceManager.d.ts +69 -0
- package/dist/cjs/src/instanceManager.js +910 -0
- package/dist/cjs/src/instances/routes.d.ts +7 -0
- package/dist/cjs/src/instances/routes.js +179 -0
- package/dist/cjs/src/middleware/cors.d.ts +6 -0
- package/dist/cjs/src/middleware/cors.js +14 -0
- package/dist/cjs/src/middleware/kapeta.d.ts +15 -0
- package/dist/cjs/src/middleware/kapeta.js +28 -0
- package/dist/cjs/src/middleware/stringBody.d.ts +9 -0
- package/dist/cjs/src/middleware/stringBody.js +18 -0
- package/dist/cjs/src/networkManager.d.ts +37 -0
- package/dist/cjs/src/networkManager.js +119 -0
- package/dist/cjs/src/operatorManager.d.ts +41 -0
- package/dist/cjs/src/operatorManager.js +211 -0
- package/dist/cjs/src/progressListener.d.ts +31 -0
- package/dist/cjs/src/progressListener.js +133 -0
- package/dist/cjs/src/providerManager.d.ts +11 -0
- package/dist/cjs/src/providerManager.js +84 -0
- package/dist/cjs/src/providers/routes.d.ts +7 -0
- package/dist/cjs/src/providers/routes.js +46 -0
- package/dist/cjs/src/proxy/routes.d.ts +7 -0
- package/dist/cjs/src/proxy/routes.js +115 -0
- package/dist/cjs/src/proxy/types/rest.d.ts +10 -0
- package/dist/cjs/src/proxy/types/rest.js +123 -0
- package/dist/cjs/src/proxy/types/web.d.ts +8 -0
- package/dist/cjs/src/proxy/types/web.js +61 -0
- package/dist/cjs/src/repositoryManager.d.ts +35 -0
- package/dist/cjs/src/repositoryManager.js +247 -0
- package/dist/cjs/src/serviceManager.d.ts +36 -0
- package/dist/cjs/src/serviceManager.js +106 -0
- package/dist/cjs/src/socketManager.d.ts +32 -0
- package/dist/cjs/src/socketManager.js +125 -0
- package/dist/cjs/src/storageService.d.ts +21 -0
- package/dist/cjs/src/storageService.js +81 -0
- package/dist/cjs/src/taskManager.d.ts +70 -0
- package/dist/cjs/src/taskManager.js +181 -0
- package/dist/cjs/src/tasks/routes.d.ts +7 -0
- package/dist/cjs/src/tasks/routes.js +39 -0
- package/dist/cjs/src/traffic/routes.d.ts +7 -0
- package/dist/cjs/src/traffic/routes.js +22 -0
- package/dist/cjs/src/types.d.ts +99 -0
- package/dist/cjs/src/types.js +39 -0
- package/dist/cjs/src/utils/BlockInstanceRunner.d.ts +28 -0
- package/dist/cjs/src/utils/BlockInstanceRunner.js +432 -0
- package/dist/cjs/src/utils/DefaultProviderInstaller.d.ts +15 -0
- package/dist/cjs/src/utils/DefaultProviderInstaller.js +136 -0
- package/dist/cjs/src/utils/InternalConfigProvider.d.ts +38 -0
- package/dist/cjs/src/utils/InternalConfigProvider.js +146 -0
- package/dist/cjs/src/utils/LogData.d.ts +23 -0
- package/dist/cjs/src/utils/LogData.js +46 -0
- package/dist/cjs/src/utils/commandLineUtils.d.ts +8 -0
- package/dist/cjs/src/utils/commandLineUtils.js +39 -0
- package/dist/cjs/src/utils/pathTemplateParser.d.ts +30 -0
- package/dist/cjs/src/utils/pathTemplateParser.js +135 -0
- package/dist/cjs/src/utils/utils.d.ts +40 -0
- package/dist/cjs/src/utils/utils.js +148 -0
- package/dist/cjs/start.d.ts +5 -0
- package/dist/cjs/start.js +17 -0
- package/dist/cjs/test/proxy/types/rest.test.d.ts +5 -0
- package/dist/cjs/test/proxy/types/rest.test.js +48 -0
- package/dist/cjs/test/utils/pathTemplateParser.test.d.ts +5 -0
- package/dist/cjs/test/utils/pathTemplateParser.test.js +27 -0
- package/dist/esm/index.d.ts +34 -0
- package/dist/esm/index.js +263 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/src/RepositoryWatcher.d.ts +30 -0
- package/dist/esm/src/RepositoryWatcher.js +332 -0
- package/dist/esm/src/ai/aiClient.d.ts +20 -0
- package/dist/esm/src/ai/aiClient.js +74 -0
- package/dist/esm/src/ai/routes.d.ts +7 -0
- package/dist/esm/src/ai/routes.js +37 -0
- package/dist/esm/src/ai/transform.d.ts +11 -0
- package/dist/esm/src/ai/transform.js +239 -0
- package/dist/esm/src/ai/types.d.ts +40 -0
- package/dist/esm/src/ai/types.js +2 -0
- package/dist/esm/src/api.d.ts +7 -0
- package/dist/esm/src/api.js +29 -0
- package/dist/esm/src/assetManager.d.ts +41 -0
- package/dist/esm/src/assetManager.js +274 -0
- package/dist/esm/src/assets/routes.d.ts +7 -0
- package/dist/esm/src/assets/routes.js +165 -0
- package/dist/esm/src/attachments/routes.d.ts +7 -0
- package/dist/esm/src/attachments/routes.js +72 -0
- package/dist/esm/src/authManager.d.ts +16 -0
- package/dist/esm/src/authManager.js +64 -0
- package/dist/esm/src/cacheManager.d.ts +20 -0
- package/dist/esm/src/cacheManager.js +51 -0
- package/dist/esm/src/clusterService.d.ts +44 -0
- package/dist/esm/src/clusterService.js +120 -0
- package/dist/esm/src/codeGeneratorManager.d.ts +14 -0
- package/dist/esm/src/codeGeneratorManager.js +93 -0
- package/dist/esm/src/config/routes.d.ts +7 -0
- package/dist/esm/src/config/routes.js +160 -0
- package/dist/esm/src/configManager.d.ts +42 -0
- package/dist/esm/src/configManager.js +136 -0
- package/dist/esm/src/containerManager.d.ts +148 -0
- package/dist/esm/src/containerManager.js +958 -0
- package/dist/esm/src/definitionsManager.d.ts +20 -0
- package/dist/esm/src/definitionsManager.js +171 -0
- package/dist/esm/src/filesystem/routes.d.ts +7 -0
- package/dist/esm/src/filesystem/routes.js +105 -0
- package/dist/esm/src/filesystemManager.d.ts +27 -0
- package/dist/esm/src/filesystemManager.js +118 -0
- package/dist/esm/src/identities/routes.d.ts +7 -0
- package/dist/esm/src/identities/routes.js +37 -0
- package/dist/esm/src/instanceManager.d.ts +69 -0
- package/dist/esm/src/instanceManager.js +910 -0
- package/dist/esm/src/instances/routes.d.ts +7 -0
- package/dist/esm/src/instances/routes.js +179 -0
- package/dist/esm/src/middleware/cors.d.ts +6 -0
- package/dist/esm/src/middleware/cors.js +14 -0
- package/dist/esm/src/middleware/kapeta.d.ts +15 -0
- package/dist/esm/src/middleware/kapeta.js +28 -0
- package/dist/esm/src/middleware/stringBody.d.ts +9 -0
- package/dist/esm/src/middleware/stringBody.js +18 -0
- package/dist/esm/src/networkManager.d.ts +37 -0
- package/dist/esm/src/networkManager.js +119 -0
- package/dist/esm/src/operatorManager.d.ts +41 -0
- package/dist/esm/src/operatorManager.js +211 -0
- package/dist/esm/src/progressListener.d.ts +31 -0
- package/dist/esm/src/progressListener.js +133 -0
- package/dist/esm/src/providerManager.d.ts +11 -0
- package/dist/esm/src/providerManager.js +84 -0
- package/dist/esm/src/providers/routes.d.ts +7 -0
- package/dist/esm/src/providers/routes.js +46 -0
- package/dist/esm/src/proxy/routes.d.ts +7 -0
- package/dist/esm/src/proxy/routes.js +115 -0
- package/dist/esm/src/proxy/types/rest.d.ts +10 -0
- package/dist/esm/src/proxy/types/rest.js +123 -0
- package/dist/esm/src/proxy/types/web.d.ts +8 -0
- package/dist/esm/src/proxy/types/web.js +61 -0
- package/dist/esm/src/repositoryManager.d.ts +35 -0
- package/dist/esm/src/repositoryManager.js +247 -0
- package/dist/esm/src/serviceManager.d.ts +36 -0
- package/dist/esm/src/serviceManager.js +106 -0
- package/dist/esm/src/socketManager.d.ts +32 -0
- package/dist/esm/src/socketManager.js +125 -0
- package/dist/esm/src/storageService.d.ts +21 -0
- package/dist/esm/src/storageService.js +81 -0
- package/dist/esm/src/taskManager.d.ts +70 -0
- package/dist/esm/src/taskManager.js +181 -0
- package/dist/esm/src/tasks/routes.d.ts +7 -0
- package/dist/esm/src/tasks/routes.js +39 -0
- package/dist/esm/src/traffic/routes.d.ts +7 -0
- package/dist/esm/src/traffic/routes.js +22 -0
- package/dist/esm/src/types.d.ts +99 -0
- package/dist/esm/src/types.js +39 -0
- package/dist/esm/src/utils/BlockInstanceRunner.d.ts +28 -0
- package/dist/esm/src/utils/BlockInstanceRunner.js +432 -0
- package/dist/esm/src/utils/DefaultProviderInstaller.d.ts +15 -0
- package/dist/esm/src/utils/DefaultProviderInstaller.js +136 -0
- package/dist/esm/src/utils/InternalConfigProvider.d.ts +38 -0
- package/dist/esm/src/utils/InternalConfigProvider.js +146 -0
- package/dist/esm/src/utils/LogData.d.ts +23 -0
- package/dist/esm/src/utils/LogData.js +46 -0
- package/dist/esm/src/utils/commandLineUtils.d.ts +8 -0
- package/dist/esm/src/utils/commandLineUtils.js +39 -0
- package/dist/esm/src/utils/pathTemplateParser.d.ts +30 -0
- package/dist/esm/src/utils/pathTemplateParser.js +135 -0
- package/dist/esm/src/utils/utils.d.ts +40 -0
- package/dist/esm/src/utils/utils.js +148 -0
- package/dist/esm/start.d.ts +5 -0
- package/dist/esm/start.js +17 -0
- package/dist/esm/test/proxy/types/rest.test.d.ts +5 -0
- package/dist/esm/test/proxy/types/rest.test.js +48 -0
- package/dist/esm/test/utils/pathTemplateParser.test.d.ts +5 -0
- package/dist/esm/test/utils/pathTemplateParser.test.js +27 -0
- package/index.ts +280 -0
- package/jest.config.js +8 -0
- package/package.json +134 -0
- package/src/RepositoryWatcher.ts +363 -0
- package/src/ai/aiClient.ts +93 -0
- package/src/ai/routes.ts +39 -0
- package/src/ai/transform.ts +275 -0
- package/src/ai/types.ts +45 -0
- package/src/api.ts +32 -0
- package/src/assetManager.ts +355 -0
- package/src/assets/routes.ts +183 -0
- package/src/attachments/routes.ts +79 -0
- package/src/authManager.ts +67 -0
- package/src/cacheManager.ts +59 -0
- package/src/clusterService.ts +142 -0
- package/src/codeGeneratorManager.ts +109 -0
- package/src/config/routes.ts +201 -0
- package/src/configManager.ts +180 -0
- package/src/containerManager.ts +1178 -0
- package/src/definitionsManager.ts +212 -0
- package/src/filesystem/routes.ts +123 -0
- package/src/filesystemManager.ts +133 -0
- package/src/identities/routes.ts +38 -0
- package/src/instanceManager.ts +1160 -0
- package/src/instances/routes.ts +203 -0
- package/src/middleware/cors.ts +14 -0
- package/src/middleware/kapeta.ts +41 -0
- package/src/middleware/stringBody.ts +21 -0
- package/src/networkManager.ts +148 -0
- package/src/operatorManager.ts +294 -0
- package/src/progressListener.ts +151 -0
- package/src/providerManager.ts +97 -0
- package/src/providers/routes.ts +51 -0
- package/src/proxy/routes.ts +153 -0
- package/src/proxy/types/rest.ts +172 -0
- package/src/proxy/types/web.ts +70 -0
- package/src/repositoryManager.ts +291 -0
- package/src/serviceManager.ts +133 -0
- package/src/socketManager.ts +138 -0
- package/src/storageService.ts +97 -0
- package/src/taskManager.ts +247 -0
- package/src/tasks/routes.ts +43 -0
- package/src/traffic/routes.ts +23 -0
- package/src/types.ts +112 -0
- package/src/utils/BlockInstanceRunner.ts +577 -0
- package/src/utils/DefaultProviderInstaller.ts +150 -0
- package/src/utils/InternalConfigProvider.ts +214 -0
- package/src/utils/LogData.ts +50 -0
- package/src/utils/commandLineUtils.ts +45 -0
- package/src/utils/pathTemplateParser.ts +157 -0
- package/src/utils/utils.ts +155 -0
- package/start.ts +14 -0
- package/test/proxy/types/rest.test.ts +54 -0
- package/test/utils/pathTemplateParser.test.ts +29 -0
- package/tsconfig.json +15 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* Copyright 2023 Kapeta Inc.
|
4
|
+
* SPDX-License-Identifier: BUSL-1.1
|
5
|
+
*/
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
7
|
+
exports.DesiredInstanceStatus = exports.InstanceStatus = exports.InstanceOwner = exports.InstanceType = exports.DOCKER_HOST_INTERNAL = exports.KIND_BLOCK_TYPE_EXECUTABLE = exports.KIND_BLOCK_TYPE_OPERATOR = exports.KIND_BLOCK_TYPE = exports.KIND_RESOURCE_OPERATOR = void 0;
|
8
|
+
exports.KIND_RESOURCE_OPERATOR = 'core/resource-type-operator';
|
9
|
+
exports.KIND_BLOCK_TYPE = 'core/block-type';
|
10
|
+
exports.KIND_BLOCK_TYPE_OPERATOR = 'core/block-type-operator';
|
11
|
+
exports.KIND_BLOCK_TYPE_EXECUTABLE = 'core/block-type-executable';
|
12
|
+
exports.DOCKER_HOST_INTERNAL = 'host.docker.internal';
|
13
|
+
var InstanceType;
|
14
|
+
(function (InstanceType) {
|
15
|
+
InstanceType["DOCKER"] = "docker";
|
16
|
+
InstanceType["LOCAL"] = "local";
|
17
|
+
InstanceType["UNKNOWN"] = "unknown";
|
18
|
+
})(InstanceType || (exports.InstanceType = InstanceType = {}));
|
19
|
+
var InstanceOwner;
|
20
|
+
(function (InstanceOwner) {
|
21
|
+
InstanceOwner["INTERNAL"] = "internal";
|
22
|
+
InstanceOwner["EXTERNAL"] = "external";
|
23
|
+
})(InstanceOwner || (exports.InstanceOwner = InstanceOwner = {}));
|
24
|
+
var InstanceStatus;
|
25
|
+
(function (InstanceStatus) {
|
26
|
+
InstanceStatus["STOPPED"] = "stopped";
|
27
|
+
InstanceStatus["STARTING"] = "starting";
|
28
|
+
InstanceStatus["BUSY"] = "busy";
|
29
|
+
InstanceStatus["READY"] = "ready";
|
30
|
+
InstanceStatus["STOPPING"] = "stopping";
|
31
|
+
InstanceStatus["UNHEALTHY"] = "unhealthy";
|
32
|
+
InstanceStatus["FAILED"] = "failed";
|
33
|
+
})(InstanceStatus || (exports.InstanceStatus = InstanceStatus = {}));
|
34
|
+
var DesiredInstanceStatus;
|
35
|
+
(function (DesiredInstanceStatus) {
|
36
|
+
DesiredInstanceStatus["STOP"] = "stop";
|
37
|
+
DesiredInstanceStatus["RUN"] = "run";
|
38
|
+
DesiredInstanceStatus["EXTERNAL"] = "external";
|
39
|
+
})(DesiredInstanceStatus || (exports.DesiredInstanceStatus = DesiredInstanceStatus = {}));
|
@@ -0,0 +1,28 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2023 Kapeta Inc.
|
3
|
+
* SPDX-License-Identifier: BUSL-1.1
|
4
|
+
*/
|
5
|
+
import { AnyMap, ProcessInfo } from '../types';
|
6
|
+
export declare function resolvePortType(portType: string): string;
|
7
|
+
export declare class BlockInstanceRunner {
|
8
|
+
private readonly _systemId;
|
9
|
+
constructor(systemId: string);
|
10
|
+
/**
|
11
|
+
* Start a block
|
12
|
+
*
|
13
|
+
*/
|
14
|
+
start(blockRef: string, instanceId: string, configuration: AnyMap): Promise<ProcessInfo>;
|
15
|
+
private _execute;
|
16
|
+
/**
|
17
|
+
* Starts local process
|
18
|
+
*/
|
19
|
+
private _startLocalProcess;
|
20
|
+
private _startDockerProcess;
|
21
|
+
private _startOperatorProcess;
|
22
|
+
/**
|
23
|
+
* Get the port bindings for a non-operator block
|
24
|
+
*/
|
25
|
+
private getServiceBlockPortBindings;
|
26
|
+
private ensureContainer;
|
27
|
+
private _handleContainer;
|
28
|
+
}
|
@@ -0,0 +1,432 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* Copyright 2023 Kapeta Inc.
|
4
|
+
* SPDX-License-Identifier: BUSL-1.1
|
5
|
+
*/
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
8
|
+
};
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
10
|
+
exports.BlockInstanceRunner = exports.resolvePortType = void 0;
|
11
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
12
|
+
const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
|
13
|
+
const utils_1 = require("./utils");
|
14
|
+
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
15
|
+
const serviceManager_1 = require("../serviceManager");
|
16
|
+
const containerManager_1 = require("../containerManager");
|
17
|
+
const LogData_1 = require("./LogData");
|
18
|
+
const clusterService_1 = require("../clusterService");
|
19
|
+
const types_1 = require("../types");
|
20
|
+
const definitionsManager_1 = require("../definitionsManager");
|
21
|
+
const node_os_1 = __importDefault(require("node:os"));
|
22
|
+
const node_path_1 = __importDefault(require("node:path"));
|
23
|
+
const taskManager_1 = require("../taskManager");
|
24
|
+
const InternalConfigProvider_1 = require("./InternalConfigProvider");
|
25
|
+
const config_mapper_1 = require("@kapeta/config-mapper");
|
26
|
+
const KAPETA_SYSTEM_ID = 'KAPETA_SYSTEM_ID';
|
27
|
+
const KAPETA_BLOCK_REF = 'KAPETA_BLOCK_REF';
|
28
|
+
const KAPETA_INSTANCE_ID = 'KAPETA_INSTANCE_ID';
|
29
|
+
/**
|
30
|
+
* Needed when running local docker containers as part of plan
|
31
|
+
* @type {string[]}
|
32
|
+
*/
|
33
|
+
const DOCKER_ENV_VARS = [
|
34
|
+
`KAPETA_LOCAL_SERVER=0.0.0.0`,
|
35
|
+
`KAPETA_LOCAL_CLUSTER_HOST=${types_1.DOCKER_HOST_INTERNAL}`,
|
36
|
+
`KAPETA_ENVIRONMENT_TYPE=docker`,
|
37
|
+
];
|
38
|
+
async function getProvider(uri) {
|
39
|
+
const providers = await definitionsManager_1.definitionsManager.getProviderDefinitions();
|
40
|
+
return providers.find((provider) => {
|
41
|
+
const ref = `${provider.definition.metadata.name}:${provider.version}`;
|
42
|
+
return (0, nodejs_utils_1.parseKapetaUri)(ref).id === uri.id;
|
43
|
+
});
|
44
|
+
}
|
45
|
+
function resolvePortType(portType) {
|
46
|
+
if (portType && serviceManager_1.HTTP_PORTS.includes(portType.toLowerCase())) {
|
47
|
+
return serviceManager_1.HTTP_PORT_TYPE;
|
48
|
+
}
|
49
|
+
return portType;
|
50
|
+
}
|
51
|
+
exports.resolvePortType = resolvePortType;
|
52
|
+
/**
|
53
|
+
* Get the port types for a non-operator block instance
|
54
|
+
*/
|
55
|
+
function getServiceProviderPorts(assetVersion, providerVersion) {
|
56
|
+
const out = assetVersion.definition?.spec?.providers
|
57
|
+
?.filter((provider) => {
|
58
|
+
// We only support HTTP provider ports for now. Need to figure out how to handle other types
|
59
|
+
return serviceManager_1.HTTP_PORTS.includes(provider.spec?.port?.type?.toLowerCase());
|
60
|
+
})
|
61
|
+
?.map((provider) => {
|
62
|
+
return resolvePortType(provider.spec?.port?.type?.toLowerCase());
|
63
|
+
})
|
64
|
+
.filter((t) => !!t) ?? [];
|
65
|
+
if (out.length === 0) {
|
66
|
+
if (providerVersion.definition.spec?.defaultPort?.type) {
|
67
|
+
return [resolvePortType(providerVersion.definition.spec?.defaultPort?.type)];
|
68
|
+
}
|
69
|
+
return [resolvePortType(serviceManager_1.DEFAULT_PORT_TYPE)];
|
70
|
+
}
|
71
|
+
// Duplicated port types are not allowed
|
72
|
+
return Array.from(new Set(out));
|
73
|
+
}
|
74
|
+
class BlockInstanceRunner {
|
75
|
+
_systemId;
|
76
|
+
constructor(systemId) {
|
77
|
+
/**
|
78
|
+
*
|
79
|
+
* @type {string}
|
80
|
+
* @private
|
81
|
+
*/
|
82
|
+
this._systemId = (0, nodejs_utils_1.normalizeKapetaUri)(systemId);
|
83
|
+
}
|
84
|
+
/**
|
85
|
+
* Start a block
|
86
|
+
*
|
87
|
+
*/
|
88
|
+
async start(blockRef, instanceId, configuration) {
|
89
|
+
return this._execute({
|
90
|
+
ref: blockRef,
|
91
|
+
id: instanceId,
|
92
|
+
configuration,
|
93
|
+
});
|
94
|
+
}
|
95
|
+
async _execute(blockInstance) {
|
96
|
+
const blockUri = (0, nodejs_utils_1.parseKapetaUri)(blockInstance.ref);
|
97
|
+
if (!blockUri.version) {
|
98
|
+
blockUri.version = 'local';
|
99
|
+
}
|
100
|
+
const assetVersion = await definitionsManager_1.definitionsManager.getDefinition(blockUri.id);
|
101
|
+
if (!assetVersion) {
|
102
|
+
throw new Error(`Block definition not found: ${blockUri.id}`);
|
103
|
+
}
|
104
|
+
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.kind);
|
105
|
+
const providerVersion = await getProvider(kindUri);
|
106
|
+
if (!providerVersion) {
|
107
|
+
throw new Error(`Kind not found: ${kindUri.id}`);
|
108
|
+
}
|
109
|
+
const baseDir = local_cluster_config_1.default.getRepositoryAssetPath(blockUri.handle, blockUri.name, blockUri.version);
|
110
|
+
const realBaseDir = await fs_extra_1.default.realpath(baseDir);
|
111
|
+
const internalConfigProvider = await (0, InternalConfigProvider_1.createInternalConfigProvider)(this._systemId, blockInstance.id, assetVersion);
|
112
|
+
// Resolve the environment variables
|
113
|
+
const envVars = await (0, config_mapper_1.resolveKapetaVariables)(realBaseDir, internalConfigProvider);
|
114
|
+
// Write out the config templates if they exist
|
115
|
+
await (0, config_mapper_1.writeConfigTemplates)(envVars, realBaseDir);
|
116
|
+
let processInfo;
|
117
|
+
if (providerVersion.definition.kind === types_1.KIND_BLOCK_TYPE_OPERATOR) {
|
118
|
+
processInfo = await this._startOperatorProcess(blockInstance, blockUri, providerVersion, envVars);
|
119
|
+
}
|
120
|
+
else {
|
121
|
+
//We need a port type to know how to connect to the block consistently
|
122
|
+
const portTypes = getServiceProviderPorts(assetVersion, providerVersion);
|
123
|
+
if (blockUri.version === 'local') {
|
124
|
+
processInfo = await this._startLocalProcess(blockInstance, blockUri, envVars, assetVersion);
|
125
|
+
}
|
126
|
+
else {
|
127
|
+
processInfo = await this._startDockerProcess(blockInstance, blockUri, envVars, assetVersion);
|
128
|
+
}
|
129
|
+
if (portTypes.length > 0) {
|
130
|
+
processInfo.portType = portTypes[0];
|
131
|
+
}
|
132
|
+
}
|
133
|
+
return processInfo;
|
134
|
+
}
|
135
|
+
/**
|
136
|
+
* Starts local process
|
137
|
+
*/
|
138
|
+
async _startLocalProcess(blockInstance, blockInfo, env, assetVersion) {
|
139
|
+
const baseDir = local_cluster_config_1.default.getRepositoryAssetPath(blockInfo.handle, blockInfo.name, blockInfo.version);
|
140
|
+
if (!fs_extra_1.default.existsSync(baseDir)) {
|
141
|
+
throw new Error(`Local block not registered correctly - expected symlink here: ${baseDir}.\n` +
|
142
|
+
`Make sure you've run "kap registry link" in your local directory to connect it to Kapeta`);
|
143
|
+
}
|
144
|
+
if (!assetVersion.definition.spec?.target?.kind) {
|
145
|
+
throw new Error('Missing target kind in block definition');
|
146
|
+
}
|
147
|
+
const realLocalPath = await fs_extra_1.default.realpath(baseDir);
|
148
|
+
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.kind);
|
149
|
+
const providerVersion = await getProvider(kindUri);
|
150
|
+
if (!providerVersion) {
|
151
|
+
throw new Error(`Block type not found: ${kindUri.id}`);
|
152
|
+
}
|
153
|
+
const targetKindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.spec?.target?.kind);
|
154
|
+
const targetVersion = await getProvider(targetKindUri);
|
155
|
+
if (!targetVersion) {
|
156
|
+
throw new Error(`Target not found: ${targetKindUri.id}`);
|
157
|
+
}
|
158
|
+
const localContainer = targetVersion.definition.spec.local;
|
159
|
+
if (!localContainer) {
|
160
|
+
throw new Error(`Missing local container information from target: ${targetKindUri.id}`);
|
161
|
+
}
|
162
|
+
let dockerImage = localContainer.image;
|
163
|
+
const isDockerImage = !localContainer.type || localContainer.type.toLowerCase() === 'docker';
|
164
|
+
const isDockerFile = Boolean(localContainer.type && localContainer.type.toLowerCase() === 'dockerfile');
|
165
|
+
if (isDockerImage && !dockerImage) {
|
166
|
+
throw new Error(`Missing docker image information: ${JSON.stringify(localContainer)}`);
|
167
|
+
}
|
168
|
+
if (isDockerFile) {
|
169
|
+
dockerImage = blockInfo.fullName + ':local';
|
170
|
+
const dockerFile = node_path_1.default.join(realLocalPath, localContainer.file ?? 'Dockerfile');
|
171
|
+
if (!fs_extra_1.default.existsSync(dockerFile)) {
|
172
|
+
throw new Error(`Dockerfile not found at: ${dockerFile}`);
|
173
|
+
}
|
174
|
+
const task = containerManager_1.containerManager.buildDockerImage(dockerFile, blockInfo.fullName + ':local');
|
175
|
+
await task.wait();
|
176
|
+
}
|
177
|
+
const containerName = await (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id, targetKindUri.id);
|
178
|
+
const startCmd = localContainer.handlers?.onCreate ? localContainer.handlers.onCreate : '';
|
179
|
+
const dockerOpts = localContainer.options ?? {};
|
180
|
+
const homeDir = localContainer.userHome ? localContainer.userHome : '/root';
|
181
|
+
const workingDir = localContainer.workingDir ? localContainer.workingDir : '/workspace';
|
182
|
+
const customHostConfigs = localContainer.HostConfig ?? {};
|
183
|
+
const Binds = customHostConfigs.Binds ?? [];
|
184
|
+
delete customHostConfigs.Binds;
|
185
|
+
const customLabels = localContainer.Labels ?? {};
|
186
|
+
const customEnvs = localContainer.Env ?? [];
|
187
|
+
delete localContainer.HostConfig;
|
188
|
+
delete localContainer.Labels;
|
189
|
+
delete localContainer.Env;
|
190
|
+
const { PortBindings, ExposedPorts, addonEnv } = await this.getServiceBlockPortBindings(blockInstance, assetVersion, providerVersion);
|
191
|
+
let HealthCheck = undefined;
|
192
|
+
if (localContainer.healthcheck) {
|
193
|
+
HealthCheck = containerManager_1.containerManager.toDockerHealth({ cmd: localContainer.healthcheck });
|
194
|
+
}
|
195
|
+
const Mounts = isDockerImage
|
196
|
+
? // For docker images we mount the local directory to the working directory
|
197
|
+
containerManager_1.containerManager.toDockerMounts({
|
198
|
+
[workingDir]: (0, containerManager_1.toLocalBindVolume)(realLocalPath),
|
199
|
+
})
|
200
|
+
: // For dockerfiles we don't mount anything
|
201
|
+
[];
|
202
|
+
const systemUri = (0, nodejs_utils_1.parseKapetaUri)(this._systemId);
|
203
|
+
return this.ensureContainer({
|
204
|
+
...dockerOpts,
|
205
|
+
Image: dockerImage,
|
206
|
+
name: containerName,
|
207
|
+
WorkingDir: workingDir,
|
208
|
+
Labels: {
|
209
|
+
...customLabels,
|
210
|
+
instance: blockInstance.id,
|
211
|
+
[containerManager_1.COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
|
212
|
+
[containerManager_1.COMPOSE_LABEL_SERVICE]: blockInfo.id.replace(/[^a-z0-9]/gi, '_'),
|
213
|
+
},
|
214
|
+
HealthCheck,
|
215
|
+
ExposedPorts,
|
216
|
+
Cmd: startCmd ? startCmd.split(/\s+/g) : [],
|
217
|
+
Env: [
|
218
|
+
...customEnvs,
|
219
|
+
...DOCKER_ENV_VARS,
|
220
|
+
`KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
|
221
|
+
...Object.entries({
|
222
|
+
...env,
|
223
|
+
...addonEnv,
|
224
|
+
}).map(([key, value]) => `${key}=${value}`),
|
225
|
+
],
|
226
|
+
HostConfig: {
|
227
|
+
...customHostConfigs,
|
228
|
+
Binds: [
|
229
|
+
`${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${homeDir}/.kapeta`,
|
230
|
+
...Binds.map((bind) => {
|
231
|
+
let [host, container] = bind.split(':');
|
232
|
+
if (host.startsWith('~')) {
|
233
|
+
host = node_os_1.default.homedir() + host.substring(1);
|
234
|
+
}
|
235
|
+
if (container.startsWith('~')) {
|
236
|
+
container = homeDir + container.substring(1);
|
237
|
+
}
|
238
|
+
return `${(0, containerManager_1.toLocalBindVolume)(host)}:${container}`;
|
239
|
+
}),
|
240
|
+
],
|
241
|
+
PortBindings,
|
242
|
+
Mounts,
|
243
|
+
},
|
244
|
+
});
|
245
|
+
}
|
246
|
+
async _startDockerProcess(blockInstance, blockInfo, env, assetVersion) {
|
247
|
+
const { versionFile } = local_cluster_config_1.default.getRepositoryAssetInfoPath(blockInfo.handle, blockInfo.name, blockInfo.version);
|
248
|
+
const versionYml = versionFile;
|
249
|
+
if (!fs_extra_1.default.existsSync(versionYml)) {
|
250
|
+
throw new Error(`Did not find version info at the expected path: ${versionYml}`);
|
251
|
+
}
|
252
|
+
const versionInfo = (0, utils_1.readYML)(versionYml);
|
253
|
+
if (versionInfo?.artifact?.type !== 'docker') {
|
254
|
+
throw new Error(`Unsupported artifact type: ${versionInfo?.artifact?.type}`);
|
255
|
+
}
|
256
|
+
const dockerImage = versionInfo?.artifact?.details?.primary;
|
257
|
+
if (!dockerImage) {
|
258
|
+
throw new Error(`Missing docker image information: ${JSON.stringify(versionInfo?.artifact?.details)}`);
|
259
|
+
}
|
260
|
+
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(assetVersion.definition.kind);
|
261
|
+
const providerVersion = await getProvider(kindUri);
|
262
|
+
if (!providerVersion) {
|
263
|
+
throw new Error(`Block type not found: ${kindUri.id}`);
|
264
|
+
}
|
265
|
+
const { PortBindings, ExposedPorts, addonEnv } = await this.getServiceBlockPortBindings(blockInstance, assetVersion, providerVersion);
|
266
|
+
const containerName = await (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id, kindUri.id);
|
267
|
+
// For windows we need to default to root
|
268
|
+
const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
|
269
|
+
const systemUri = (0, nodejs_utils_1.parseKapetaUri)(this._systemId);
|
270
|
+
return this.ensureContainer({
|
271
|
+
Image: dockerImage,
|
272
|
+
name: containerName,
|
273
|
+
ExposedPorts,
|
274
|
+
Labels: {
|
275
|
+
instance: blockInstance.id,
|
276
|
+
[containerManager_1.COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
|
277
|
+
[containerManager_1.COMPOSE_LABEL_SERVICE]: blockInfo.id.replace(/[^a-z0-9]/gi, '_'),
|
278
|
+
},
|
279
|
+
Env: [
|
280
|
+
...DOCKER_ENV_VARS,
|
281
|
+
`KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
|
282
|
+
...Object.entries({
|
283
|
+
...env,
|
284
|
+
...addonEnv,
|
285
|
+
}).map(([key, value]) => `${key}=${value}`),
|
286
|
+
],
|
287
|
+
HostConfig: {
|
288
|
+
Binds: [`${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`],
|
289
|
+
PortBindings,
|
290
|
+
},
|
291
|
+
});
|
292
|
+
}
|
293
|
+
async _startOperatorProcess(blockInstance, blockUri, providerDefinition, env) {
|
294
|
+
const { assetFile } = local_cluster_config_1.default.getRepositoryAssetInfoPath(blockUri.handle, blockUri.name, blockUri.version);
|
295
|
+
const kapetaYmlPath = assetFile;
|
296
|
+
if (!fs_extra_1.default.existsSync(kapetaYmlPath)) {
|
297
|
+
throw new Error(`Did not find kapeta.yml at the expected path: ${kapetaYmlPath}`);
|
298
|
+
}
|
299
|
+
const spec = providerDefinition.definition.spec;
|
300
|
+
const providerRef = `${providerDefinition.definition.metadata.name}:${providerDefinition.version}`;
|
301
|
+
if (!spec?.local?.image) {
|
302
|
+
throw new Error(`Provider did not have local image: ${providerRef}`);
|
303
|
+
}
|
304
|
+
const local = spec.local;
|
305
|
+
const dockerImage = local.image;
|
306
|
+
const operatorUri = local.singleton ? (0, nodejs_utils_1.parseKapetaUri)(providerRef) : blockUri;
|
307
|
+
const operatorId = local.singleton ? providerRef : blockInstance.id;
|
308
|
+
const operatorRef = local.singleton ? providerRef : blockInstance.ref;
|
309
|
+
if (local.singleton && env) {
|
310
|
+
env[KAPETA_BLOCK_REF] = operatorRef;
|
311
|
+
env[KAPETA_INSTANCE_ID] = operatorId;
|
312
|
+
}
|
313
|
+
const containerName = await (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id, providerRef);
|
314
|
+
const task = taskManager_1.taskManager.add(`container:start:${containerName}`, async () => {
|
315
|
+
const logs = new LogData_1.LogData();
|
316
|
+
const hostIp = (0, utils_1.getDockerHostIp)();
|
317
|
+
const ExposedPorts = {};
|
318
|
+
const addonEnv = {};
|
319
|
+
const PortBindings = {};
|
320
|
+
let HealthCheck = undefined;
|
321
|
+
let Mounts = [];
|
322
|
+
const instancePorts = await (0, utils_1.getOperatorInstancePorts)(this._systemId, operatorId, local);
|
323
|
+
const labels = {};
|
324
|
+
instancePorts.forEach((portInfo) => {
|
325
|
+
const dockerPort = `${portInfo.port}/${portInfo.protocol}`;
|
326
|
+
ExposedPorts[dockerPort] = {};
|
327
|
+
addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portInfo.portType.toUpperCase()}`] = `${portInfo.port}`;
|
328
|
+
PortBindings[dockerPort] = [
|
329
|
+
{
|
330
|
+
HostIp: hostIp,
|
331
|
+
HostPort: `${portInfo.hostPort}`,
|
332
|
+
},
|
333
|
+
];
|
334
|
+
labels[containerManager_1.CONTAINER_LABEL_PORT_PREFIX + portInfo.hostPort] = portInfo.portType;
|
335
|
+
});
|
336
|
+
if (local.env) {
|
337
|
+
Object.entries(local.env).forEach(([key, value]) => {
|
338
|
+
addonEnv[key] = value;
|
339
|
+
});
|
340
|
+
}
|
341
|
+
if (local.mounts) {
|
342
|
+
Mounts = await containerManager_1.containerManager.createVolumes(this._systemId, operatorUri.id, local.mounts);
|
343
|
+
}
|
344
|
+
if (local.health) {
|
345
|
+
HealthCheck = containerManager_1.containerManager.toDockerHealth(local.health);
|
346
|
+
}
|
347
|
+
// For windows we need to default to root
|
348
|
+
const innerHome = process.platform === 'win32' ? '/root/.kapeta' : local_cluster_config_1.default.getKapetaBasedir();
|
349
|
+
const Binds = local.singleton
|
350
|
+
? [`${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`]
|
351
|
+
: [
|
352
|
+
`${(0, containerManager_1.toLocalBindVolume)(kapetaYmlPath)}:/kapeta.yml:ro`,
|
353
|
+
`${(0, containerManager_1.toLocalBindVolume)(local_cluster_config_1.default.getKapetaBasedir())}:${innerHome}`,
|
354
|
+
];
|
355
|
+
const systemUri = (0, nodejs_utils_1.parseKapetaUri)(this._systemId);
|
356
|
+
console.log(`Ensuring container for operator block: ${containerName} [singleton: ${!!local.singleton}]`);
|
357
|
+
logs.addLog(`Ensuring container for operator block: ${containerName}`);
|
358
|
+
const out = await this.ensureContainer({
|
359
|
+
Image: dockerImage,
|
360
|
+
name: containerName,
|
361
|
+
ExposedPorts,
|
362
|
+
HealthCheck,
|
363
|
+
HostConfig: {
|
364
|
+
Binds,
|
365
|
+
PortBindings,
|
366
|
+
Mounts,
|
367
|
+
},
|
368
|
+
Labels: {
|
369
|
+
...labels,
|
370
|
+
instance: operatorId,
|
371
|
+
[containerManager_1.COMPOSE_LABEL_PROJECT]: systemUri.id.replace(/[^a-z0-9]/gi, '_'),
|
372
|
+
[containerManager_1.COMPOSE_LABEL_SERVICE]: operatorUri.id.replace(/[^a-z0-9]/gi, '_'),
|
373
|
+
},
|
374
|
+
Env: [
|
375
|
+
`KAPETA_INSTANCE_NAME=${operatorRef}`,
|
376
|
+
`KAPETA_LOCAL_CLUSTER_PORT=${clusterService_1.clusterService.getClusterServicePort()}`,
|
377
|
+
...DOCKER_ENV_VARS,
|
378
|
+
...Object.entries({
|
379
|
+
...env,
|
380
|
+
...addonEnv,
|
381
|
+
}).map(([key, value]) => `${key}=${value}`),
|
382
|
+
],
|
383
|
+
});
|
384
|
+
const portTypes = local.ports ? Object.keys(local.ports) : [];
|
385
|
+
if (portTypes.length > 0) {
|
386
|
+
out.portType = portTypes[0];
|
387
|
+
}
|
388
|
+
return out;
|
389
|
+
}, {
|
390
|
+
name: `Starting container for ${providerRef}`,
|
391
|
+
systemId: this._systemId,
|
392
|
+
});
|
393
|
+
return task.wait();
|
394
|
+
}
|
395
|
+
/**
|
396
|
+
* Get the port bindings for a non-operator block
|
397
|
+
*/
|
398
|
+
async getServiceBlockPortBindings(blockInstance, assetVersion, providerVersion) {
|
399
|
+
const hostIp = (0, utils_1.getDockerHostIp)();
|
400
|
+
const ExposedPorts = {};
|
401
|
+
const addonEnv = {};
|
402
|
+
const PortBindings = {};
|
403
|
+
const portTypes = getServiceProviderPorts(assetVersion, providerVersion);
|
404
|
+
let port = 80;
|
405
|
+
const promises = portTypes.map(async (portType) => {
|
406
|
+
const publicPort = await serviceManager_1.serviceManager.ensureServicePort(this._systemId, blockInstance.id, portType);
|
407
|
+
const thisPort = port++; //TODO: Not sure how we should handle multiple ports or non-HTTP ports
|
408
|
+
const dockerPort = `${thisPort}/tcp`;
|
409
|
+
ExposedPorts[dockerPort] = {};
|
410
|
+
addonEnv[`KAPETA_LOCAL_SERVER_PORT_${portType.toUpperCase()}`] = '' + thisPort;
|
411
|
+
PortBindings[dockerPort] = [
|
412
|
+
{
|
413
|
+
HostIp: hostIp,
|
414
|
+
HostPort: `${publicPort}`,
|
415
|
+
},
|
416
|
+
];
|
417
|
+
});
|
418
|
+
await Promise.all(promises);
|
419
|
+
return { PortBindings, ExposedPorts, addonEnv };
|
420
|
+
}
|
421
|
+
async ensureContainer(opts) {
|
422
|
+
const container = await containerManager_1.containerManager.ensureContainer(opts);
|
423
|
+
return this._handleContainer(container);
|
424
|
+
}
|
425
|
+
async _handleContainer(container) {
|
426
|
+
return {
|
427
|
+
type: types_1.InstanceType.DOCKER,
|
428
|
+
pid: container.id,
|
429
|
+
};
|
430
|
+
}
|
431
|
+
}
|
432
|
+
exports.BlockInstanceRunner = BlockInstanceRunner;
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2023 Kapeta Inc.
|
3
|
+
* SPDX-License-Identifier: BUSL-1.1
|
4
|
+
*/
|
5
|
+
declare class DefaultProviderInstaller {
|
6
|
+
private readonly progressListener;
|
7
|
+
checkForDefault(): Promise<void>;
|
8
|
+
private install;
|
9
|
+
private linkLocal;
|
10
|
+
private scanProjectBase;
|
11
|
+
private ensureDefaultProjectHome;
|
12
|
+
private download;
|
13
|
+
}
|
14
|
+
export declare const defaultProviderInstaller: DefaultProviderInstaller;
|
15
|
+
export {};
|
@@ -0,0 +1,136 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* Copyright 2023 Kapeta Inc.
|
4
|
+
* SPDX-License-Identifier: BUSL-1.1
|
5
|
+
*/
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
8
|
+
};
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
10
|
+
exports.defaultProviderInstaller = void 0;
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
12
|
+
const node_os_1 = __importDefault(require("node:os"));
|
13
|
+
const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
|
14
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
15
|
+
const request_1 = __importDefault(require("request"));
|
16
|
+
const tar_stream_1 = require("tar-stream");
|
17
|
+
const gunzip_maybe_1 = __importDefault(require("gunzip-maybe"));
|
18
|
+
const filesystemManager_1 = require("../filesystemManager");
|
19
|
+
const nodejs_registry_utils_1 = require("@kapeta/nodejs-registry-utils");
|
20
|
+
const progressListener_1 = require("../progressListener");
|
21
|
+
const glob_1 = require("glob");
|
22
|
+
const PROVIDERS_FILENAME = local_cluster_config_1.default.getEnvironment() === 'staging'
|
23
|
+
? 'default-providers-staging.tar.gz'
|
24
|
+
: 'default-providers.tar.gz';
|
25
|
+
const DEFAULT_PROVIDERS_URL = `https://storage.googleapis.com/kapeta-production-cdn/archives/${PROVIDERS_FILENAME}`;
|
26
|
+
const DEFAULT_PROJECT_HOME_DIR = 'KapetaProjects';
|
27
|
+
const ARCHIVE_LOCAL_PREFIX = 'local';
|
28
|
+
class DefaultProviderInstaller {
|
29
|
+
progressListener = new progressListener_1.ProgressListener();
|
30
|
+
async checkForDefault() {
|
31
|
+
const definitions = local_cluster_config_1.default.getDefinitions();
|
32
|
+
if (definitions.length < 1) {
|
33
|
+
console.log('Installing default providers');
|
34
|
+
try {
|
35
|
+
await this.install();
|
36
|
+
}
|
37
|
+
catch (e) {
|
38
|
+
console.warn('Failed to install defaults', e);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
async install() {
|
43
|
+
await this.download();
|
44
|
+
await this.linkLocal();
|
45
|
+
}
|
46
|
+
async linkLocal() {
|
47
|
+
const projectBase = await this.ensureDefaultProjectHome();
|
48
|
+
const folders = this.scanProjectBase(projectBase);
|
49
|
+
for (let folder of folders) {
|
50
|
+
console.log('Linking %s', folder);
|
51
|
+
await nodejs_registry_utils_1.Actions.link(this.progressListener, folder);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
scanProjectBase(projectBase) {
|
55
|
+
const assetFiles = glob_1.glob.sync('*/**/kapeta.yml', { cwd: projectBase });
|
56
|
+
return assetFiles.map((assetFile) => {
|
57
|
+
return node_path_1.default.dirname(node_path_1.default.join(projectBase, assetFile));
|
58
|
+
});
|
59
|
+
}
|
60
|
+
async ensureDefaultProjectHome() {
|
61
|
+
const defaultProjectHome = node_path_1.default.join(node_os_1.default.homedir(), DEFAULT_PROJECT_HOME_DIR);
|
62
|
+
let projectBase = filesystemManager_1.filesystemManager.getProjectRootFolder();
|
63
|
+
if (!projectBase) {
|
64
|
+
filesystemManager_1.filesystemManager.setProjectRootFolder(defaultProjectHome);
|
65
|
+
projectBase = defaultProjectHome;
|
66
|
+
if (!(await fs_extra_1.default.pathExists(projectBase))) {
|
67
|
+
await fs_extra_1.default.mkdirp(projectBase);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
return projectBase;
|
71
|
+
}
|
72
|
+
async download() {
|
73
|
+
const projectBase = await this.ensureDefaultProjectHome();
|
74
|
+
const repoBase = local_cluster_config_1.default.getRepositoryBasedir();
|
75
|
+
return new Promise((resolve, reject) => {
|
76
|
+
const extractor = (0, tar_stream_1.extract)();
|
77
|
+
const dirCache = new Set();
|
78
|
+
extractor.on('entry', async function (header, stream, next) {
|
79
|
+
if (header.type !== 'file') {
|
80
|
+
stream.on('end', function () {
|
81
|
+
next(); // ready for next entry
|
82
|
+
});
|
83
|
+
stream.resume(); // just auto drain the stream
|
84
|
+
return;
|
85
|
+
}
|
86
|
+
// Local (editable) assets should be stored in the project folder
|
87
|
+
// - installed assets goes into the repository folder
|
88
|
+
const baseDir = header.name.startsWith(ARCHIVE_LOCAL_PREFIX) ? projectBase : repoBase;
|
89
|
+
const parts = header.name.split(/\//g);
|
90
|
+
parts.shift();
|
91
|
+
const filename = parts.join(node_path_1.default.sep);
|
92
|
+
try {
|
93
|
+
const dirname = node_path_1.default.join(baseDir, node_path_1.default.dirname(filename));
|
94
|
+
if (!dirCache.has(dirname)) {
|
95
|
+
let dirExists = false;
|
96
|
+
try {
|
97
|
+
await fs_extra_1.default.stat(dirname);
|
98
|
+
dirExists = true;
|
99
|
+
}
|
100
|
+
catch (e) { }
|
101
|
+
if (!dirExists) {
|
102
|
+
await fs_extra_1.default.mkdirp(dirname);
|
103
|
+
}
|
104
|
+
dirCache.add(dirname);
|
105
|
+
}
|
106
|
+
const fileTarget = node_path_1.default.join(baseDir, filename);
|
107
|
+
stream.on('error', (err) => {
|
108
|
+
reject(err);
|
109
|
+
});
|
110
|
+
stream.on('end', next);
|
111
|
+
stream.pipe(fs_extra_1.default.createWriteStream(fileTarget, {
|
112
|
+
mode: header.mode,
|
113
|
+
}));
|
114
|
+
}
|
115
|
+
catch (e) {
|
116
|
+
reject(e);
|
117
|
+
}
|
118
|
+
});
|
119
|
+
extractor.on('finish', function () {
|
120
|
+
// all entries done - lets finalize it
|
121
|
+
console.log('Default providers installed');
|
122
|
+
resolve();
|
123
|
+
});
|
124
|
+
extractor.on('error', function (err) {
|
125
|
+
reject(err);
|
126
|
+
});
|
127
|
+
console.log('Downloading default providers from %s', DEFAULT_PROVIDERS_URL);
|
128
|
+
const response = (0, request_1.default)(DEFAULT_PROVIDERS_URL);
|
129
|
+
response.on('error', function (err) {
|
130
|
+
reject(err);
|
131
|
+
});
|
132
|
+
response.pipe((0, gunzip_maybe_1.default)()).pipe(extractor);
|
133
|
+
});
|
134
|
+
}
|
135
|
+
}
|
136
|
+
exports.defaultProviderInstaller = new DefaultProviderInstaller();
|