@kapeta/local-cluster-service 0.40.1 → 0.40.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/codeGeneratorManager.js +2 -2
- package/dist/cjs/src/containerManager.js +15 -5
- package/dist/cjs/src/definitionsManager.d.ts +1 -1
- package/dist/cjs/src/definitionsManager.js +10 -2
- package/dist/cjs/src/proxy/types/rest.js +5 -0
- package/dist/cjs/src/proxy/types/web.js +2 -2
- package/dist/cjs/src/utils/BlockInstanceRunner.js +11 -4
- package/dist/cjs/src/utils/InternalConfigProvider.js +2 -2
- package/dist/esm/src/codeGeneratorManager.js +2 -2
- package/dist/esm/src/containerManager.js +15 -5
- package/dist/esm/src/definitionsManager.d.ts +1 -1
- package/dist/esm/src/definitionsManager.js +10 -2
- package/dist/esm/src/proxy/types/rest.js +5 -0
- package/dist/esm/src/proxy/types/web.js +2 -2
- package/dist/esm/src/utils/BlockInstanceRunner.js +11 -4
- package/dist/esm/src/utils/InternalConfigProvider.js +2 -2
- package/package.json +1 -1
- package/src/codeGeneratorManager.ts +2 -2
- package/src/containerManager.ts +20 -12
- package/src/definitionsManager.ts +13 -6
- package/src/proxy/types/rest.ts +5 -0
- package/src/proxy/types/web.ts +2 -2
- package/src/utils/BlockInstanceRunner.ts +12 -4
- package/src/utils/InternalConfigProvider.ts +2 -2
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## [0.40.3](https://github.com/kapetacom/local-cluster-service/compare/v0.40.2...v0.40.3) (2024-03-26)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* codegen for 'core/block-type.*' regexp ([8e544b0](https://github.com/kapetacom/local-cluster-service/commit/8e544b0ca91acf0b467e60ee0249a5a96ece6393))
|
7
|
+
|
8
|
+
## [0.40.2](https://github.com/kapetacom/local-cluster-service/compare/v0.40.1...v0.40.2) (2024-03-11)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Several issues when running external docker images ([#132](https://github.com/kapetacom/local-cluster-service/issues/132)) ([5218368](https://github.com/kapetacom/local-cluster-service/commit/521836819aa39084fe1c4f781fb560682e42fc8f))
|
14
|
+
|
1
15
|
## [0.40.1](https://github.com/kapetacom/local-cluster-service/compare/v0.40.0...v0.40.1) (2024-02-28)
|
2
16
|
|
3
17
|
|
@@ -15,7 +15,7 @@ const assetManager_1 = require("./assetManager");
|
|
15
15
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
16
16
|
const repositoryManager_1 = require("./repositoryManager");
|
17
17
|
const TARGET_KIND = 'core/language-target';
|
18
|
-
const
|
18
|
+
const BLOCK_TYPE_REGEX = /^core\/block-type.*/;
|
19
19
|
class CodeGeneratorManager {
|
20
20
|
async ensureLanguageTargetInRegistry(path, version, definition) {
|
21
21
|
const key = `${definition.metadata.name}:${version}`;
|
@@ -63,7 +63,7 @@ class CodeGeneratorManager {
|
|
63
63
|
return false;
|
64
64
|
}
|
65
65
|
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(yamlContent.kind);
|
66
|
-
const blockTypes = await definitionsManager_1.definitionsManager.getDefinitions(
|
66
|
+
const blockTypes = await definitionsManager_1.definitionsManager.getDefinitions([BLOCK_TYPE_REGEX]);
|
67
67
|
const blockTypeKinds = blockTypes.map((blockType) => (0, nodejs_utils_1.parseKapetaUri)(blockType.definition.metadata.name).fullName);
|
68
68
|
return blockTypeKinds.includes(kindUri.fullName);
|
69
69
|
}
|
@@ -216,6 +216,10 @@ class ContainerManager {
|
|
216
216
|
if (!tag) {
|
217
217
|
tag = 'latest';
|
218
218
|
}
|
219
|
+
if (tag === 'local') {
|
220
|
+
// Local image - no need to pull
|
221
|
+
return false;
|
222
|
+
}
|
219
223
|
const imageTagList = (await this.docker().listImages({}))
|
220
224
|
.filter((imageData) => !!imageData.RepoTags)
|
221
225
|
.map((imageData) => imageData.RepoTags);
|
@@ -619,16 +623,22 @@ class ContainerManager {
|
|
619
623
|
buildDockerImage(dockerFile, imageName) {
|
620
624
|
const taskName = `Building docker image: ${imageName}`;
|
621
625
|
const processor = async (task) => {
|
622
|
-
const
|
623
|
-
const
|
626
|
+
const baseDir = path_1.default.dirname(dockerFile);
|
627
|
+
const entries = await fs_extra_1.default.readdir(baseDir);
|
628
|
+
const contextInfo = {
|
624
629
|
context: path_1.default.dirname(dockerFile),
|
625
|
-
src:
|
626
|
-
}
|
630
|
+
src: entries,
|
631
|
+
};
|
632
|
+
const stream = await this.docker().buildImage(contextInfo, {
|
627
633
|
t: imageName,
|
628
634
|
dockerfile: path_1.default.basename(dockerFile),
|
629
635
|
});
|
630
636
|
await processJsonStream(`image:build:${imageName}`, stream, (data) => {
|
631
|
-
if (data.
|
637
|
+
if (data.error) {
|
638
|
+
task.future.reject(new Error(data.error));
|
639
|
+
task.addLog(data.error, 'ERROR');
|
640
|
+
}
|
641
|
+
else if (data.stream) {
|
632
642
|
// Emit raw output to the task log
|
633
643
|
task.addLog(data.stream);
|
634
644
|
}
|
@@ -8,7 +8,7 @@ declare class DefinitionsManager {
|
|
8
8
|
private resolveDefinitionsAndSamples;
|
9
9
|
private prepareSample;
|
10
10
|
private applyFilters;
|
11
|
-
getDefinitions(kindFilter?: string | string[]): Promise<DefinitionInfo[]>;
|
11
|
+
getDefinitions(kindFilter?: string | (string | RegExp)[]): Promise<DefinitionInfo[]>;
|
12
12
|
exists(ref: string): Promise<boolean>;
|
13
13
|
getProviderDefinitions(): Promise<DefinitionInfo[]>;
|
14
14
|
getDefinition(ref: string): Promise<DefinitionInfo | undefined>;
|
@@ -38,7 +38,7 @@ function normalizeFilters(kindFilter) {
|
|
38
38
|
resolvedFilters = [kindFilter];
|
39
39
|
}
|
40
40
|
}
|
41
|
-
return resolvedFilters
|
41
|
+
return resolvedFilters;
|
42
42
|
}
|
43
43
|
class DefinitionsManager {
|
44
44
|
async resolveDefinitionsAndSamples() {
|
@@ -120,7 +120,15 @@ class DefinitionsManager {
|
|
120
120
|
return definitions;
|
121
121
|
}
|
122
122
|
return definitions.filter((d) => {
|
123
|
-
|
123
|
+
const kind = d.definition.kind.toLowerCase();
|
124
|
+
return kindFilter.some(filter => {
|
125
|
+
if (filter instanceof RegExp) {
|
126
|
+
return filter.test(kind);
|
127
|
+
}
|
128
|
+
else {
|
129
|
+
return kind === filter.toLowerCase();
|
130
|
+
}
|
131
|
+
});
|
124
132
|
});
|
125
133
|
}
|
126
134
|
async getDefinitions(kindFilter) {
|
@@ -15,6 +15,7 @@ const pathTemplateParser_1 = require("../../utils/pathTemplateParser");
|
|
15
15
|
const networkManager_1 = require("../../networkManager");
|
16
16
|
const socketManager_1 = require("../../socketManager");
|
17
17
|
const qs_1 = require("qs");
|
18
|
+
const web_1 = require("./web");
|
18
19
|
function getRestMethodId(restResource, httpMethod, httpPath) {
|
19
20
|
return lodash_1.default.findKey(restResource.spec.methods, (method) => {
|
20
21
|
let methodType = method.method ? method.method.toUpperCase() : 'GET';
|
@@ -63,6 +64,10 @@ function resolveMethods(req, opts) {
|
|
63
64
|
};
|
64
65
|
}
|
65
66
|
function proxyRestRequest(req, res, opts) {
|
67
|
+
if (lodash_1.default.isEmpty(opts.consumerResource.spec.methods) && lodash_1.default.isEmpty(opts.providerResource.spec.methods)) {
|
68
|
+
// If there are no methods defined, we assume the user controls the path and we just proxy the raw request
|
69
|
+
return (0, web_1.proxyHttpRequest)(req, res, opts);
|
70
|
+
}
|
66
71
|
let { consumerMethod, providerMethod } = resolveMethods(req, opts);
|
67
72
|
const consumerPathTemplate = (0, pathTemplateParser_1.pathTemplateParser)(consumerMethod.path);
|
68
73
|
const providerPathTemplate = (0, pathTemplateParser_1.pathTemplateParser)(providerMethod.path);
|
@@ -20,8 +20,8 @@ function proxyHttpRequest(req, res, opts) {
|
|
20
20
|
delete requestHeaders['connection'];
|
21
21
|
delete requestHeaders['host'];
|
22
22
|
delete requestHeaders['origin'];
|
23
|
-
const sourceBasePath = opts.consumerResource.spec.path;
|
24
|
-
const targetBasePath = opts.providerResource.spec.path;
|
23
|
+
const sourceBasePath = opts.consumerResource.spec.path ?? '/';
|
24
|
+
const targetBasePath = opts.providerResource.spec.path ?? '/';
|
25
25
|
let path = opts.consumerPath;
|
26
26
|
if (opts.consumerPath.startsWith(sourceBasePath)) {
|
27
27
|
path = path.replace(sourceBasePath, targetBasePath);
|
@@ -34,7 +34,7 @@ const DOCKER_ENV_VARS = [
|
|
34
34
|
`KAPETA_LOCAL_SERVER=0.0.0.0`,
|
35
35
|
`KAPETA_LOCAL_CLUSTER_HOST=${types_1.DOCKER_HOST_INTERNAL}`,
|
36
36
|
`KAPETA_ENVIRONMENT_TYPE=docker`,
|
37
|
-
`KAPETA_ENVIRONMENT_PLATFORM=${node_os_1.default.platform()}
|
37
|
+
`KAPETA_ENVIRONMENT_PLATFORM=${node_os_1.default.platform()}`,
|
38
38
|
];
|
39
39
|
async function getProvider(uri) {
|
40
40
|
const providers = await definitionsManager_1.definitionsManager.getProviderDefinitions();
|
@@ -172,8 +172,15 @@ class BlockInstanceRunner {
|
|
172
172
|
if (!fs_extra_1.default.existsSync(dockerFile)) {
|
173
173
|
throw new Error(`Dockerfile not found at: ${dockerFile}`);
|
174
174
|
}
|
175
|
-
|
176
|
-
|
175
|
+
console.log('Building docker image from Dockerfile "%s": %s ', dockerFile, dockerImage);
|
176
|
+
try {
|
177
|
+
const task = containerManager_1.containerManager.buildDockerImage(dockerFile, dockerImage);
|
178
|
+
await task.wait();
|
179
|
+
}
|
180
|
+
catch (err) {
|
181
|
+
throw new Error(`Error building docker image: ${err}`);
|
182
|
+
}
|
183
|
+
console.log('Docker images was build from file "%s": %s', dockerFile, dockerImage);
|
177
184
|
}
|
178
185
|
const containerName = await (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id, targetKindUri.id);
|
179
186
|
const startCmd = localContainer.handlers?.onCreate ? localContainer.handlers.onCreate : '';
|
@@ -205,7 +212,7 @@ class BlockInstanceRunner {
|
|
205
212
|
...dockerOpts,
|
206
213
|
Image: dockerImage,
|
207
214
|
name: containerName,
|
208
|
-
WorkingDir: workingDir,
|
215
|
+
WorkingDir: isDockerImage ? workingDir : undefined,
|
209
216
|
Labels: {
|
210
217
|
...customLabels,
|
211
218
|
instance: blockInstance.id,
|
@@ -41,8 +41,8 @@ class InternalConfigProvider {
|
|
41
41
|
getInstanceId() {
|
42
42
|
return this.instanceId;
|
43
43
|
}
|
44
|
-
getServerPort(portType) {
|
45
|
-
return
|
44
|
+
async getServerPort(portType) {
|
45
|
+
return '80';
|
46
46
|
}
|
47
47
|
async getServiceAddress(serviceName, portType) {
|
48
48
|
return serviceManager_1.serviceManager.getConsumerAddress(this.systemId, this.instanceId, serviceName, portType, this.environment);
|
@@ -15,7 +15,7 @@ const assetManager_1 = require("./assetManager");
|
|
15
15
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
16
16
|
const repositoryManager_1 = require("./repositoryManager");
|
17
17
|
const TARGET_KIND = 'core/language-target';
|
18
|
-
const
|
18
|
+
const BLOCK_TYPE_REGEX = /^core\/block-type.*/;
|
19
19
|
class CodeGeneratorManager {
|
20
20
|
async ensureLanguageTargetInRegistry(path, version, definition) {
|
21
21
|
const key = `${definition.metadata.name}:${version}`;
|
@@ -63,7 +63,7 @@ class CodeGeneratorManager {
|
|
63
63
|
return false;
|
64
64
|
}
|
65
65
|
const kindUri = (0, nodejs_utils_1.parseKapetaUri)(yamlContent.kind);
|
66
|
-
const blockTypes = await definitionsManager_1.definitionsManager.getDefinitions(
|
66
|
+
const blockTypes = await definitionsManager_1.definitionsManager.getDefinitions([BLOCK_TYPE_REGEX]);
|
67
67
|
const blockTypeKinds = blockTypes.map((blockType) => (0, nodejs_utils_1.parseKapetaUri)(blockType.definition.metadata.name).fullName);
|
68
68
|
return blockTypeKinds.includes(kindUri.fullName);
|
69
69
|
}
|
@@ -216,6 +216,10 @@ class ContainerManager {
|
|
216
216
|
if (!tag) {
|
217
217
|
tag = 'latest';
|
218
218
|
}
|
219
|
+
if (tag === 'local') {
|
220
|
+
// Local image - no need to pull
|
221
|
+
return false;
|
222
|
+
}
|
219
223
|
const imageTagList = (await this.docker().listImages({}))
|
220
224
|
.filter((imageData) => !!imageData.RepoTags)
|
221
225
|
.map((imageData) => imageData.RepoTags);
|
@@ -619,16 +623,22 @@ class ContainerManager {
|
|
619
623
|
buildDockerImage(dockerFile, imageName) {
|
620
624
|
const taskName = `Building docker image: ${imageName}`;
|
621
625
|
const processor = async (task) => {
|
622
|
-
const
|
623
|
-
const
|
626
|
+
const baseDir = path_1.default.dirname(dockerFile);
|
627
|
+
const entries = await fs_extra_1.default.readdir(baseDir);
|
628
|
+
const contextInfo = {
|
624
629
|
context: path_1.default.dirname(dockerFile),
|
625
|
-
src:
|
626
|
-
}
|
630
|
+
src: entries,
|
631
|
+
};
|
632
|
+
const stream = await this.docker().buildImage(contextInfo, {
|
627
633
|
t: imageName,
|
628
634
|
dockerfile: path_1.default.basename(dockerFile),
|
629
635
|
});
|
630
636
|
await processJsonStream(`image:build:${imageName}`, stream, (data) => {
|
631
|
-
if (data.
|
637
|
+
if (data.error) {
|
638
|
+
task.future.reject(new Error(data.error));
|
639
|
+
task.addLog(data.error, 'ERROR');
|
640
|
+
}
|
641
|
+
else if (data.stream) {
|
632
642
|
// Emit raw output to the task log
|
633
643
|
task.addLog(data.stream);
|
634
644
|
}
|
@@ -8,7 +8,7 @@ declare class DefinitionsManager {
|
|
8
8
|
private resolveDefinitionsAndSamples;
|
9
9
|
private prepareSample;
|
10
10
|
private applyFilters;
|
11
|
-
getDefinitions(kindFilter?: string | string[]): Promise<DefinitionInfo[]>;
|
11
|
+
getDefinitions(kindFilter?: string | (string | RegExp)[]): Promise<DefinitionInfo[]>;
|
12
12
|
exists(ref: string): Promise<boolean>;
|
13
13
|
getProviderDefinitions(): Promise<DefinitionInfo[]>;
|
14
14
|
getDefinition(ref: string): Promise<DefinitionInfo | undefined>;
|
@@ -38,7 +38,7 @@ function normalizeFilters(kindFilter) {
|
|
38
38
|
resolvedFilters = [kindFilter];
|
39
39
|
}
|
40
40
|
}
|
41
|
-
return resolvedFilters
|
41
|
+
return resolvedFilters;
|
42
42
|
}
|
43
43
|
class DefinitionsManager {
|
44
44
|
async resolveDefinitionsAndSamples() {
|
@@ -120,7 +120,15 @@ class DefinitionsManager {
|
|
120
120
|
return definitions;
|
121
121
|
}
|
122
122
|
return definitions.filter((d) => {
|
123
|
-
|
123
|
+
const kind = d.definition.kind.toLowerCase();
|
124
|
+
return kindFilter.some(filter => {
|
125
|
+
if (filter instanceof RegExp) {
|
126
|
+
return filter.test(kind);
|
127
|
+
}
|
128
|
+
else {
|
129
|
+
return kind === filter.toLowerCase();
|
130
|
+
}
|
131
|
+
});
|
124
132
|
});
|
125
133
|
}
|
126
134
|
async getDefinitions(kindFilter) {
|
@@ -15,6 +15,7 @@ const pathTemplateParser_1 = require("../../utils/pathTemplateParser");
|
|
15
15
|
const networkManager_1 = require("../../networkManager");
|
16
16
|
const socketManager_1 = require("../../socketManager");
|
17
17
|
const qs_1 = require("qs");
|
18
|
+
const web_1 = require("./web");
|
18
19
|
function getRestMethodId(restResource, httpMethod, httpPath) {
|
19
20
|
return lodash_1.default.findKey(restResource.spec.methods, (method) => {
|
20
21
|
let methodType = method.method ? method.method.toUpperCase() : 'GET';
|
@@ -63,6 +64,10 @@ function resolveMethods(req, opts) {
|
|
63
64
|
};
|
64
65
|
}
|
65
66
|
function proxyRestRequest(req, res, opts) {
|
67
|
+
if (lodash_1.default.isEmpty(opts.consumerResource.spec.methods) && lodash_1.default.isEmpty(opts.providerResource.spec.methods)) {
|
68
|
+
// If there are no methods defined, we assume the user controls the path and we just proxy the raw request
|
69
|
+
return (0, web_1.proxyHttpRequest)(req, res, opts);
|
70
|
+
}
|
66
71
|
let { consumerMethod, providerMethod } = resolveMethods(req, opts);
|
67
72
|
const consumerPathTemplate = (0, pathTemplateParser_1.pathTemplateParser)(consumerMethod.path);
|
68
73
|
const providerPathTemplate = (0, pathTemplateParser_1.pathTemplateParser)(providerMethod.path);
|
@@ -20,8 +20,8 @@ function proxyHttpRequest(req, res, opts) {
|
|
20
20
|
delete requestHeaders['connection'];
|
21
21
|
delete requestHeaders['host'];
|
22
22
|
delete requestHeaders['origin'];
|
23
|
-
const sourceBasePath = opts.consumerResource.spec.path;
|
24
|
-
const targetBasePath = opts.providerResource.spec.path;
|
23
|
+
const sourceBasePath = opts.consumerResource.spec.path ?? '/';
|
24
|
+
const targetBasePath = opts.providerResource.spec.path ?? '/';
|
25
25
|
let path = opts.consumerPath;
|
26
26
|
if (opts.consumerPath.startsWith(sourceBasePath)) {
|
27
27
|
path = path.replace(sourceBasePath, targetBasePath);
|
@@ -34,7 +34,7 @@ const DOCKER_ENV_VARS = [
|
|
34
34
|
`KAPETA_LOCAL_SERVER=0.0.0.0`,
|
35
35
|
`KAPETA_LOCAL_CLUSTER_HOST=${types_1.DOCKER_HOST_INTERNAL}`,
|
36
36
|
`KAPETA_ENVIRONMENT_TYPE=docker`,
|
37
|
-
`KAPETA_ENVIRONMENT_PLATFORM=${node_os_1.default.platform()}
|
37
|
+
`KAPETA_ENVIRONMENT_PLATFORM=${node_os_1.default.platform()}`,
|
38
38
|
];
|
39
39
|
async function getProvider(uri) {
|
40
40
|
const providers = await definitionsManager_1.definitionsManager.getProviderDefinitions();
|
@@ -172,8 +172,15 @@ class BlockInstanceRunner {
|
|
172
172
|
if (!fs_extra_1.default.existsSync(dockerFile)) {
|
173
173
|
throw new Error(`Dockerfile not found at: ${dockerFile}`);
|
174
174
|
}
|
175
|
-
|
176
|
-
|
175
|
+
console.log('Building docker image from Dockerfile "%s": %s ', dockerFile, dockerImage);
|
176
|
+
try {
|
177
|
+
const task = containerManager_1.containerManager.buildDockerImage(dockerFile, dockerImage);
|
178
|
+
await task.wait();
|
179
|
+
}
|
180
|
+
catch (err) {
|
181
|
+
throw new Error(`Error building docker image: ${err}`);
|
182
|
+
}
|
183
|
+
console.log('Docker images was build from file "%s": %s', dockerFile, dockerImage);
|
177
184
|
}
|
178
185
|
const containerName = await (0, utils_1.getBlockInstanceContainerName)(this._systemId, blockInstance.id, targetKindUri.id);
|
179
186
|
const startCmd = localContainer.handlers?.onCreate ? localContainer.handlers.onCreate : '';
|
@@ -205,7 +212,7 @@ class BlockInstanceRunner {
|
|
205
212
|
...dockerOpts,
|
206
213
|
Image: dockerImage,
|
207
214
|
name: containerName,
|
208
|
-
WorkingDir: workingDir,
|
215
|
+
WorkingDir: isDockerImage ? workingDir : undefined,
|
209
216
|
Labels: {
|
210
217
|
...customLabels,
|
211
218
|
instance: blockInstance.id,
|
@@ -41,8 +41,8 @@ class InternalConfigProvider {
|
|
41
41
|
getInstanceId() {
|
42
42
|
return this.instanceId;
|
43
43
|
}
|
44
|
-
getServerPort(portType) {
|
45
|
-
return
|
44
|
+
async getServerPort(portType) {
|
45
|
+
return '80';
|
46
46
|
}
|
47
47
|
async getServiceAddress(serviceName, portType) {
|
48
48
|
return serviceManager_1.serviceManager.getConsumerAddress(this.systemId, this.instanceId, serviceName, portType, this.environment);
|
package/package.json
CHANGED
@@ -13,7 +13,7 @@ import { normalizeKapetaUri, parseKapetaUri } from '@kapeta/nodejs-utils';
|
|
13
13
|
import { repositoryManager } from './repositoryManager';
|
14
14
|
|
15
15
|
const TARGET_KIND = 'core/language-target';
|
16
|
-
const
|
16
|
+
const BLOCK_TYPE_REGEX = /^core\/block-type.*/;
|
17
17
|
|
18
18
|
class CodeGeneratorManager {
|
19
19
|
private async ensureLanguageTargetInRegistry(path: string, version: string, definition: Definition) {
|
@@ -68,7 +68,7 @@ class CodeGeneratorManager {
|
|
68
68
|
|
69
69
|
const kindUri = parseKapetaUri(yamlContent.kind);
|
70
70
|
|
71
|
-
const blockTypes = await definitionsManager.getDefinitions(
|
71
|
+
const blockTypes = await definitionsManager.getDefinitions([BLOCK_TYPE_REGEX]);
|
72
72
|
const blockTypeKinds = blockTypes.map(
|
73
73
|
(blockType) => parseKapetaUri(blockType.definition.metadata.name).fullName
|
74
74
|
);
|
package/src/containerManager.ts
CHANGED
@@ -306,6 +306,11 @@ class ContainerManager {
|
|
306
306
|
tag = 'latest';
|
307
307
|
}
|
308
308
|
|
309
|
+
if (tag === 'local') {
|
310
|
+
// Local image - no need to pull
|
311
|
+
return false;
|
312
|
+
}
|
313
|
+
|
309
314
|
const imageTagList = (await this.docker().listImages({}))
|
310
315
|
.filter((imageData) => !!imageData.RepoTags)
|
311
316
|
.map((imageData) => imageData.RepoTags as string[]);
|
@@ -786,20 +791,23 @@ class ContainerManager {
|
|
786
791
|
buildDockerImage(dockerFile: string, imageName: string) {
|
787
792
|
const taskName = `Building docker image: ${imageName}`;
|
788
793
|
const processor = async (task: Task) => {
|
789
|
-
const
|
790
|
-
const
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
);
|
794
|
+
const baseDir = Path.dirname(dockerFile);
|
795
|
+
const entries = await FSExtra.readdir(baseDir);
|
796
|
+
const contextInfo = {
|
797
|
+
context: Path.dirname(dockerFile),
|
798
|
+
src: entries,
|
799
|
+
};
|
800
|
+
|
801
|
+
const stream = await this.docker().buildImage(contextInfo, {
|
802
|
+
t: imageName,
|
803
|
+
dockerfile: Path.basename(dockerFile),
|
804
|
+
});
|
800
805
|
|
801
806
|
await processJsonStream<string>(`image:build:${imageName}`, stream, (data) => {
|
802
|
-
if (data.
|
807
|
+
if (data.error) {
|
808
|
+
task.future.reject(new Error(data.error));
|
809
|
+
task.addLog(data.error, 'ERROR');
|
810
|
+
} else if (data.stream) {
|
803
811
|
// Emit raw output to the task log
|
804
812
|
task.addLog(data.stream);
|
805
813
|
}
|
@@ -27,8 +27,8 @@ function applyHandleChange(definition: DefinitionInfo, targetHandle: string) {
|
|
27
27
|
return definition;
|
28
28
|
}
|
29
29
|
|
30
|
-
function normalizeFilters(kindFilter?: string | string[]) {
|
31
|
-
let resolvedFilters:
|
30
|
+
function normalizeFilters(kindFilter?: string | (string | RegExp)[]) {
|
31
|
+
let resolvedFilters: any[] = [];
|
32
32
|
|
33
33
|
if (kindFilter) {
|
34
34
|
if (Array.isArray(kindFilter)) {
|
@@ -38,7 +38,7 @@ function normalizeFilters(kindFilter?: string | string[]) {
|
|
38
38
|
}
|
39
39
|
}
|
40
40
|
|
41
|
-
return resolvedFilters
|
41
|
+
return resolvedFilters;
|
42
42
|
}
|
43
43
|
|
44
44
|
class DefinitionsManager {
|
@@ -138,17 +138,24 @@ class DefinitionsManager {
|
|
138
138
|
console.log('Rewrite done for sample plan');
|
139
139
|
}
|
140
140
|
|
141
|
-
private applyFilters(definitions: DefinitionInfo[], kindFilter: string[]): DefinitionInfo[] {
|
141
|
+
private applyFilters(definitions: DefinitionInfo[], kindFilter: (string|RegExp)[]): DefinitionInfo[] {
|
142
142
|
if (kindFilter.length === 0) {
|
143
143
|
return definitions;
|
144
144
|
}
|
145
145
|
|
146
146
|
return definitions.filter((d) => {
|
147
|
-
|
147
|
+
const kind = d.definition.kind.toLowerCase();
|
148
|
+
return kindFilter.some(filter => {
|
149
|
+
if (filter instanceof RegExp) {
|
150
|
+
return filter.test(kind);
|
151
|
+
} else {
|
152
|
+
return kind === filter.toLowerCase();
|
153
|
+
}
|
154
|
+
});
|
148
155
|
});
|
149
156
|
}
|
150
157
|
|
151
|
-
public async getDefinitions(kindFilter?: string | string[]): Promise<DefinitionInfo[]> {
|
158
|
+
public async getDefinitions(kindFilter?: string | (string | RegExp)[]): Promise<DefinitionInfo[]> {
|
152
159
|
kindFilter = normalizeFilters(kindFilter);
|
153
160
|
|
154
161
|
const definitions = await doCached<Promise<DefinitionInfo[]>>('definitionsManager:all', () =>
|
package/src/proxy/types/rest.ts
CHANGED
@@ -15,6 +15,7 @@ import { ProxyRequestInfo, SimpleRequest, StringMap } from '../../types';
|
|
15
15
|
import { StringBodyRequest } from '../../middleware/stringBody';
|
16
16
|
import { Resource } from '@kapeta/schemas';
|
17
17
|
import { stringify } from 'qs';
|
18
|
+
import { proxyHttpRequest } from './web';
|
18
19
|
|
19
20
|
export function getRestMethodId(restResource: Resource, httpMethod: string, httpPath: string) {
|
20
21
|
return _.findKey(restResource.spec.methods, (method) => {
|
@@ -86,6 +87,10 @@ function resolveMethods(req: Request, opts: ProxyRequestInfo) {
|
|
86
87
|
}
|
87
88
|
|
88
89
|
export function proxyRestRequest(req: StringBodyRequest, res: Response, opts: ProxyRequestInfo) {
|
90
|
+
if (_.isEmpty(opts.consumerResource.spec.methods) && _.isEmpty(opts.providerResource.spec.methods)) {
|
91
|
+
// If there are no methods defined, we assume the user controls the path and we just proxy the raw request
|
92
|
+
return proxyHttpRequest(req, res, opts);
|
93
|
+
}
|
89
94
|
let { consumerMethod, providerMethod } = resolveMethods(req, opts);
|
90
95
|
|
91
96
|
const consumerPathTemplate = pathTemplateParser(consumerMethod.path);
|
package/src/proxy/types/web.ts
CHANGED
@@ -21,8 +21,8 @@ export function proxyHttpRequest(req: StringBodyRequest, res: Response, opts: Pr
|
|
21
21
|
delete requestHeaders['host'];
|
22
22
|
delete requestHeaders['origin'];
|
23
23
|
|
24
|
-
const sourceBasePath = opts.consumerResource.spec.path;
|
25
|
-
const targetBasePath = opts.providerResource.spec.path;
|
24
|
+
const sourceBasePath = opts.consumerResource.spec.path ?? '/';
|
25
|
+
const targetBasePath = opts.providerResource.spec.path ?? '/';
|
26
26
|
let path = opts.consumerPath;
|
27
27
|
if (opts.consumerPath.startsWith(sourceBasePath)) {
|
28
28
|
path = path.replace(sourceBasePath, targetBasePath);
|
@@ -48,7 +48,7 @@ const DOCKER_ENV_VARS = [
|
|
48
48
|
`KAPETA_LOCAL_SERVER=0.0.0.0`,
|
49
49
|
`KAPETA_LOCAL_CLUSTER_HOST=${DOCKER_HOST_INTERNAL}`,
|
50
50
|
`KAPETA_ENVIRONMENT_TYPE=docker`,
|
51
|
-
`KAPETA_ENVIRONMENT_PLATFORM=${OS.platform()}
|
51
|
+
`KAPETA_ENVIRONMENT_PLATFORM=${OS.platform()}`,
|
52
52
|
];
|
53
53
|
|
54
54
|
async function getProvider(uri: KapetaURI) {
|
@@ -231,8 +231,16 @@ export class BlockInstanceRunner {
|
|
231
231
|
if (!FSExtra.existsSync(dockerFile)) {
|
232
232
|
throw new Error(`Dockerfile not found at: ${dockerFile}`);
|
233
233
|
}
|
234
|
-
|
235
|
-
|
234
|
+
|
235
|
+
console.log('Building docker image from Dockerfile "%s": %s ', dockerFile, dockerImage);
|
236
|
+
try {
|
237
|
+
const task = containerManager.buildDockerImage(dockerFile, dockerImage);
|
238
|
+
await task.wait();
|
239
|
+
} catch (err: any) {
|
240
|
+
throw new Error(`Error building docker image: ${err}`);
|
241
|
+
}
|
242
|
+
|
243
|
+
console.log('Docker images was build from file "%s": %s', dockerFile, dockerImage);
|
236
244
|
}
|
237
245
|
|
238
246
|
const containerName = await getBlockInstanceContainerName(this._systemId, blockInstance.id, targetKindUri.id);
|
@@ -275,7 +283,7 @@ export class BlockInstanceRunner {
|
|
275
283
|
...dockerOpts,
|
276
284
|
Image: dockerImage,
|
277
285
|
name: containerName,
|
278
|
-
WorkingDir: workingDir,
|
286
|
+
WorkingDir: isDockerImage ? workingDir : undefined,
|
279
287
|
Labels: {
|
280
288
|
...customLabels,
|
281
289
|
instance: blockInstance.id,
|
@@ -59,8 +59,8 @@ export class InternalConfigProvider implements ConfigProvider {
|
|
59
59
|
getInstanceId(): string {
|
60
60
|
return this.instanceId;
|
61
61
|
}
|
62
|
-
getServerPort(portType?: string | undefined): Promise<string> {
|
63
|
-
return
|
62
|
+
async getServerPort(portType?: string | undefined): Promise<string> {
|
63
|
+
return '80';
|
64
64
|
}
|
65
65
|
async getServiceAddress(serviceName: string, portType: string): Promise<string | null> {
|
66
66
|
return serviceManager.getConsumerAddress(
|