@enspirit/emb 0.22.1 → 0.24.0
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/README.md +91 -117
- package/dist/src/cli/abstract/KubernetesCommand.d.ts +5 -1
- package/dist/src/cli/abstract/KubernetesCommand.js +11 -2
- package/dist/src/cli/commands/components/shell.d.ts +1 -1
- package/dist/src/cli/commands/components/shell.js +8 -6
- package/dist/src/cli/commands/down.d.ts +4 -0
- package/dist/src/cli/commands/down.js +17 -12
- package/dist/src/cli/commands/kubernetes/logs.js +7 -12
- package/dist/src/cli/commands/kubernetes/ps.js +2 -1
- package/dist/src/cli/commands/kubernetes/restart.js +2 -1
- package/dist/src/cli/commands/kubernetes/shell.js +7 -10
- package/dist/src/cli/commands/logs/archive.d.ts +1 -1
- package/dist/src/cli/commands/logs/archive.js +12 -11
- package/dist/src/cli/commands/logs/index.d.ts +1 -1
- package/dist/src/cli/commands/logs/index.js +12 -12
- package/dist/src/cli/commands/restart.d.ts +1 -1
- package/dist/src/cli/commands/restart.js +10 -9
- package/dist/src/cli/commands/start.d.ts +1 -1
- package/dist/src/cli/commands/start.js +7 -10
- package/dist/src/cli/commands/stop.d.ts +4 -0
- package/dist/src/cli/commands/stop.js +17 -12
- package/dist/src/cli/commands/up.d.ts +1 -1
- package/dist/src/cli/commands/up.js +20 -19
- package/dist/src/config/schema.d.ts +33 -1
- package/dist/src/config/schema.json +42 -1
- package/dist/src/docker/compose/client.d.ts +15 -1
- package/dist/src/docker/compose/client.js +32 -2
- package/dist/src/docker/compose/operations/ComposeDownOperation.d.ts +6 -6
- package/dist/src/docker/compose/operations/ComposeDownOperation.js +28 -9
- package/dist/src/docker/compose/operations/ComposeLogsArchiveOperation.d.ts +3 -3
- package/dist/src/docker/compose/operations/ComposeLogsArchiveOperation.js +12 -13
- package/dist/src/docker/compose/operations/ComposeStopOperation.d.ts +6 -6
- package/dist/src/docker/compose/operations/ComposeStopOperation.js +28 -9
- package/dist/src/docker/compose/operations/ComposeUpOperation.d.ts +1 -1
- package/dist/src/docker/compose/operations/ComposeUpOperation.js +4 -4
- package/dist/src/kubernetes/index.d.ts +1 -0
- package/dist/src/kubernetes/index.js +1 -0
- package/dist/src/kubernetes/operations/GetComponentPodOperation.d.ts +17 -0
- package/dist/src/kubernetes/operations/GetComponentPodOperation.js +77 -0
- package/dist/src/kubernetes/operations/GetDeploymentPodsOperation.js +3 -2
- package/dist/src/kubernetes/operations/PodExecOperation.d.ts +20 -0
- package/dist/src/kubernetes/operations/PodExecOperation.js +158 -0
- package/dist/src/kubernetes/operations/index.d.ts +3 -0
- package/dist/src/kubernetes/operations/index.js +3 -0
- package/dist/src/kubernetes/utils/index.d.ts +1 -0
- package/dist/src/kubernetes/utils/index.js +1 -0
- package/dist/src/kubernetes/utils/resolveNamespace.d.ts +13 -0
- package/dist/src/kubernetes/utils/resolveNamespace.js +12 -0
- package/dist/src/monorepo/operations/tasks/RunTasksOperation.d.ts +2 -0
- package/dist/src/monorepo/operations/tasks/RunTasksOperation.js +43 -3
- package/oclif.manifest.json +228 -278
- package/package.json +1 -1
- package/dist/src/cli/commands/components/logs.d.ts +0 -14
- package/dist/src/cli/commands/components/logs.js +0 -44
|
@@ -4,7 +4,7 @@ import { ComposeExecShellOperation } from '../../../docker/index.js';
|
|
|
4
4
|
import { ShellExitError } from '../../../errors.js';
|
|
5
5
|
export default class ComponentShellCommand extends BaseCommand {
|
|
6
6
|
static aliases = ['shell'];
|
|
7
|
-
static description = 'Get a shell on a running
|
|
7
|
+
static description = 'Get a shell on a running service.';
|
|
8
8
|
static enableJsonFlag = false;
|
|
9
9
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
10
10
|
static flags = {
|
|
@@ -16,18 +16,20 @@ export default class ComponentShellCommand extends BaseCommand {
|
|
|
16
16
|
}),
|
|
17
17
|
};
|
|
18
18
|
static args = {
|
|
19
|
-
|
|
20
|
-
name: '
|
|
21
|
-
description: 'The
|
|
19
|
+
service: Args.string({
|
|
20
|
+
name: 'service',
|
|
21
|
+
description: 'The service you want to get a shell on',
|
|
22
22
|
required: true,
|
|
23
23
|
}),
|
|
24
24
|
};
|
|
25
25
|
async run() {
|
|
26
26
|
const { flags, args } = await this.parse(ComponentShellCommand);
|
|
27
|
-
const { monorepo } =
|
|
27
|
+
const { monorepo, compose } = getContext();
|
|
28
|
+
// Validate service exists in docker-compose.yml
|
|
29
|
+
await compose.validateService(args.service);
|
|
28
30
|
try {
|
|
29
31
|
await monorepo.run(new ComposeExecShellOperation(), {
|
|
30
|
-
service: args.
|
|
32
|
+
service: args.service,
|
|
31
33
|
shell: flags.shell,
|
|
32
34
|
});
|
|
33
35
|
}
|
|
@@ -4,5 +4,9 @@ export default class DownCommand extends FlavoredCommand<typeof DownCommand> {
|
|
|
4
4
|
static enableJsonFlag: boolean;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {};
|
|
7
|
+
static args: {
|
|
8
|
+
service: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
9
|
+
};
|
|
10
|
+
static strict: boolean;
|
|
7
11
|
run(): Promise<void>;
|
|
8
12
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
2
|
import { FlavoredCommand, getContext } from '../index.js';
|
|
3
3
|
import { ComposeDownOperation } from '../../docker/index.js';
|
|
4
4
|
export default class DownCommand extends FlavoredCommand {
|
|
@@ -6,17 +6,22 @@ export default class DownCommand extends FlavoredCommand {
|
|
|
6
6
|
static enableJsonFlag = true;
|
|
7
7
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
8
8
|
static flags = {};
|
|
9
|
+
static args = {
|
|
10
|
+
service: Args.string({
|
|
11
|
+
name: 'service',
|
|
12
|
+
description: 'The service(s) to stop and remove',
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
15
|
+
static strict = false;
|
|
9
16
|
async run() {
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
]);
|
|
20
|
-
await runner.run();
|
|
17
|
+
const { argv } = await this.parse(DownCommand);
|
|
18
|
+
const { monorepo, compose } = getContext();
|
|
19
|
+
let services;
|
|
20
|
+
if (argv.length > 0) {
|
|
21
|
+
services = await compose.validateServices(argv);
|
|
22
|
+
}
|
|
23
|
+
await monorepo.run(new ComposeDownOperation(), {
|
|
24
|
+
services,
|
|
25
|
+
});
|
|
21
26
|
}
|
|
22
27
|
}
|
|
@@ -2,7 +2,7 @@ import { Log } from '@kubernetes/client-node';
|
|
|
2
2
|
import { Args, Flags } from '@oclif/core';
|
|
3
3
|
import { PassThrough } from 'node:stream';
|
|
4
4
|
import { KubernetesCommand } from '../../index.js';
|
|
5
|
-
import {
|
|
5
|
+
import { GetComponentPodOperation } from '../../../kubernetes/operations/index.js';
|
|
6
6
|
export default class KubernetesLogs extends KubernetesCommand {
|
|
7
7
|
static description = 'Follow kubernetes logs.';
|
|
8
8
|
static enableJsonFlag = false;
|
|
@@ -26,23 +26,18 @@ export default class KubernetesLogs extends KubernetesCommand {
|
|
|
26
26
|
async run() {
|
|
27
27
|
const { flags, args } = await this.parse(KubernetesLogs);
|
|
28
28
|
const { monorepo, kubernetes } = this.context;
|
|
29
|
-
|
|
30
|
-
monorepo.component(args.component);
|
|
31
|
-
const
|
|
32
|
-
namespace
|
|
33
|
-
|
|
29
|
+
const namespace = this.resolveNamespace(flags.namespace);
|
|
30
|
+
const component = monorepo.component(args.component);
|
|
31
|
+
const { pod, container } = await monorepo.run(new GetComponentPodOperation(), {
|
|
32
|
+
namespace,
|
|
33
|
+
component,
|
|
34
34
|
});
|
|
35
|
-
if (pods.length === 0) {
|
|
36
|
-
throw new Error(`No running pod found for component ${args.component}`);
|
|
37
|
-
}
|
|
38
35
|
const k8sLogs = new Log(kubernetes.config);
|
|
39
36
|
const transform = new PassThrough();
|
|
40
37
|
transform.on('data', (chunk) => {
|
|
41
38
|
process.stdout.write(chunk);
|
|
42
39
|
});
|
|
43
|
-
|
|
44
|
-
const container = pod.spec.containers[0];
|
|
45
|
-
await k8sLogs.log(flags.namespace, pod.metadata.name, container.name, transform, {
|
|
40
|
+
await k8sLogs.log(namespace, pod.metadata.name, container, transform, {
|
|
46
41
|
follow: flags.follow,
|
|
47
42
|
tailLines: 50,
|
|
48
43
|
pretty: false,
|
|
@@ -15,8 +15,9 @@ export default class KPSCommand extends KubernetesCommand {
|
|
|
15
15
|
async run() {
|
|
16
16
|
const { flags } = await this.parse(KPSCommand);
|
|
17
17
|
const { kubernetes } = getContext();
|
|
18
|
+
const namespace = this.resolveNamespace(flags.namespace);
|
|
18
19
|
const { items } = await kubernetes.core.listNamespacedPod({
|
|
19
|
-
namespace
|
|
20
|
+
namespace,
|
|
20
21
|
});
|
|
21
22
|
const pods = items.map((i) => {
|
|
22
23
|
const restarts = i.status?.containerStatuses
|
|
@@ -14,8 +14,9 @@ export default class KRestartCommand extends KubernetesCommand {
|
|
|
14
14
|
async run() {
|
|
15
15
|
const { flags, argv } = await this.parse(KRestartCommand);
|
|
16
16
|
const { monorepo } = getContext();
|
|
17
|
+
const namespace = this.resolveNamespace(flags.namespace);
|
|
17
18
|
await monorepo.run(new PodsRestartOperation(), {
|
|
18
|
-
namespace
|
|
19
|
+
namespace,
|
|
19
20
|
deployments: argv.length > 0 ? argv : undefined,
|
|
20
21
|
});
|
|
21
22
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Exec } from '@kubernetes/client-node';
|
|
2
2
|
import { Args, Flags } from '@oclif/core';
|
|
3
3
|
import { getContext, KubernetesCommand } from '../../index.js';
|
|
4
|
-
import {
|
|
4
|
+
import { GetComponentPodOperation } from '../../../kubernetes/operations/index.js';
|
|
5
5
|
import { enableRawMode } from '../../../utils/streams.js';
|
|
6
6
|
export default class PodShellCommand extends KubernetesCommand {
|
|
7
7
|
static aliases = ['shell'];
|
|
@@ -26,18 +26,15 @@ export default class PodShellCommand extends KubernetesCommand {
|
|
|
26
26
|
async run() {
|
|
27
27
|
const { flags, args } = await this.parse(PodShellCommand);
|
|
28
28
|
const { monorepo, kubernetes } = await getContext();
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
const namespace = this.resolveNamespace(flags.namespace);
|
|
30
|
+
const component = monorepo.component(args.component);
|
|
31
|
+
const { pod, container } = await monorepo.run(new GetComponentPodOperation(), {
|
|
32
|
+
namespace,
|
|
33
|
+
component,
|
|
32
34
|
});
|
|
33
|
-
if (pods.length === 0) {
|
|
34
|
-
throw new Error(`No running pod found for component ${args.component}`);
|
|
35
|
-
}
|
|
36
|
-
const pod = pods[0];
|
|
37
|
-
const container = pod.spec.containers[0];
|
|
38
35
|
const exec = new Exec(kubernetes.config);
|
|
39
36
|
enableRawMode(process.stdin);
|
|
40
|
-
const res = await exec.exec(
|
|
37
|
+
const res = await exec.exec(namespace, pod.metadata.name, container, [flags.shell], process.stdout, process.stderr, process.stdin, true);
|
|
41
38
|
res.on('close', () => {
|
|
42
39
|
// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit
|
|
43
40
|
process.exit(0);
|
|
@@ -10,7 +10,7 @@ export default class LogsArchive extends BaseCommand {
|
|
|
10
10
|
output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
11
|
};
|
|
12
12
|
static args: {
|
|
13
|
-
|
|
13
|
+
service: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
14
14
|
};
|
|
15
15
|
run(): Promise<void>;
|
|
16
16
|
}
|
|
@@ -2,7 +2,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
2
2
|
import { BaseCommand, getContext } from '../../index.js';
|
|
3
3
|
import { ComposeLogsArchiveOperation } from '../../../docker/index.js';
|
|
4
4
|
export default class LogsArchive extends BaseCommand {
|
|
5
|
-
static description = 'Archive docker compose logs to files (one file per
|
|
5
|
+
static description = 'Archive docker compose logs to files (one file per service).';
|
|
6
6
|
static enableJsonFlag = true;
|
|
7
7
|
static examples = [
|
|
8
8
|
'<%= config.bin %> <%= command.id %>',
|
|
@@ -26,22 +26,23 @@ export default class LogsArchive extends BaseCommand {
|
|
|
26
26
|
}),
|
|
27
27
|
};
|
|
28
28
|
static args = {
|
|
29
|
-
|
|
30
|
-
name: '
|
|
31
|
-
description: 'The
|
|
29
|
+
service: Args.string({
|
|
30
|
+
name: 'service',
|
|
31
|
+
description: 'The service(s) to archive logs for (all if omitted)',
|
|
32
32
|
required: false,
|
|
33
33
|
}),
|
|
34
34
|
};
|
|
35
35
|
async run() {
|
|
36
36
|
const { flags, argv } = await this.parse(LogsArchive);
|
|
37
|
-
const { monorepo } =
|
|
38
|
-
const
|
|
39
|
-
// Validate that all specified
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const { monorepo, compose } = getContext();
|
|
38
|
+
const serviceNames = argv;
|
|
39
|
+
// Validate that all specified services exist in docker-compose.yml
|
|
40
|
+
let services;
|
|
41
|
+
if (serviceNames.length > 0) {
|
|
42
|
+
services = await compose.validateServices(serviceNames);
|
|
42
43
|
}
|
|
43
44
|
const result = await monorepo.run(new ComposeLogsArchiveOperation(), {
|
|
44
|
-
|
|
45
|
+
services,
|
|
45
46
|
outputDir: flags.output,
|
|
46
47
|
timestamps: flags.timestamps,
|
|
47
48
|
tail: flags.tail,
|
|
@@ -52,7 +53,7 @@ export default class LogsArchive extends BaseCommand {
|
|
|
52
53
|
else {
|
|
53
54
|
this.log('Archived logs:');
|
|
54
55
|
for (const file of result) {
|
|
55
|
-
this.log(` ${file.
|
|
56
|
+
this.log(` ${file.service}: ${file.path}`);
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
}
|
|
@@ -8,7 +8,7 @@ export default class Logs extends BaseCommand {
|
|
|
8
8
|
follow: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
9
|
};
|
|
10
10
|
static args: {
|
|
11
|
-
|
|
11
|
+
service: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
12
12
|
};
|
|
13
13
|
run(): Promise<void>;
|
|
14
14
|
}
|
|
@@ -2,7 +2,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
2
2
|
import { BaseCommand, getContext } from '../../index.js';
|
|
3
3
|
import { ComposeLogsOperation } from '../../../docker/index.js';
|
|
4
4
|
export default class Logs extends BaseCommand {
|
|
5
|
-
static description = 'Get
|
|
5
|
+
static description = 'Get service logs.';
|
|
6
6
|
static enableJsonFlag = false;
|
|
7
7
|
static examples = [
|
|
8
8
|
'<%= config.bin %> <%= command.id %>',
|
|
@@ -21,23 +21,23 @@ export default class Logs extends BaseCommand {
|
|
|
21
21
|
}),
|
|
22
22
|
};
|
|
23
23
|
static args = {
|
|
24
|
-
|
|
25
|
-
name: '
|
|
26
|
-
description: 'The
|
|
24
|
+
service: Args.string({
|
|
25
|
+
name: 'service',
|
|
26
|
+
description: 'The service(s) you want to see the logs of (all if omitted)',
|
|
27
27
|
required: false,
|
|
28
28
|
}),
|
|
29
29
|
};
|
|
30
30
|
async run() {
|
|
31
31
|
const { flags, argv } = await this.parse(Logs);
|
|
32
|
-
const { monorepo } =
|
|
33
|
-
const
|
|
34
|
-
// Validate that all specified
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
32
|
+
const { monorepo, compose } = getContext();
|
|
33
|
+
const serviceNames = argv;
|
|
34
|
+
// Validate that all specified services exist in docker-compose.yml
|
|
35
|
+
let services;
|
|
36
|
+
if (serviceNames.length > 0) {
|
|
37
|
+
services = await compose.validateServices(serviceNames);
|
|
38
|
+
}
|
|
39
39
|
await monorepo.run(new ComposeLogsOperation(), {
|
|
40
|
-
services
|
|
40
|
+
services,
|
|
41
41
|
follow: flags.follow,
|
|
42
42
|
});
|
|
43
43
|
}
|
|
@@ -7,7 +7,7 @@ export default class RestartComand extends BaseCommand {
|
|
|
7
7
|
'no-deps': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
8
|
};
|
|
9
9
|
static args: {
|
|
10
|
-
|
|
10
|
+
service: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
11
11
|
};
|
|
12
12
|
static strict: boolean;
|
|
13
13
|
run(): Promise<void>;
|
|
@@ -9,26 +9,27 @@ export default class RestartComand extends BaseCommand {
|
|
|
9
9
|
'no-deps': Flags.boolean({
|
|
10
10
|
char: 'f',
|
|
11
11
|
default: false,
|
|
12
|
-
description: "Don't restart
|
|
12
|
+
description: "Don't restart dependent services",
|
|
13
13
|
name: 'no-deps',
|
|
14
14
|
}),
|
|
15
15
|
};
|
|
16
16
|
static args = {
|
|
17
|
-
|
|
18
|
-
name: '
|
|
19
|
-
description: 'The
|
|
17
|
+
service: Args.string({
|
|
18
|
+
name: 'service',
|
|
19
|
+
description: 'The service(s) to restart',
|
|
20
20
|
}),
|
|
21
21
|
};
|
|
22
22
|
static strict = false;
|
|
23
23
|
async run() {
|
|
24
24
|
const { flags, argv } = await this.parse(RestartComand);
|
|
25
|
-
const { monorepo } = getContext();
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
const { monorepo, compose } = getContext();
|
|
26
|
+
let services;
|
|
27
|
+
if (argv.length > 0) {
|
|
28
|
+
services = await compose.validateServices(argv);
|
|
29
|
+
}
|
|
29
30
|
await monorepo.run(new ComposeRestartOperation(), {
|
|
30
31
|
noDeps: flags['no-deps'],
|
|
31
|
-
services
|
|
32
|
+
services,
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
}
|
|
@@ -5,7 +5,7 @@ export default class StartCommand extends BaseCommand {
|
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {};
|
|
7
7
|
static args: {
|
|
8
|
-
|
|
8
|
+
service: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
9
9
|
};
|
|
10
10
|
static strict: boolean;
|
|
11
11
|
run(): Promise<void>;
|
|
@@ -7,24 +7,21 @@ export default class StartCommand extends BaseCommand {
|
|
|
7
7
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
8
8
|
static flags = {};
|
|
9
9
|
static args = {
|
|
10
|
-
|
|
11
|
-
name: '
|
|
12
|
-
description: 'The
|
|
10
|
+
service: Args.string({
|
|
11
|
+
name: 'service',
|
|
12
|
+
description: 'The service(s) to start',
|
|
13
13
|
}),
|
|
14
14
|
};
|
|
15
15
|
static strict = false;
|
|
16
16
|
async run() {
|
|
17
17
|
const { argv } = await this.parse(StartCommand);
|
|
18
|
-
const { monorepo } = getContext();
|
|
19
|
-
let
|
|
18
|
+
const { monorepo, compose } = getContext();
|
|
19
|
+
let services;
|
|
20
20
|
if (argv.length > 0) {
|
|
21
|
-
|
|
22
|
-
argv.length > 0
|
|
23
|
-
? argv.map((name) => monorepo.component(name))
|
|
24
|
-
: undefined;
|
|
21
|
+
services = await compose.validateServices(argv);
|
|
25
22
|
}
|
|
26
23
|
await monorepo.run(new ComposeStartOperation(), {
|
|
27
|
-
services
|
|
24
|
+
services,
|
|
28
25
|
});
|
|
29
26
|
}
|
|
30
27
|
}
|
|
@@ -4,5 +4,9 @@ export default class StopCommand extends FlavoredCommand<typeof StopCommand> {
|
|
|
4
4
|
static enableJsonFlag: boolean;
|
|
5
5
|
static examples: string[];
|
|
6
6
|
static flags: {};
|
|
7
|
+
static args: {
|
|
8
|
+
service: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
9
|
+
};
|
|
10
|
+
static strict: boolean;
|
|
7
11
|
run(): Promise<void>;
|
|
8
12
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
2
|
import { FlavoredCommand, getContext } from '../index.js';
|
|
3
3
|
import { ComposeStopOperation } from '../../docker/index.js';
|
|
4
4
|
export default class StopCommand extends FlavoredCommand {
|
|
@@ -6,17 +6,22 @@ export default class StopCommand extends FlavoredCommand {
|
|
|
6
6
|
static enableJsonFlag = true;
|
|
7
7
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
8
8
|
static flags = {};
|
|
9
|
+
static args = {
|
|
10
|
+
service: Args.string({
|
|
11
|
+
name: 'service',
|
|
12
|
+
description: 'The service(s) to stop',
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
15
|
+
static strict = false;
|
|
9
16
|
async run() {
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
]);
|
|
20
|
-
await runner.run();
|
|
17
|
+
const { argv } = await this.parse(StopCommand);
|
|
18
|
+
const { monorepo, compose } = getContext();
|
|
19
|
+
let services;
|
|
20
|
+
if (argv.length > 0) {
|
|
21
|
+
services = await compose.validateServices(argv);
|
|
22
|
+
}
|
|
23
|
+
await monorepo.run(new ComposeStopOperation(), {
|
|
24
|
+
services,
|
|
25
|
+
});
|
|
21
26
|
}
|
|
22
27
|
}
|
|
@@ -7,7 +7,7 @@ export default class UpCommand extends FlavoredCommand<typeof UpCommand> {
|
|
|
7
7
|
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
8
|
};
|
|
9
9
|
static args: {
|
|
10
|
-
|
|
10
|
+
service: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
11
11
|
};
|
|
12
12
|
static strict: boolean;
|
|
13
13
|
run(): Promise<void>;
|
|
@@ -15,27 +15,25 @@ export default class UpCommand extends FlavoredCommand {
|
|
|
15
15
|
}),
|
|
16
16
|
};
|
|
17
17
|
static args = {
|
|
18
|
-
|
|
19
|
-
name: '
|
|
20
|
-
description: 'The
|
|
18
|
+
service: Args.string({
|
|
19
|
+
name: 'service',
|
|
20
|
+
description: 'The service(s) to build and start',
|
|
21
21
|
}),
|
|
22
22
|
};
|
|
23
23
|
static strict = false;
|
|
24
24
|
async run() {
|
|
25
25
|
const { flags, argv } = await this.parse(UpCommand);
|
|
26
|
-
const { monorepo } = getContext();
|
|
27
|
-
|
|
28
|
-
if (flags.force) {
|
|
29
|
-
buildFlags.push('--force');
|
|
30
|
-
}
|
|
31
|
-
let components;
|
|
26
|
+
const { monorepo, compose } = getContext();
|
|
27
|
+
let services;
|
|
32
28
|
let resources;
|
|
33
29
|
if (argv.length > 0) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
// Validate service names against docker-compose.yml
|
|
31
|
+
services = await compose.validateServices(argv);
|
|
32
|
+
// Build resources for services that have corresponding components
|
|
33
|
+
const componentNames = new Set(monorepo.components.map((c) => c.name));
|
|
34
|
+
const componentsToBuild = services.filter((s) => componentNames.has(s));
|
|
35
|
+
resources = componentsToBuild.reduce((resources, name) => {
|
|
36
|
+
const component = monorepo.component(name);
|
|
39
37
|
return [
|
|
40
38
|
...resources,
|
|
41
39
|
...Object.values(component.resources).map((r) => r.id),
|
|
@@ -45,13 +43,16 @@ export default class UpCommand extends FlavoredCommand {
|
|
|
45
43
|
else {
|
|
46
44
|
resources = monorepo.resources.map((r) => r.id);
|
|
47
45
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
// Only build resources if there are any to build
|
|
47
|
+
if (resources && resources.length > 0) {
|
|
48
|
+
await monorepo.run(new BuildResourcesOperation(), {
|
|
49
|
+
force: flags.force,
|
|
50
|
+
resources,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
52
53
|
await monorepo.run(new ComposeUpOperation(), {
|
|
53
54
|
forceRecreate: flags.force,
|
|
54
|
-
|
|
55
|
+
services,
|
|
55
56
|
});
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -18,7 +18,7 @@ export type TaskConfig = TaskConfig1 & {
|
|
|
18
18
|
[k: string]: unknown;
|
|
19
19
|
};
|
|
20
20
|
pre?: QualifiedIdentifier[];
|
|
21
|
-
executors?: ("local" | "container")[];
|
|
21
|
+
executors?: ("local" | "container" | "kubernetes")[];
|
|
22
22
|
/**
|
|
23
23
|
* Whether the task is interactive (requires TTY)
|
|
24
24
|
*/
|
|
@@ -107,6 +107,24 @@ export interface DefaultsConfig {
|
|
|
107
107
|
};
|
|
108
108
|
[k: string]: unknown;
|
|
109
109
|
};
|
|
110
|
+
kubernetes?: KubernetesConfig;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Kubernetes configuration for the project
|
|
114
|
+
*/
|
|
115
|
+
export interface KubernetesConfig {
|
|
116
|
+
/**
|
|
117
|
+
* Default Kubernetes namespace to use
|
|
118
|
+
*/
|
|
119
|
+
namespace?: string;
|
|
120
|
+
/**
|
|
121
|
+
* Kubernetes context to use from kubeconfig
|
|
122
|
+
*/
|
|
123
|
+
context?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Label name used in pod selectors. Defaults to 'app.kubernetes.io/component'
|
|
126
|
+
*/
|
|
127
|
+
selectorLabel?: string;
|
|
110
128
|
}
|
|
111
129
|
export interface ComponentConfig {
|
|
112
130
|
/**
|
|
@@ -126,6 +144,7 @@ export interface ComponentConfig {
|
|
|
126
144
|
flavors?: {
|
|
127
145
|
[k: string]: ComponentFlavorConfig;
|
|
128
146
|
};
|
|
147
|
+
kubernetes?: ComponentKubernetesConfig;
|
|
129
148
|
}
|
|
130
149
|
export interface ComponentFlavorConfig {
|
|
131
150
|
patches?: JsonPatchOperation[];
|
|
@@ -154,6 +173,19 @@ export interface JsonPatchCopyOperation {
|
|
|
154
173
|
path: string;
|
|
155
174
|
from: string;
|
|
156
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Kubernetes configuration for a component
|
|
178
|
+
*/
|
|
179
|
+
export interface ComponentKubernetesConfig {
|
|
180
|
+
/**
|
|
181
|
+
* Label selector to find pods (e.g., 'app=api,tier=backend'). Defaults to '{componentLabel}={component}'
|
|
182
|
+
*/
|
|
183
|
+
selector?: string;
|
|
184
|
+
/**
|
|
185
|
+
* Container name for multi-container pods
|
|
186
|
+
*/
|
|
187
|
+
container?: string;
|
|
188
|
+
}
|
|
157
189
|
export interface ProjectFlavorConfig {
|
|
158
190
|
patches?: JsonPatchOperation[];
|
|
159
191
|
}
|
|
@@ -71,6 +71,40 @@
|
|
|
71
71
|
"type": "string",
|
|
72
72
|
"pattern": "^([a-zA-Z]+[\\w._-]+:)?[a-zA-Z]+[\\w._-]+$"
|
|
73
73
|
},
|
|
74
|
+
"KubernetesConfig": {
|
|
75
|
+
"type": "object",
|
|
76
|
+
"description": "Kubernetes configuration for the project",
|
|
77
|
+
"properties": {
|
|
78
|
+
"namespace": {
|
|
79
|
+
"type": "string",
|
|
80
|
+
"description": "Default Kubernetes namespace to use"
|
|
81
|
+
},
|
|
82
|
+
"context": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"description": "Kubernetes context to use from kubeconfig"
|
|
85
|
+
},
|
|
86
|
+
"selectorLabel": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"description": "Label name used in pod selectors. Defaults to 'app.kubernetes.io/component'"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"additionalProperties": false
|
|
92
|
+
},
|
|
93
|
+
"ComponentKubernetesConfig": {
|
|
94
|
+
"type": "object",
|
|
95
|
+
"description": "Kubernetes configuration for a component",
|
|
96
|
+
"properties": {
|
|
97
|
+
"selector": {
|
|
98
|
+
"type": "string",
|
|
99
|
+
"description": "Label selector to find pods (e.g., 'app=api,tier=backend'). Defaults to '{componentLabel}={component}'"
|
|
100
|
+
},
|
|
101
|
+
"container": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"description": "Container name for multi-container pods"
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"additionalProperties": false
|
|
107
|
+
},
|
|
74
108
|
"DefaultsConfig": {
|
|
75
109
|
"type": "object",
|
|
76
110
|
"description": "Default settings for build aspects",
|
|
@@ -103,6 +137,9 @@
|
|
|
103
137
|
}
|
|
104
138
|
}
|
|
105
139
|
}
|
|
140
|
+
},
|
|
141
|
+
"kubernetes": {
|
|
142
|
+
"$ref": "#/definitions/KubernetesConfig"
|
|
106
143
|
}
|
|
107
144
|
}
|
|
108
145
|
},
|
|
@@ -138,7 +175,8 @@
|
|
|
138
175
|
"items": {
|
|
139
176
|
"anyOf": [
|
|
140
177
|
{ "const": "local" },
|
|
141
|
-
{ "const": "container" }
|
|
178
|
+
{ "const": "container" },
|
|
179
|
+
{ "const": "kubernetes" }
|
|
142
180
|
]
|
|
143
181
|
}
|
|
144
182
|
},
|
|
@@ -200,6 +238,9 @@
|
|
|
200
238
|
"additionalProperties": {
|
|
201
239
|
"$ref": "#/definitions/ComponentFlavorConfig"
|
|
202
240
|
}
|
|
241
|
+
},
|
|
242
|
+
"kubernetes": {
|
|
243
|
+
"$ref": "#/definitions/ComponentKubernetesConfig"
|
|
203
244
|
}
|
|
204
245
|
},
|
|
205
246
|
"additionalProperties": false
|