@augment-vir/node 31.43.2 → 31.44.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 +0 -2
- package/dist/file-paths.mock.d.ts +0 -6
- package/dist/file-paths.mock.js +0 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/package.json +4 -6
- package/src/file-paths.mock.ts +0 -7
- package/src/index.ts +0 -1
- package/dist/augments/docker.d.ts +0 -92
- package/dist/augments/docker.js +0 -87
- package/dist/docker/containers/container-info.d.ts +0 -57
- package/dist/docker/containers/container-info.js +0 -18
- package/dist/docker/containers/container-status.d.ts +0 -32
- package/dist/docker/containers/container-status.js +0 -68
- package/dist/docker/containers/copy-to-container.d.ts +0 -14
- package/dist/docker/containers/copy-to-container.js +0 -10
- package/dist/docker/containers/docker-command-inputs.d.ts +0 -74
- package/dist/docker/containers/docker-command-inputs.js +0 -45
- package/dist/docker/containers/kill-container.d.ts +0 -10
- package/dist/docker/containers/kill-container.js +0 -12
- package/dist/docker/containers/run-command.d.ts +0 -18
- package/dist/docker/containers/run-command.js +0 -24
- package/dist/docker/containers/run-container.d.ts +0 -23
- package/dist/docker/containers/run-container.js +0 -47
- package/dist/docker/containers/run-container.mock.d.ts +0 -2
- package/dist/docker/containers/run-container.mock.js +0 -16
- package/dist/docker/containers/try-or-kill-container.d.ts +0 -6
- package/dist/docker/containers/try-or-kill-container.js +0 -14
- package/dist/docker/docker-image.d.ts +0 -9
- package/dist/docker/docker-image.js +0 -50
- package/dist/docker/docker-startup.d.ts +0 -2
- package/dist/docker/docker-startup.js +0 -39
- package/dist/docker/run-docker-test.mock.d.ts +0 -2
- package/dist/docker/run-docker-test.mock.js +0 -23
- package/src/augments/docker.ts +0 -119
- package/src/docker/containers/container-info.ts +0 -83
- package/src/docker/containers/container-status.ts +0 -110
- package/src/docker/containers/copy-to-container.ts +0 -34
- package/src/docker/containers/docker-command-inputs.ts +0 -122
- package/src/docker/containers/kill-container.ts +0 -25
- package/src/docker/containers/run-command.ts +0 -51
- package/src/docker/containers/run-container.mock.ts +0 -22
- package/src/docker/containers/run-container.ts +0 -92
- package/src/docker/containers/try-or-kill-container.ts +0 -18
- package/src/docker/docker-image.ts +0 -61
- package/src/docker/docker-startup.ts +0 -49
- package/src/docker/run-docker-test.mock.ts +0 -26
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { check } from '@augment-vir/assert';
|
|
2
|
-
import { runShellCommand } from '../../augments/terminal/shell.js';
|
|
3
|
-
import { makeEnvFlags } from './docker-command-inputs.js';
|
|
4
|
-
export async function runContainerCommand({ tty, containerNameOrId, command, envMapping, executionEnv, dockerFlags = [], }) {
|
|
5
|
-
const envFlags = makeEnvFlags(envMapping);
|
|
6
|
-
/** Can't test tty in automated tests. */
|
|
7
|
-
/* node:coverage ignore next 1 */
|
|
8
|
-
const ttyFlag = tty ? '-it' : '';
|
|
9
|
-
const fullCommand = [
|
|
10
|
-
'docker',
|
|
11
|
-
'exec',
|
|
12
|
-
ttyFlag,
|
|
13
|
-
envFlags,
|
|
14
|
-
...dockerFlags,
|
|
15
|
-
containerNameOrId,
|
|
16
|
-
command,
|
|
17
|
-
]
|
|
18
|
-
.filter(check.isTruthy)
|
|
19
|
-
.join(' ');
|
|
20
|
-
return await runShellCommand(fullCommand, {
|
|
21
|
-
env: executionEnv,
|
|
22
|
-
rejectOnError: true,
|
|
23
|
-
});
|
|
24
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type DockerEnvMap, type DockerPortMap, type DockerVolumeMap } from './docker-command-inputs.js';
|
|
2
|
-
/**
|
|
3
|
-
* Parameters for `docker.container.run`.
|
|
4
|
-
*
|
|
5
|
-
* @category Node : Docker : Util
|
|
6
|
-
* @category Package : @augment-vir/node
|
|
7
|
-
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
8
|
-
*/
|
|
9
|
-
export type RunDockerContainerParams = {
|
|
10
|
-
imageName: string;
|
|
11
|
-
detach: boolean;
|
|
12
|
-
command?: string;
|
|
13
|
-
containerName: string;
|
|
14
|
-
volumeMapping?: ReadonlyArray<DockerVolumeMap> | undefined;
|
|
15
|
-
portMapping?: ReadonlyArray<DockerPortMap> | undefined;
|
|
16
|
-
envMapping?: DockerEnvMap | undefined;
|
|
17
|
-
executionEnv?: Record<string, string>;
|
|
18
|
-
removeWhenDone?: boolean;
|
|
19
|
-
dockerFlags?: ReadonlyArray<string>;
|
|
20
|
-
useCurrentUser?: boolean;
|
|
21
|
-
platform?: string;
|
|
22
|
-
};
|
|
23
|
-
export declare function runContainer({ containerName, imageName, detach, command, portMapping, volumeMapping, envMapping, executionEnv, removeWhenDone, useCurrentUser, dockerFlags, platform, }: RunDockerContainerParams): Promise<void>;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { check } from '@augment-vir/assert';
|
|
2
|
-
import { runShellCommand } from '../../augments/terminal/shell.js';
|
|
3
|
-
import { updateImage } from '../docker-image.js';
|
|
4
|
-
import { waitUntilContainerRunning } from './container-status.js';
|
|
5
|
-
import { makeEnvFlags, makePortMapFlags, makeVolumeFlags, } from './docker-command-inputs.js';
|
|
6
|
-
import { killContainer } from './kill-container.js';
|
|
7
|
-
export async function runContainer({ containerName, imageName, detach, command, portMapping, volumeMapping, envMapping, executionEnv, removeWhenDone, useCurrentUser, dockerFlags = [], platform, }) {
|
|
8
|
-
try {
|
|
9
|
-
const portMapFlags = makePortMapFlags(portMapping);
|
|
10
|
-
const envFlags = makeEnvFlags(envMapping);
|
|
11
|
-
const detachFlag = detach ? '-d' : '';
|
|
12
|
-
const volumeMapFlags = makeVolumeFlags(volumeMapping);
|
|
13
|
-
const rmFlag = removeWhenDone ? '--rm' : '';
|
|
14
|
-
const userFlag = useCurrentUser ? '--user "$(id -u)":"$(id -g)"' : '';
|
|
15
|
-
await updateImage(imageName, platform);
|
|
16
|
-
const fullCommand = [
|
|
17
|
-
'docker',
|
|
18
|
-
'run',
|
|
19
|
-
portMapFlags,
|
|
20
|
-
userFlag,
|
|
21
|
-
volumeMapFlags,
|
|
22
|
-
envFlags,
|
|
23
|
-
rmFlag,
|
|
24
|
-
detachFlag,
|
|
25
|
-
`--name='${containerName}'`,
|
|
26
|
-
...dockerFlags,
|
|
27
|
-
imageName,
|
|
28
|
-
command,
|
|
29
|
-
]
|
|
30
|
-
.filter(check.isTruthy)
|
|
31
|
-
.join(' ');
|
|
32
|
-
await runShellCommand(fullCommand, {
|
|
33
|
-
env: executionEnv,
|
|
34
|
-
rejectOnError: true,
|
|
35
|
-
});
|
|
36
|
-
if (removeWhenDone) {
|
|
37
|
-
await killContainer(containerName);
|
|
38
|
-
}
|
|
39
|
-
else if (detach) {
|
|
40
|
-
await waitUntilContainerRunning(containerName);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
await killContainer(containerName);
|
|
45
|
-
throw error;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-deprecated */
|
|
2
|
-
import { docker } from '../../augments/docker.js';
|
|
3
|
-
export async function runMockLongLivingContainer(containerName, args = {}) {
|
|
4
|
-
await docker.container.run({
|
|
5
|
-
containerName,
|
|
6
|
-
detach: true,
|
|
7
|
-
imageName: 'alpine:3.20.2',
|
|
8
|
-
dockerFlags: [
|
|
9
|
-
'-i',
|
|
10
|
-
'-t',
|
|
11
|
-
],
|
|
12
|
-
command: 'sh',
|
|
13
|
-
platform: 'amd64',
|
|
14
|
-
...args,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { type MaybePromise } from '@augment-vir/core';
|
|
2
|
-
/**
|
|
3
|
-
* Runs a callback (which presumably runs a command within the given `containerName`) and kills the
|
|
4
|
-
* given `containerName` container if the callback fails.
|
|
5
|
-
*/
|
|
6
|
-
export declare function tryOrKillContainer<T>(containerNameOrId: string, callback: (containerNameOrId: string) => MaybePromise<T>): Promise<Awaited<T>>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { killContainer } from './kill-container.js';
|
|
2
|
-
/**
|
|
3
|
-
* Runs a callback (which presumably runs a command within the given `containerName`) and kills the
|
|
4
|
-
* given `containerName` container if the callback fails.
|
|
5
|
-
*/
|
|
6
|
-
export async function tryOrKillContainer(containerNameOrId, callback) {
|
|
7
|
-
try {
|
|
8
|
-
return await callback(containerNameOrId);
|
|
9
|
-
}
|
|
10
|
-
catch (error) {
|
|
11
|
-
await killContainer(containerNameOrId);
|
|
12
|
-
throw error;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export declare function updateImage(
|
|
2
|
-
/** @example 'alpine:3.20.2' */
|
|
3
|
-
imageName: string, platform?: string): Promise<void>;
|
|
4
|
-
export declare function isImageInLocalRegistry(
|
|
5
|
-
/** @example 'alpine:3.20.2' */
|
|
6
|
-
imageName: string): Promise<boolean>;
|
|
7
|
-
export declare function removeImageFromLocalRegistry(
|
|
8
|
-
/** @example 'alpine:3.20.2' */
|
|
9
|
-
imageName: string): Promise<void>;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { wrapString } from '@augment-vir/common';
|
|
2
|
-
import { ensureError } from '@augment-vir/core';
|
|
3
|
-
import { runShellCommand } from '../augments/terminal/shell.js';
|
|
4
|
-
export async function updateImage(
|
|
5
|
-
/** @example 'alpine:3.20.2' */
|
|
6
|
-
imageName, platform) {
|
|
7
|
-
if (await isImageInLocalRegistry(imageName)) {
|
|
8
|
-
/** If image already exists then we don't need to update it. */
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
const command = [
|
|
12
|
-
'docker',
|
|
13
|
-
'pull',
|
|
14
|
-
...(platform
|
|
15
|
-
? [
|
|
16
|
-
'--platform',
|
|
17
|
-
platform,
|
|
18
|
-
]
|
|
19
|
-
: []),
|
|
20
|
-
wrapString({ value: imageName, wrapper: "'" }),
|
|
21
|
-
].join(' ');
|
|
22
|
-
await runShellCommand(command, {
|
|
23
|
-
rejectOnError: true,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
export async function isImageInLocalRegistry(
|
|
27
|
-
/** @example 'alpine:3.20.2' */
|
|
28
|
-
imageName) {
|
|
29
|
-
const output = await runShellCommand(`docker inspect '${imageName}'`);
|
|
30
|
-
return output.exitCode === 0;
|
|
31
|
-
}
|
|
32
|
-
export async function removeImageFromLocalRegistry(
|
|
33
|
-
/** @example 'alpine:3.20.2' */
|
|
34
|
-
imageName) {
|
|
35
|
-
try {
|
|
36
|
-
await runShellCommand(`docker image rm '${imageName}'`, {
|
|
37
|
-
rejectOnError: true,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
catch (caught) {
|
|
41
|
-
const error = ensureError(caught);
|
|
42
|
-
if (error.message.includes('No such image:')) {
|
|
43
|
-
/** Ignore the case where the image has already been deleted. */
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
/** An edge case that I don't know how to intentionally trigger. */
|
|
47
|
-
/* node:coverage ignore next 2 */
|
|
48
|
-
throw error;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { waitUntil } from '@augment-vir/assert';
|
|
2
|
-
import { currentOperatingSystem, OperatingSystem } from '../augments/os/operating-system.js';
|
|
3
|
-
import { runShellCommand } from '../augments/terminal/shell.js';
|
|
4
|
-
export async function isDockerRunning() {
|
|
5
|
-
const output = await runShellCommand('docker info');
|
|
6
|
-
return output.exitCode === 0;
|
|
7
|
-
}
|
|
8
|
-
const startDockerCommands = {
|
|
9
|
-
/**
|
|
10
|
-
* Officially supported for the following distros:
|
|
11
|
-
*
|
|
12
|
-
* - [Ubuntu](https://docs.docker.com/desktop/install/ubuntu/#launch-docker-desktop)
|
|
13
|
-
* - [Debian](https://docs.docker.com/desktop/install/debian/#launch-docker-desktop)
|
|
14
|
-
* - [Fedora](https://docs.docker.com/desktop/install/fedora/#launch-docker-desktop)
|
|
15
|
-
* - [Arch](https://docs.docker.com/desktop/install/archlinux/#launch-docker-desktop)
|
|
16
|
-
*/
|
|
17
|
-
[OperatingSystem.Linux]: 'systemctl --user start docker-desktop',
|
|
18
|
-
[OperatingSystem.Mac]: 'open -a Docker',
|
|
19
|
-
[OperatingSystem.Windows]: String.raw `/c/Program\ Files/Docker/Docker/Docker\ Desktop.exe`,
|
|
20
|
-
};
|
|
21
|
-
export async function startDocker() {
|
|
22
|
-
const command = startDockerCommands[currentOperatingSystem];
|
|
23
|
-
/* node:coverage disable */
|
|
24
|
-
if (await isDockerRunning()) {
|
|
25
|
-
/** Docker is already running. Nothing to do. */
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
await waitUntil.isTrue(async () => {
|
|
29
|
-
await runShellCommand(command, { rejectOnError: true });
|
|
30
|
-
return isDockerRunning();
|
|
31
|
-
}, {
|
|
32
|
-
interval: {
|
|
33
|
-
seconds: 1,
|
|
34
|
-
},
|
|
35
|
-
timeout: {
|
|
36
|
-
minutes: 1,
|
|
37
|
-
},
|
|
38
|
-
}, 'Failed to start Docker.');
|
|
39
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { isOperatingSystem, OperatingSystem } from '../augments/os/operating-system.js';
|
|
2
|
-
export function dockerTest(callback) {
|
|
3
|
-
if (!isOperatingSystem(OperatingSystem.Linux) && process.env.CI) {
|
|
4
|
-
/**
|
|
5
|
-
* We cannot test Docker on macOS GitHub Actions runners.
|
|
6
|
-
*
|
|
7
|
-
* @see
|
|
8
|
-
* - https://github.com/actions/runner-images/issues/8104
|
|
9
|
-
* - https://github.com/douglascamata/setup-docker-macos-action?tab=readme-ov-file#arm64-processors-m1-m2-m3-series-used-on-macos-14-images-are-unsupported
|
|
10
|
-
* - https://github.com/actions/runner-images/issues/2150
|
|
11
|
-
* - https://github.com/actions/runner/issues/1456
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* We cannot test Docker on Windows GitHub Actions runners because Docker cannot run in
|
|
15
|
-
* Linux container mode on Windows GitHub Actions runners.
|
|
16
|
-
*
|
|
17
|
-
* @see
|
|
18
|
-
* - https://github.com/orgs/community/discussions/25491#discussioncomment-3248089
|
|
19
|
-
*/
|
|
20
|
-
return () => { };
|
|
21
|
-
}
|
|
22
|
-
return callback;
|
|
23
|
-
}
|
package/src/augments/docker.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import {getContainerInfo} from '../docker/containers/container-info.js';
|
|
2
|
-
import {
|
|
3
|
-
getContainerLogs,
|
|
4
|
-
getContainerStatus,
|
|
5
|
-
waitUntilContainerExited,
|
|
6
|
-
waitUntilContainerRemoved,
|
|
7
|
-
waitUntilContainerRunning,
|
|
8
|
-
} from '../docker/containers/container-status.js';
|
|
9
|
-
import {copyToContainer} from '../docker/containers/copy-to-container.js';
|
|
10
|
-
import {
|
|
11
|
-
makeEnvFlags,
|
|
12
|
-
makePortMapFlags,
|
|
13
|
-
makeVolumeFlags,
|
|
14
|
-
} from '../docker/containers/docker-command-inputs.js';
|
|
15
|
-
import {killContainer} from '../docker/containers/kill-container.js';
|
|
16
|
-
import {runContainerCommand} from '../docker/containers/run-command.js';
|
|
17
|
-
import {runContainer} from '../docker/containers/run-container.js';
|
|
18
|
-
import {tryOrKillContainer} from '../docker/containers/try-or-kill-container.js';
|
|
19
|
-
import {
|
|
20
|
-
isImageInLocalRegistry,
|
|
21
|
-
removeImageFromLocalRegistry,
|
|
22
|
-
updateImage,
|
|
23
|
-
} from '../docker/docker-image.js';
|
|
24
|
-
import {isDockerRunning, startDocker} from '../docker/docker-startup.js';
|
|
25
|
-
|
|
26
|
-
export {
|
|
27
|
-
type DockerContainerInfo,
|
|
28
|
-
type DockerContainerInfoState,
|
|
29
|
-
} from '../docker/containers/container-info.js';
|
|
30
|
-
export {
|
|
31
|
-
DockerContainerStatus,
|
|
32
|
-
exitedDockerContainerStatuses,
|
|
33
|
-
} from '../docker/containers/container-status.js';
|
|
34
|
-
export {type CopyToDockerContainerParams} from '../docker/containers/copy-to-container.js';
|
|
35
|
-
export {
|
|
36
|
-
type DockerEnvMap,
|
|
37
|
-
type DockerPortMap,
|
|
38
|
-
type DockerVolumeMap,
|
|
39
|
-
type DockerVolumeMappingType,
|
|
40
|
-
} from '../docker/containers/docker-command-inputs.js';
|
|
41
|
-
export {type RunDockerContainerCommandParams} from '../docker/containers/run-command.js';
|
|
42
|
-
export {type RunDockerContainerParams} from '../docker/containers/run-container.js';
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Centralized Docker API.
|
|
46
|
-
*
|
|
47
|
-
* @deprecated Use the [docker-vir](https://www.npmjs.com/package/docker-vir) package instead.
|
|
48
|
-
* @category Node : Docker
|
|
49
|
-
* @category Package : @augment-vir/node
|
|
50
|
-
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
51
|
-
*/
|
|
52
|
-
export const docker = {
|
|
53
|
-
/** Detects if the Docker service is running. */
|
|
54
|
-
isRunning: isDockerRunning,
|
|
55
|
-
/**
|
|
56
|
-
* Tries to start Docker based ont he current operating system's supported commands. The success
|
|
57
|
-
* of this operation is heavily dependent on how you have Docker setup on your system.
|
|
58
|
-
*/
|
|
59
|
-
start: startDocker,
|
|
60
|
-
image: {
|
|
61
|
-
/** Downloads an image if it is missing from the local registry. */
|
|
62
|
-
update: updateImage,
|
|
63
|
-
/** Removes an image from the local registry. */
|
|
64
|
-
remove: removeImageFromLocalRegistry,
|
|
65
|
-
/** Detects if an image exists in the local registry. */
|
|
66
|
-
exists: isImageInLocalRegistry,
|
|
67
|
-
},
|
|
68
|
-
container: {
|
|
69
|
-
/**
|
|
70
|
-
* Get the current status of a container. If the container does not exist at all, the status
|
|
71
|
-
* will be {@link DockerContainerStatus.Removed}.
|
|
72
|
-
*/
|
|
73
|
-
getStatus: getContainerStatus,
|
|
74
|
-
/** Wait until a container is running and responsive. */
|
|
75
|
-
waitUntilRunning: waitUntilContainerRunning,
|
|
76
|
-
/**
|
|
77
|
-
* Wait until a container has a status that can be classified as "exited".
|
|
78
|
-
*
|
|
79
|
-
* @see {@link exitedDockerContainerStatuses}
|
|
80
|
-
*/
|
|
81
|
-
waitUntilExited: waitUntilContainerExited,
|
|
82
|
-
/** Wait until a container is completely removed. */
|
|
83
|
-
waitUntilRemoved: waitUntilContainerRemoved,
|
|
84
|
-
/**
|
|
85
|
-
* Runs a callback (which presumably will run a command within the given `containerName`)
|
|
86
|
-
* and kills the container if the callback fails.
|
|
87
|
-
*/
|
|
88
|
-
tryOrKill: tryOrKillContainer,
|
|
89
|
-
/** Run a container that isn't already running. */
|
|
90
|
-
run: runContainer,
|
|
91
|
-
/** Kill a container. */
|
|
92
|
-
kill: killContainer,
|
|
93
|
-
/** Copy a file or directory to a container. */
|
|
94
|
-
copyTo: copyToContainer,
|
|
95
|
-
/** Run a command on a container that is already running. */
|
|
96
|
-
runCommand: runContainerCommand,
|
|
97
|
-
/** Run `docker inspect` on a container and return its output. */
|
|
98
|
-
getInfo: getContainerInfo,
|
|
99
|
-
/** Get a container's logs. */
|
|
100
|
-
getLogs: getContainerLogs,
|
|
101
|
-
},
|
|
102
|
-
util: {
|
|
103
|
-
/**
|
|
104
|
-
* Manually create a string of volume mapping flags. This is automatically done already
|
|
105
|
-
* inside the run container methods.
|
|
106
|
-
*/
|
|
107
|
-
makeVolumeFlags,
|
|
108
|
-
/**
|
|
109
|
-
* Manually create a string of port mapping flags. This is automatically done already inside
|
|
110
|
-
* the run container methods.
|
|
111
|
-
*/
|
|
112
|
-
makePortMapFlags,
|
|
113
|
-
/**
|
|
114
|
-
* Manually create a string of env mapping flags. This is automatically done already inside
|
|
115
|
-
* the run container methods.
|
|
116
|
-
*/
|
|
117
|
-
makeEnvFlags,
|
|
118
|
-
},
|
|
119
|
-
};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import {type JsonCompatibleArray, type JsonCompatibleObject} from '@augment-vir/common';
|
|
2
|
-
import {runShellCommand} from '../../augments/terminal/shell.js';
|
|
3
|
-
import {type DockerContainerStatus} from './container-status.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Properties on {@link DockerContainerInfo}.State, retrieved from `docker.container.getInfo()`.
|
|
7
|
-
*
|
|
8
|
-
* @category Node : Docker : Util
|
|
9
|
-
* @category Package : @augment-vir/node
|
|
10
|
-
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
11
|
-
*/
|
|
12
|
-
export type DockerContainerInfoState = {
|
|
13
|
-
Status: DockerContainerStatus;
|
|
14
|
-
Running: boolean;
|
|
15
|
-
Paused: boolean;
|
|
16
|
-
Restarting: boolean;
|
|
17
|
-
OOMKilled: boolean;
|
|
18
|
-
Dead: boolean;
|
|
19
|
-
Pid: number;
|
|
20
|
-
ExitCode: number;
|
|
21
|
-
Error: string;
|
|
22
|
-
StartedAt: string;
|
|
23
|
-
FinishedAt: string;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/** This type signature is incomplete. Add to it as necessary. */
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Properties on the output from `docker.container.getInfo()`. Not all these properties are filled
|
|
30
|
-
* in all the way, particularly most of properties with nested objects.
|
|
31
|
-
*
|
|
32
|
-
* @category Node : Docker : Util
|
|
33
|
-
* @category Package : @augment-vir/node
|
|
34
|
-
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
35
|
-
*/
|
|
36
|
-
export type DockerContainerInfo = Readonly<{
|
|
37
|
-
Id: string;
|
|
38
|
-
Created: string;
|
|
39
|
-
Path: string;
|
|
40
|
-
Args: ReadonlyArray<string>;
|
|
41
|
-
State: DockerContainerInfoState;
|
|
42
|
-
Image: string;
|
|
43
|
-
ResolvConfPath: string;
|
|
44
|
-
HostnamePath: string;
|
|
45
|
-
HostsPath: string;
|
|
46
|
-
LogPath: string;
|
|
47
|
-
Name: string;
|
|
48
|
-
RestartCount: number;
|
|
49
|
-
Driver: string;
|
|
50
|
-
Platform: string;
|
|
51
|
-
MountLabel: string;
|
|
52
|
-
ProcessLabel: string;
|
|
53
|
-
AppArmorProfile: string;
|
|
54
|
-
ExecIDs: unknown;
|
|
55
|
-
HostConfig: JsonCompatibleObject;
|
|
56
|
-
GraphDriver: JsonCompatibleObject;
|
|
57
|
-
Mounts: JsonCompatibleArray;
|
|
58
|
-
Config: JsonCompatibleObject;
|
|
59
|
-
NetworkSettings: JsonCompatibleObject;
|
|
60
|
-
}>;
|
|
61
|
-
|
|
62
|
-
export async function getContainerInfo(
|
|
63
|
-
containerNameOrId: string,
|
|
64
|
-
): Promise<DockerContainerInfo | undefined> {
|
|
65
|
-
const command = `docker inspect '${containerNameOrId}'`;
|
|
66
|
-
const output = await runShellCommand(command);
|
|
67
|
-
|
|
68
|
-
if (output.stderr.includes('Error: No such object')) {
|
|
69
|
-
return undefined;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const parsedOutput = JSON.parse(output.stdout) as ReadonlyArray<DockerContainerInfo>;
|
|
73
|
-
|
|
74
|
-
/** Edge cases that I don't know how to intentionally trigger. */
|
|
75
|
-
/* node:coverage ignore next 5 */
|
|
76
|
-
if (parsedOutput.length === 0) {
|
|
77
|
-
throw new Error(`Got no output from "${command}"`);
|
|
78
|
-
} else if (parsedOutput.length > 1) {
|
|
79
|
-
throw new Error(`Got more than one output from "${command}"`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return parsedOutput[0];
|
|
83
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import {assert, waitUntil} from '@augment-vir/assert';
|
|
2
|
-
import {runShellCommand} from '../../augments/terminal/shell.js';
|
|
3
|
-
|
|
4
|
-
export async function getContainerLogs(
|
|
5
|
-
containerNameOrId: string,
|
|
6
|
-
latestLineCount?: number,
|
|
7
|
-
): Promise<string> {
|
|
8
|
-
const latestLinesArg = latestLineCount == undefined ? '' : `--tail ${latestLineCount}`;
|
|
9
|
-
const logResult = await runShellCommand(
|
|
10
|
-
`docker logs ${latestLinesArg} '${containerNameOrId}'`,
|
|
11
|
-
{rejectOnError: true},
|
|
12
|
-
);
|
|
13
|
-
return logResult.stdout;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* All possible statuses for an existing container.
|
|
18
|
-
*
|
|
19
|
-
* @category Node : Docker : Util
|
|
20
|
-
* @category Package : @augment-vir/node
|
|
21
|
-
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
22
|
-
*/
|
|
23
|
-
export enum DockerContainerStatus {
|
|
24
|
-
Created = 'created',
|
|
25
|
-
Running = 'running',
|
|
26
|
-
Paused = 'paused',
|
|
27
|
-
Restarting = 'restarting',
|
|
28
|
-
Exited = 'exited',
|
|
29
|
-
Removing = 'removing',
|
|
30
|
-
Dead = 'dead',
|
|
31
|
-
|
|
32
|
-
/** This is not a native Docker status but indicates that the container does not exist. */
|
|
33
|
-
Removed = 'removed',
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Statuses from {@link DockerContainerStatus} that indicate that a container has been exited in some
|
|
38
|
-
* way.
|
|
39
|
-
*
|
|
40
|
-
* @category Node : Docker : Util
|
|
41
|
-
* @category Package : @augment-vir/node
|
|
42
|
-
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
43
|
-
*/
|
|
44
|
-
export const exitedDockerContainerStatuses = [
|
|
45
|
-
DockerContainerStatus.Dead,
|
|
46
|
-
DockerContainerStatus.Removed,
|
|
47
|
-
DockerContainerStatus.Exited,
|
|
48
|
-
];
|
|
49
|
-
|
|
50
|
-
export async function getContainerStatus(
|
|
51
|
-
containerNameOrId: string,
|
|
52
|
-
): Promise<DockerContainerStatus> {
|
|
53
|
-
const statusResult = await runShellCommand(
|
|
54
|
-
`docker container inspect -f '{{.State.Status}}' '${containerNameOrId}'`,
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
if (statusResult.exitCode !== 0) {
|
|
58
|
-
return DockerContainerStatus.Removed;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const status = statusResult.stdout.trim();
|
|
62
|
-
assert.isEnumValue(status, DockerContainerStatus, 'Unexpected container status value');
|
|
63
|
-
|
|
64
|
-
return status;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export async function waitUntilContainerRunning(
|
|
68
|
-
containerNameOrId: string,
|
|
69
|
-
failureMessage?: string | undefined,
|
|
70
|
-
): Promise<void> {
|
|
71
|
-
await waitUntil.isTrue(
|
|
72
|
-
async (): Promise<boolean> => {
|
|
73
|
-
/** Check if logs can be accessed yet. */
|
|
74
|
-
await getContainerLogs(containerNameOrId, 1);
|
|
75
|
-
const status = await getContainerStatus(containerNameOrId);
|
|
76
|
-
|
|
77
|
-
return status === DockerContainerStatus.Running;
|
|
78
|
-
},
|
|
79
|
-
{},
|
|
80
|
-
failureMessage,
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export async function waitUntilContainerRemoved(
|
|
85
|
-
containerNameOrId: string,
|
|
86
|
-
failureMessage?: string | undefined,
|
|
87
|
-
): Promise<void> {
|
|
88
|
-
await waitUntil.isTrue(
|
|
89
|
-
async (): Promise<boolean> => {
|
|
90
|
-
const status = await getContainerStatus(containerNameOrId);
|
|
91
|
-
return status === DockerContainerStatus.Removed;
|
|
92
|
-
},
|
|
93
|
-
{},
|
|
94
|
-
failureMessage,
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export async function waitUntilContainerExited(
|
|
99
|
-
containerNameOrId: string,
|
|
100
|
-
failureMessage?: string | undefined,
|
|
101
|
-
): Promise<void> {
|
|
102
|
-
await waitUntil.isTrue(
|
|
103
|
-
async (): Promise<boolean> => {
|
|
104
|
-
const status = await getContainerStatus(containerNameOrId);
|
|
105
|
-
return exitedDockerContainerStatuses.includes(status);
|
|
106
|
-
},
|
|
107
|
-
{},
|
|
108
|
-
failureMessage,
|
|
109
|
-
);
|
|
110
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import {addSuffix} from '@augment-vir/common';
|
|
2
|
-
import {stat} from 'node:fs/promises';
|
|
3
|
-
import {runShellCommand} from '../../augments/terminal/shell.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Parameters for `docker.container.copyTo`.
|
|
7
|
-
*
|
|
8
|
-
* @category Node : Docker : Util
|
|
9
|
-
* @category Package : @augment-vir/node
|
|
10
|
-
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
11
|
-
*/
|
|
12
|
-
export type CopyToDockerContainerParams = {
|
|
13
|
-
hostPath: string;
|
|
14
|
-
containerAbsolutePath: string;
|
|
15
|
-
containerNameOrId: string;
|
|
16
|
-
dockerFlags?: ReadonlyArray<string>;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export async function copyToContainer({
|
|
20
|
-
containerAbsolutePath,
|
|
21
|
-
hostPath,
|
|
22
|
-
containerNameOrId,
|
|
23
|
-
dockerFlags = [],
|
|
24
|
-
}: CopyToDockerContainerParams): Promise<void> {
|
|
25
|
-
const isDir = (await stat(hostPath)).isDirectory();
|
|
26
|
-
const suffix = isDir ? '/.' : '';
|
|
27
|
-
const fullHostPath = addSuffix({value: hostPath, suffix});
|
|
28
|
-
const extraInputs: string = dockerFlags.join(' ');
|
|
29
|
-
|
|
30
|
-
await runShellCommand(
|
|
31
|
-
`docker cp ${extraInputs} '${fullHostPath}' '${containerNameOrId}:${containerAbsolutePath}'`,
|
|
32
|
-
{rejectOnError: true},
|
|
33
|
-
);
|
|
34
|
-
}
|