From aa0df6f73ac9cc53264c5db8aec39e3ffd372b7b Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sun, 18 Sep 2022 02:24:38 +0200 Subject: [PATCH] nodes metadata JSON ouput Signed-off-by: CrazyMax --- .github/workflows/ci.yml | 7 +++++ README.md | 44 +++++++++++++++++++++----- __tests__/buildx.test.ts | 2 +- action.yml | 16 +++++----- src/buildx.ts | 67 ++++++++++++++++++++++++++++------------ src/main.ts | 21 ++++++++----- 6 files changed, 113 insertions(+), 44 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99aa63b..505418a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,9 +30,16 @@ jobs: uses: actions/checkout@v3 - name: Set up Docker Buildx + id: buildx uses: ./ with: version: ${{ matrix.buildx-version }} + - + name: Nodes output + run: | + cat << EOF + ${{ steps.buildx.outputs.nodes }} + EOF multi: runs-on: ubuntu-latest diff --git a/README.md b/README.md index 3b9d6d8..272e28f 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ ___ * [outputs](#outputs) * [environment variables](#environment-variables) * [Notes](#notes) + * [`nodes` output](#nodes-output) * [BuildKit container logs](#buildkit-container-logs) * [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot) @@ -98,14 +99,12 @@ Following inputs can be used as `step.with` keys Following outputs are available -| Name | Type | Description | -|---------------|---------|---------------------------------------| -| `name` | String | Builder name | -| `driver` | String | Builder driver | -| `endpoint` | String | Builder node endpoint | -| `status` | String | Builder node status | -| `flags` | String | Builder node flags (if applicable) | -| `platforms` | String | Builder node platforms available (comma separated) | +| Name | Type | Description | +|-------------|--------|-------------------------------------------------| +| `name` | String | Builder name | +| `driver` | String | Builder driver | +| `platforms` | String | Builder node platforms (preferred or available) | +| `nodes` | JSON | Builder [nodes metadata](#nodes-output) | ### environment variables @@ -117,6 +116,35 @@ The following [official docker environment variables](https://docs.docker.com/en ## Notes +### `nodes` output + +```json +[ + { + "name": "builder-3820d274-502c-4498-ae24-d4c32b3023d90", + "endpoint": "unix:///var/run/docker.sock", + "driver-opts": [ + "network=host", + "image=moby/buildkit:master" + ], + "status": "running", + "buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host", + "buildkit": "3fab389", + "platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386" + } +] +``` + +| Name | Type | Description | +|-------------------|--------|----------------------------| +| `name` | String | Node name | +| `endpoint` | String | Node endpoint | +| `driver-opts` | List | Options for the driver | +| `status` | String | Node status | +| `buildkitd-flags` | String | Flags for buildkitd daemon | +| `buildkit` | String | BuildKit version | +| `platforms` | String | Platforms available | + ### BuildKit container logs To display BuildKit container logs (when `docker-container` driver is used) you have to [enable step debug logging](https://docs.github.com/en/actions/managing-workflow-runs/enabling-debug-logging#enabling-step-debug-logging), diff --git a/__tests__/buildx.test.ts b/__tests__/buildx.test.ts index 5015f9b..025b344 100644 --- a/__tests__/buildx.test.ts +++ b/__tests__/buildx.test.ts @@ -73,7 +73,7 @@ describe('inspect', () => { expect(builder).not.toBeUndefined(); expect(builder.name).not.toEqual(''); expect(builder.driver).not.toEqual(''); - expect(builder.node_platforms).not.toEqual(''); + expect(builder.nodes).not.toEqual({}); }, 100000); }); diff --git a/action.yml b/action.yml index ad5c167..a36fa4f 100644 --- a/action.yml +++ b/action.yml @@ -44,14 +44,16 @@ outputs: description: 'Builder name' driver: description: 'Builder driver' - endpoint: - description: 'Builder node endpoint' - status: - description: 'Builder node status' - flags: - description: 'Builder node flags (if applicable)' platforms: - description: 'Builder node platforms available (comma separated)' + description: 'Builder node platforms (preferred or available)' + nodes: + description: 'Builder nodes metadata' + endpoint: + description: 'Builder node endpoint (deprecated, use nodes output instead)' + status: + description: 'Builder node status (deprecated, use nodes output instead)' + flags: + description: 'Builder node flags (deprecated, use nodes output instead)' runs: using: 'node16' diff --git a/src/buildx.ts b/src/buildx.ts index aa441cb..db0d5ca 100644 --- a/src/buildx.ts +++ b/src/buildx.ts @@ -12,11 +12,15 @@ import * as tc from '@actions/tool-cache'; export type Builder = { name?: string; driver?: string; - node_name?: string; - node_endpoint?: string; - node_status?: string; - node_flags?: string; - node_platforms?: string; + nodes: Node[]; +}; + +export type Node = { + name?: string; + endpoint?: string; + status?: string; + 'buildkitd-flags'?: string; + platforms?: string; }; export async function getConfigInline(s: string): Promise { @@ -98,44 +102,67 @@ export async function inspect(name: string, standalone?: boolean): Promise 0 && res.exitCode != 0) { throw new Error(res.stderr.trim()); } - const builder: Builder = {}; - itlines: for (const line of res.stdout.trim().split(`\n`)) { + const builder: Builder = { + nodes: [] + }; + let node: Node = {}; + for (const line of res.stdout.trim().split(`\n`)) { const [key, ...rest] = line.split(':'); const value = rest.map(v => v.trim()).join(':'); if (key.length == 0 || value.length == 0) { continue; } - switch (key) { - case 'Name': { + switch (key.toLowerCase()) { + case 'name': { if (builder.name == undefined) { builder.name = value; } else { - builder.node_name = value; + if (Object.keys(node).length > 0) { + builder.nodes.push(node); + node = {}; + } + node.name = value; } break; } - case 'Driver': { + case 'driver': { builder.driver = value; break; } - case 'Endpoint': { - builder.node_endpoint = value; + case 'endpoint': { + node.endpoint = value; break; } - case 'Status': { - builder.node_status = value; + case 'status': { + node.status = value; break; } - case 'Flags': { - builder.node_flags = value; + case 'flags': { + node['buildkitd-flags'] = value; break; } - case 'Platforms': { - builder.node_platforms = value.replace(/\s/g, ''); - break itlines; + case 'platforms': { + let platforms: Array = []; + // if a preferred platform is being set then use only these + // https://docs.docker.com/engine/reference/commandline/buildx_inspect/#get-information-about-a-builder-instance + if (value.includes('*')) { + for (const platform of value.split(', ')) { + if (platform.includes('*')) { + platforms.push(platform.replace('*', '')); + } + } + } else { + // otherwise set all platforms available + platforms = value.split(', '); + } + node.platforms = platforms.join(','); + break; } } } + if (Object.keys(node).length > 0) { + builder.nodes.push(node); + } return builder; }); } diff --git a/src/main.ts b/src/main.ts index 2d34d68..a0d4f6b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -115,21 +115,26 @@ async function run(): Promise { core.startGroup(`Inspect builder`); const builder = await buildx.inspect(builderName, standalone); + const firstNode = builder.nodes[0]; core.info(JSON.stringify(builder, undefined, 2)); context.setOutput('driver', builder.driver); - context.setOutput('endpoint', builder.node_endpoint); - context.setOutput('status', builder.node_status); - context.setOutput('flags', builder.node_flags); - context.setOutput('platforms', builder.node_platforms); + context.setOutput('platforms', firstNode.platforms); + context.setOutput('nodes', JSON.stringify(builder.nodes, undefined, 2)); + context.setOutput('endpoint', firstNode.endpoint); // TODO: deprecated, to be removed in a later version + context.setOutput('status', firstNode.status); // TODO: deprecated, to be removed in a later version + context.setOutput('flags', firstNode['buildkitd-flags']); // TODO: deprecated, to be removed in a later version core.endGroup(); - if (!standalone && inputs.driver == 'docker-container') { - stateHelper.setContainerName(`buildx_buildkit_${builder.node_name}`); + if (!standalone && builder.driver == 'docker-container') { + stateHelper.setContainerName(`buildx_buildkit_${firstNode.name}`); core.startGroup(`BuildKit version`); - core.info(await buildx.getBuildKitVersion(`buildx_buildkit_${builder.node_name}`)); + for (const node of builder.nodes) { + const bkvers = await buildx.getBuildKitVersion(`buildx_buildkit_${node.name}`); + core.info(`${node.name}: ${bkvers}`); + } core.endGroup(); } - if (core.isDebug() || builder.node_flags?.includes('--debug')) { + if (core.isDebug() || firstNode['buildkitd-flags']?.includes('--debug')) { stateHelper.setDebug('true'); } } catch (error) {