nodes metadata JSON ouput

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax 2022-09-18 02:24:38 +02:00
parent f0ad70c1de
commit aa0df6f73a
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7
6 changed files with 113 additions and 44 deletions

@ -30,9 +30,16 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
id: buildx
uses: ./ uses: ./
with: with:
version: ${{ matrix.buildx-version }} version: ${{ matrix.buildx-version }}
-
name: Nodes output
run: |
cat << EOF
${{ steps.buildx.outputs.nodes }}
EOF
multi: multi:
runs-on: ubuntu-latest runs-on: ubuntu-latest

@ -29,6 +29,7 @@ ___
* [outputs](#outputs) * [outputs](#outputs)
* [environment variables](#environment-variables) * [environment variables](#environment-variables)
* [Notes](#notes) * [Notes](#notes)
* [`nodes` output](#nodes-output)
* [BuildKit container logs](#buildkit-container-logs) * [BuildKit container logs](#buildkit-container-logs)
* [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot) * [Keep up-to-date with GitHub Dependabot](#keep-up-to-date-with-github-dependabot)
@ -99,13 +100,11 @@ Following inputs can be used as `step.with` keys
Following outputs are available Following outputs are available
| Name | Type | Description | | Name | Type | Description |
|---------------|---------|---------------------------------------| |-------------|--------|-------------------------------------------------|
| `name` | String | Builder name | | `name` | String | Builder name |
| `driver` | String | Builder driver | | `driver` | String | Builder driver |
| `endpoint` | String | Builder node endpoint | | `platforms` | String | Builder node platforms (preferred or available) |
| `status` | String | Builder node status | | `nodes` | JSON | Builder [nodes metadata](#nodes-output) |
| `flags` | String | Builder node flags (if applicable) |
| `platforms` | String | Builder node platforms available (comma separated) |
### environment variables ### environment variables
@ -117,6 +116,35 @@ The following [official docker environment variables](https://docs.docker.com/en
## Notes ## 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 ### 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), 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),

@ -73,7 +73,7 @@ describe('inspect', () => {
expect(builder).not.toBeUndefined(); expect(builder).not.toBeUndefined();
expect(builder.name).not.toEqual(''); expect(builder.name).not.toEqual('');
expect(builder.driver).not.toEqual(''); expect(builder.driver).not.toEqual('');
expect(builder.node_platforms).not.toEqual(''); expect(builder.nodes).not.toEqual({});
}, 100000); }, 100000);
}); });

@ -44,14 +44,16 @@ outputs:
description: 'Builder name' description: 'Builder name'
driver: driver:
description: 'Builder driver' description: 'Builder driver'
endpoint:
description: 'Builder node endpoint'
status:
description: 'Builder node status'
flags:
description: 'Builder node flags (if applicable)'
platforms: 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: runs:
using: 'node16' using: 'node16'

@ -12,11 +12,15 @@ import * as tc from '@actions/tool-cache';
export type Builder = { export type Builder = {
name?: string; name?: string;
driver?: string; driver?: string;
node_name?: string; nodes: Node[];
node_endpoint?: string; };
node_status?: string;
node_flags?: string; export type Node = {
node_platforms?: string; name?: string;
endpoint?: string;
status?: string;
'buildkitd-flags'?: string;
platforms?: string;
}; };
export async function getConfigInline(s: string): Promise<string> { export async function getConfigInline(s: string): Promise<string> {
@ -98,43 +102,66 @@ export async function inspect(name: string, standalone?: boolean): Promise<Build
if (res.stderr.length > 0 && res.exitCode != 0) { if (res.stderr.length > 0 && res.exitCode != 0) {
throw new Error(res.stderr.trim()); throw new Error(res.stderr.trim());
} }
const builder: Builder = {}; const builder: Builder = {
itlines: for (const line of res.stdout.trim().split(`\n`)) { nodes: []
};
let node: Node = {};
for (const line of res.stdout.trim().split(`\n`)) {
const [key, ...rest] = line.split(':'); const [key, ...rest] = line.split(':');
const value = rest.map(v => v.trim()).join(':'); const value = rest.map(v => v.trim()).join(':');
if (key.length == 0 || value.length == 0) { if (key.length == 0 || value.length == 0) {
continue; continue;
} }
switch (key) { switch (key.toLowerCase()) {
case 'Name': { case 'name': {
if (builder.name == undefined) { if (builder.name == undefined) {
builder.name = value; builder.name = value;
} else { } else {
builder.node_name = value; if (Object.keys(node).length > 0) {
builder.nodes.push(node);
node = {};
}
node.name = value;
} }
break; break;
} }
case 'Driver': { case 'driver': {
builder.driver = value; builder.driver = value;
break; break;
} }
case 'Endpoint': { case 'endpoint': {
builder.node_endpoint = value; node.endpoint = value;
break; break;
} }
case 'Status': { case 'status': {
builder.node_status = value; node.status = value;
break; break;
} }
case 'Flags': { case 'flags': {
builder.node_flags = value; node['buildkitd-flags'] = value;
break; break;
} }
case 'Platforms': { case 'platforms': {
builder.node_platforms = value.replace(/\s/g, ''); let platforms: Array<string> = [];
break itlines; // 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; return builder;
}); });

@ -115,21 +115,26 @@ async function run(): Promise<void> {
core.startGroup(`Inspect builder`); core.startGroup(`Inspect builder`);
const builder = await buildx.inspect(builderName, standalone); const builder = await buildx.inspect(builderName, standalone);
const firstNode = builder.nodes[0];
core.info(JSON.stringify(builder, undefined, 2)); core.info(JSON.stringify(builder, undefined, 2));
context.setOutput('driver', builder.driver); context.setOutput('driver', builder.driver);
context.setOutput('endpoint', builder.node_endpoint); context.setOutput('platforms', firstNode.platforms);
context.setOutput('status', builder.node_status); context.setOutput('nodes', JSON.stringify(builder.nodes, undefined, 2));
context.setOutput('flags', builder.node_flags); context.setOutput('endpoint', firstNode.endpoint); // TODO: deprecated, to be removed in a later version
context.setOutput('platforms', builder.node_platforms); 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(); core.endGroup();
if (!standalone && inputs.driver == 'docker-container') { if (!standalone && builder.driver == 'docker-container') {
stateHelper.setContainerName(`buildx_buildkit_${builder.node_name}`); stateHelper.setContainerName(`buildx_buildkit_${firstNode.name}`);
core.startGroup(`BuildKit version`); 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(); core.endGroup();
} }
if (core.isDebug() || builder.node_flags?.includes('--debug')) { if (core.isDebug() || firstNode['buildkitd-flags']?.includes('--debug')) {
stateHelper.setDebug('true'); stateHelper.setDebug('true');
} }
} catch (error) { } catch (error) {