retrasar instalación de paquetes para instalarlos todos juntos (perf) (y refactor)

asdfasdf
This commit is contained in:
Cat /dev/Nulo 2023-02-20 15:20:37 -03:00
parent 26e9feff98
commit dc96394d5e
4 changed files with 58 additions and 27 deletions

View file

@ -21,6 +21,7 @@ export class Alpine {
this.dir = dir; this.dir = dir;
} }
fstab: Fstab = new Fstab(this); fstab: Fstab = new Fstab(this);
packages: string[] = [];
async mkdirP(dir: string): Promise<void> { async mkdirP(dir: string): Promise<void> {
await mkdir(this.path(dir), { recursive: true }); await mkdir(this.path(dir), { recursive: true });
@ -69,8 +70,27 @@ export class Alpine {
readPasswd(): Promise<PasswdEntry[]> { readPasswd(): Promise<PasswdEntry[]> {
return readPasswd(this.path("/etc/passwd")); return readPasswd(this.path("/etc/passwd"));
} }
async userAdd(user: string): Promise<PasswdEntry> { async userAdd(
await execFile("useradd", ["--user-group", "--root", this.dir, user]); user: string,
{
system,
homeDir,
createHome,
}: { system: boolean; homeDir?: string; createHome: boolean } = {
system: false,
homeDir: "",
createHome: true,
}
): Promise<PasswdEntry> {
await execFile("useradd", [
"--user-group",
...(system ? ["--system"] : []),
...(homeDir ? ["--home-dir", homeDir] : []),
...(createHome ? ["--create-home"] : []),
"--root",
this.dir,
user,
]);
const passwd = await this.readPasswd(); const passwd = await this.readPasswd();
const entry = passwd.find((e) => e.name === user); const entry = passwd.find((e) => e.name === user);
if (!entry) { if (!entry) {
@ -79,9 +99,13 @@ export class Alpine {
return entry; return entry;
} }
async addPackages(packages: string[]): Promise<void> { async actuallyInstallPackages(): Promise<void> {
await this.installPackages(this.packages);
}
async installPackages(packages: string[]): Promise<void> {
logDebug( logDebug(
"addPackages", "installPackages",
await execFile("apk", [ await execFile("apk", [
"add", "add",
"--clean-protected", "--clean-protected",
@ -91,6 +115,9 @@ export class Alpine {
]) ])
); );
} }
async addPackages(packages: string[]): Promise<void> {
this.packages = this.packages.concat(packages);
}
static async makeWorld({ static async makeWorld({
dir, dir,

View file

@ -41,9 +41,7 @@ async function timed<T>(fn: () => Promise<T>): Promise<T> {
console.debug(rootfsDir); console.debug(rootfsDir);
const alpine = await timed(() => Alpine.makeWorld({ dir: rootfsDir })); const alpine = await timed(() => Alpine.makeWorld({ dir: rootfsDir }));
await timed(() => await alpine.addPackages(["helix", "htop", "iproute2-ss", "socat"]);
alpine.addPackages(["helix", "htop", "iproute2-ss", "socat"])
);
await alpine.writeFile( await alpine.writeFile(
"/root/.ash_history", "/root/.ash_history",
` `
@ -60,19 +58,22 @@ socat tcp-listen:80,reuseaddr,fork tcp:localhost:3050 &
await timed(() => setupGrafana(alpine, runit)); await timed(() => setupGrafana(alpine, runit));
const kernel = await timed(() => setupKernel(alpine, kernelDir)); const kernel = await timed(() => setupKernel(alpine, kernelDir));
await timed(() => alpine.actuallyInstallPackages());
const squashfs = path.join(artifactsDir, "image.squashfs"); const squashfs = path.join(artifactsDir, "image.squashfs");
await execFile("mksquashfs", [ await timed(() =>
alpine.dir, execFile("mksquashfs", [
squashfs, alpine.dir,
"-root-mode", squashfs,
"755", "-root-mode",
"-comp", "755",
"zstd", "-comp",
"-Xcompression-level", "zstd",
"3", "-Xcompression-level",
"-noappend", "3",
"-quiet", "-noappend",
]); "-quiet",
])
);
console.timeEnd("Building"); console.timeEnd("Building");

View file

@ -63,7 +63,7 @@ default=lts
`features="${features.join(" ")}"` `features="${features.join(" ")}"`
); );
await alpine.addPackages([`linux-${kind}`]); await alpine.installPackages([`linux-${kind}`]);
const initramfs = path.join(alpine.dir, `/boot/initramfs-${kind}`); const initramfs = path.join(alpine.dir, `/boot/initramfs-${kind}`);
const vmlinuz = path.join(alpine.dir, `/boot/vmlinuz-${kind}`); const vmlinuz = path.join(alpine.dir, `/boot/vmlinuz-${kind}`);

View file

@ -6,6 +6,7 @@ import { FluentBitParser, runitLokiLogger } from "../../software/fluentbit.js";
import { loadGrafanaSecretsFile } from "./secrets.js"; import { loadGrafanaSecretsFile } from "./secrets.js";
const provisioningDir = "/etc/grafana/provisioning/"; const provisioningDir = "/etc/grafana/provisioning/";
const grafanaHome = "/var/lib/grafana";
// TODO: grafana-image-renderer? // TODO: grafana-image-renderer?
// /etc/conf.d/grafana // /etc/conf.d/grafana
@ -23,12 +24,14 @@ export async function setupGrafana(
): Promise<void> { ): Promise<void> {
await alpine.addPackages(["grafana"]); await alpine.addPackages(["grafana"]);
const passwd = await alpine.readPasswd(); const user = await alpine.userAdd("grafana", {
const user = passwd.find((e) => e.name === "grafana"); system: true,
assert(!!user, "no existe el usuario grafana"); homeDir: grafanaHome,
createHome: false,
});
// TODO: data // TODO: data
await alpine.fstab.addTmpfs("/var/lib/grafana", { await alpine.fstab.addTmpfs(grafanaHome, {
uid: user.uid, uid: user.uid,
gid: user.gid, gid: user.gid,
mode: "700", mode: "700",
@ -59,7 +62,7 @@ exec chpst -u grafana:grafana grafana-cli --homepath /usr/share/grafana --config
await runit.addService( await runit.addService(
"grafana", "grafana",
`#!/bin/sh `#!/bin/sh
export GRAFANA_HOME=/var/lib/grafana export GRAFANA_HOME='${grafanaHome}'
cd "$GRAFANA_HOME" cd "$GRAFANA_HOME"
@ -80,7 +83,7 @@ async function genConfig(): Promise<string> {
#################################### Paths #################################### #################################### Paths ####################################
[paths] [paths]
data = /var/lib/grafana data = ${grafanaHome}
# Temporary files in \`data\` directory older than given duration will be removed # Temporary files in \`data\` directory older than given duration will be removed
;temp_data_lifetime = 24h ;temp_data_lifetime = 24h
@ -88,7 +91,7 @@ data = /var/lib/grafana
# Directory where grafana can store logs # Directory where grafana can store logs
;logs = /var/log/grafana ;logs = /var/log/grafana
plugins = /var/lib/grafana/plugins plugins = ${grafanaHome}/plugins
# folder that contains provisioning config files that grafana will apply on startup and while running. # folder that contains provisioning config files that grafana will apply on startup and while running.
provisioning = ${provisioningDir} provisioning = ${provisioningDir}