205 lines
No EOL
4.9 KiB
JavaScript
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;
|
|
}
|
|
}
|
|
} |