-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
solve disk usage #79
solve disk usage #79
Changes from all commits
610ab2a
d9716b9
df72419
c8372b3
4d008fb
161a066
e8fce15
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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' }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I gather this |
||
execSync('docker system df', { stdio: 'inherit' }); | ||
} | ||
} | ||
break; | ||
case 'doctor': | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,13 +64,16 @@ export const buildProposalSubmissions = (proposals: ProposalInfo[]) => { | |
|
||
/** | ||
* Bake images using the docker buildx bake command. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not familiar with |
||
* | ||
* 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' }); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,13 +27,17 @@ const fixupProposal = (proposal: ProposalInfo) => { | |
} | ||
|
||
// default to node-modules linker | ||
// (The pnpm linker has little benefit because hard links can't cross | ||
// volumes so each Docker layer will have copies of the deps anyway. The | ||
// pnp linker might work but requires other changes.) | ||
const yarnRc = path.join(proposalPath, '.yarnrc.yml'); | ||
if (!fs.existsSync(yarnRc)) { | ||
console.log(`creating ${yarnRc} with node-modules linker`); | ||
fs.writeFileSync(yarnRc, 'nodeLinker: node-modules\n'); | ||
} | ||
|
||
// refresh install | ||
execSync('rm -rf node_modules', { cwd: proposalPath }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 |
||
execSync('yarn install', { cwd: proposalPath }); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the API change from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the CLI's modules aren't part of the package API. The package doesn't yet define That said, this package doesn't claim backwards compatibility because, following semver, it's not yet 1.0. |
||
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) => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these blocks aren't necessary for main, but I'd like to leave it in this PR.
If #2 is not compelling, I'm open to cutting e8fce15 from this branch and merging without another green.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
diagnostics of this sort are somewhere between cost-effective and priceless, IME. (unless they're very, very verbose; I haven't checked in this case).