penguins-eggs
Version:
A remaster system tool, compatible with Arch, Debian, Devuan, Ubuntu and others
289 lines (288 loc) • 9.88 kB
JavaScript
/**
* penguins-eggs
*
* Kernel management utilities
* Handle vmlinuz and initramfs detection across different distributions
*/
import fs from 'node:fs';
import Distro from '../distro.js';
import Diversions from '../diversions.js';
/**
* Kernel utilities for managing vmlinuz and initramfs paths
*/
export default class Kernel {
/**
* Ricava path per vmlinuz
*
* Normalmente cerca BOOT_IMAGE nei parametri del kernel
* BOOT_IMAGE=/boot/vmlinuz-5.16.0-3-amd64 root=UUID=... ro quiet splash
*
* Se non è presente, come nel caso di Franco, cerca initrd e ricostruisce vmlinuz
* ro root=UUID=... initrd=boot\initrd.img-5.15.0-0.bpo.3-amd64
*
* @param kernel - Versione specifica del kernel (opzionale)
* @returns Path al file vmlinuz
*/
static vmlinuz(kernel = '') {
const distro = new Distro();
let vmlinuz = '';
if (kernel === '') {
// Auto-detection del kernel dai moduli disponibili
vmlinuz = this.detectKernelFromModules(distro);
}
else {
// Kernel specificato manualmente
vmlinuz = this.getSpecificKernelPath(kernel, distro);
}
// Validazione finale
if (!fs.existsSync(vmlinuz)) {
console.error(`ERROR: file ${vmlinuz} does not exist!`);
console.error('Available kernels in /boot:');
this.listAvailableKernels();
process.exit(1);
}
return vmlinuz;
}
/**
* Ricava path per initramfs/initrd
*
* @param kernel - Versione del kernel
* @returns Path al file initramfs
*/
static initramfs(kernel = '') {
const distro = new Distro();
let initramfs = '';
if (kernel === '') {
// Auto-detection
const kernelModulesPath = this.getKernelModulesPath();
const kernels = this.getAvailableKernels(kernelModulesPath);
const latestKernel = kernels[kernels.length - 1];
kernel = latestKernel;
}
if (distro.familyId === "archlinux") {
initramfs = this.getArchInitramfs(kernel, distro);
}
else {
// Debian/Ubuntu/derivati
const possiblePaths = [
`/boot/initrd.img-${kernel}`,
`/boot/initramfs-${kernel}.img`,
`/boot/initramfs-${kernel}`
];
for (const path of possiblePaths) {
if (fs.existsSync(path)) {
initramfs = path;
break;
}
}
}
if (!fs.existsSync(initramfs)) {
console.error(`ERROR: initramfs file ${initramfs} does not exist!`);
this.listAvailableInitramfs();
process.exit(1);
}
return initramfs;
}
/**
* Rileva automaticamente il kernel dai moduli disponibili
*/
static detectKernelFromModules(distro) {
const kernelModulesPath = this.getKernelModulesPath();
const kernels = this.getAvailableKernels(kernelModulesPath);
if (kernels.length === 0) {
throw new Error(`No kernels found in ${kernelModulesPath}`);
}
if (distro.familyId === "archlinux") {
return this.getArchLinuxKernelPath(distro, kernelModulesPath, kernels);
}
else {
// Per Debian/Ubuntu usa l'ultimo kernel disponibile
const latestKernel = kernels[kernels.length - 1];
return `/boot/vmlinuz-${latestKernel}`;
}
}
/**
* Ottiene il path per un kernel specifico
*/
static getSpecificKernelPath(kernel, distro) {
if (distro.familyId === "archlinux") {
return this.getArchLinuxSpecificKernel(kernel, distro);
}
else {
return `/boot/vmlinuz-${kernel}`;
}
}
/**
* Trova la directory dei moduli del kernel
*/
static getKernelModulesPath() {
const possiblePaths = ['/usr/lib/modules', '/lib/modules'];
for (const path of possiblePaths) {
if (fs.existsSync(path)) {
return path;
}
}
throw new Error('No kernel modules directory found');
}
/**
* Ottiene la lista dei kernel disponibili, ordinati
*/
static getAvailableKernels(modulesPath) {
try {
const kernels = fs.readdirSync(modulesPath);
return kernels.sort();
}
catch (error) {
throw new Error(`Cannot read kernel modules from ${modulesPath}: ${error}`);
}
}
/**
* Gestisce il rilevamento del kernel per Arch Linux
*/
static getArchLinuxKernelPath(distro, modulesPath, kernels) {
if (Diversions.isManjaroBased(distro.distroId)) {
return this.getManjaroKernelPath(kernels);
}
else {
return this.getStandardArchKernelPath(kernels[0]);
}
}
/**
* Gestisce il path del kernel per Manjaro
*/
static getManjaroKernelPath(kernels) {
const latestKernel = kernels[kernels.length - 1];
const versionMatch = latestKernel.match(/^(\d+)\.(\d+)\./);
if (!versionMatch) {
throw new Error(`Cannot parse Manjaro kernel version from: ${latestKernel}`);
}
const [, major, minor] = versionMatch;
return `/boot/vmlinuz-${major}.${minor}-x86_64`;
}
/**
* Gestisce il path del kernel standard per Arch Linux
*/
static getStandardArchKernelPath(firstKernel) {
const kernelTypeMap = [
{ pattern: '-lts', name: 'linux-lts' },
{ pattern: '-hardened', name: 'linux-hardened' },
{ pattern: '-zen', name: 'linux-zen' }
];
// Cerca un tipo specifico di kernel
for (const { pattern, name } of kernelTypeMap) {
if (firstKernel.includes(pattern)) {
return `/boot/vmlinuz-${name}`;
}
}
// Default: kernel linux standard
return '/boot/vmlinuz-linux';
}
/**
* Gestisce il kernel specifico per Arch Linux
*/
static getArchLinuxSpecificKernel(kernel, distro) {
if (Diversions.isManjaroBased(distro.distroId)) {
const versionMatch = kernel.match(/^(\d+)\.(\d+)\./);
if (versionMatch) {
const [, major, minor] = versionMatch;
return `/boot/vmlinuz-${major}.${minor}-x86_64`;
}
}
// Cerca i kernel Arch in ordine di preferenza
const archKernelCandidates = [
'/boot/vmlinuz-linux',
'/boot/vmlinuz-linux-lts',
'/boot/vmlinuz-linux-rt'
];
for (const candidate of archKernelCandidates) {
if (fs.existsSync(candidate)) {
return candidate;
}
}
// Se nessun candidato è trovato, prova con il pattern originale
return `/boot/vmlinuz-${kernel}`;
}
/**
* Gestisce initramfs per Arch Linux
*/
static getArchInitramfs(kernel, distro) {
if (Diversions.isManjaroBased(distro.distroId)) {
const versionMatch = kernel.match(/^(\d+)\.(\d+)\./);
if (versionMatch) {
const [, major, minor] = versionMatch;
return `/boot/initramfs-${major}.${minor}-x86_64.img`;
}
}
// Standard Arch initramfs paths
const archInitramfsCandidates = [
'/boot/initramfs-linux.img',
'/boot/initramfs-linux-lts.img',
'/boot/initramfs-linux-rt.img',
'/boot/initramfs-linux-zen.img',
'/boot/initramfs-linux-hardened.img'
];
for (const candidate of archInitramfsCandidates) {
if (fs.existsSync(candidate)) {
return candidate;
}
}
// Fallback generico
return `/boot/initramfs-${kernel}.img`;
}
/**
* Lista i kernel disponibili in /boot per debugging
*/
static listAvailableKernels() {
try {
const bootFiles = fs.readdirSync('/boot')
.filter(f => f.startsWith('vmlinuz'))
.sort();
if (bootFiles.length > 0) {
bootFiles.forEach(file => console.error(` - ${file}`));
}
else {
console.error(' No vmlinuz files found in /boot');
}
}
catch (error) {
console.error(' Cannot read /boot directory');
}
}
/**
* Lista gli initramfs disponibili in /boot per debugging
*/
static listAvailableInitramfs() {
try {
const bootFiles = fs.readdirSync('/boot')
.filter(f => f.startsWith('initrd') || f.startsWith('initramfs'))
.sort();
if (bootFiles.length > 0) {
console.error('Available initramfs files in /boot:');
bootFiles.forEach(file => console.error(` - ${file}`));
}
else {
console.error(' No initramfs files found in /boot');
}
}
catch (error) {
console.error(' Cannot read /boot directory');
}
}
/**
* Ottiene informazioni sul kernel corrente
*/
static getCurrentKernelInfo() {
try {
const version = fs.readFileSync('/proc/version', 'utf8').trim();
const kernelRelease = fs.readFileSync('/proc/sys/kernel/osrelease', 'utf8').trim();
return {
version: kernelRelease,
vmlinuz: this.vmlinuz(kernelRelease),
initramfs: this.initramfs(kernelRelease)
};
}
catch (error) {
throw new Error(`Cannot get current kernel info: ${error}`);
}
}
}