From 5f3653ede11af7841c47a967544918dc2d799ba7 Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:13:37 +0100 Subject: [PATCH] tcp-port opt to expose Docker API to a local TCP address --- .github/workflows/ci.yml | 28 ++++++++++++++++++++++++++++ README.md | 8 +++++--- __tests__/context.test.ts | 30 ++++++++++++++++++++++++++++++ action.yml | 6 ++++++ src/context.ts | 2 ++ src/main.ts | 14 +++++++++++++- 6 files changed, 84 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b8b276d..afc3023 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -271,3 +271,31 @@ jobs: name: List contexts run: | docker context ls + + tcp: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + #- macos-14 # no virt: https://github.com/docker/actions-toolkit/issues/317 + - macos-13 + - windows-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Set up Docker + id: setup_docker + uses: ./ + with: + version: ${{ env.DOCKER_VERSION }} + tcp-port: 2378 + - + name: Check docker info through TCP + run: | + docker info + env: + DOCKER_HOST: ${{ steps.setup_docker.outputs.tcp }} diff --git a/README.md b/README.md index 5588c83..b1a088e 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ The following inputs can be used as `step.with` keys | `version` | String | `latest` | Docker CE version (e.g., `v24.0.6`). | | `channel` | String | `stable` | Docker CE [channel](https://download.docker.com/linux/static/) (e.g, `stable`, `edge` or `test`). | | `daemon-config` | String | | [Docker daemon JSON configuration](https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file) | +| `tcp-port` | Number | | TCP port to expose the Docker API locally | | `context` | String | `setup-docker-action` | Docker context name. | | `set-host` | Bool | `false` | Set `DOCKER_HOST` environment variable to docker socket path. | | `rootless` | Bool | `false` | Start daemon in rootless mode | @@ -125,9 +126,10 @@ The following inputs can be used as `step.with` keys The following outputs are available -| Name | Type | Description | -|--------|--------|--------------------| -| `sock` | String | Docker socket path | +| Name | Type | Description | +|--------|--------|---------------------------------------| +| `sock` | String | Docker socket path | +| `tcp` | String | Docker TCP address if tcp-port is set | ## Contributing diff --git a/__tests__/context.test.ts b/__tests__/context.test.ts index 585f28e..c271c76 100644 --- a/__tests__/context.test.ts +++ b/__tests__/context.test.ts @@ -29,6 +29,7 @@ describe('getInputs', () => { }, context: '', daemonConfig: '', + tcpPort: 0, rootless: false, setHost: false } as context.Inputs @@ -51,6 +52,7 @@ describe('getInputs', () => { }, context: 'foo', daemonConfig: `{"debug":true,"features":{"containerd-snapshotter":true}}`, + tcpPort: 0, rootless: false, setHost: false } as context.Inputs @@ -69,6 +71,7 @@ describe('getInputs', () => { }, context: '', daemonConfig: '', + tcpPort: 0, rootless: false, setHost: true } as context.Inputs @@ -89,6 +92,7 @@ describe('getInputs', () => { }, context: 'foo', daemonConfig: `{"debug":true,"features":{"containerd-snapshotter":true}}`, + tcpPort: 0, rootless: false, setHost: false } as context.Inputs @@ -107,6 +111,7 @@ describe('getInputs', () => { }, context: '', daemonConfig: '', + tcpPort: 0, rootless: false, setHost: false } as context.Inputs @@ -127,6 +132,7 @@ describe('getInputs', () => { setHost: false, context: '', daemonConfig: '', + tcpPort: 0, rootless: false, } as context.Inputs ], @@ -146,6 +152,7 @@ describe('getInputs', () => { setHost: false, context: '', daemonConfig: '', + tcpPort: 0, rootless: false, } as context.Inputs ], @@ -164,6 +171,7 @@ describe('getInputs', () => { setHost: false, context: '', daemonConfig: '', + tcpPort: 0, rootless: false, } as context.Inputs ], @@ -182,9 +190,31 @@ describe('getInputs', () => { setHost: false, context: '', daemonConfig: '', + tcpPort: 0, rootless: true, } as context.Inputs ], + [ + 9, + new Map([ + ['version', 'v24.0.8'], + ['tcp-port', '2378'], + ['set-host', 'false'], + ['rootless', 'false'], + ]), + { + source: { + type: 'archive', + version: 'v24.0.8', + channel: 'stable' + }, + context: '', + daemonConfig: '', + tcpPort: 2378, + rootless: false, + setHost: false + } as context.Inputs + ], ])( '[%d] given %p as inputs, returns %p', async (num: number, inputs: Map, expected: context.Inputs) => { diff --git a/action.yml b/action.yml index 5c3cc63..0cdc532 100644 --- a/action.yml +++ b/action.yml @@ -17,6 +17,10 @@ inputs: daemon-config: description: 'Docker daemon JSON configuration' required: false + tcp-port: + description: 'TCP port to expose the Docker API locally' + default: 'false' + required: false context: description: 'Docker context name. (default setup-docker-action)' required: false @@ -32,6 +36,8 @@ inputs: outputs: sock: description: "Docker socket path" + tcp: + description: "Docker TCP address if tcp-port is set" runs: using: 'node20' diff --git a/src/context.ts b/src/context.ts index 70fb2cb..b0f2bbf 100644 --- a/src/context.ts +++ b/src/context.ts @@ -5,6 +5,7 @@ import {parse} from 'csv-parse/sync'; export interface Inputs { source: InstallSource; daemonConfig?: string; + tcpPort?: number; context: string; setHost: boolean; rootless: boolean; @@ -21,6 +22,7 @@ export function getInputs(): Inputs { return { source: source, daemonConfig: core.getInput('daemon-config'), + tcpPort: parseInt(core.getInput('tcp-port') || '0'), context: core.getInput('context'), setHost: core.getBooleanInput('set-host'), rootless: core.getBooleanInput('rootless') diff --git a/src/main.ts b/src/main.ts index 2ac2361..421a1fd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -19,12 +19,20 @@ actionsToolkit.run( throw new Error(`'default' context cannot be used.`); } + let tcpPort: number | undefined; + let tcpAddress: string | undefined; + if (input.tcpPort > 0) { + tcpPort = input.tcpPort; + tcpAddress = `tcp://127.0.0.1:${tcpPort}`; + } + const install = new Install({ runDir: runDir, source: input.source, rootless: input.rootless, contextName: input.context || 'setup-docker-action', - daemonConfig: input.daemonConfig + daemonConfig: input.daemonConfig, + localTCPPort: tcpPort }); let toolDir; if (!(await Docker.isAvailable()) || input.source) { @@ -38,6 +46,10 @@ actionsToolkit.run( await core.group(`Setting outputs`, async () => { core.info(`sock=${sockPath}`); core.setOutput('sock', sockPath); + if (tcpAddress) { + core.info(`tcp=${tcpAddress}`); + core.setOutput('tcp', tcpAddress); + } }); if (input.setHost) {