Skip to content

Commit

Permalink
append nodes to builder support
Browse files Browse the repository at this point in the history
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
  • Loading branch information
crazy-max committed Sep 19, 2022
1 parent 7af92ce commit 19925f3
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 9 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Expand Up @@ -416,3 +416,28 @@ jobs:
echo "::error::Should have failed"
exit 1
fi
append:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Create dummy contexts
run: |
docker context create ctxbuilder2
docker context create ctxbuilder3
-
name: Set up Docker Buildx
uses: ./
with:
append: |
- name: builder2
endpoint: ctxbuilder2
platforms: linux/amd64
driver-opts:
- image=moby/buildkit:master
- network=host
- endpoint: ctxbuilder3
platforms: linux/arm64
5 changes: 4 additions & 1 deletion README.md
Expand Up @@ -21,6 +21,7 @@ ___
* [Usage](#usage)
* [Advanced usage](#advanced-usage)
* [Authentication to a remote node](docs/advanced/auth.md)
* [Append additional nodes to the builder](docs/advanced/append-nodes.md)
* [Install by default](docs/advanced/install-default.md)
* [BuildKit daemon configuration](docs/advanced/buildkit-config.md)
* [Standalone mode](docs/advanced/standalone.md)
Expand Down Expand Up @@ -59,7 +60,8 @@ jobs:

## Advanced usage

* [Authentication to a remote node](docs/advanced/auth.md)
* [Authenticationto a remote node](docs/advanced/auth.md)
* [Append additional nodes to the builder](docs/advanced/append-nodes.md)
* [Install by default](docs/advanced/install-default.md)
* [BuildKit daemon configuration](docs/advanced/buildkit-config.md)
* [Standalone mode](docs/advanced/standalone.md)
Expand All @@ -81,6 +83,7 @@ Following inputs can be used as `step.with` keys
| `endpoint` | String | [Optional address for docker socket](https://docs.docker.com/engine/reference/commandline/buildx_create/#description) or context from `docker context ls` |
| `config`¹ | String | [BuildKit config file](https://docs.docker.com/engine/reference/commandline/buildx_create/#config) |
| `config-inline`¹ | String | Same as `config` but inline |
| `append` | YAML | [Append additional nodes](docs/advanced/append-nodes.md) to the builder |

> * ¹ `config` and `config-inline` are mutually exclusive
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Expand Up @@ -38,6 +38,9 @@ inputs:
config-inline:
description: 'Inline BuildKit config'
required: false
append:
description: 'Append additional nodes to the builder'
required: false

outputs:
name:
Expand Down
99 changes: 99 additions & 0 deletions docs/advanced/append-nodes.md
@@ -0,0 +1,99 @@
# Append additional nodes to the builder

You can append nodes to the builder that is going to be created with the
`append` input in the form of a YAML string document to remove limitations
intrinsically linked to GitHub Actions (only string format is handled in the
input fields). Following fields are supported:

* `name`: [name of the node](https://docs.docker.com/engine/reference/commandline/buildx_create/#node). If empty, it is the name of the builder it belongs to, with an index number suffix.
* `endpoint`: [Docker context or endpoint](https://docs.docker.com/engine/reference/commandline/buildx_create/#description) of the node to add to the builder
* `driver-opts`: List of additional [driver-specific options](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver-opt)
* `buildkitd-flags`: [Flags for buildkitd](https://docs.docker.com/engine/reference/commandline/buildx_create/#buildkitd-flags) daemon
* `platforms`: Fixed [platforms](https://docs.docker.com/engine/reference/commandline/buildx_create/#platform) for the node. If not empty, values take priority over the detected ones.

```yaml
name: ci

on:
push:

jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
append: |
- endpoint: ssh://me@graviton2
platforms: linux/arm64
- endpoint: ssh://foo@linuxone
driver-opts:
- image=moby/buildkit:master
```

In this example, a `docker-container` builder will be created on the GitHub
Runner with a local node and two remote nodes.

To [set up the SSH authentication](auth.md) for the remote nodes, you can use
the following workflow:

```yaml
name: ci

on:
push:

jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
append: |
- endpoint: ssh://me@graviton2
platforms: linux/arm64
- endpoint: ssh://foo@linuxone
platforms: linux/s390x
env:
BUILDER_NODE_1_AUTH_SSH_PPK: ${{ secrets.GRAVITON2_SSH_PPK }}
BUILDER_NODE_2_AUTH_SSH_PPK: ${{ secrets.LINUXONE_SSH_PPK }}
```

Here is another example using only remote nodes with the `remote` driver:

```yaml
name: ci

on:
push:

jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver: remote
endpoint: tcp://oneprovider:1234
append: |
- endpoint: tcp://graviton2:1234
platforms: linux/arm64
- endpoint: tcp://linuxone:1234
platforms: linux/s390x
env:
BUILDER_NODE_0_AUTH_TLS_CACERT: ${{ secrets.ONEPROVIDER_CA }}
BUILDER_NODE_0_AUTH_TLS_CERT: ${{ secrets.ONEPROVIDER_CERT }}
BUILDER_NODE_0_AUTH_TLS_KEY: ${{ secrets.ONEPROVIDER_KEY }}
BUILDER_NODE_1_AUTH_TLS_CACERT: ${{ secrets.GRAVITON2_CA }}
BUILDER_NODE_1_AUTH_TLS_CERT: ${{ secrets.GRAVITON2_CERT }}
BUILDER_NODE_1_AUTH_TLS_KEY: ${{ secrets.GRAVITON2_KEY }}
BUILDER_NODE_2_AUTH_TLS_CACERT: ${{ secrets.LINUXONE_CA }}
BUILDER_NODE_2_AUTH_TLS_CERT: ${{ secrets.LINUXONE_CERT }}
BUILDER_NODE_2_AUTH_TLS_KEY: ${{ secrets.LINUXONE_KEY }}
```
7 changes: 5 additions & 2 deletions jest.config.ts
@@ -1,10 +1,13 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
setupFiles: ["dotenv/config"],
setupFiles: ['dotenv/config'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.ts$': 'ts-jest'
},
moduleNameMapper: {
'^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
},
verbose: true
}
};
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -31,6 +31,8 @@
"@actions/exec": "^1.1.1",
"@actions/http-client": "^2.0.1",
"@actions/tool-cache": "^2.0.1",
"csv-parse": "^5.1.0",
"js-yaml": "^4.1.0",
"semver": "^7.3.7",
"tmp": "^0.2.1",
"uuid": "^8.3.2"
Expand Down
54 changes: 48 additions & 6 deletions src/context.ts
Expand Up @@ -3,7 +3,9 @@ import * as os from 'os';
import path from 'path';
import * as tmp from 'tmp';
import * as uuid from 'uuid';
import {parse} from 'csv-parse/sync';
import * as buildx from './buildx';
import * as nodes from './nodes';
import * as core from '@actions/core';
import {issueCommand} from '@actions/core/lib/command';

Expand Down Expand Up @@ -33,6 +35,7 @@ export interface Inputs {
endpoint: string;
config: string;
configInline: string;
append: string;
}

export async function getInputs(): Promise<Inputs> {
Expand All @@ -46,7 +49,8 @@ export async function getInputs(): Promise<Inputs> {
use: core.getBooleanInput('use'),
endpoint: core.getInput('endpoint'),
config: core.getInput('config'),
configInline: core.getInput('config-inline')
configInline: core.getInput('config-inline'),
append: core.getInput('append')
};
}

Expand Down Expand Up @@ -80,6 +84,25 @@ export async function getCreateArgs(inputs: Inputs, buildxVersion: string): Prom
return args;
}

export async function getAppendArgs(inputs: Inputs, node: nodes.Node, buildxVersion: string): Promise<Array<string>> {
const args: Array<string> = ['create', '--name', inputs.name, '--append'];
if (node.name) {
args.push('--node', node.name);
}
if (node['driver-opts'] && buildx.satisfies(buildxVersion, '>=0.3.0')) {
await asyncForEach(node['driver-opts'], async driverOpt => {
args.push('--driver-opt', driverOpt);
});
}
if (node.platforms) {
args.push('--platform', node.platforms);
}
if (node.endpoint) {
args.push(node.endpoint);
}
return args;
}

export async function getInspectArgs(inputs: Inputs, buildxVersion: string): Promise<Array<string>> {
const args: Array<string> = ['inspect', '--bootstrap'];
if (buildx.satisfies(buildxVersion, '>=0.4.0')) {
Expand All @@ -89,14 +112,33 @@ export async function getInspectArgs(inputs: Inputs, buildxVersion: string): Pro
}

export async function getInputList(name: string, ignoreComma?: boolean): Promise<string[]> {
const res: Array<string> = [];

const items = core.getInput(name);
if (items == '') {
return [];
return res;
}
return items
.split(/\r?\n/)
.filter(x => x)
.reduce<string[]>((acc, line) => acc.concat(!ignoreComma ? line.split(',').filter(x => x) : line).map(pat => pat.trim()), []);

const records = parse(items, {
columns: false,
relaxQuotes: true,
comment: '#',
relaxColumnCount: true,
skipEmptyLines: true
});

for (const record of records as Array<string[]>) {
if (record.length == 1) {
res.push(record[0]);
continue;
} else if (!ignoreComma) {
res.push(...record);
continue;
}
res.push(record.join(','));
}

return res.filter(item => item).map(pat => pat.trim());
}

export const asyncForEach = async (array, callback) => {
Expand Down
16 changes: 16 additions & 0 deletions src/main.ts
Expand Up @@ -5,6 +5,7 @@ import * as auth from './auth';
import * as buildx from './buildx';
import * as context from './context';
import * as docker from './docker';
import * as nodes from './nodes';
import * as stateHelper from './state-helper';
import * as util from './util';
import * as core from '@actions/core';
Expand Down Expand Up @@ -71,6 +72,21 @@ async function run(): Promise<void> {
core.endGroup();
}

if (inputs.append) {
core.startGroup(`Appending node(s) to builder`);
let nodeIndex = 1;
for (const node of nodes.Parse(inputs.append)) {
const authOpts = auth.setCredentials(credsdir, nodeIndex, node.endpoint || '');
if (authOpts.length > 0) {
node['driver-opts'] = [...(node['driver-opts'] || []), ...authOpts];
}
const appendCmd = buildx.getCommand(await context.getAppendArgs(inputs, node, buildxVersion), standalone);
await exec.exec(appendCmd.commandLine, appendCmd.args);
nodeIndex++;
}
core.endGroup();
}

core.startGroup(`Booting builder`);
const inspectCmd = buildx.getCommand(await context.getInspectArgs(inputs, buildxVersion), standalone);
await exec.exec(inspectCmd.commandLine, inspectCmd.args);
Expand Down
13 changes: 13 additions & 0 deletions src/nodes.ts
@@ -0,0 +1,13 @@
import * as yaml from 'js-yaml';

export type Node = {
name?: string;
endpoint?: string;
'driver-opts'?: Array<string>;
'buildkitd-flags'?: string;
platforms?: string;
};

export function Parse(data: string): Node[] {
return yaml.load(data) as Node[];
}
5 changes: 5 additions & 0 deletions yarn.lock
Expand Up @@ -1450,6 +1450,11 @@ cssstyle@^2.3.0:
dependencies:
cssom "~0.3.6"

csv-parse@^5.1.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-5.3.0.tgz#85cc02fc9d1c89bd1b02e69069c960f8b8064322"
integrity sha512-UXJCGwvJ2fep39purtAn27OUYmxB1JQto+zhZ4QlJpzsirtSFbzLvip1aIgziqNdZp/TptvsKEV5BZSxe10/DQ==

data-urls@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
Expand Down

0 comments on commit 19925f3

Please sign in to comment.