@enspirit/emb 0.5.2 → 0.6.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 +87 -3
- package/dist/src/cli/abstract/BaseCommand.js +3 -1
- package/dist/src/cli/commands/components/logs.js +7 -19
- package/dist/src/cli/commands/images/push.d.ts +11 -0
- package/dist/src/cli/commands/images/push.js +29 -0
- package/dist/src/cli/commands/resources/index.js +9 -1
- package/dist/src/cli/commands/restart.d.ts +14 -0
- package/dist/src/cli/commands/restart.js +38 -0
- package/dist/src/cli/commands/stop.js +2 -2
- package/dist/src/cli/commands/tasks/index.js +1 -1
- package/dist/src/cli/commands/tasks/run.d.ts +1 -0
- package/dist/src/cli/commands/tasks/run.js +1 -0
- package/dist/src/config/schema.d.ts +6 -0
- package/dist/src/config/schema.json +7 -0
- package/dist/src/docker/compose/client.d.ts +24 -0
- package/dist/src/docker/compose/client.js +55 -0
- package/dist/src/docker/compose/index.d.ts +1 -0
- package/dist/src/docker/compose/index.js +1 -0
- package/dist/src/docker/compose/operations/ComposeExecOperation.d.ts +1 -0
- package/dist/src/docker/compose/operations/ComposeExecOperation.js +12 -1
- package/dist/src/docker/compose/operations/ComposeRestartOperation.d.ts +14 -0
- package/dist/src/docker/compose/operations/ComposeRestartOperation.js +46 -0
- package/dist/src/docker/compose/operations/index.d.ts +1 -0
- package/dist/src/docker/compose/operations/index.js +1 -0
- package/dist/src/docker/index.d.ts +0 -1
- package/dist/src/docker/index.js +0 -1
- package/dist/src/docker/operations/containers/ContainerExecOperation.d.ts +0 -3
- package/dist/src/docker/operations/containers/ContainerExecOperation.js +3 -19
- package/dist/src/docker/operations/images/PushImagesOperation.d.ts +9 -3
- package/dist/src/docker/operations/images/PushImagesOperation.js +104 -6
- package/dist/src/docker/resources/DockerImageResource.js +9 -6
- package/dist/src/monorepo/component.d.ts +1 -0
- package/dist/src/monorepo/component.js +3 -0
- package/dist/src/monorepo/config.js +1 -1
- package/dist/src/monorepo/monorepo.js +1 -8
- package/dist/src/monorepo/operations/resources/BuildResourcesOperation.js +0 -1
- package/dist/src/monorepo/operations/shell/ExecuteLocalCommandOperation.js +1 -0
- package/dist/src/monorepo/operations/tasks/RunTasksOperation.d.ts +5 -1
- package/dist/src/monorepo/operations/tasks/RunTasksOperation.js +8 -5
- package/dist/src/monorepo/resources/FileResourceBuilder.d.ts +1 -0
- package/dist/src/monorepo/resources/FileResourceBuilder.js +4 -1
- package/dist/src/monorepo/resources/ResourceFactory.js +1 -1
- package/dist/src/monorepo/resources/abstract/AbstractResourceBuilder.d.ts +1 -0
- package/dist/src/monorepo/resources/types.d.ts +6 -0
- package/dist/src/monorepo/types.d.ts +6 -1
- package/dist/src/monorepo/utils/EMBCollection.d.ts +0 -3
- package/dist/src/monorepo/utils/EMBCollection.js +0 -14
- package/dist/src/monorepo/utils/index.d.ts +7 -4
- package/dist/src/monorepo/utils/index.js +14 -8
- package/dist/src/types.d.ts +2 -0
- package/oclif.manifest.json +139 -36
- package/package.json +1 -1
- package/dist/src/docker/containers/getContainer.d.ts +0 -2
- package/dist/src/docker/containers/getContainer.js +0 -5
- package/dist/src/docker/containers/index.d.ts +0 -1
- package/dist/src/docker/containers/index.js +0 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ $ npm install -g @enspirit/emb
|
|
|
14
14
|
$ emb COMMAND
|
|
15
15
|
running command...
|
|
16
16
|
$ emb (--version)
|
|
17
|
-
@enspirit/emb/0.
|
|
17
|
+
@enspirit/emb/0.6.0 darwin-x64 node-v22.18.0
|
|
18
18
|
$ emb --help [COMMAND]
|
|
19
19
|
USAGE
|
|
20
20
|
$ emb COMMAND
|
|
@@ -36,10 +36,13 @@ USAGE
|
|
|
36
36
|
* [`emb images`](#emb-images)
|
|
37
37
|
* [`emb images delete`](#emb-images-delete)
|
|
38
38
|
* [`emb images prune`](#emb-images-prune)
|
|
39
|
+
* [`emb images push`](#emb-images-push)
|
|
39
40
|
* [`emb logs COMPONENT`](#emb-logs-component)
|
|
40
41
|
* [`emb ps`](#emb-ps)
|
|
41
42
|
* [`emb resources`](#emb-resources)
|
|
42
43
|
* [`emb resources build [COMPONENT]`](#emb-resources-build-component)
|
|
44
|
+
* [`emb restart [COMPONENT]`](#emb-restart-component)
|
|
45
|
+
* [`emb run TASK`](#emb-run-task)
|
|
43
46
|
* [`emb shell COMPONENT`](#emb-shell-component)
|
|
44
47
|
* [`emb stop`](#emb-stop)
|
|
45
48
|
* [`emb tasks`](#emb-tasks)
|
|
@@ -132,7 +135,7 @@ ARGUMENTS
|
|
|
132
135
|
COMPONENT The component you want to see the logs of
|
|
133
136
|
|
|
134
137
|
FLAGS
|
|
135
|
-
-f, --follow Follow log output
|
|
138
|
+
-f, --[no-]follow Follow log output
|
|
136
139
|
|
|
137
140
|
DESCRIPTION
|
|
138
141
|
Get components logs.
|
|
@@ -336,6 +339,31 @@ EXAMPLES
|
|
|
336
339
|
$ emb images prune
|
|
337
340
|
```
|
|
338
341
|
|
|
342
|
+
## `emb images push`
|
|
343
|
+
|
|
344
|
+
Push docker images.
|
|
345
|
+
|
|
346
|
+
```
|
|
347
|
+
USAGE
|
|
348
|
+
$ emb images push [--json] [--flavor <value>] [--registry <value>] [--retag <value>]
|
|
349
|
+
|
|
350
|
+
FLAGS
|
|
351
|
+
--flavor=<value> Specify the flavor to use.
|
|
352
|
+
--registry=<value> Override the registry to push to
|
|
353
|
+
--retag=<value> Override the original tag to push to a new tag
|
|
354
|
+
|
|
355
|
+
GLOBAL FLAGS
|
|
356
|
+
--json Format output as json.
|
|
357
|
+
|
|
358
|
+
DESCRIPTION
|
|
359
|
+
Push docker images.
|
|
360
|
+
|
|
361
|
+
EXAMPLES
|
|
362
|
+
$ emb images push
|
|
363
|
+
|
|
364
|
+
$ emb images push --registry my.registry.io --retag newtag
|
|
365
|
+
```
|
|
366
|
+
|
|
339
367
|
## `emb logs COMPONENT`
|
|
340
368
|
|
|
341
369
|
Get components logs.
|
|
@@ -348,7 +376,7 @@ ARGUMENTS
|
|
|
348
376
|
COMPONENT The component you want to see the logs of
|
|
349
377
|
|
|
350
378
|
FLAGS
|
|
351
|
-
-f, --follow Follow log output
|
|
379
|
+
-f, --[no-]follow Follow log output
|
|
352
380
|
|
|
353
381
|
DESCRIPTION
|
|
354
382
|
Get components logs.
|
|
@@ -431,6 +459,59 @@ EXAMPLES
|
|
|
431
459
|
$ emb resources build build --flavor development
|
|
432
460
|
```
|
|
433
461
|
|
|
462
|
+
## `emb restart [COMPONENT]`
|
|
463
|
+
|
|
464
|
+
Restart the whole project.
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
USAGE
|
|
468
|
+
$ emb restart [COMPONENT...] [--json] [-f]
|
|
469
|
+
|
|
470
|
+
ARGUMENTS
|
|
471
|
+
COMPONENT... The component(s) to restart
|
|
472
|
+
|
|
473
|
+
FLAGS
|
|
474
|
+
-f, --no-deps Don't restart depdendent components
|
|
475
|
+
|
|
476
|
+
GLOBAL FLAGS
|
|
477
|
+
--json Format output as json.
|
|
478
|
+
|
|
479
|
+
DESCRIPTION
|
|
480
|
+
Restart the whole project.
|
|
481
|
+
|
|
482
|
+
EXAMPLES
|
|
483
|
+
$ emb restart
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
## `emb run TASK`
|
|
487
|
+
|
|
488
|
+
Run tasks.
|
|
489
|
+
|
|
490
|
+
```
|
|
491
|
+
USAGE
|
|
492
|
+
$ emb run TASK... [--json] [-x container|local] [-a]
|
|
493
|
+
|
|
494
|
+
ARGUMENTS
|
|
495
|
+
TASK... List of tasks to run. You can provide either ids or names (eg: component:task or task)
|
|
496
|
+
|
|
497
|
+
FLAGS
|
|
498
|
+
-a, --all-matching Run all tasks matching (when multiple matches)
|
|
499
|
+
-x, --executor=<option> Where to run the task. (experimental!)
|
|
500
|
+
<options: container|local>
|
|
501
|
+
|
|
502
|
+
GLOBAL FLAGS
|
|
503
|
+
--json Format output as json.
|
|
504
|
+
|
|
505
|
+
DESCRIPTION
|
|
506
|
+
Run tasks.
|
|
507
|
+
|
|
508
|
+
ALIASES
|
|
509
|
+
$ emb run
|
|
510
|
+
|
|
511
|
+
EXAMPLES
|
|
512
|
+
$ emb run
|
|
513
|
+
```
|
|
514
|
+
|
|
434
515
|
## `emb shell COMPONENT`
|
|
435
516
|
|
|
436
517
|
Get a shell on a running component.
|
|
@@ -516,6 +597,9 @@ GLOBAL FLAGS
|
|
|
516
597
|
DESCRIPTION
|
|
517
598
|
Run tasks.
|
|
518
599
|
|
|
600
|
+
ALIASES
|
|
601
|
+
$ emb run
|
|
602
|
+
|
|
519
603
|
EXAMPLES
|
|
520
604
|
$ emb tasks run
|
|
521
605
|
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getContext, setContext } from '../../index.js';
|
|
1
|
+
import { DockerComposeClient, getContext, setContext } from '../../index.js';
|
|
2
2
|
import { Command, Performance } from '@oclif/core';
|
|
3
3
|
import Dockerode from 'dockerode';
|
|
4
4
|
import { loadConfig } from '../../config/index.js';
|
|
@@ -21,9 +21,11 @@ export class BaseCommand extends Command {
|
|
|
21
21
|
const monorepo = await withMarker('emb:monorepo', 'init', () => {
|
|
22
22
|
return new Monorepo(config, rootDir).init();
|
|
23
23
|
});
|
|
24
|
+
const compose = new DockerComposeClient(monorepo);
|
|
24
25
|
this.context = setContext({
|
|
25
26
|
docker: new Dockerode(),
|
|
26
27
|
monorepo,
|
|
28
|
+
compose,
|
|
27
29
|
});
|
|
28
30
|
}
|
|
29
31
|
catch (error) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import { BaseCommand, getContext } from '../../index.js';
|
|
3
|
-
import { ListContainersOperation } from '../../../docker/index.js';
|
|
4
3
|
export default class ComponentsLogs extends BaseCommand {
|
|
5
4
|
static aliases = ['logs'];
|
|
6
5
|
static description = 'Get components logs.';
|
|
@@ -10,8 +9,9 @@ export default class ComponentsLogs extends BaseCommand {
|
|
|
10
9
|
follow: Flags.boolean({
|
|
11
10
|
name: 'follow',
|
|
12
11
|
char: 'f',
|
|
12
|
+
allowNo: true,
|
|
13
13
|
description: 'Follow log output',
|
|
14
|
-
default:
|
|
14
|
+
default: true,
|
|
15
15
|
}),
|
|
16
16
|
};
|
|
17
17
|
static args = {
|
|
@@ -23,31 +23,19 @@ export default class ComponentsLogs extends BaseCommand {
|
|
|
23
23
|
};
|
|
24
24
|
async run() {
|
|
25
25
|
const { flags, args } = await this.parse(ComponentsLogs);
|
|
26
|
-
const { monorepo, docker } = await getContext();
|
|
26
|
+
const { monorepo, docker, compose } = await getContext();
|
|
27
27
|
const component = monorepo.component(args.component);
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
label: [
|
|
31
|
-
`emb/project=${monorepo.name}`,
|
|
32
|
-
`emb/component=${component.name}`,
|
|
33
|
-
`emb/flavor=${monorepo.currentFlavor}`,
|
|
34
|
-
],
|
|
35
|
-
},
|
|
28
|
+
const containerId = await compose.getContainer(component.name, {
|
|
29
|
+
mustBeRunning: false,
|
|
36
30
|
});
|
|
37
|
-
|
|
38
|
-
return this.error(`No container found for component \`${component.name}\``);
|
|
39
|
-
}
|
|
40
|
-
if (containers.length > 1) {
|
|
41
|
-
return this.error(`More than one container found for component \`${component.name}\``);
|
|
42
|
-
}
|
|
43
|
-
const container = await docker.getContainer(containers[0].Id);
|
|
31
|
+
const container = await docker.getContainer(containerId);
|
|
44
32
|
if (flags.follow) {
|
|
45
33
|
const stream = await container.logs({
|
|
46
34
|
follow: true,
|
|
47
35
|
stderr: true,
|
|
48
36
|
stdout: true,
|
|
49
37
|
});
|
|
50
|
-
|
|
38
|
+
docker.modem.demuxStream(stream, process.stdout, process.stderr);
|
|
51
39
|
}
|
|
52
40
|
else {
|
|
53
41
|
const res = await container.logs({
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FlavoredCommand } from '../../index.js';
|
|
2
|
+
export default class ImagesPush extends FlavoredCommand<typeof ImagesPush> {
|
|
3
|
+
static description: string;
|
|
4
|
+
static enableJsonFlag: boolean;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
registry: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
retag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
};
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { FlavoredCommand } from '../../index.js';
|
|
3
|
+
import { PushImagesOperation } from '../../../docker/operations/images/PushImagesOperation.js';
|
|
4
|
+
export default class ImagesPush extends FlavoredCommand {
|
|
5
|
+
static description = 'Push docker images.';
|
|
6
|
+
static enableJsonFlag = true;
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %>',
|
|
9
|
+
'<%= config.bin %> <%= command.id %> --registry my.registry.io --retag newtag',
|
|
10
|
+
];
|
|
11
|
+
static flags = {
|
|
12
|
+
registry: Flags.string({
|
|
13
|
+
name: 'registry',
|
|
14
|
+
description: 'Override the registry to push to',
|
|
15
|
+
}),
|
|
16
|
+
retag: Flags.string({
|
|
17
|
+
name: 'retag',
|
|
18
|
+
description: 'Override the original tag to push to a new tag',
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
async run() {
|
|
22
|
+
const { flags } = await this.parse(ImagesPush);
|
|
23
|
+
const { monorepo } = this.context;
|
|
24
|
+
await monorepo.run(new PushImagesOperation(process.stdout), {
|
|
25
|
+
registry: flags.registry,
|
|
26
|
+
retag: flags.retag,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { printTable } from '@oclif/table';
|
|
2
2
|
import { FlavoredCommand, getContext, TABLE_DEFAULTS } from '../../index.js';
|
|
3
|
+
import { ResourceFactory } from '../../../monorepo/resources/ResourceFactory.js';
|
|
3
4
|
export default class ResourcesIndex extends FlavoredCommand {
|
|
4
5
|
static description = 'List resources.';
|
|
5
6
|
static enableJsonFlag = true;
|
|
@@ -9,14 +10,21 @@ export default class ResourcesIndex extends FlavoredCommand {
|
|
|
9
10
|
const { flags } = await this.parse(ResourcesIndex);
|
|
10
11
|
const { monorepo } = await getContext();
|
|
11
12
|
const resources = await Promise.all(monorepo.resources.map(async (config) => {
|
|
13
|
+
const component = monorepo.component(config.component);
|
|
14
|
+
const builder = ResourceFactory.factor(config.type, {
|
|
15
|
+
config,
|
|
16
|
+
monorepo,
|
|
17
|
+
component,
|
|
18
|
+
});
|
|
12
19
|
return {
|
|
13
20
|
...config,
|
|
21
|
+
reference: await builder.getReference(),
|
|
14
22
|
};
|
|
15
23
|
}));
|
|
16
24
|
if (!flags.json) {
|
|
17
25
|
printTable({
|
|
18
26
|
...TABLE_DEFAULTS,
|
|
19
|
-
columns: ['name', 'type', 'id'],
|
|
27
|
+
columns: ['name', 'type', 'reference', 'id'],
|
|
20
28
|
data: resources,
|
|
21
29
|
sort: {
|
|
22
30
|
name: 'asc',
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from '../index.js';
|
|
2
|
+
export default class RestartComand extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static enableJsonFlag: boolean;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
'no-deps': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
static args: {
|
|
10
|
+
component: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
11
|
+
};
|
|
12
|
+
static strict: boolean;
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { BaseCommand, getContext } from '../index.js';
|
|
3
|
+
import { ComposeRestartOperation } from '../../docker/index.js';
|
|
4
|
+
export default class RestartComand extends BaseCommand {
|
|
5
|
+
static description = 'Restart the whole project.';
|
|
6
|
+
static enableJsonFlag = true;
|
|
7
|
+
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
8
|
+
static flags = {
|
|
9
|
+
'no-deps': Flags.boolean({
|
|
10
|
+
char: 'f',
|
|
11
|
+
default: false,
|
|
12
|
+
description: "Don't restart depdendent components",
|
|
13
|
+
name: 'no-deps',
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
static args = {
|
|
17
|
+
component: Args.string({
|
|
18
|
+
name: 'component',
|
|
19
|
+
description: 'The component(s) to restart',
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
static strict = false;
|
|
23
|
+
async run() {
|
|
24
|
+
const { flags, argv } = await this.parse(RestartComand);
|
|
25
|
+
const { monorepo } = getContext();
|
|
26
|
+
let components;
|
|
27
|
+
if (argv.length > 0) {
|
|
28
|
+
components =
|
|
29
|
+
argv.length > 0
|
|
30
|
+
? argv.map((name) => monorepo.component(name))
|
|
31
|
+
: monorepo.components;
|
|
32
|
+
}
|
|
33
|
+
await monorepo.run(new ComposeRestartOperation(), {
|
|
34
|
+
noDeps: flags['no-deps'],
|
|
35
|
+
services: components?.map((c) => c.name),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Listr } from 'listr2';
|
|
2
2
|
import { FlavoredCommand, getContext } from '../index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { ComposeStopOperation } from '../../docker/index.js';
|
|
4
4
|
export default class StopCommand extends FlavoredCommand {
|
|
5
5
|
static description = 'Stop the whole project.';
|
|
6
6
|
static enableJsonFlag = true;
|
|
@@ -12,7 +12,7 @@ export default class StopCommand extends FlavoredCommand {
|
|
|
12
12
|
{
|
|
13
13
|
rendererOptions: { persistentOutput: true },
|
|
14
14
|
async task(ctx, task) {
|
|
15
|
-
return monorepo.run(new
|
|
15
|
+
return monorepo.run(new ComposeStopOperation(task.stdout()), {});
|
|
16
16
|
},
|
|
17
17
|
title: 'Stopping project',
|
|
18
18
|
},
|
|
@@ -20,7 +20,7 @@ export default class TasksIndex extends BaseCommand {
|
|
|
20
20
|
return 1;
|
|
21
21
|
}
|
|
22
22
|
// Compare components (if both not null)
|
|
23
|
-
if (Boolean(ac) && Boolean(bc)) {
|
|
23
|
+
if (ac && bc && Boolean(ac) && Boolean(bc)) {
|
|
24
24
|
const cmp = ac.localeCompare(bc);
|
|
25
25
|
if (cmp !== 0) {
|
|
26
26
|
return cmp;
|
|
@@ -3,6 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { BaseCommand } from '../../index.js';
|
|
4
4
|
import { ExecutorType, RunTasksOperation } from '../../../monorepo/index.js';
|
|
5
5
|
export default class RunTask extends BaseCommand {
|
|
6
|
+
static aliases = ['run'];
|
|
6
7
|
static args = {
|
|
7
8
|
task: Args.string({
|
|
8
9
|
description: 'List of tasks to run. You can provide either ids or names (eg: component:task or task)',
|
|
@@ -136,6 +136,13 @@
|
|
|
136
136
|
"items": {
|
|
137
137
|
"$ref": "#/definitions/Identifier"
|
|
138
138
|
}
|
|
139
|
+
},
|
|
140
|
+
"vars": {
|
|
141
|
+
"type": "object",
|
|
142
|
+
"description": "Variables to pass onto the task",
|
|
143
|
+
"additionalProperties": {
|
|
144
|
+
"type": "string"
|
|
145
|
+
}
|
|
139
146
|
}
|
|
140
147
|
},
|
|
141
148
|
"additionalProperties": false
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Monorepo } from '../../index.js';
|
|
2
|
+
export type ComposeContainer = {
|
|
3
|
+
Name: string;
|
|
4
|
+
ID: string;
|
|
5
|
+
State: 'exited' | 'running';
|
|
6
|
+
};
|
|
7
|
+
export type ComposeService = {
|
|
8
|
+
name: string;
|
|
9
|
+
containers: Array<ComposeContainer>;
|
|
10
|
+
};
|
|
11
|
+
export type ComposeServices = Map<string, ComposeService>;
|
|
12
|
+
export type GetContainerOptions = {
|
|
13
|
+
mustBeRunning: boolean;
|
|
14
|
+
mustBeUnique: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare const DefaultGetContainerOptions: GetContainerOptions;
|
|
17
|
+
export declare class DockerComposeClient {
|
|
18
|
+
protected monorepo: Monorepo;
|
|
19
|
+
protected containers?: ComposeServices;
|
|
20
|
+
constructor(monorepo: Monorepo);
|
|
21
|
+
init(): Promise<void>;
|
|
22
|
+
getContainer(serviceName: string, options?: Partial<GetContainerOptions>): Promise<string>;
|
|
23
|
+
private loadContainers;
|
|
24
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
export const DefaultGetContainerOptions = {
|
|
3
|
+
mustBeRunning: true,
|
|
4
|
+
mustBeUnique: true,
|
|
5
|
+
};
|
|
6
|
+
export class DockerComposeClient {
|
|
7
|
+
monorepo;
|
|
8
|
+
containers;
|
|
9
|
+
constructor(monorepo) {
|
|
10
|
+
this.monorepo = monorepo;
|
|
11
|
+
}
|
|
12
|
+
async init() {
|
|
13
|
+
await this.loadContainers();
|
|
14
|
+
}
|
|
15
|
+
async getContainer(serviceName, options = DefaultGetContainerOptions) {
|
|
16
|
+
const getOptions = { ...DefaultGetContainerOptions, ...options };
|
|
17
|
+
await this.loadContainers();
|
|
18
|
+
const service = this.containers?.get(serviceName);
|
|
19
|
+
if (!service) {
|
|
20
|
+
throw new Error(`No compose service found with name ${serviceName}`);
|
|
21
|
+
}
|
|
22
|
+
const containers = getOptions.mustBeRunning
|
|
23
|
+
? service.containers.filter((c) => c.State === 'running')
|
|
24
|
+
: service.containers;
|
|
25
|
+
if (containers.length === 0) {
|
|
26
|
+
throw new Error(`No container found for service ${serviceName}`);
|
|
27
|
+
}
|
|
28
|
+
if (containers.length > 1 && getOptions.mustBeUnique) {
|
|
29
|
+
throw new Error(`Multiple containers found`);
|
|
30
|
+
}
|
|
31
|
+
return containers[0].ID;
|
|
32
|
+
}
|
|
33
|
+
async loadContainers(force = false) {
|
|
34
|
+
if (this.containers && !force) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const { stdout } = await execa({
|
|
38
|
+
cwd: this.monorepo.rootDir,
|
|
39
|
+
}) `docker compose ps -a --format json`;
|
|
40
|
+
this.containers = stdout
|
|
41
|
+
.split('\n')
|
|
42
|
+
.map((l) => JSON.parse(l))
|
|
43
|
+
.reduce((services, entry) => {
|
|
44
|
+
if (!services.has(entry.Service)) {
|
|
45
|
+
services.set(entry.Service, {
|
|
46
|
+
name: entry.Service,
|
|
47
|
+
containers: [],
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const svc = services.get(entry.Service);
|
|
51
|
+
svc?.containers.push(entry);
|
|
52
|
+
return services;
|
|
53
|
+
}, new Map());
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -3,6 +3,7 @@ import * as z from 'zod';
|
|
|
3
3
|
import { AbstractOperation } from '../../../operations/index.js';
|
|
4
4
|
declare const schema: z.ZodObject<{
|
|
5
5
|
command: z.ZodString;
|
|
6
|
+
env: z.ZodOptional<z.ZodObject<{}, z.core.$catchall<z.ZodString>>>;
|
|
6
7
|
service: z.ZodString;
|
|
7
8
|
}, z.core.$strip>;
|
|
8
9
|
export declare class ComposeExecOperation extends AbstractOperation<typeof schema, void> {
|
|
@@ -4,6 +4,11 @@ import { ComposeExecError } from '../../../errors.js';
|
|
|
4
4
|
import { AbstractOperation } from '../../../operations/index.js';
|
|
5
5
|
const schema = z.object({
|
|
6
6
|
command: z.string().describe('The command to execute on the service'),
|
|
7
|
+
env: z
|
|
8
|
+
.object()
|
|
9
|
+
.catchall(z.string())
|
|
10
|
+
.describe('Environment variables to pass to the execution')
|
|
11
|
+
.optional(),
|
|
7
12
|
service: z
|
|
8
13
|
.string()
|
|
9
14
|
.describe('The name of the compose service to exec a shell'),
|
|
@@ -17,7 +22,13 @@ export class ComposeExecOperation extends AbstractOperation {
|
|
|
17
22
|
async _run(input) {
|
|
18
23
|
const { monorepo } = this.context;
|
|
19
24
|
const cmd = 'docker';
|
|
20
|
-
const args = ['compose', 'exec'
|
|
25
|
+
const args = ['compose', 'exec'];
|
|
26
|
+
// Add any env vars
|
|
27
|
+
Object.entries(input.env || {}).forEach(([key, value]) => {
|
|
28
|
+
args.push('-e', `${key.trim()}=${value.trim()}`);
|
|
29
|
+
});
|
|
30
|
+
// add component and script
|
|
31
|
+
args.push(input.service, input.command);
|
|
21
32
|
const child = spawn(cmd, args, {
|
|
22
33
|
stdio: 'pipe',
|
|
23
34
|
shell: true,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
import { AbstractOperation } from '../../../operations/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* https://docs.docker.com/reference/cli/docker/compose/restart/
|
|
5
|
+
*/
|
|
6
|
+
declare const schema: z.ZodOptional<z.ZodObject<{
|
|
7
|
+
services: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
8
|
+
noDeps: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
}, z.core.$strip>>;
|
|
10
|
+
export declare class ComposeRestartOperation extends AbstractOperation<typeof schema, void> {
|
|
11
|
+
constructor();
|
|
12
|
+
protected _run(input: z.input<typeof schema>): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getContext } from '../../../index.js';
|
|
2
|
+
import * as z from 'zod';
|
|
3
|
+
import { ExecuteLocalCommandOperation, taskManagerFactory } from '../../../monorepo/index.js';
|
|
4
|
+
import { AbstractOperation } from '../../../operations/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* https://docs.docker.com/reference/cli/docker/compose/restart/
|
|
7
|
+
*/
|
|
8
|
+
const schema = z
|
|
9
|
+
.object({
|
|
10
|
+
services: z
|
|
11
|
+
.array(z.string())
|
|
12
|
+
.optional()
|
|
13
|
+
.describe('The list of service to restart'),
|
|
14
|
+
noDeps: z.boolean().optional().describe("Don't restart dependent services"),
|
|
15
|
+
})
|
|
16
|
+
.optional();
|
|
17
|
+
export class ComposeRestartOperation extends AbstractOperation {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(schema);
|
|
20
|
+
}
|
|
21
|
+
async _run(input) {
|
|
22
|
+
const { monorepo } = getContext();
|
|
23
|
+
const manager = taskManagerFactory();
|
|
24
|
+
const command = ['docker', 'compose', 'restart'];
|
|
25
|
+
if (input?.services) {
|
|
26
|
+
command.push(...input.services);
|
|
27
|
+
}
|
|
28
|
+
if (input?.noDeps) {
|
|
29
|
+
command.push('--no-deps');
|
|
30
|
+
}
|
|
31
|
+
manager.add([
|
|
32
|
+
{
|
|
33
|
+
async task(ctx, task) {
|
|
34
|
+
return monorepo.run(new ExecuteLocalCommandOperation(task.stdout()), {
|
|
35
|
+
script: command.join(' '),
|
|
36
|
+
workingDir: monorepo.rootDir,
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
title: input?.services
|
|
40
|
+
? `Restarting ${input.services.join(', ')}`
|
|
41
|
+
: 'Restarting project',
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
await manager.runAll();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './ComposeDownOperation.js';
|
|
2
2
|
export * from './ComposeExecOperation.js';
|
|
3
3
|
export * from './ComposeExecShellOperation.js';
|
|
4
|
+
export * from './ComposeRestartOperation.js';
|
|
4
5
|
export * from './ComposeStopOperation.js';
|
|
5
6
|
export * from './ComposeUpOperation.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './ComposeDownOperation.js';
|
|
2
2
|
export * from './ComposeExecOperation.js';
|
|
3
3
|
export * from './ComposeExecShellOperation.js';
|
|
4
|
+
export * from './ComposeRestartOperation.js';
|
|
4
5
|
export * from './ComposeStopOperation.js';
|
|
5
6
|
export * from './ComposeUpOperation.js';
|
package/dist/src/docker/index.js
CHANGED
|
@@ -5,9 +5,6 @@ import { AbstractOperation } from '../../../operations/index.js';
|
|
|
5
5
|
* https://docs.docker.com/reference/api/engine/version/v1.37/#tag/Exec/operation/ContainerExec
|
|
6
6
|
*/
|
|
7
7
|
declare const schema: z.ZodObject<{
|
|
8
|
-
attachStderr: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
9
|
-
attachStdin: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
10
|
-
attachStdout: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
11
8
|
container: z.ZodString;
|
|
12
9
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
13
10
|
script: z.ZodString;
|