UNPKG

penguins-eggs

Version:

A remaster system tool, compatible with Almalinux, Alpine, Arch, Debian, Devuan, Fedora, Manjaro, Opensuse, Ubuntu and derivatives

169 lines (168 loc) 6.81 kB
/** * penguins-eggs * Kernel management utilities */ import fs from 'node:fs'; import path from 'path'; import { execSync } from '../../lib/utils.js'; import Utils from '../utils.js'; export default class Kernel { /** * Cerca initramfs */ static initramfs(kernel = '') { let targetKernel = kernel; if (targetKernel === '') { if (Utils.isContainer() && !Utils.isChroot()) { Utils.warning('Non è possibile determinare il kernel in un container.'); process.exit(1); } targetKernel = (execSync('uname -r', { stdio: 'ignore' }) || '').trim(); } const kernelVersionShort = targetKernel.split('.').slice(0, 2).join('.'); const bootDir = '/boot'; let bootFiles; try { bootFiles = fs.readdirSync(bootDir); } catch { console.error(`ERRORE: Impossibile leggere la directory ${bootDir}.`); process.exit(1); } const candidates = []; for (const filename of bootFiles) { if ((filename.startsWith('initramfs-') || filename.startsWith('initrd.img-') || filename.startsWith('initrd-')) && (filename.includes(targetKernel) || filename.includes(kernelVersionShort))) { candidates.push(filename); } } if (candidates.length > 0) { let foundPath = path.join(bootDir, candidates[0]); if (candidates.length > 1) { const nonFallbackCandidates = candidates.filter((c) => !c.includes('-fallback')); const searchArray = nonFallbackCandidates.length > 0 ? nonFallbackCandidates : candidates; foundPath = path.join(bootDir, searchArray[0]); for (const candidate of searchArray) { const current = path.join(bootDir, candidate); if (current.length < foundPath.length) { foundPath = current; } } } return foundPath; } // Fallbacks const staticFallbacks = ['initramfs-lts', 'initramfs-virt', 'initramfs-standard', 'initramfs-rpi', 'initramfs-linux.img', 'initramfs-linux-lts.img', 'initramfs-linux-zen.img', 'initramfs-linux-hardened.img', 'initramfs-linux-cachyos.img', 'initramfs-linux-cachyos-lts.img']; for (const fallback of staticFallbacks) { const fallbackPath = path.join(bootDir, fallback); if (fs.existsSync(fallbackPath)) { return fallbackPath; } } Utils.warning(`Could not find an initramfs file for kernel ${targetKernel} in ${bootDir}.`); process.exit(1); } /** * Ricava path per vmlinuz (o vmlinux su RISC-V) */ static vmlinuz(kernel = '') { let kernelFile = ''; // Esegui se NON è un container if (Utils.isContainer()) { Utils.warning('cannot work on containers actually!'); process.exit(1); } else { kernelFile = this.vmlinuzFromUname(); if (kernelFile === '') { kernelFile = this.vmlinuzFromCmdline(); if (kernelFile === '') { console.log('kernel (vmlinuz/vmlinux) not found'); process.exit(1); } } } if (!fs.existsSync(kernelFile)) { console.log(`kernel: ${kernelFile} does not exist!`); process.exit(1); } return kernelFile; } /** * PRIVATE METHODS */ static vmlinuzFromCmdline() { let kernelFile = ''; // ... (Logica esistente invariata) ... try { const cmdline = fs.readFileSync('/proc/cmdline', 'utf8').split(' '); for (const cmd of cmdline) { if (cmd.includes('BOOT_IMAGE')) { kernelFile = cmd.slice(Math.max(0, cmd.indexOf('=') + 1)); if (kernelFile.includes(')')) { kernelFile = cmd.slice(Math.max(0, cmd.indexOf(')') + 1)); } if (!fs.existsSync(kernelFile) && fs.existsSync(`/boot/${kernelFile}`)) { kernelFile = `/boot/${kernelFile}`; } } } if (kernelFile.includes('@')) { const subvolumeEnd = kernelFile.indexOf('/', kernelFile.indexOf('@')); kernelFile = kernelFile.slice(Math.max(0, subvolumeEnd)); } if (path.dirname(kernelFile) === '/' && fs.existsSync(`/boot${kernelFile}`)) { kernelFile = `/boot${kernelFile}`; } } catch { /* ignore read error */ } return kernelFile; } static vmlinuzFromUname() { const kernelVersion = (execSync('uname -r', { stdio: 'ignore' }) || '').trim(); // --- CHECK FOR RISC-V (vmlinux) --- if (process.arch === 'riscv64') { // 1. Caso Perfetto: uname corrisponde al file vmlinux const riscvPath = `/boot/vmlinux-${kernelVersion}`; if (fs.existsSync(riscvPath)) { return riscvPath; } // 2. Caso "Ciambella di Salvataggio": uname non trova file esatto? // Scansioniamo la cartella per trovare QUALSIASI vmlinux disponibile. try { const files = fs.readdirSync('/boot'); const found = files.find((file) => file.startsWith('vmlinux-')); if (found) { return path.join('/boot', found); } } catch (error) { console.error('Errore leggendo /boot:', error); } // 3. Fallback su vmlinuz (se usassero kernel compressi) const riscvZPath = `/boot/vmlinuz-${kernelVersion}`; if (fs.existsSync(riscvZPath)) { return riscvZPath; } } // --- STANDARD ARCHITECTURES (x86, ARM) --- const standardPath = `/boot/vmlinuz-${kernelVersion}`; if (fs.existsSync(standardPath)) { return standardPath; } // Arch Linux specifics let archPath = ''; if (kernelVersion.includes('-lts')) archPath = `/boot/vmlinuz-linux-lts`; else if (kernelVersion.includes('-zen')) archPath = `/boot/vmlinuz-linux-zen`; else if (kernelVersion.includes('-hardened')) archPath = `/boot/vmlinuz-linux-hardened`; else if (kernelVersion.includes('-arch')) archPath = `/boot/vmlinuz-linux`; if (archPath && fs.existsSync(archPath)) return archPath; return ''; } }