UNPKG

penguins-eggs

Version:

A remaster system tool, compatible with Arch, Debian, Devuan, Ubuntu and others

289 lines (288 loc) 9.88 kB
/** * 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}`); } } }