RaveOS-Gnome/releng/airootfs/usr/share/gnome-shell/extensions/customreboot@nova1545/grub.js
2025-03-15 15:27:53 +01:00

205 lines
No EOL
4.9 KiB
JavaScript

import Gio from "gi://Gio";
import { ExecCommand, Log, LogWarning } from './utils.js';
/**
* Represents grub
*/
export class Grub {
/**
* Get's all available boot options
* @returns {[Map, string]} Map(title, id), defaultOption
*/
static async GetBootOptions() {
try {
let cfgpath = await this.GetConfig();
if (cfgpath == "") {
throw new String("Failed to find grub config");
}
let bootOptions = new Map();
let defualtEn = "";
let file = Gio.file_new_for_path(cfgpath);
let [suc, content] = file.load_contents(null);
if (!suc) {
throw new String("Failed to load grub config");
}
let lines;
if (content instanceof Uint8Array) {
lines = new TextDecoder().decode(content);
}
else {
lines = content.toString();
}
let entryRx = /^menuentry ['"]([^'"]+)/;
let defaultRx = /(?<=set default=\")([A-Za-z- ()/0-9]*)(?=\")/
lines.split('\n').forEach(l => {
let res = entryRx.exec(l);
if (res && res.length) {
bootOptions.set(res[1], res[1]);
}
let def = defaultRx.exec(l);
if (def && def.length) {
defualtEn = def[0];
}
});
bootOptions.forEach((v, k) => {
Log(`${k} = ${v}`);
});
if (defualtEn == "") defualtEn = bootOptions.keys().next().value;
return [bootOptions, defualtEn];
} catch (e) {
LogWarning(e);
return undefined;
}
}
/**
* Set's the next boot option
* @param {string} id
* @returns True if the boot option was set, otherwise false
*/
static async SetBootOption(id) {
try {
let [status, stdout, stderr] = await ExecCommand(
['/usr/bin/pkexec', '/usr/sbin/grub-reboot', id],
);
Log(`Set boot option to ${id}: ${status}\n${stdout}\n${stderr}`);
return true;
} catch (e) {
LogWarning(e);
return false;
}
}
/**
* Can we use this bootloader?
* @returns True if useable otherwise false
*/
static async IsUseable() {
return await this.GetConfig() !== "";
}
/**
* Get's grub config file
* @returns A string containing the location of the config file, if none is found returns a blank string
*/
static async GetConfig() {
let paths = ["/boot/grub/grub.cfg", "/boot/grub2/grub.cfg"];
let file;
for (let i = 0; i < paths.length; i++) {
file = Gio.file_new_for_path(paths[i]);
if (file.query_exists(null)) {
return paths[i];
}
}
return "";
}
/**
* Copies a custom grub script to allow the extension to quickly reboot into another OS
* If anyone reads this: Idk how to combine these into one pkexec call, if you do please leave a commit fixing it
*/
static async EnableQuickReboot(ext) {
try {
let [status, stdout, stderr] = await ExecCommand([
'pkexec',
'sh',
'-c',
`/usr/bin/cp ${ext.lookupByUUID('customreboot@nova1545').path()}/42_custom_reboot /etc/grub.d/42_custom_reboot && /usr/bin/chmod 755 /etc/grub.d/42_custom_reboot && /usr/sbin/update-grub`
]);
if (status !== 0) {
return false;
}
return true;
}
catch (e) {
LogWarning(e);
return false;
}
}
/**
* Removes the script used to allow the extension to quickly reboot into another OS without waiting for grub's timeout
* If anyone reads this: Idk how to combine these into one pkexec call, if you do please leave a commit fixing it
*/
static async DisableQuickReboot() {
try {
let [status, stdout, stderr] = await ExecCommand([
'pkexec',
'sh',
'-c',
'/usr/bin/rm /etc/grub.d/42_custom_reboot && /usr/sbin/update-grub'
]);
if (status !== 0) {
return false;
}
return true;
}
catch (e) {
LogWarning(e);
return false;
}
}
/**
* This boot loader can be quick rebooted
*/
static async CanQuickReboot() {
return true;
}
/**
* Checks if /etc/grub.d/42_custom_reboot exists
*/
static async QuickRebootEnabled() {
try {
let [status, stdout, stderr] = await ExecCommand(['/usr/bin/cat', '/etc/grub.d/42_custom_reboot'],);
if (status !== 0) {
LogWarning(`/etc/grub.d/42_custom_reboot not found`);
return false;
}
Log(`/etc/grub.d/42_custom_reboot found`);
return true;
}
catch (e) {
LogWarning(e);
return false;
}
}
static async SetReadable() {
try {
const config = GetConfig();
let [status, stdout, stderr] = await ExecCommand(['/usr/bin/pkexec', '/usr/bin/chmod', '644', config],);
if (status !== 0) {
Log(`Failed to make ${config} readable`);
return false;
}
Log(`Made ${config} readable`);
return true;
}
catch (e) {
Log(e);
return false;
}
}
}