From 968cad49ce5d312c3b1ccbacb6a2cfec7f9db187 Mon Sep 17 00:00:00 2001 From: Turadg Aleahmad Date: Fri, 26 Jan 2024 07:46:11 -0800 Subject: [PATCH] feat: reclaim disk space after each test --- packages/synthetic-chain/cli.ts | 31 ++++++++++++++++------- packages/synthetic-chain/src/cli/build.ts | 11 +++++--- packages/synthetic-chain/src/cli/run.ts | 14 +++++----- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/packages/synthetic-chain/cli.ts b/packages/synthetic-chain/cli.ts index 987c9a01..f728d335 100755 --- a/packages/synthetic-chain/cli.ts +++ b/packages/synthetic-chain/cli.ts @@ -1,20 +1,20 @@ #!/usr/bin/env tsx -import { parseArgs } from 'node:util'; -import path from 'node:path'; import { execSync } from 'node:child_process'; +import path from 'node:path'; +import { parseArgs } from 'node:util'; import { + bakeTarget, buildProposalSubmissions, - bakeImages, readBuildConfig, } from './src/cli/build.js'; import { writeBakefileProposals, writeDockerfile, } from './src/cli/dockerfileGen.js'; -import { matchOneProposal, readProposals } from './src/cli/proposals.js'; -import { debugTestImage, runTestImages } from './src/cli/run.js'; import { runDoctor } from './src/cli/doctor.js'; +import { imageNameForProposal, matchOneProposal, readProposals } from './src/cli/proposals.js'; +import { debugTestImage, runTestImage } from './src/cli/run.js'; const { positionals, values } = parseArgs({ options: { @@ -62,18 +62,31 @@ const prepareDockerBuild = () => { switch (cmd) { case 'build': { prepareDockerBuild(); - bakeImages('use', values.dry); + bakeTarget('use', values.dry); break; } case 'test': // Always rebuild all test images to keep it simple. With the "use" stages // cached, these are pretty fast building doesn't run agd. prepareDockerBuild(); - bakeImages('test', values.dry); + if (values.debug) { - debugTestImage(matchOneProposal(proposals, match!)); + const proposal = matchOneProposal(proposals, match!); + bakeTarget(imageNameForProposal(proposal, 'test').target, values.dry); + debugTestImage(proposal); + // don't bother to delete the test image because there's just one + // and the user probably wants to run it again. } else { - runTestImages(proposals); + for (const proposal of proposals) { + const image = imageNameForProposal(proposal, 'test'); + bakeTarget(image.target, values.dry); + runTestImage(proposal); + // delete the image to reclaim disk space. The next build + // will use the build cache. + execSync('docker system df', { stdio: 'inherit' }); + execSync(`docker rmi ${image.name}`, { stdio: 'inherit' }); + execSync('docker system df', { stdio: 'inherit' }); + } } break; case 'doctor': diff --git a/packages/synthetic-chain/src/cli/build.ts b/packages/synthetic-chain/src/cli/build.ts index 8843dda3..5753bb23 100755 --- a/packages/synthetic-chain/src/cli/build.ts +++ b/packages/synthetic-chain/src/cli/build.ts @@ -64,13 +64,16 @@ export const buildProposalSubmissions = (proposals: ProposalInfo[]) => { /** * Bake images using the docker buildx bake command. + * + * Note this uses `--load` which pushes the completed images to the builder, + * consuming 2-3 GB per image. + * @see {@link https://docs.docker.com/engine/reference/commandline/buildx_build/#load} * - * @param matrix - The group target + * @param target - The image or group target * @param [dry] - Whether to skip building and just print the build config. */ -export const bakeImages = (matrix: 'test' | 'use', dry = false) => { - // https://docs.docker.com/engine/reference/commandline/buildx_build/#load - const cmd = `docker buildx bake --load ${matrix} ${dry ? '--print' : ''}`; +export const bakeTarget = (target: string, dry = false) => { + const cmd = `docker buildx bake --load ${target} ${dry ? '--print' : ''}`; console.log(cmd); execSync(cmd, { stdio: 'inherit' }); }; diff --git a/packages/synthetic-chain/src/cli/run.ts b/packages/synthetic-chain/src/cli/run.ts index b4a5d7a1..511639b8 100755 --- a/packages/synthetic-chain/src/cli/run.ts +++ b/packages/synthetic-chain/src/cli/run.ts @@ -1,14 +1,12 @@ import { execSync } from 'node:child_process'; import { ProposalInfo, imageNameForProposal } from './proposals.js'; -export const runTestImages = (proposals: ProposalInfo[]) => { - for (const proposal of proposals) { - console.log(`Running test image for proposal ${proposal.proposalName}`); - const { name } = imageNameForProposal(proposal, 'test'); - // 'rm' to remove the container when it exits - const cmd = `docker run --rm ${name}`; - execSync(cmd, { stdio: 'inherit' }); - } +export const runTestImage = (proposal: ProposalInfo) => { + console.log(`Running test image for proposal ${proposal.proposalName}`); + const { name } = imageNameForProposal(proposal, 'test'); + // 'rm' to remove the container when it exits + const cmd = `docker run --rm ${name}`; + execSync(cmd, { stdio: 'inherit' }); }; export const debugTestImage = (proposal: ProposalInfo) => {