2023-01-16 12:42:10 +00:00
|
|
|
import {
|
|
|
|
execFile as execFileCallback,
|
|
|
|
spawn as spawnCallback,
|
|
|
|
} from "node:child_process";
|
|
|
|
import { copyFile, mkdir, mkdtemp, opendir, writeFile } from "node:fs/promises";
|
|
|
|
import { tmpdir } from "node:os";
|
|
|
|
import path from "node:path";
|
|
|
|
import { promisify } from "node:util";
|
|
|
|
const execFile = promisify(execFileCallback);
|
|
|
|
const spawn = promisify(spawnCallback);
|
|
|
|
|
|
|
|
{
|
|
|
|
const rootfsDir = await mkdtemp(path.join(tmpdir(), "define-alpine-"));
|
|
|
|
console.debug(rootfsDir);
|
|
|
|
await makeWorld(rootfsDir);
|
|
|
|
try {
|
|
|
|
await spawn("sudo", ["chroot", rootfsDir], { stdio: "inherit" });
|
|
|
|
} catch {}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function makeWorld(dir: string): Promise<void> {
|
|
|
|
const apkDir = path.join(dir, "/etc/apk");
|
|
|
|
await mkdir(apkDir, { recursive: true });
|
|
|
|
|
|
|
|
{
|
|
|
|
const apkKeysDir = path.join(apkDir, "keys");
|
|
|
|
const keysSrcDir = "alpine/keys";
|
|
|
|
await mkdir(apkKeysDir);
|
|
|
|
for await (const { name } of await opendir(keysSrcDir))
|
|
|
|
await copyFile(path.join(keysSrcDir, name), path.join(apkKeysDir, name));
|
|
|
|
}
|
|
|
|
|
|
|
|
await writeFile(
|
|
|
|
path.join(apkDir, "repositories"),
|
|
|
|
[
|
|
|
|
"https://dl-cdn.alpinelinux.org/alpine/v3.17/main",
|
|
|
|
"https://dl-cdn.alpinelinux.org/alpine/v3.17/community",
|
|
|
|
].join("\n")
|
|
|
|
);
|
|
|
|
await execFile("sudo", [
|
|
|
|
"apk",
|
|
|
|
"add",
|
|
|
|
"--initdb",
|
|
|
|
"--clean-protected",
|
|
|
|
"--root",
|
|
|
|
dir,
|
|
|
|
...["alpine-baselayout", "busybox", "libc-utils", "alpine-keys"],
|
|
|
|
]);
|
|
|
|
}
|