UNPKG

penguins-eggs

Version:

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

446 lines (445 loc) 17.8 kB
/** * ./src/classes/incubation/incubator.ts * penguins-eggs v.25.7.x / ecmascript 2020 * author: Piero Proietti * email: piero.proietti@gmail.com * license: MIT */ // pjson import { createRequire } from 'node:module'; const require = createRequire(import.meta.url); // partition import yaml from 'js-yaml'; import fs from 'node:fs'; import path from 'node:path'; const pjson = require('../../../package.json'); import { shx } from '../../lib/utils.js'; import Pacman from '../pacman.js'; import Utils from '../utils.js'; import { branding } from './branding.js'; import { customizePartitions } from './customize/customize-partitions.js'; // incubator.d import { Alpine } from './incubator.d/alpine.js'; import { Archlinux } from './incubator.d/archlinux.js'; import { Buster } from './incubator.d/buster.js'; import { Fedora } from './incubator.d/fedora.js'; import { Manjaro } from './incubator.d/manjaro.js'; import { Noble } from './incubator.d/noble.js'; import { Openmamba } from './incubator.d/openmamba.js'; import { Opensuse } from './incubator.d/opensuse.js'; import { Trixie } from './incubator.d/trixie.js'; import { installer } from './installer.js'; // _dirname const __dirname = path.dirname(new URL(import.meta.url).pathname); /** * */ export default class Incubator { distro; installer = {}; isClone; remix; theme; user_opt; verbose = false; /** * * @param remix * @param distro * @param verbose */ constructor(remix, distro, user_opt = 'live', theme = 'eggs', isClone = false, verbose = false) { this.installer = installer(); this.remix = remix; this.distro = distro; this.user_opt = user_opt; this.theme = theme; this.verbose = verbose; this.remix.branding = theme; this.isClone = isClone; // branding è solo il basename this.remix.branding = path.basename(theme); } /** * config */ async config(release = false) { const verbose = true; const echo = Utils.setEcho(verbose); Utils.warning(`creating ${installer().name} configuration files on ${installer().configRoot}`); this.createInstallerDirs(); this.createBranding(); const { distroUniqueId } = this.distro; try { /** * Alpine */ switch (distroUniqueId) { case 'alpine': { const alpine = new Alpine(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await alpine.create(); /** * Archlinux */ break; } case 'archlinux': { const archlinux = new Archlinux(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await archlinux.create(); /** * Manjaro ex rolling */ break; } case 'beowulf': { const beowulf = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await beowulf.create(); break; } case 'bookworm': { const bookworm = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await bookworm.create(); break; } case 'bullseye': { const bullseye = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await bullseye.create(); break; } case 'buster': { const buster = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await buster.create(); break; } case 'chimaera': { const chimaera = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await chimaera.create(); break; } case 'daedalus': { const daedalus = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await daedalus.create(); break; } case 'devel': { const devel = new Noble(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await devel.create(); break; } case 'excalibur': { const excalibur = new Trixie(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await excalibur.create(); /** * fedora */ break; } case 'fedora': { const fedora = new Fedora(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await fedora.create(); /** * openmamba */ break; } case 'focal': { const focal = new Noble(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await focal.create(); break; } case 'forky': { const forky = new Trixie(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await forky.create(); /** * Devuan */ break; } case 'jammy': { const jammy = new Noble(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await jammy.create(); break; } case 'manjaro': { const manjaro = new Manjaro(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await manjaro.create(); /** * Debian */ break; } case 'noble': { const noble = new Noble(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await noble.create(); break; } case 'openmamba': { const mamba = new Openmamba(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await mamba.create(); /** * opensuse */ break; } case 'opensuse': { const suse = new Opensuse(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await suse.create(); /** * Ubuntu */ break; } case 'trixie': { const trixie = new Trixie(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose); await trixie.create(); break; } // No default } } catch (error) { console.error('--- ERRORE FATALE CATTURATO ---'); console.error("L'esecuzione si è interrotta durante la creazione della configurazione specifica per la distro."); console.error(error); process.exit(1); } if (Pacman.calamaresExists()) { await customizePartitions(); } Utils.warning(`cleanup ${installer().name} configuration files`); await this.cleanupConfiguration(); } /** * Rewrite modules */ async cleanupConfiguration() { // modules const elements = fs.readdirSync(this.installer.modules); elements.sort(); for (const elem of elements) { const file = path.join(this.installer.modules, elem); const fileContent = fs.readFileSync(file, 'utf8'); const yamlContent = yaml.load(fileContent); let destContent = `# ${elem} on ${this.distro.distroId}, penguins-eggs ${pjson.version}\n`; destContent += '---\n'; destContent += yaml.dump(yamlContent); fs.writeFileSync(file, destContent, 'utf8'); } // settings const file = path.join(this.installer.configRoot, 'settings.conf'); const fileContent = fs.readFileSync(file, 'utf8'); const yamlContent = yaml.load(fileContent); let destContent = `# settings.conf on ${this.distro.distroId} penguins-eggs ${pjson.version}\n`; destContent += '---\n'; destContent += yaml.dump(yamlContent); fs.writeFileSync(file, destContent, 'utf8'); } /** * */ createBranding() { const dir = path.join(this.installer.configRoot, 'branding', this.remix.branding); if (!fs.existsSync(dir)) { shx.exec(`mkdir ${dir} -p`); } const file = path.join(dir, 'branding.desc'); let destContent = `# branding.desc on ${this.distro.distroId} penguins-eggs ${pjson.version}\n`; destContent += '---\n'; destContent += branding(this.remix, this.distro, this.theme, this.verbose); write(file, destContent, this.verbose); } /** * */ createInstallerDirs() { if (this.installer.name !== 'calamares') { // Remove krill configuration and multiarc if present try { shx.exec('rm ' + this.installer.configRoot + ' -rf'); } catch (error) { console.log('error: ' + error + ' removing ' + this.installer.configRoot + ' -rf'); } try { shx.exec('rm ' + this.installer.multiarch + ' -rf'); } catch (error) { console.log('error: ' + error + ' removing ' + this.installer.multiarch + ' -rf'); } } // rootConfiguration krill/calamares if (!fs.existsSync(this.installer.configRoot)) { try { fs.mkdirSync(this.installer.configRoot); } catch (error) { console.log('error: ' + error + ' creating ' + this.installer.configRoot); } } if (!fs.existsSync(path.join(this.installer.configRoot, 'branding'))) { try { fs.mkdirSync(path.join(this.installer.configRoot, 'branding')); } catch (error) { console.log('error: ' + error + ' creating ' + path.join(this.installer.configRoot, 'branding')); } } if (!fs.existsSync(path.join(this.installer.configRoot, 'branding/eggs'))) { try { fs.mkdirSync(path.join(this.installer.configRoot, 'branding/eggs')); } catch (error) { console.log('error: ' + error + ' creating ' + path.join(this.installer.configRoot, 'branding/eggs')); } } if (!fs.existsSync(path.join(this.installer.configRoot, 'modules'))) { try { fs.mkdirSync(path.join(this.installer.configRoot, 'modules')); } catch (error) { console.log('error: ' + error + ' creating ' + path.join(this.installer.configRoot, 'modules')); } } if (!fs.existsSync(this.installer.multiarch)) { try { fs.mkdirSync(this.installer.multiarch); } catch (error) { console.log('error: ' + error + ' creating ' + this.installer.multiarch); } } if (!fs.existsSync(this.installer.multiarchModules)) { try { fs.mkdirSync(this.installer.multiarchModules); } catch (error) { console.log('error: ' + error + ' creating ' + this.installer.multiarchModules); } } /** * themes krill/calamares */ let calamaresBranding = path.resolve(__dirname, `../../../addons/eggs/theme/calamares/branding`); if (this.theme.includes('/')) { calamaresBranding = `${this.theme}/theme/calamares/branding`; } // console.log(`calamaresBranding: ${calamaresBranding}`) if (fs.existsSync(calamaresBranding)) { if (!fs.existsSync(path.join(this.installer.configRoot, `branding/${this.remix.branding}`))) { try { fs.mkdirSync(path.join(this.installer.configRoot, `branding/${this.remix.branding}`)); } catch (error) { console.log('error: ' + error + ' creating ' + path.join(this.installer.configRoot, `branding/${this.remix.branding}`)); } } // patch quirinux shx.cp('-r', path.join(calamaresBranding, '*'), path.join(this.installer.configRoot, `branding/${this.remix.branding}`)); } else { console.log(calamaresBranding); console.log(`${calamaresBranding} branding not found!`); process.exit(); } /** * install-system.png */ let calamaresIcon = path.resolve(__dirname, `../../../addons/${this.remix.branding}/theme/artwork/install-system.png`); if (this.theme.includes('/')) { calamaresIcon = `${this.theme}/theme/artwork/install-system.png`; } if (Pacman.calamaresExists()) { if (fs.existsSync(calamaresIcon)) { shx.cp(calamaresIcon, '/usr/share/icons/'); } else { console.log(`${calamaresIcon} icon not found!`); process.exit(); } } /** * install-system.desktop */ let calamaresLauncher = path.resolve(__dirname, `../../../addons/${this.remix.branding}/theme/applications/install-system.desktop`); if (this.theme.includes('/')) { calamaresLauncher = `${this.theme}/theme/applications/install-system.desktop`; } if (fs.existsSync(calamaresLauncher)) { shx.cp(calamaresLauncher, '/usr/share/applications/'); } else { console.log(`${calamaresLauncher} launcher not found!`); process.exit(); } /** * install-system.sh */ { const sourceScript = path.resolve(__dirname, '../../../assets/calamares/install-system.sh'); const targetScript = '/usr/bin/install-system.sh'; fs.copyFileSync(sourceScript, targetScript); fs.chmodSync(targetScript, 0o755); fs.chownSync(targetScript, 0, 0); } this.sudoers(); } /** * soluzione tampone from Glenn */ sudoers() { const live = this.user_opt; if (!live) return; const sudoersPath = '/etc/sudoers.d/99-eggs-calamares'; const sudoersDir = '/etc/sudoers.d'; // O usa path.dirname(sudoersPath) // FIX: Crea la directory se non esiste if (!fs.existsSync(sudoersDir)) { try { fs.mkdirSync(sudoersDir, { mode: 0o755, recursive: true }); } catch (error) { console.error(`Error creating ${sudoersDir}:`, error); } } // Nota il SETENV: prima di NOPASSWD const content = `${live} ALL=(ALL) SETENV: NOPASSWD: /usr/bin/calamares\n`; try { fs.writeFileSync(sudoersPath, content, { encoding: 'utf8', mode: 0o440 }); fs.chownSync(sudoersPath, 0, 0); } catch (error) { console.error(error); } } /** * soluzione tampone from Glenn * */ sudoersToRemove() { const live = this.user_opt; if (!live) return; const sudoersPath = '/etc/sudoers.d/99-eggs-calamares'; // Nota il SETENV: prima di NOPASSWD const content = `${live} ALL=(ALL) SETENV: NOPASSWD: /usr/bin/calamares\n`; try { fs.writeFileSync(sudoersPath, content, { encoding: 'utf8', mode: 0o440 }); fs.chownSync(sudoersPath, 0, 0); } catch (error) { console.error(error); } } } /** * * @param file * @param content * @param verbose */ function write(file, content, verbose = false) { if (verbose) { console.log(`calamares: create ${file}`); } fs.writeFileSync(file, content, 'utf8'); }