n8n-nodes-docker-api 0.1.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/LICENSE +7 -0
- package/README.md +278 -0
- package/dist/credentials/DockerApi.credentials.d.ts +7 -0
- package/dist/credentials/DockerApi.credentials.js +125 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/nodes/Docker/Docker/docker.svg +25 -0
- package/dist/nodes/Docker/Docker.node.d.ts +5 -0
- package/dist/nodes/Docker/Docker.node.js +73 -0
- package/dist/nodes/Docker/actions/container/getLogs.operation.d.ts +3 -0
- package/dist/nodes/Docker/actions/container/getLogs.operation.js +82 -0
- package/dist/nodes/Docker/actions/container/list.operation.d.ts +3 -0
- package/dist/nodes/Docker/actions/container/list.operation.js +40 -0
- package/dist/nodes/Docker/actions/container/start.operation.d.ts +3 -0
- package/dist/nodes/Docker/actions/container/start.operation.js +21 -0
- package/dist/nodes/Docker/actions/container/stop.operation.d.ts +3 -0
- package/dist/nodes/Docker/actions/container/stop.operation.js +38 -0
- package/dist/nodes/Docker/actions/index.d.ts +3 -0
- package/dist/nodes/Docker/actions/index.js +25 -0
- package/dist/nodes/Docker/descriptions/container/getLogs.description.d.ts +2 -0
- package/dist/nodes/Docker/descriptions/container/getLogs.description.js +64 -0
- package/dist/nodes/Docker/descriptions/container/list.description.d.ts +2 -0
- package/dist/nodes/Docker/descriptions/container/list.description.js +66 -0
- package/dist/nodes/Docker/descriptions/container/start.description.d.ts +2 -0
- package/dist/nodes/Docker/descriptions/container/start.description.js +20 -0
- package/dist/nodes/Docker/descriptions/container/stop.description.d.ts +2 -0
- package/dist/nodes/Docker/descriptions/container/stop.description.js +46 -0
- package/dist/nodes/Docker/descriptions/index.d.ts +3 -0
- package/dist/nodes/Docker/descriptions/index.js +53 -0
- package/dist/nodes/Docker/helpers/accessGuard.d.ts +2 -0
- package/dist/nodes/Docker/helpers/accessGuard.js +13 -0
- package/dist/nodes/Docker/helpers/errorHandler.d.ts +1 -0
- package/dist/nodes/Docker/helpers/errorHandler.js +36 -0
- package/dist/nodes/Docker/helpers/normalizeContainer.d.ts +16 -0
- package/dist/nodes/Docker/helpers/normalizeContainer.js +71 -0
- package/dist/nodes/Docker/helpers/resolveContainer.d.ts +11 -0
- package/dist/nodes/Docker/helpers/resolveContainer.js +32 -0
- package/dist/utils/dockerClient.d.ts +3 -0
- package/dist/utils/dockerClient.js +31 -0
- package/package.json +69 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startContainer = startContainer;
|
|
4
|
+
const errorHandler_1 = require("../../helpers/errorHandler");
|
|
5
|
+
const normalizeContainer_1 = require("../../helpers/normalizeContainer");
|
|
6
|
+
const resolveContainer_1 = require("../../helpers/resolveContainer");
|
|
7
|
+
async function startContainer(docker, itemIndex) {
|
|
8
|
+
try {
|
|
9
|
+
const containerId = this.getNodeParameter('containerId', itemIndex);
|
|
10
|
+
// Resolve name to ID first
|
|
11
|
+
const resolved = await (0, resolveContainer_1.resolveContainer)(docker, containerId);
|
|
12
|
+
const container = docker.getContainer(resolved.id);
|
|
13
|
+
await container.start();
|
|
14
|
+
// Get updated info using the same container instance
|
|
15
|
+
const containerInfo = await container.inspect();
|
|
16
|
+
return (0, normalizeContainer_1.normalizeContainerInfo)(containerInfo);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
throw new Error((0, errorHandler_1.translateDockerError)(error));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stopContainer = stopContainer;
|
|
4
|
+
const errorHandler_1 = require("../../helpers/errorHandler");
|
|
5
|
+
const normalizeContainer_1 = require("../../helpers/normalizeContainer");
|
|
6
|
+
const resolveContainer_1 = require("../../helpers/resolveContainer");
|
|
7
|
+
async function stopContainer(docker, itemIndex) {
|
|
8
|
+
try {
|
|
9
|
+
const containerId = this.getNodeParameter('containerId', itemIndex);
|
|
10
|
+
const timeout = this.getNodeParameter('timeout', itemIndex, 10);
|
|
11
|
+
const dryRun = this.getNodeParameter('dryRun', itemIndex, false);
|
|
12
|
+
// Resolve name to ID first
|
|
13
|
+
const resolved = await (0, resolveContainer_1.resolveContainer)(docker, containerId);
|
|
14
|
+
const container = docker.getContainer(resolved.id);
|
|
15
|
+
// Handle dry run
|
|
16
|
+
if (dryRun) {
|
|
17
|
+
return {
|
|
18
|
+
dryRun: true,
|
|
19
|
+
action: 'stop',
|
|
20
|
+
target: {
|
|
21
|
+
id: resolved.id,
|
|
22
|
+
shortId: resolved.id.substring(0, 12),
|
|
23
|
+
name: resolved.name,
|
|
24
|
+
},
|
|
25
|
+
executed: false,
|
|
26
|
+
message: `Dry run: container '${resolved.name}' (${resolved.id.substring(0, 12)}) would have been stopped.`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// Actually stop the container
|
|
30
|
+
await container.stop({ t: timeout });
|
|
31
|
+
// Get updated info using the same container instance
|
|
32
|
+
const containerInfo = await container.inspect();
|
|
33
|
+
return (0, normalizeContainer_1.normalizeContainerInfo)(containerInfo);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw new Error((0, errorHandler_1.translateDockerError)(error));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeContainerOperation = executeContainerOperation;
|
|
4
|
+
const list_operation_1 = require("./container/list.operation");
|
|
5
|
+
const getLogs_operation_1 = require("./container/getLogs.operation");
|
|
6
|
+
const start_operation_1 = require("./container/start.operation");
|
|
7
|
+
const stop_operation_1 = require("./container/stop.operation");
|
|
8
|
+
async function executeContainerOperation(docker, operation, itemIndex) {
|
|
9
|
+
switch (operation) {
|
|
10
|
+
case 'list':
|
|
11
|
+
const listResult = await list_operation_1.listContainers.call(this, docker, itemIndex);
|
|
12
|
+
return listResult.map((item) => ({ json: item }));
|
|
13
|
+
case 'getLogs':
|
|
14
|
+
const logsResult = await getLogs_operation_1.getContainerLogs.call(this, docker, itemIndex);
|
|
15
|
+
return [{ json: logsResult }];
|
|
16
|
+
case 'start':
|
|
17
|
+
const startResult = await start_operation_1.startContainer.call(this, docker, itemIndex);
|
|
18
|
+
return [{ json: startResult }];
|
|
19
|
+
case 'stop':
|
|
20
|
+
const stopResult = await stop_operation_1.stopContainer.call(this, docker, itemIndex);
|
|
21
|
+
return [{ json: stopResult }];
|
|
22
|
+
default:
|
|
23
|
+
throw new Error(`Unknown operation: ${operation}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLogsContainerFields = void 0;
|
|
4
|
+
exports.getLogsContainerFields = [
|
|
5
|
+
{
|
|
6
|
+
displayName: 'Container ID or Name',
|
|
7
|
+
name: 'containerId',
|
|
8
|
+
type: 'string',
|
|
9
|
+
required: true,
|
|
10
|
+
displayOptions: {
|
|
11
|
+
show: {
|
|
12
|
+
resource: ['container'],
|
|
13
|
+
operation: ['getLogs'],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
default: '',
|
|
17
|
+
description: 'The ID or name of the container to retrieve logs from',
|
|
18
|
+
placeholder: 'my-container or abc123def456',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
displayName: 'Tail (Lines)',
|
|
22
|
+
name: 'tail',
|
|
23
|
+
type: 'number',
|
|
24
|
+
displayOptions: {
|
|
25
|
+
show: {
|
|
26
|
+
resource: ['container'],
|
|
27
|
+
operation: ['getLogs'],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
default: 100,
|
|
31
|
+
description: 'Number of lines from the end of the log to return. Use 0 for all lines.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Include Timestamps',
|
|
35
|
+
name: 'timestamps',
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
displayOptions: {
|
|
38
|
+
show: {
|
|
39
|
+
resource: ['container'],
|
|
40
|
+
operation: ['getLogs'],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
default: false,
|
|
44
|
+
description: 'Whether to prepend timestamps to each log line',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
displayName: 'Stream',
|
|
48
|
+
name: 'stream',
|
|
49
|
+
type: 'options',
|
|
50
|
+
displayOptions: {
|
|
51
|
+
show: {
|
|
52
|
+
resource: ['container'],
|
|
53
|
+
operation: ['getLogs'],
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
options: [
|
|
57
|
+
{ name: 'Both (stdout + stderr)', value: 'both' },
|
|
58
|
+
{ name: 'stdout Only', value: 'stdout' },
|
|
59
|
+
{ name: 'stderr Only', value: 'stderr' },
|
|
60
|
+
],
|
|
61
|
+
default: 'both',
|
|
62
|
+
description: 'Which output stream(s) to include in the logs',
|
|
63
|
+
},
|
|
64
|
+
];
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listContainerFields = void 0;
|
|
4
|
+
exports.listContainerFields = [
|
|
5
|
+
{
|
|
6
|
+
displayName: 'Show All Containers',
|
|
7
|
+
name: 'showAll',
|
|
8
|
+
type: 'boolean',
|
|
9
|
+
displayOptions: {
|
|
10
|
+
show: {
|
|
11
|
+
resource: ['container'],
|
|
12
|
+
operation: ['list'],
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
default: false,
|
|
16
|
+
description: 'Whether to show stopped and exited containers in addition to running ones',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
displayName: 'Filters',
|
|
20
|
+
name: 'filters',
|
|
21
|
+
type: 'collection',
|
|
22
|
+
placeholder: 'Add Filter',
|
|
23
|
+
default: {},
|
|
24
|
+
displayOptions: {
|
|
25
|
+
show: {
|
|
26
|
+
resource: ['container'],
|
|
27
|
+
operation: ['list'],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
options: [
|
|
31
|
+
{
|
|
32
|
+
displayName: 'Name',
|
|
33
|
+
name: 'name',
|
|
34
|
+
type: 'string',
|
|
35
|
+
default: '',
|
|
36
|
+
description: 'Filter containers by name (partial match supported)',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
displayName: 'Status',
|
|
40
|
+
name: 'status',
|
|
41
|
+
type: 'options',
|
|
42
|
+
options: [
|
|
43
|
+
{ name: 'All', value: '' },
|
|
44
|
+
{ name: 'Running', value: 'running' },
|
|
45
|
+
{ name: 'Exited', value: 'exited' },
|
|
46
|
+
{ name: 'Paused', value: 'paused' },
|
|
47
|
+
],
|
|
48
|
+
default: '',
|
|
49
|
+
description: 'Filter containers by status',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
displayName: 'Include Labels',
|
|
55
|
+
name: 'includeLabels',
|
|
56
|
+
type: 'boolean',
|
|
57
|
+
displayOptions: {
|
|
58
|
+
show: {
|
|
59
|
+
resource: ['container'],
|
|
60
|
+
operation: ['list'],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
default: true,
|
|
64
|
+
description: 'Whether to include container labels in the output (can be verbose)',
|
|
65
|
+
},
|
|
66
|
+
];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startContainerFields = void 0;
|
|
4
|
+
exports.startContainerFields = [
|
|
5
|
+
{
|
|
6
|
+
displayName: 'Container ID or Name',
|
|
7
|
+
name: 'containerId',
|
|
8
|
+
type: 'string',
|
|
9
|
+
required: true,
|
|
10
|
+
displayOptions: {
|
|
11
|
+
show: {
|
|
12
|
+
resource: ['container'],
|
|
13
|
+
operation: ['start'],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
default: '',
|
|
17
|
+
description: 'The ID or name of the container to start',
|
|
18
|
+
placeholder: 'my-container or abc123def456',
|
|
19
|
+
},
|
|
20
|
+
];
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stopContainerFields = void 0;
|
|
4
|
+
exports.stopContainerFields = [
|
|
5
|
+
{
|
|
6
|
+
displayName: 'Container ID or Name',
|
|
7
|
+
name: 'containerId',
|
|
8
|
+
type: 'string',
|
|
9
|
+
required: true,
|
|
10
|
+
displayOptions: {
|
|
11
|
+
show: {
|
|
12
|
+
resource: ['container'],
|
|
13
|
+
operation: ['stop'],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
default: '',
|
|
17
|
+
description: 'The ID or name of the container to stop',
|
|
18
|
+
placeholder: 'my-container or abc123def456',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
displayName: 'Timeout (Seconds)',
|
|
22
|
+
name: 'timeout',
|
|
23
|
+
type: 'number',
|
|
24
|
+
displayOptions: {
|
|
25
|
+
show: {
|
|
26
|
+
resource: ['container'],
|
|
27
|
+
operation: ['stop'],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
default: 10,
|
|
31
|
+
description: 'Seconds to wait before force-killing the container. Default is 10.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Dry Run',
|
|
35
|
+
name: 'dryRun',
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
displayOptions: {
|
|
38
|
+
show: {
|
|
39
|
+
resource: ['container'],
|
|
40
|
+
operation: ['stop'],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
default: false,
|
|
44
|
+
description: 'Whether to preview the action without executing it. No changes will be made.',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.containerFields = exports.containerOperations = void 0;
|
|
4
|
+
const list_description_1 = require("./container/list.description");
|
|
5
|
+
const getLogs_description_1 = require("./container/getLogs.description");
|
|
6
|
+
const start_description_1 = require("./container/start.description");
|
|
7
|
+
const stop_description_1 = require("./container/stop.description");
|
|
8
|
+
exports.containerOperations = [
|
|
9
|
+
{
|
|
10
|
+
displayName: 'Operation',
|
|
11
|
+
name: 'operation',
|
|
12
|
+
type: 'options',
|
|
13
|
+
noDataExpression: true,
|
|
14
|
+
displayOptions: {
|
|
15
|
+
show: {
|
|
16
|
+
resource: ['container'],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
options: [
|
|
20
|
+
{
|
|
21
|
+
name: 'List Containers',
|
|
22
|
+
value: 'list',
|
|
23
|
+
description: 'List all containers',
|
|
24
|
+
action: 'List containers',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'Get Container Logs',
|
|
28
|
+
value: 'getLogs',
|
|
29
|
+
description: 'Retrieve logs from a container',
|
|
30
|
+
action: 'Get container logs',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'Start Container',
|
|
34
|
+
value: 'start',
|
|
35
|
+
description: 'Start a container',
|
|
36
|
+
action: 'Start container',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'Stop Container',
|
|
40
|
+
value: 'stop',
|
|
41
|
+
description: 'Stop a container',
|
|
42
|
+
action: 'Stop container',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
default: 'list',
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
exports.containerFields = [
|
|
49
|
+
...list_description_1.listContainerFields,
|
|
50
|
+
...getLogs_description_1.getLogsContainerFields,
|
|
51
|
+
...start_description_1.startContainerFields,
|
|
52
|
+
...stop_description_1.stopContainerFields,
|
|
53
|
+
];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.enforceAccessMode = enforceAccessMode;
|
|
4
|
+
// Operations that require full-control access
|
|
5
|
+
const WRITE_OPERATIONS = ['start', 'stop', 'remove', 'restart', 'run', 'pull', 'build', 'prune'];
|
|
6
|
+
function enforceAccessMode(credentials, operation) {
|
|
7
|
+
const accessMode = credentials.accessMode;
|
|
8
|
+
if (accessMode === 'readonly' && WRITE_OPERATIONS.includes(operation)) {
|
|
9
|
+
throw new Error(`Operation "${operation}" requires Full Control access. ` +
|
|
10
|
+
`This credential is configured as Read Only. ` +
|
|
11
|
+
`Update your Docker API credential to enable write operations.`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function translateDockerError(error: unknown): string;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.translateDockerError = translateDockerError;
|
|
4
|
+
function translateDockerError(error) {
|
|
5
|
+
var _a;
|
|
6
|
+
const msg = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : String(error);
|
|
7
|
+
if (msg.includes('ECONNREFUSED')) {
|
|
8
|
+
return 'Cannot connect to Docker daemon. Is Docker running? Check your connection settings.';
|
|
9
|
+
}
|
|
10
|
+
if (msg.includes('ENOENT') && msg.includes('docker.sock')) {
|
|
11
|
+
return 'Docker socket not found at the specified path. Verify the socket path in your credential.';
|
|
12
|
+
}
|
|
13
|
+
if (msg.toLowerCase().includes('permission denied')) {
|
|
14
|
+
return 'Permission denied accessing Docker socket. Ensure the n8n process has permission to access the socket.';
|
|
15
|
+
}
|
|
16
|
+
if (msg.includes('No such container') || msg.includes('not found')) {
|
|
17
|
+
return 'Container not found. Verify the container ID or name is correct and the container exists.';
|
|
18
|
+
}
|
|
19
|
+
if (msg.includes('is not running')) {
|
|
20
|
+
return 'Container is not running. Start the container before performing this operation.';
|
|
21
|
+
}
|
|
22
|
+
if (msg.includes('already started') || msg.includes('already running')) {
|
|
23
|
+
return 'Container is already running.';
|
|
24
|
+
}
|
|
25
|
+
if (msg.includes('404')) {
|
|
26
|
+
return 'Resource not found. The container or image may have been removed.';
|
|
27
|
+
}
|
|
28
|
+
if (msg.includes('409')) {
|
|
29
|
+
return 'Conflict: The container may already be in the requested state.';
|
|
30
|
+
}
|
|
31
|
+
if (msg.includes('timeout') || msg.includes('ETIMEDOUT')) {
|
|
32
|
+
return 'Connection timed out. Check network connectivity to the Docker host.';
|
|
33
|
+
}
|
|
34
|
+
// Fallback: return original message without prefix for cleaner output
|
|
35
|
+
return msg;
|
|
36
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ContainerInfo, ContainerInspectInfo } from 'dockerode';
|
|
2
|
+
export interface NormalizedContainer {
|
|
3
|
+
id: string;
|
|
4
|
+
shortId: string;
|
|
5
|
+
name: string;
|
|
6
|
+
image: string;
|
|
7
|
+
status: 'running' | 'stopped' | 'exited' | 'paused' | 'restarting' | 'dead' | 'created' | 'unknown';
|
|
8
|
+
createdAt: string;
|
|
9
|
+
ports: Array<{
|
|
10
|
+
containerPort: number;
|
|
11
|
+
hostPort?: number;
|
|
12
|
+
protocol: string;
|
|
13
|
+
}>;
|
|
14
|
+
labels?: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
export declare function normalizeContainerInfo(raw: ContainerInfo | ContainerInspectInfo, includeLabels?: boolean): NormalizedContainer;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeContainerInfo = normalizeContainerInfo;
|
|
4
|
+
function normalizeContainerInfo(raw, includeLabels = true) {
|
|
5
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
6
|
+
// Handle both ContainerInfo (from listContainers) and ContainerInspectInfo (from inspect)
|
|
7
|
+
const isInspectInfo = 'Name' in raw;
|
|
8
|
+
const name = isInspectInfo
|
|
9
|
+
? raw.Name.replace(/^\//, '')
|
|
10
|
+
: (_c = (_b = (_a = raw.Names) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.replace(/^\//, '')) !== null && _c !== void 0 ? _c : 'unknown';
|
|
11
|
+
const dockerState = isInspectInfo
|
|
12
|
+
? (_e = (_d = raw.State) === null || _d === void 0 ? void 0 : _d.Status) !== null && _e !== void 0 ? _e : 'unknown'
|
|
13
|
+
: (_f = raw.State) !== null && _f !== void 0 ? _f : 'unknown';
|
|
14
|
+
const status = mapStatus(dockerState);
|
|
15
|
+
// Handle ports - only available in ContainerInfo
|
|
16
|
+
const portsInfo = raw.Ports;
|
|
17
|
+
const seenPorts = new Set();
|
|
18
|
+
const uniquePorts = [];
|
|
19
|
+
if (portsInfo) {
|
|
20
|
+
for (const port of portsInfo) {
|
|
21
|
+
const key = `${port.PrivatePort}-${(_g = port.PublicPort) !== null && _g !== void 0 ? _g : 'none'}-${port.Type}`;
|
|
22
|
+
if (!seenPorts.has(key)) {
|
|
23
|
+
seenPorts.add(key);
|
|
24
|
+
uniquePorts.push({
|
|
25
|
+
containerPort: port.PrivatePort,
|
|
26
|
+
hostPort: port.PublicPort,
|
|
27
|
+
protocol: port.Type,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Handle image
|
|
33
|
+
const image = isInspectInfo
|
|
34
|
+
? (_j = (_h = raw.Config) === null || _h === void 0 ? void 0 : _h.Image) !== null && _j !== void 0 ? _j : 'unknown'
|
|
35
|
+
: (_k = raw.Image) !== null && _k !== void 0 ? _k : 'unknown';
|
|
36
|
+
// Handle created timestamp
|
|
37
|
+
const created = isInspectInfo
|
|
38
|
+
? (_l = raw.Created) !== null && _l !== void 0 ? _l : new Date().toISOString()
|
|
39
|
+
: new Date(((_m = raw.Created) !== null && _m !== void 0 ? _m : 0) * 1000).toISOString();
|
|
40
|
+
// Handle labels - only include if requested
|
|
41
|
+
const labelsData = isInspectInfo
|
|
42
|
+
? (_p = (_o = raw.Config) === null || _o === void 0 ? void 0 : _o.Labels) !== null && _p !== void 0 ? _p : {}
|
|
43
|
+
: (_q = raw.Labels) !== null && _q !== void 0 ? _q : {};
|
|
44
|
+
const result = {
|
|
45
|
+
id: raw.Id,
|
|
46
|
+
shortId: raw.Id.substring(0, 12),
|
|
47
|
+
name,
|
|
48
|
+
image,
|
|
49
|
+
status,
|
|
50
|
+
createdAt: created,
|
|
51
|
+
ports: uniquePorts,
|
|
52
|
+
};
|
|
53
|
+
// Only add labels field if includeLabels is true
|
|
54
|
+
if (includeLabels) {
|
|
55
|
+
result.labels = labelsData;
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
function mapStatus(dockerState) {
|
|
60
|
+
var _a;
|
|
61
|
+
const map = {
|
|
62
|
+
running: 'running',
|
|
63
|
+
exited: 'exited',
|
|
64
|
+
stopped: 'stopped',
|
|
65
|
+
paused: 'paused',
|
|
66
|
+
restarting: 'restarting',
|
|
67
|
+
dead: 'dead',
|
|
68
|
+
created: 'created',
|
|
69
|
+
};
|
|
70
|
+
return (_a = map[dockerState === null || dockerState === void 0 ? void 0 : dockerState.toLowerCase()]) !== null && _a !== void 0 ? _a : 'unknown';
|
|
71
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Docker from 'dockerode';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a container ID or name to a full container info object.
|
|
4
|
+
* Docker API requires exact ID or name (with leading /).
|
|
5
|
+
* This function handles user-friendly names by finding the matching container.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveContainer(docker: Docker, containerIdOrName: string): Promise<{
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
info: Docker.ContainerInfo;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveContainer = resolveContainer;
|
|
4
|
+
/**
|
|
5
|
+
* Resolves a container ID or name to a full container info object.
|
|
6
|
+
* Docker API requires exact ID or name (with leading /).
|
|
7
|
+
* This function handles user-friendly names by finding the matching container.
|
|
8
|
+
*/
|
|
9
|
+
async function resolveContainer(docker, containerIdOrName) {
|
|
10
|
+
var _a, _b, _c;
|
|
11
|
+
const allContainers = await docker.listContainers({ all: true });
|
|
12
|
+
// Try exact match first (ID or name with /)
|
|
13
|
+
let containerInfo = allContainers.find((c) => {
|
|
14
|
+
var _a;
|
|
15
|
+
return c.Id === containerIdOrName ||
|
|
16
|
+
c.Id.startsWith(containerIdOrName) ||
|
|
17
|
+
((_a = c.Names) === null || _a === void 0 ? void 0 : _a.some((n) => n === containerIdOrName || n === `/${containerIdOrName}`));
|
|
18
|
+
});
|
|
19
|
+
// If not found, try name without leading /
|
|
20
|
+
if (!containerInfo) {
|
|
21
|
+
containerInfo = allContainers.find((c) => { var _a; return (_a = c.Names) === null || _a === void 0 ? void 0 : _a.some((n) => n.replace(/^\//, '') === containerIdOrName); });
|
|
22
|
+
}
|
|
23
|
+
if (!containerInfo) {
|
|
24
|
+
throw new Error(`Container '${containerIdOrName}' not found. Verify the container ID or name is correct and the container exists.`);
|
|
25
|
+
}
|
|
26
|
+
const name = (_c = (_b = (_a = containerInfo.Names) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.replace(/^\//, '')) !== null && _c !== void 0 ? _c : 'unknown';
|
|
27
|
+
return {
|
|
28
|
+
id: containerInfo.Id,
|
|
29
|
+
name,
|
|
30
|
+
info: containerInfo,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createDockerClient = createDockerClient;
|
|
7
|
+
const dockerode_1 = __importDefault(require("dockerode"));
|
|
8
|
+
function createDockerClient(credentials) {
|
|
9
|
+
const { authMode, socketPath, host, port, tlsPort, ca, cert, clientKey } = credentials;
|
|
10
|
+
if (authMode === 'socket') {
|
|
11
|
+
return new dockerode_1.default({ socketPath: socketPath });
|
|
12
|
+
}
|
|
13
|
+
if (authMode === 'tcp') {
|
|
14
|
+
return new dockerode_1.default({
|
|
15
|
+
host: host,
|
|
16
|
+
port: port,
|
|
17
|
+
protocol: 'http',
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (authMode === 'tls') {
|
|
21
|
+
return new dockerode_1.default({
|
|
22
|
+
host: host,
|
|
23
|
+
port: tlsPort,
|
|
24
|
+
ca: ca,
|
|
25
|
+
cert: cert,
|
|
26
|
+
key: clientKey,
|
|
27
|
+
protocol: 'https',
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
throw new Error(`Unknown authMode: ${authMode}`);
|
|
31
|
+
}
|