penguins-eggs
Version:
A remaster system tool, compatible with Arch, Debian, Devuan, Ubuntu and others
383 lines (382 loc) • 15.6 kB
JavaScript
/**
* ./src/classes/incubation/incubator.ts
* penguins-eggs v.10.0.0 / ecmascript 2020
* author: Piero Proietti
* email: piero.proietti@gmail.com
* license: MIT
*/
// pjson
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const pjson = require('../../../package.json');
// partition
import yaml from 'js-yaml';
import fs from 'node:fs';
import path from 'node:path';
import shx from 'shelljs';
import { exec } from '../../lib/utils.js';
import Pacman from '../pacman.js';
import Utils from '../utils.js';
import { installer } from './installer.js';
import { branding } from './branding.js';
// incubator.d
import { Alpine } from './incubator.d/alpine.js';
import { Bionic } from './incubator.d/bionic.js';
import { Buster } from './incubator.d/buster.js';
import { Jessie } from './incubator.d/jessie.js';
import { Noble } from './incubator.d/noble.js';
import { Openmamba } from './incubator.d/openmamba.js';
import { Opensuse } from './incubator.d/opensuse.js';
import { Rolling } from './incubator.d/rolling.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 codenameLikeId = this.distro.codenameLikeId;
/**
* aldos
*/
if (codenameLikeId === 'aldos') {
const aldos = new Openmamba(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await aldos.create();
/**
* Alpine
*/
}
else if (codenameLikeId === 'alpine') {
const alpine = new Alpine(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await alpine.create();
/**
* Arch
*/
}
else if (codenameLikeId === 'rolling') {
const rolling = new Rolling(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await rolling.create();
/**
* Debian
*/
}
else if (codenameLikeId === 'jessie') {
const jessie = new Jessie(this.installer, this.remix, this.distro, this.user_opt, release, this.verbose);
await jessie.create();
}
else if (codenameLikeId === 'stretch') {
const stretch = new Jessie(this.installer, this.remix, this.distro, this.user_opt, release, this.verbose);
await stretch.create();
}
else if (codenameLikeId === 'buster') {
const buster = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await buster.create();
}
else if (codenameLikeId === 'bullseye') {
const bullseye = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await bullseye.create();
}
else if (codenameLikeId === 'bookworm') {
const bookworm = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await bookworm.create();
}
else if (codenameLikeId === 'trixie') {
const trixie = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await trixie.create();
/**
* Devuan
*/
}
else if (codenameLikeId === 'beowulf') {
const beowulf = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await beowulf.create();
}
else if (codenameLikeId === 'chimaera') {
const chimaera = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await chimaera.create();
}
else if (codenameLikeId === 'daedalus') {
const daedalus = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await daedalus.create();
}
else if (codenameLikeId === 'excalibur') {
const excalibur = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await excalibur.create();
/**
* fedora
*/
}
else if (codenameLikeId === 'fedora') {
const fedora = new Rolling(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await fedora.create();
/**
* openmamba
*/
}
else if (codenameLikeId === '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
*/
}
else if (codenameLikeId === '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
*/
}
else if (codenameLikeId === 'bionic') {
const bionic = new Bionic(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await bionic.create();
}
else if (codenameLikeId === 'focal') {
const focal = new Noble(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await focal.create();
}
else if (codenameLikeId === 'jammy') {
const jammy = new Noble(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await jammy.create();
}
else if (codenameLikeId === 'noble') {
const noble = new Noble(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await noble.create();
}
else if (codenameLikeId === 'devel') {
const devel = new Noble(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
await devel.create();
}
if (Pacman.calamaresExists()) {
await partitionCustomize();
}
Utils.warning(`cleanup ${installer().name} configuration files`);
await this.cleanupConfiguration();
}
/**
* Rewrite modules
*/
async cleanupConfiguration() {
// modules
const elements = fs.readdirSync(this.installer.modules);
for (const elem of elements) {
let file = this.installer.modules + elem;
let fileContent = fs.readFileSync(file, 'utf8');
let 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
let file = this.installer.configRoot + '/settings.conf';
let fileContent = fs.readFileSync(file, 'utf8');
let 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 = this.installer.configRoot + 'branding/' + this.remix.branding + '/';
if (!fs.existsSync(dir)) {
shx.exec(`mkdir ${dir} -p`);
}
const file = 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(this.installer.configRoot + 'branding')) {
try {
fs.mkdirSync(this.installer.configRoot + 'branding');
}
catch (error) {
console.log('error: ' + error + ' creating ' + this.installer.configRoot + 'branding');
}
}
if (!fs.existsSync(this.installer.configRoot + 'branding/eggs')) {
try {
fs.mkdirSync(this.installer.configRoot + 'branding/eggs');
}
catch (error) {
console.log('error: ' + error + ' creating ' + this.installer.configRoot + 'branding/eggs');
}
}
if (!fs.existsSync(this.installer.configRoot + 'modules')) {
try {
fs.mkdirSync(this.installer.configRoot + 'modules');
}
catch (error) {
console.log('error: ' + error + ' creating ' + 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(this.installer.configRoot + `branding/${this.remix.branding}`)) {
try {
fs.mkdirSync(this.installer.configRoot + `branding/${this.remix.branding}`);
}
catch (error) {
console.log('error: ' + error + ' creating ' + this.installer.configRoot + `branding/${this.remix.branding}`);
}
}
// patch quirinux
shx.cp('-r', calamaresBranding + '/*', this.installer.configRoot + `branding/${this.remix.branding}/`);
}
else {
console.log(calamaresBranding);
console.log(`${calamaresBranding} branding not found!`);
process.exit();
}
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`;
}
// se non esiste non copio la icona
if (Pacman.calamaresExists()) {
if (fs.existsSync(calamaresIcon)) {
shx.cp(calamaresIcon, '/usr/share/icons/');
}
else {
console.log(`${calamaresIcon} icon not found!`);
process.exit();
}
}
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();
}
// script di avvio
shx.cp(path.resolve(__dirname, '../../../assets/calamares/install-system.sh'), '/usr/sbin/install-system.sh');
shx.chmod('+x', '/usr/sbin/install-system.sh');
}
}
/**
*
* @param file
* @param content
* @param verbose
*/
function write(file, content, verbose = false) {
if (verbose) {
console.log(`calamares: create ${file}`);
}
fs.writeFileSync(file, content, 'utf8');
}
/**
*
*/
async function partitionCustomize() {
const filePartition = '/etc/calamares/modules/partition.conf';
const partition = yaml.load(fs.readFileSync(filePartition, 'utf8'));
// detect filesystem type
let test = await exec(`df -T / | awk 'NR==2 {print $2}'`, { capture: true, echo: false });
partition.defaultFileSystemType = test.data.trim();
partition.availableFileSystemTypes = ['ext4'];
if (Pacman.packageIsInstalled('btrfs-progs')) {
partition.availableFileSystemTypes.push('btrfs');
}
if (Pacman.packageIsInstalled('xfsprogs')) {
partition.availableFileSystemTypes.push('xfs');
}
if (Pacman.packageIsInstalled('f2fs-tools')) {
partition.availableFileSystemTypes.push('f2fs');
}
fs.writeFileSync(filePartition, yaml.dump(partition), 'utf-8');
}