UNPKG

penguins-eggs

Version:

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

264 lines (263 loc) 9.83 kB
/** * ./src/classes/incubation/fisherman.ts * penguins-eggs v.10.0.0 / ecmascript 2020 * author: Piero Proietti * email: piero.proietti@gmail.com * license: MIT */ import chalk from 'chalk'; import mustache from 'mustache'; import fs from 'node:fs'; import path from 'node:path'; import shx from 'shelljs'; import yaml from 'js-yaml'; import { exec } from '../../lib/utils.js'; import { settings } from './fisherman-helper/settings.js'; // _dirname const __dirname = path.dirname(new URL(import.meta.url).pathname); // pjson import { createRequire } from 'node:module'; const require = createRequire(import.meta.url); const pjson = require('../../../package.json'); import { displaymanager } from './fisherman-helper/displaymanager.js'; import { remove as removePackages, tryInstall } from './fisherman-helper/packages.js'; export default class Fisherman { distro; installer = {}; verbose = false; constructor(distro, installer, verbose = false) { this.distro = distro; this.installer = installer; this.verbose = verbose; } /** * * @param name * @param isScript */ async buildCalamaresModule(name, isScript = true, theme = 'eggs') { let moduleTemplate = path.resolve(__dirname, this.installer.templateMultiarch + name); if (theme !== 'eggs') { moduleTemplate = theme + '/theme/calamares/calamares-modules/' + name; } const moduleDest = this.installer.multiarchModules + name; const moduleScript = `/usr/sbin/${name}.sh`; if (this.verbose) this.show(name, 'module', moduleDest); if (!fs.existsSync(moduleDest)) { fs.mkdirSync(moduleDest); } shx.cp(`${moduleTemplate}/module.yml`, `${moduleDest}/module.desc`); if (isScript) { shx.cp(`${moduleTemplate}/${name}.sh`, moduleScript); await exec(`chmod +x ${moduleScript}`); } return moduleScript; } /** * * @param name */ async buildCalamaresPy(name) { const moduleSource = path.resolve(__dirname, this.installer.templateMultiarch + '/' + name); const moduleDest = this.installer.multiarchModules + name; if (this.verbose) this.show(name, 'python', moduleDest); if (!fs.existsSync(moduleDest)) { fs.mkdirSync(moduleDest); } shx.cp(`${moduleSource}/module.yml`, `${moduleDest}/module.desc`); shx.cp(`${moduleSource}/${name}.yml`, `${moduleDest}/${name}.conf`); shx.cp(`${moduleSource}/main.py`, moduleDest); await exec(`chmod +x ${moduleSource}/main.py`); } /** * * @param name * @param replaces [['search','replace']] */ async buildModule(name, vendor = 'eggs') { let moduleSource = path.resolve(__dirname, this.installer.templateModules + name + '.yml'); /** * We need vendor here to have possibility to load custom modules for calamares * the custom modules live in: /addons/vendor/theme/calamares/modules * and - if exist - take priority on distro modules on /conf/distros/calamares/modules * * example: * * ./addons/openos/theme/calamares/modules/partition.yml * take place of: * ./conf/distros/bullseye/calamares/modules/partition.yml * and end in: * /etc/calamares/modules/partition.conf * * And we solve the issue of Sebastien who need btrfs * */ if (vendor !== 'eggs') { let customModuleSource = path.resolve(__dirname, `../../../addons/${vendor}/theme/calamares/modules/${name}.yml`); if (vendor.includes('/')) { customModuleSource = `${vendor}/theme/calamares/modules/${name}.yml`; } if (fs.existsSync(customModuleSource)) { moduleSource = customModuleSource; } } const moduleDest = this.installer.modules + name + '.conf'; if (fs.existsSync(moduleSource)) { if (this.verbose) { this.show(name, 'module', moduleDest); } // We need to adapt just mount.conf if (name === 'mount') { const calamaresVersion = (await exec('calamares --version', { capture: true, echo: false, ignore: false })).data.trim().slice(10, 13); let options = '[ bind ]'; if (calamaresVersion === '3.2') { options = 'bind'; } const view = { options }; const moduleSourceTemplate = fs.readFileSync(moduleSource, 'utf8'); fs.writeFileSync(moduleDest, mustache.render(moduleSourceTemplate, view)); } else { shx.cp(moduleSource, moduleDest); } } else if (this.verbose) { console.log('unchanged: ' + chalk.greenBright(name)); } } /** * * @param name */ async contextualprocess(name) { const moduleSource = path.resolve(__dirname, this.installer.templateModules + name + '_context.yml'); const moduleDest = this.installer.modules + name + '_context.conf'; if (fs.existsSync(moduleSource)) { if (this.verbose) this.show(name, 'contextualprocess', moduleDest); shx.cp(moduleSource, moduleDest); } else if (this.verbose) { console.log(`calamares: ${name} contextualprocess, nothing to do!`); } } /** * write settings */ async createCalamaresSettings(theme = 'eggs', isClone = false) { await settings(this.installer.template, this.installer.configRoot, theme, isClone); } /** * * @param name */ async shellprocess(name) { const moduleSource = path.resolve(__dirname, this.installer.templateModules + 'shellprocess_' + name + '.yml'); const moduleDest = this.installer.modules + 'shellprocess_' + name + '.conf'; if (fs.existsSync(moduleSource)) { if (this.verbose) this.show(name, 'shellprocess', moduleDest); shx.cp(moduleSource, moduleDest); } else if (this.verbose) { console.log(`calamares: ${name} shellprocess, nothing to do`); } } /** * * @param module * @param type * @param path */ show(name, type, path) { switch (type) { case 'module': { console.log('fisherman: ' + chalk.yellow(name) + ' module in ' + chalk.yellow(path)); break; } case 'calamares_module': { console.log('fisherman: ' + chalk.cyanBright(name) + ' calamares_module in ' + chalk.cyanBright(path)); break; } case 'shellprocess': { console.log('fisherman: ' + chalk.green(name) + ' shellprocess in ' + chalk.green(path)); break; } case 'contextualprocess': { console.log('fisherman: ' + chalk.cyanBright(name) + ' shellprocess in ' + chalk.cyanBright(path)); break; } // No default } } /** * ==================================================================================== * M O D U L E S * ==================================================================================== */ /** * Al momento rimane con la vecchia configurazione */ async moduleDisplaymanager() { const name = 'displaymanager'; this.buildModule(name); let file = this.installer.modules + name + '.conf'; let fileContent = fs.readFileSync(file, 'utf8'); let values = yaml.load(fileContent); values.displaymanagers = displaymanager(); let destContent = `# ${name}.conf, created by penguins-eggs ${pjson.version}\n`; destContent += '---\n'; destContent += yaml.dump(values); fs.writeFileSync(file, destContent, 'utf8'); } /** * Al momento rimane con la vecchia configurazione */ async moduleFinished() { const name = 'finished'; await this.buildModule(name); let file = this.installer.modules + name + '.conf'; let fileContent = fs.readFileSync(file, 'utf8'); let values = yaml.load(fileContent); values.restartNowCommand = 'reboot'; let destContent = `# ${name}.conf, created by penguins-eggs ${pjson.version}\n`; destContent += '---\n'; destContent += yaml.dump(values); fs.writeFileSync(file, destContent, 'utf8'); } /** * packages */ async modulePackages(distro, release = false) { const name = 'packages'; this.buildModule(name); const yamlInstall = tryInstall(distro); let yamlRemove = ''; if (release) { yamlRemove = removePackages(distro); } let operations = ''; if (yamlRemove !== '' || yamlInstall !== '') { operations = 'operations:\n' + yamlRemove + yamlInstall; } shx.sed('-i', '{{operations}}', operations, this.installer.modules + name + '.conf'); } /** * Al momento rimane con la vecchia configurazione */ async moduleRemoveuser(username) { const name = 'removeuser'; this.buildModule(name); shx.sed('-i', '{{username}}', username, this.installer.modules + name + '.conf'); } /** * unpackFs */ async moduleUnpackfs() { const name = 'unpackfs'; this.buildModule(name); shx.sed('-i', '{{source}}', this.distro.liveMediumPath + this.distro.squashfs, this.installer.modules + name + '.conf'); } }