initial commit
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { join } from "node:path";
|
||||
import { config, toolchain } from "./config";
|
||||
import { ensureHostKey, guest } from "./guest";
|
||||
import { fail, log } from "./shell";
|
||||
import { tart } from "./tart";
|
||||
|
||||
type BakeOptions = { base: string; ref: string };
|
||||
|
||||
export async function bake({ base, ref }: BakeOptions): Promise<void> {
|
||||
const { image, cpu, memoryMb } = config.tart;
|
||||
const staging = `${image}-new`;
|
||||
const publicKey = await ensureHostKey();
|
||||
|
||||
log(`pull ${base}`);
|
||||
await tart.pull(base);
|
||||
|
||||
await tart.destroy(staging);
|
||||
log(`clone ${base} -> ${staging} (cpu=${cpu} mem=${memoryMb}MB)`);
|
||||
await tart.clone(base, staging);
|
||||
await tart.configure(staging, cpu, memoryMb);
|
||||
|
||||
log(`boot ${staging}`);
|
||||
const vm = tart.start(staging, `/tmp/bake-${staging}.log`);
|
||||
const ip = (await tart.waitForSsh(staging, 60)) ?? fail(`${staging} never came up; see /tmp/bake-${staging}.log`);
|
||||
log(`guest up at ${ip}`);
|
||||
|
||||
(await tart.waitForAgent(staging)) ?? fail("tart guest agent not responding");
|
||||
await tart.exec(
|
||||
staging,
|
||||
`mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '${publicKey}' > ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys`,
|
||||
);
|
||||
|
||||
const g = guest(ip);
|
||||
await g.push(join(import.meta.dir, "..", "guest", "bake.sh"), "/tmp/bake.sh");
|
||||
|
||||
log(`bootstrap toolchain in guest (${config.bun.repo}@${ref})`);
|
||||
const status = await g.run(
|
||||
`/bin/bash -l /tmp/bake.sh ${config.bun.repo} ${ref} ${config.buildkiteAgent.version} '${toolchain.join(" ")}' 2>&1 | tee /tmp/bake.log; grep -qx BAKE_OK /tmp/bake.log`,
|
||||
);
|
||||
if (status !== 0) fail(`bake failed in guest; ${image} untouched, ${staging} left running at ${ip} for inspection`);
|
||||
|
||||
await g.run("sync; sudo shutdown -h now").catch(() => {});
|
||||
log("waiting for guest to power off");
|
||||
await Promise.race([vm.exited, Bun.sleep(180_000)]);
|
||||
await tart.stop(staging);
|
||||
|
||||
await tart.remove(image);
|
||||
await tart.rename(staging, image);
|
||||
log(`${image} ready`);
|
||||
}
|
||||
Reference in New Issue
Block a user