From 4143b5899b9d18631036cc02b1fee89f71bc07fc Mon Sep 17 00:00:00 2001 From: Balaji Arun Date: Thu, 23 Feb 2023 13:11:05 -0800 Subject: [PATCH] Support to retain cache Signed-off-by: Balaji Arun --- README.md | 1 + __tests__/context.test.ts | 71 +++++++++++++++++++++++++++++++++++---- action.yml | 6 ++++ src/context.ts | 13 ++++--- src/main.ts | 3 +- src/state-helper.ts | 5 +++ 6 files changed, 88 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index bdf9e20..794ed88 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,7 @@ The following inputs can be used as `step.with` keys: | `append` | YAML | | [Append additional nodes](https://docs.docker.com/build/ci/github-actions/configure-builder/#append-additional-nodes-to-the-builder) to the builder | | `cache-binary` | Bool | `true` | Cache buildx binary to GitHub Actions cache backend | | `cleanup` | Bool | `true` | Cleanup temp files and remove builder at the end of a job | +| `name` | String | Default Docker Context | Name of the builder to create or use. If a builder with this name already exists, it will be used instead of creating a new one. | > [!IMPORTANT] > If you set the `buildkitd-flags` input, the default flags (`--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host`) diff --git a/__tests__/context.test.ts b/__tests__/context.test.ts index bfbd804..c300fa4 100644 --- a/__tests__/context.test.ts +++ b/__tests__/context.test.ts @@ -56,6 +56,7 @@ describe('getCreateArgs', () => { ['use', 'true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), [ 'create', @@ -74,6 +75,7 @@ describe('getCreateArgs', () => { ['use', 'true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), [ 'create', @@ -92,6 +94,7 @@ describe('getCreateArgs', () => { ['driver-opts', 'image=moby/buildkit:master\nnetwork=host'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), [ 'create', @@ -112,6 +115,7 @@ describe('getCreateArgs', () => { ['use', 'true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), [ 'create', @@ -132,6 +136,7 @@ describe('getCreateArgs', () => { ['use', 'true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), [ 'create', @@ -151,6 +156,7 @@ describe('getCreateArgs', () => { ['driver-opts', `"env.no_proxy=localhost,127.0.0.1,.mydomain"`], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'], ]), [ 'create', @@ -169,6 +175,7 @@ describe('getCreateArgs', () => { ['platforms', 'linux/amd64\n"linux/arm64,linux/arm/v7"'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'], ]), [ 'create', @@ -187,6 +194,7 @@ describe('getCreateArgs', () => { ['driver', 'unknown'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'], ]), [ 'create', @@ -203,6 +211,7 @@ describe('getCreateArgs', () => { ['buildkitd-config', path.join(fixturesDir, 'buildkitd.toml')], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'], ]), [ 'create', @@ -221,6 +230,7 @@ describe('getCreateArgs', () => { ['buildkitd-config-inline', 'debug = true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'], ]), [ 'create', @@ -240,6 +250,7 @@ describe('getCreateArgs', () => { ['buildkitd-flags', '--allow-insecure-entitlement network.host'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'], ]), [ 'create', @@ -247,7 +258,45 @@ describe('getCreateArgs', () => { '--driver', 'cloud', '--buildkitd-flags', '--allow-insecure-entitlement network.host', ] - ] + ], + [ + 11, + 'v0.10.3', + new Map([ + ['install', 'false'], + ['use', 'true'], + ['cleanup', 'true'], + ['cache-binary', 'true'], + ['keep-state', 'false'], + ['name', 'test-builder-name'], + ]), + [ + 'create', + '--name', 'test-builder-name', + '--driver', 'docker-container', + '--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', + '--use' + ] + ], + [ + 12, + 'v0.10.3', + new Map([ + ['install', 'false'], + ['use', 'true'], + ['cleanup', 'true'], + ['cache-binary', 'true'], + ['keep-state', 'true'], + ['name', 'test-builder-name'], + ]), + [ + 'create', + '--name', 'test-builder-name', + '--driver', 'docker-container', + '--buildkitd-flags', '--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host', + '--use', + ] + ], ])( '[%d] given buildx %s and %p as inputs, returns %p', async (num: number, buildxVersion: string, inputs: Map, expected: Array) => { @@ -285,6 +334,7 @@ describe('getAppendArgs', () => { ['use', 'true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), { "name": "aws_graviton2", @@ -343,6 +393,7 @@ describe('getVersion', () => { ['use', 'true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), '' ], @@ -354,7 +405,8 @@ describe('getVersion', () => { ['install', 'false'], ['use', 'true'], ['cache-binary', 'true'], - ['cleanup', 'true'] + ['cleanup', 'true'], + ['keep-state', 'false'] ]), 'latest' ], @@ -366,7 +418,8 @@ describe('getVersion', () => { ['install', 'false'], ['use', 'true'], ['cache-binary', 'true'], - ['cleanup', 'true'] + ['cleanup', 'true'], + ['keep-state', 'false'] ]), 'edge' ], @@ -378,7 +431,8 @@ describe('getVersion', () => { ['install', 'false'], ['use', 'true'], ['cache-binary', 'true'], - ['cleanup', 'true'] + ['cleanup', 'true'], + ['keep-state', 'false'] ]), 'v0.19.2' ], @@ -391,7 +445,8 @@ describe('getVersion', () => { ['install', 'false'], ['use', 'true'], ['cache-binary', 'true'], - ['cleanup', 'true'] + ['cleanup', 'true'], + ['keep-state', 'false'] ]), 'cloud:latest' ], @@ -404,7 +459,8 @@ describe('getVersion', () => { ['install', 'false'], ['use', 'true'], ['cache-binary', 'true'], - ['cleanup', 'true'] + ['cleanup', 'true'], + ['keep-state', 'false'] ]), 'cloud:edge' ], @@ -417,6 +473,7 @@ describe('getVersion', () => { ['use', 'true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), 'cloud:latest' ], @@ -430,6 +487,7 @@ describe('getVersion', () => { ['use', 'true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), 'cloud:v0.11.2-desktop.2' ], @@ -442,6 +500,7 @@ describe('getVersion', () => { ['use', 'true'], ['cache-binary', 'true'], ['cleanup', 'true'], + ['keep-state', 'false'] ]), 'cloud:v0.11.2-desktop.2' ], diff --git a/action.yml b/action.yml index 110fbed..4c1895d 100644 --- a/action.yml +++ b/action.yml @@ -50,6 +50,12 @@ inputs: cleanup: description: 'Cleanup temp files and remove builder at the end of a job' default: 'true' + keep-state: + description: 'Keep BuildKit state on cleanup. This is only useful on persistent self-hosted runners.' + default: 'false' + required: false + name: + description: 'Builder name set when creating the builder. If not specified, one will be generated.' required: false # TODO: remove deprecated config and config-inline inputs config: diff --git a/src/context.ts b/src/context.ts index 20b07ec..bd6162d 100644 --- a/src/context.ts +++ b/src/context.ts @@ -25,12 +25,13 @@ export interface Inputs { append: string; cacheBinary: boolean; cleanup: boolean; + keepState: boolean; } export async function getInputs(): Promise { return { version: core.getInput('version'), - name: await getBuilderName(core.getInput('driver') || 'docker-container'), + name: await getBuilderName(core.getInput('name'), core.getInput('driver') || 'docker-container'), driver: core.getInput('driver') || 'docker-container', driverOpts: Util.getInputList('driver-opts', {ignoreComma: true, quote: false}), buildkitdFlags: core.getInput('buildkitd-flags'), @@ -42,12 +43,16 @@ export async function getInputs(): Promise { buildkitdConfigInline: core.getInput('buildkitd-config-inline') || core.getInput('config-inline'), append: core.getInput('append'), cacheBinary: core.getBooleanInput('cache-binary'), - cleanup: core.getBooleanInput('cleanup') + cleanup: core.getBooleanInput('cleanup'), + keepState: core.getBooleanInput('keep-state') }; } -export async function getBuilderName(driver: string): Promise { - return driver == 'docker' ? await Docker.context() : `builder-${crypto.randomUUID()}`; +export async function getBuilderName(name: string, driver: string): Promise { + if (driver == 'docker') { + return await Docker.context(); + } + return name || `builder-${crypto.randomUUID()}`; } export async function getCreateArgs(inputs: Inputs, toolkit: Toolkit): Promise> { diff --git a/src/main.ts b/src/main.ts index cf22ee3..2203b3f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -115,6 +115,7 @@ actionsToolkit.run( }); } } + stateHelper.setKeepState(inputs.keepState); if (inputs.driver !== 'docker') { await core.group(`Creating a new builder instance`, async () => { @@ -249,7 +250,7 @@ actionsToolkit.run( const buildx = new Buildx({standalone: stateHelper.standalone}); const builder = new Builder({buildx: buildx}); if (await builder.exists(stateHelper.builderName)) { - const rmCmd = await buildx.getCommand(['rm', stateHelper.builderName]); + const rmCmd = await buildx.getCommand(['rm', stateHelper.builderName, ...(stateHelper.keepState ? ['--keep-state'] : [])]); await Exec.getExecOutput(rmCmd.command, rmCmd.args, { ignoreReturnCode: true }).then(res => { diff --git a/src/state-helper.ts b/src/state-helper.ts index ca9d6b4..1a197f6 100644 --- a/src/state-helper.ts +++ b/src/state-helper.ts @@ -9,6 +9,7 @@ export const certsDir = process.env['STATE_certsDir'] || ''; export const tmpDockerContext = process.env['STATE_tmpDockerContext'] || ''; export const cleanup = /true/i.test(process.env['STATE_cleanup'] || ''); export const buildxIsDefaultBuilder = /true/i.test(process.env['STATE_buildxIsDefaultBuilder'] || ''); +export const keepState = !!process.env['STATE_keepState']; export function setDebug(debug: string) { core.saveState('isDebug', debug); @@ -45,3 +46,7 @@ export function setCleanup(cleanup: boolean) { export function setBuildxIsDefaultBuilder(buildxIsDefaultBuilder: boolean) { core.saveState('buildxIsDefaultBuilder', buildxIsDefaultBuilder); } + +export function setKeepState(retain: boolean) { + core.saveState('keepState', retain); +}