93 lines
1.9 KiB
TypeScript
93 lines
1.9 KiB
TypeScript
import { $ } from "bun";
|
|
import type z from "zod";
|
|
import type { BootEntries } from "./efibootmgr.schema";
|
|
import { logger } from "./logger";
|
|
|
|
export class EfiBootMgrService {
|
|
async reboot() {
|
|
await $`reboot`;
|
|
}
|
|
|
|
async setNextBoot(bootNum: number) {
|
|
await $`efibootmgr -n ${bootNum}`;
|
|
}
|
|
|
|
parseEfiBootMgrOutput(output: string): z.output<typeof BootEntries> {
|
|
const lines = output.split("\n");
|
|
|
|
const isBootNextSet = output.includes("BootNext:");
|
|
|
|
if (lines.length < 4) {
|
|
throw new Error("Invalid output!");
|
|
}
|
|
|
|
let outputValues: {
|
|
bootNext?: string;
|
|
bootCurrent: string;
|
|
timeout: string;
|
|
bootOrder: string;
|
|
entries: Array<string>;
|
|
};
|
|
|
|
if (isBootNextSet) {
|
|
const [bootNext, bootCurrent, timeout, bootOrder, ...entries] = lines;
|
|
|
|
if (!bootNext || !bootCurrent || !timeout || !bootOrder) {
|
|
throw new Error("Invalid output!");
|
|
}
|
|
|
|
outputValues = {
|
|
bootNext,
|
|
bootCurrent,
|
|
timeout,
|
|
bootOrder,
|
|
entries,
|
|
};
|
|
} else {
|
|
const [bootCurrent, timeout, bootOrder, ...entries] = lines;
|
|
|
|
if (!bootCurrent || !timeout || !bootOrder) {
|
|
throw new Error("Invalid output!");
|
|
}
|
|
|
|
outputValues = {
|
|
bootCurrent,
|
|
timeout,
|
|
bootOrder,
|
|
entries,
|
|
};
|
|
}
|
|
|
|
return outputValues.entries
|
|
.filter((e) => !![e].join(""))
|
|
.map((v) => {
|
|
logger.debug(`Processing boot entry: ${v}`);
|
|
|
|
const [bootStr, labelStr] = v.split("* ");
|
|
|
|
if (!bootStr || !labelStr) throw new Error("Invalid output!");
|
|
|
|
const digits = bootStr.match(/\d/g);
|
|
|
|
if (digits === null) throw new Error("invalid output!");
|
|
|
|
const [osName] = labelStr.split("\t");
|
|
|
|
if (!osName) throw new Error("Invalid output!");
|
|
|
|
return {
|
|
label: osName,
|
|
number: Number.parseInt(digits.join(""), 10),
|
|
};
|
|
});
|
|
}
|
|
|
|
async listBootEntries(): Promise<z.output<typeof BootEntries>> {
|
|
const output = await $`efibootmgr`.text();
|
|
|
|
logger.info(output);
|
|
|
|
return this.parseEfiBootMgrOutput(output);
|
|
}
|
|
}
|