UNPKG

penguins-eggs

Version:

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

741 lines (740 loc) 26.5 kB
/** * ./src/classes/pacman.ts * penguins-eggs v.25.7.x / ecmascript 2020 * author: Piero Proietti * email: piero.proietti@gmail.com * license: MIT */ import fs from 'node:fs'; // _dirname import path from 'node:path'; import { exec, execSync, shx } from '../lib/utils.js'; import Distro from './distro.js'; import Diversions from './diversions.js'; import Alpine from './pacman.d/alpine.js'; import Archlinux from './pacman.d/archlinux.js'; import Debian from './pacman.d/debian.js'; import Fedora from './pacman.d/fedora.js'; import Openmamba from './pacman.d/openmamba.js'; import Opensuse from './pacman.d/opensuse.js'; import Settings from './settings.js'; import Utils from './utils.js'; const __dirname = path.dirname(new URL(import.meta.url).pathname); const config_file = '/etc/penguins-eggs.d/eggs.yaml'; const config_tools = '/etc/penguins-eggs.d/tools.yaml'; /** * Utils: general porpouse utils * @remarks all the utilities */ export default class Pacman { static debs4calamares = ['calamares', 'qml-module-qtquick2', 'qml-module-qtquick-controls']; distro = {}; remix = {}; /** * autocompleteInstall() * @param verbose */ static async autocompleteInstall() { if (Pacman.packageIsInstalled('bash-completion') && fs.existsSync('/usr/share/bash-completion/completions/')) { await exec(`cp ${__dirname}/../../scripts/eggs.bash /usr/share/bash-completion/completions/`); } // Su arch è ok, su debian God know if (Pacman.packageIsInstalled('zsh-completions') && fs.existsSync('/usr/share/zsh/site-functions')) { await exec(`cp ${__dirname}/../../scripts/_eggs /usr/share/zsh/site-functions/`); } } /** * autocompleteRemove * @param verbose */ static async autocompleteRemove(verbose = false) { await exec(`rm -f /usr/share/bash-completion/completions/eggs.bash`); await exec(`rm -f /usr/share/zsh/site-functions/._eggs`); } /** * return true if calamares is installed */ static calamaresExists() { return Utils.commandExists('calamares'); } /** * */ static async calamaresInstall(verbose = false) { if (this.isInstalledGui()) { const { familyId } = this.distro(); switch (familyId) { case 'alpine': { await Alpine.calamaresInstall(verbose); break; } case 'archlinux': { if (Diversions.isManjaroBased(this.distro().distroId)) { await exec(`pacman -Sy --noconfirm calamares`, Utils.setEcho(true)); } else { await Archlinux.calamaresInstall(verbose); } break; } case 'debian': { await Debian.calamaresInstall(verbose); break; } case 'fedora': { await Fedora.calamaresInstall(verbose); break; } case 'openmamba': { await Openmamba.calamaresInstall(verbose); break; } case 'opensuse': { await Opensuse.calamaresInstall(verbose); break; } // No default } } } /** * calamaresPolicies */ static async calamaresPolicies(verbose = false) { const { familyId } = this.distro(); switch (familyId) { case 'alpine': { await Alpine.calamaresPolicies(verbose); break; } case 'archlinux': { await Archlinux.calamaresPolicies(verbose); break; } case 'debian': { await Debian.calamaresPolicies(verbose); break; } case 'fedora': { await Fedora.calamaresPolicies(verbose); break; } case 'openmamba': { await Openmamba.calamaresPolicies(verbose); break; } case 'opensuse': { await Opensuse.calamaresPolicies(verbose); break; } // No default } } /** * */ static async calamaresRemove(verbose = true) { let retVal = false; const { familyId } = this.distro(); switch (familyId) { case 'alpine': { retVal = await Alpine.calamaresRemove(verbose); break; } case 'archlinux': { retVal = await Archlinux.calamaresRemove(verbose); break; } case 'debian': { retVal = await Debian.calamaresRemove(verbose); break; } case 'fedora': { retVal = await Fedora.calamaresRemove(verbose); break; } case 'openmamba': { retVal = await Openmamba.calamaresRemove(verbose); break; } case 'opensuse': { retVal = await Opensuse.calamaresRemove(verbose); break; } // No default } return retVal; } /** * Restituisce VERO se i file di configurazione SONO presenti */ static configurationCheck() { const confExists = fs.existsSync(config_file); return confExists; } /** * */ static async configurationFresh() { const config = {}; config.version = Utils.getPackageVersion(); config.snapshot_dir = '/home/eggs'; config.snapshot_prefix = ''; config.snapshot_excludes = '/etc/penguins-eggs.d/exclude.list'; config.snapshot_basename = ''; // before default was hostname config.user_opt = 'live'; config.user_opt_passwd = 'evolution'; config.root_passwd = 'evolution'; config.theme = 'eggs'; config.force_installer = true; config.make_efi = true; config.make_md5sum = false; config.make_isohybrid = true; config.compression = 'xz'; config.ssh_pass = false; config.timezone = 'America/New_York'; /** * Salvo la configurazione di eggs.yaml */ config.vmlinuz = Utils.vmlinuz(); config.initrd_img = Utils.initrdImg(); const settings = new Settings(); await settings.save(config); } /** * Creazione del file di configurazione /etc/penguins-eggs */ static async configurationInstall(links = true, verbose = false) { const confRoot = '/etc/penguins-eggs.d'; if (!fs.existsSync(confRoot)) { execSync(`mkdir ${confRoot}`); } if (verbose) { console.log('configuration install: ' + confRoot); } const addons = `${confRoot}/addons`; if (fs.existsSync(addons)) { execSync(`rm -rf ${addons}`); } const distros = `${confRoot}/distros`; if (fs.existsSync(distros)) { execSync(`rm -rf ${distros}`); } execSync(`mkdir -p ${distros}`); /** * We use /etc/penguins-eggs.d/init for our init scripts: * # unattended.sh -> eggs install --unattended * # cuckoo -> eggs cuckoo */ const init = `${confRoot}/init`; if (fs.existsSync(init)) { execSync(`rm -rf ${init}`); } execSync(`mkdir -p ${init}`); shx.cp(path.resolve(__dirname, '../../conf/README.md'), confRoot); shx.cp(path.resolve(__dirname, '../../conf/derivatives.yaml'), confRoot); shx.cp(path.resolve(__dirname, '../../conf/derivatives_fedora.yaml'), confRoot); shx.cp(path.resolve(__dirname, '../../conf/krill.yaml'), confRoot); shx.cp(path.resolve(__dirname, '../../conf/love.yaml'), confRoot); shx.cp(path.resolve(__dirname, '../../conf/tools.yaml'), config_tools); shx.cp(path.resolve(__dirname, '../../conf/yolk.yaml'), confRoot); // init shx.cp(path.resolve(__dirname, '../../conf/init/unattended.sh'), '/etc/penguins-eggs.d/init'); shx.chmod('+x', '/etc/penguins-eggs.d/init/unattended.sh'); shx.cp(path.resolve(__dirname, '../../conf/init/cuckoo.sh'), '/etc/penguins-eggs.d/init'); shx.chmod('+x', '/etc/penguins-eggs.d/init/cuckoo.sh'); // creazione cartella exclude.list.d execSync(`mkdir -p /etc/penguins-eggs.d/exclude.list.d`); shx.cp(path.resolve(__dirname, '../../conf/exclude.list.d/*'), '/etc/penguins-eggs.d/exclude.list.d'); await this.configurationFresh(); } /** * Rimozione dei file di configurazione */ static async configurationRemove(verbose = false) { const echo = Utils.setEcho(verbose); if (fs.existsSync('/etc/penguins-eggs.d')) { await exec('rm /etc/penguins-eggs.d -rf', echo); } /** * No remove calamares more */ // if (fs.existsSync('/etc/calamares')) { // await exec('rm /etc/calamares -rf', echo) // } } /** * * @returns */ static distro() { return new Distro(); } /** * distroTemplateCheck */ static distroTemplateCheck() { const { distroUniqueId } = this.distro(); // console.log(distroUniqueId) return fs.existsSync(`/etc/penguins-eggs.d/distros/${distroUniqueId}`); } /** * */ static async distroTemplateInstall(verbose = false) { if (verbose) { console.log('distroTemplateInstall'); } const echo = Utils.setEcho(verbose); const rootPen = Utils.rootPenguin(); await exec(`mkdir /etc/penguins-eggs.d/distros/${this.distro().distroUniqueId}`); /** * Debian 10 - Buster: è il master per tutte le altre */ const buster = `${rootPen}/conf/distros/buster`; const trixie = `${rootPen}/conf/distros/trixie`; const { distroUniqueId } = this.distro(); /*********************************************************************************** * Alpine **********************************************************************************/ switch (distroUniqueId) { case 'alpine': { // eredita solo da alpine const dest = '/etc/penguins-eggs.d/distros/alpine/'; const alpine = `${rootPen}/conf/distros/alpine/`; await exec(`cp -r ${alpine}/calamares ${dest}/calamares`, echo); /*********************************************************************************** * Arch Linux **********************************************************************************/ break; } case 'archlinux': { const dest = '/etc/penguins-eggs.d/distros/archlinux/'; const arch = `${rootPen}/conf/distros/archlinux/*`; await exec(`cp -r ${arch} ${dest}`, echo); /*********************************************************************************** * Manjaro **********************************************************************************/ break; } case 'beowulf': { const dest = '/etc/penguins-eggs.d/distros/beowulf'; await exec(`cp -r ${buster}/calamares ${dest}/calamares`, echo); /** * Devuan chimaera: eredita tutto da buster */ break; } case 'bookworm': { const dest = '/etc/penguins-eggs.d/distros/bookworm'; await exec(`cp -r ${buster}/calamares ${dest}/calamares`, echo); /** * Debian 13 trixie: eredita tutto da trixie */ break; } case 'bullseye': { const dest = '/etc/penguins-eggs.d/distros/bullseye'; await exec(`cp -r ${buster}/calamares ${dest}/calamares`, echo); /** * Debian 12 bookworm: eredita tutto da buster */ break; } case 'buster': { const dest = '/etc/penguins-eggs.d/distros/buster'; await exec(`cp -r ${buster}/calamares ${dest}/calamares`, echo); /** * Debian 11 bullseye: eredita tutto da buster */ break; } case 'chimaera': { const dest = '/etc/penguins-eggs.d/distros/chimaera'; await exec(`cp -r ${buster}/calamares ${dest}/calamares`, echo); /** * Devuan daedalus: eredita tutto da buster */ break; } case 'daedalus': { const dest = '/etc/penguins-eggs.d/distros/daedalus'; await exec(`cp -r ${buster}/calamares ${dest}/calamares`, echo); /** * Devuan excalibur: eredita tutto da trixie */ break; } case 'excalibur': { const dest = '/etc/penguins-eggs.d/distros/excalibur'; await exec(`cp -r ${trixie}/calamares ${dest}/calamares`, echo); /*********************************************************************************** * Fedora **********************************************************************************/ break; } case 'fedora': { const dest = '/etc/penguins-eggs.d/distros/fedora/'; const fedora = `${rootPen}/conf/distros/fedora/*`; await exec(`cp -r ${fedora} ${dest}`, echo); /*********************************************************************************** * openmamba **********************************************************************************/ break; } case 'focal': { const dest = '/etc/penguins-eggs.d/distros/focal'; const focal = `${rootPen}/conf/distros/focal`; await exec(`cp -r ${focal}/* ${dest}`, echo); /** * Ubuntu 22.04 jammy: eredita da focal */ break; } case 'forky': { const dest = '/etc/penguins-eggs.d/distros/forky'; await exec(`cp -r ${trixie}/calamares ${dest}/calamares`, echo); /*********************************************************************************** * Devuan **********************************************************************************/ /** * Devuan beowulf: eredita tutto da buster */ break; } case 'jammy': { const dest = '/etc/penguins-eggs.d/distros/jammy'; const focal = `${rootPen}/conf/distros/focal`; await exec(`cp -r ${focal}/* ${dest}`, echo); /** * Ubuntu noble: e la nuova baseline per ubuntu * */ break; } case 'manjaro': { const dest = '/etc/penguins-eggs.d/distros/manjaro/'; const manjaro = `${rootPen}/conf/distros/manjaro/*`; await exec(`cp -r ${manjaro} ${dest}`, echo); /*********************************************************************************** * Debian **********************************************************************************/ /** * Debian 10 buster: eredita tutto da buster */ break; } case 'openmamba': { // eredita solo da openmamba const dest = '/etc/penguins-eggs.d/distros/openmamba/'; const mamba = `${rootPen}/conf/distros/openmamba/*`; await exec(`cp -r ${mamba} ${dest}`, echo); /*********************************************************************************** * opensuse **********************************************************************************/ break; } case 'opensuse': { const dest = '/etc/penguins-eggs.d/distros/opensuse/'; const suse = `${rootPen}/conf/distros/opensuse/*`; await exec(`cp -r ${suse} ${dest}`, echo); /*********************************************************************************** * Ubuntu **********************************************************************************/ /** * Ubuntu focal: eredita da focal */ break; } case 'trixie': { const dest = '/etc/penguins-eggs.d/distros/trixie'; await exec(`cp -r ${trixie}/calamares ${dest}/calamares`, echo); /** * Debian 14 forky eredita tutto da trixie */ break; } default: { if (this.distro().distroUniqueId === 'noble') { const dest = '/etc/penguins-eggs.d/distros/noble'; const noble = `${rootPen}/conf/distros/noble`; await exec(`cp -r ${noble}/* ${dest}`, echo); /** * Ubuntu rhino: devel * */ } else if (distroUniqueId === 'devel') { const dest = '/etc/penguins-eggs.d/distros/devel'; const noble = `${rootPen}/conf/distros/noble`; await exec(`cp -r ${noble}/* ${dest}`, echo); } } } } /** * Controlla se calamares è installabile * @returns */ static isCalamaresAvailable() { let result = this.distro().isCalamaresAvailable; if (process.arch === 'arm' || process.arch === 'arm64') { result = false; } return result; } /** * * @returns true se GUI */ static isInstalledGui() { return this.isInstalledXorg() || this.isInstalledWayland(); } /** * check if it's installed wayland * @returns true if wayland */ static isInstalledWayland() { let installed = false; const { familyId } = this.distro(); switch (familyId) { case 'alpine': { if (Alpine.packageIsInstalled('xwayland*')) { installed = true; } break; } case 'archlinux': { if (Archlinux.packageIsInstalled('xwayland')) { installed = true; } break; } case 'debian': { if (Debian.packageIsInstalled('xwayland')) { installed = true; } break; } case 'fedora': { if (Fedora.packageIsInstalled('xorg-x11-server-Xwayland*')) { installed = true; } break; } case 'openmamba': { if (Openmamba.packageIsInstalled('wayland')) { installed = true; } break; } case 'opensuse': { if (Opensuse.packageIsInstalled('wayland')) { installed = true; } break; } // No default } return installed; } /** * check if it's installed xorg * @returns */ static isInstalledXorg() { let installed = false; const { familyId } = this.distro(); switch (familyId) { case 'alpine': { if (Alpine.packageIsInstalled('xorg-server')) { installed = true; } break; } case 'archlinux': { if (Archlinux.packageIsInstalled('xorg-server-common')) { installed = true; } break; } case 'debian': { if (Debian.packageIsInstalled('xserver-xorg-core')) { installed = true; } break; } case 'fedora': { if (Fedora.packageIsInstalled('xorg-x11-server-Xorg.x86_64')) { installed = true; } break; } case 'openmamba': { if (Openmamba.packageIsInstalled('xorg-server')) { installed = true; } break; } case 'opensuse': { if (Opensuse.packageIsInstalled('xorg-x11-server')) { installed = true; } break; } // No default } return installed; } /** * Check if the system is just CLI */ static isRunningCli() { return !this.isRunningGui(); } /** * Check if the system is GUI able */ static isRunningGui() { return this.isRunningXorg() || this.isRunningWayland(); } /** * Constrolla se è operante wayland */ static isRunningWayland() { return process.env.XDG_SESSION_TYPE === 'wayland'; } /** * controlla se è operante xserver-xorg-core */ static isRunningXorg() { return process.env.XDG_SESSION_TYPE === 'x11'; } /** * Check se la macchina ha grub adatto ad efi * Forse conviene spostarlo in pacman */ static isUefi() { let isUefi = false; if (this.distro().familyId === 'debian') { if (Utils.uefiArch() !== 'i386' && this.packageIsInstalled('grub-efi-' + Utils.uefiArch() + '-bin')) { isUefi = true; } } else { isUefi = true; } return isUefi; } /** * Installa manPage */ static async manpageInstall() { const manpageSrc = path.resolve(__dirname, '../../manpages/doc/man/eggs.1.gz'); if (fs.existsSync(manpageSrc)) { const manpageDest = `/usr/share/man/man1`; if (!fs.existsSync(manpageDest)) { await exec(`mkdir ${manpageDest} -p`); } await exec(`cp ${manpageSrc} ${manpageDest}`); // if (shx.exec('which mandb', { silent: true }).stdout.trim() !== '') { // await exec('mandb > /dev/null') // } } } /** * manpageRemove */ static async manpageRemove() { const manpageEggs = `/usr/share/man/man1/eggs.1.gz`; await exec(`rm -rf ${manpageEggs}`); } /** * * @param debPackage * @returns */ static async packageAptLast(debPackage) { let version = ''; if (this.distro().familyId === 'debian') { version = await Debian.packageAptLast(debPackage); } return version; } /** * Install the package packageName * @param packageName {string} Pacchetto Debian da installare * @returns {boolean} True if success */ static async packageInstall(packageName) { let retVal = false; const { familyId } = this.distro(); switch (familyId) { case 'alpine': { retVal = await Alpine.packageInstall(packageName); break; } case 'archlinux': { retVal = await Archlinux.packageInstall(packageName); break; } case 'debian': { retVal = await Debian.packageInstall(packageName); break; } case 'fedora': { retVal = await Fedora.packageInstall(packageName); break; } case 'openmamba': { retVal = await Openmamba.packageInstall(packageName); break; } case 'opensuse': { retVal = await Opensuse.packageInstall(packageName); break; } // No default } return retVal; } /** * restuisce VERO se il pacchetto è installato * @param debPackage */ static packageIsInstalled(packageName) { let installed = false; const { familyId } = this.distro(); switch (familyId) { case 'alpine': { installed = Alpine.packageIsInstalled(packageName); break; } case 'archlinux': { installed = Archlinux.packageIsInstalled(packageName); break; } case 'debian': { installed = Debian.packageIsInstalled(packageName); break; } case 'fedora': { installed = Fedora.packageIsInstalled(packageName); break; } case 'openmamba': { installed = Openmamba.packageIsInstalled(packageName); break; } case 'opensuse': { installed = Opensuse.packageIsInstalled(packageName); break; } // No default } return installed; } static async packagePnpmLast(packageNpm = 'penguins-eggs') { return shx.exec('pnpm view ' + packageNpm + ' version', { silent: true }).stdout.trim(); } }