penguins-eggs 25.11.21 → 25.12.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.oclif.manifest.json +53 -41
- package/README.md +80 -36
- package/README.pdf +21575 -3241
- package/addons/eggs/theme/livecd/full.grub.main.cfg +39 -4
- package/addons/eggs/theme/livecd/full.isolinux.main.cfg +47 -4
- package/bin/run.js +11 -0
- package/conf/derivatives.yaml +4 -2
- package/conf/exclude.list.d/var.list +11 -6
- package/dist/appimage/dependency-manager.d.ts +31 -0
- package/dist/appimage/dependency-manager.js +292 -0
- package/dist/appimage/first-run-check.js +3 -3
- package/dist/bin/run.js +11 -0
- package/dist/classes/cli-autologin.js +78 -53
- package/dist/classes/compressors.d.ts +7 -10
- package/dist/classes/compressors.js +44 -31
- package/dist/classes/daddy.js +11 -11
- package/dist/classes/distro.js +2 -2
- package/dist/classes/diversions.js +2 -3
- package/dist/classes/incubation/fisherman-helper/initcpio.d.ts +4 -0
- package/dist/classes/incubation/fisherman-helper/initcpio.js +14 -4
- package/dist/classes/incubation/fisherman-helper/settings.js +1 -1
- package/dist/classes/incubation/fisherman.js +1 -3
- package/dist/classes/incubation/incubator.js +1 -1
- package/dist/classes/network.d.ts +1 -1
- package/dist/classes/ovary.d/create-xdg-autostart.js +1 -1
- package/dist/classes/ovary.d/edit-live-fs.d.ts +1 -12
- package/dist/classes/ovary.d/edit-live-fs.js +216 -186
- package/dist/classes/ovary.d/fertilization.js +1 -1
- package/dist/classes/ovary.d/make-dot-disk.js +1 -1
- package/dist/classes/ovary.d/produce.js +1 -1
- package/dist/classes/ovary.d/user-create-live.d.ts +4 -10
- package/dist/classes/ovary.d/user-create-live.js +82 -84
- package/dist/classes/ovary.d/users-remove.d.ts +5 -6
- package/dist/classes/ovary.d/users-remove.js +61 -31
- package/dist/classes/ovary.d/xorriso-command.js +1 -5
- package/dist/classes/ovary.d.ts +2 -2
- package/dist/classes/ovary.js +2 -2
- package/dist/classes/pacman.d/alpine.js +2 -2
- package/dist/classes/pacman.d/archlinux.js +2 -2
- package/dist/classes/pacman.d/debian.js +2 -3
- package/dist/classes/pacman.d/fedora.js +2 -3
- package/dist/classes/pacman.d/openmamba.js +2 -3
- package/dist/classes/pacman.d/opensuse.js +2 -3
- package/dist/classes/pacman.d.ts +21 -12
- package/dist/classes/pacman.js +55 -47
- package/dist/classes/pve-live.js +1 -1
- package/dist/classes/settings.js +1 -1
- package/dist/classes/sys-users.d.ts +76 -0
- package/dist/classes/sys-users.js +206 -0
- package/dist/classes/utils.d/kernel.js +3 -3
- package/dist/classes/utils.d.ts +16 -11
- package/dist/classes/utils.js +92 -56
- package/dist/classes/xdg.js +1 -1
- package/dist/classes/yolk.js +2 -4
- package/dist/commands/config.js +3 -14
- package/dist/commands/cuckoo.js +1 -1
- package/dist/commands/export/appimage.js +3 -3
- package/dist/commands/export/pkg.js +3 -3
- package/dist/commands/export/tarballs.js +3 -3
- package/dist/commands/krill.js +1 -1
- package/dist/commands/produce.js +9 -4
- package/dist/commands/{setup.d.ts → setup/install.d.ts} +1 -5
- package/dist/commands/setup/install.js +71 -0
- package/dist/commands/setup/purge.d.ts +17 -0
- package/dist/commands/setup/purge.js +71 -0
- package/dist/commands/tools/yolk.js +1 -1
- package/dist/commands/update.d.ts +15 -0
- package/dist/commands/update.js +74 -7
- package/dist/interfaces/i-exec.d.ts +1 -0
- package/dist/krill/classes/prepare.d/location.js +1 -1
- package/dist/krill/classes/prepare.d/partitions.js +1 -1
- package/dist/krill/classes/prepare.d/users.js +2 -2
- package/dist/krill/classes/prepare.js +5 -5
- package/dist/krill/classes/sequence.d/add_user.d.ts +3 -15
- package/dist/krill/classes/sequence.d/add_user.js +87 -57
- package/dist/krill/classes/sequence.d/change_password.d.ts +5 -7
- package/dist/krill/classes/sequence.d/change_password.js +25 -10
- package/dist/krill/classes/sequence.d/del_live_user.d.ts +5 -7
- package/dist/krill/classes/sequence.d/del_live_user.js +39 -25
- package/dist/krill/classes/sequence.d/fstab.js +1 -1
- package/dist/krill/classes/sequence.d/grubcfg.d.ts +3 -7
- package/dist/krill/classes/sequence.d/grubcfg.js +33 -13
- package/dist/krill/classes/sequence.d/mkfs.js +1 -2
- package/dist/krill/classes/sequence.d/unpackfs.d.ts +2 -4
- package/dist/krill/classes/sequence.d/unpackfs.js +8 -5
- package/dist/krill/classes/sequence.js +2 -3
- package/dist/krill/components/title.js +4 -4
- package/dist/krill/lib/select_installation_device.js +1 -1
- package/dist/krill/lib/select_replaced_partition.js +1 -1
- package/dist/lib/utils.d.ts +51 -19
- package/dist/lib/utils.js +225 -39
- package/manpages/doc/man/eggs.1.gz +0 -0
- package/manpages/doc/man/eggs.html +29 -17
- package/package.json +13 -14
- package/perrisbrewery/template/dependencies.yaml +1 -0
- package/scripts/_eggs +35 -7
- package/scripts/boot-encrypted-root.sh +220 -0
- package/scripts/eggs.bash +2 -1
- package/scripts/mount-encrypted-home.sh +324 -0
- package/dist/appimage/prerequisites.d.ts +0 -34
- package/dist/appimage/prerequisites.js +0 -350
- package/dist/commands/setup.js +0 -90
- package/dracut/create-symlink +0 -71
- package/dracut/dracut-log.txt +0 -3
- package/dracut/export +0 -4
- package/dracut/export-dracut-analysis +0 -51
- package/dracut/export-dracut-log +0 -2
- package/dracut/mkisofs +0 -10
- package/dracut/renew-initramfs +0 -17
- package/dracut/sbin2bin +0 -10
- package/dracut/update-dracut-conf-d +0 -2
- package/dracut/update-dracut-modules +0 -62
- package/scripts/appimage-build.sh +0 -152
- package/scripts/appimage-install.sh +0 -43
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ./src/krill/modules/grubcfg.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
* email: piero.proietti@gmail.com
|
|
6
|
-
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
4
|
+
* * REFACTORED: Adds SELinux permissive mode for RHEL family
|
|
8
5
|
*/
|
|
9
6
|
import fs from 'node:fs';
|
|
10
7
|
import Utils from '../../../classes/utils.js';
|
|
@@ -12,24 +9,47 @@ import { InstallationMode } from '../krill_enums.js';
|
|
|
12
9
|
/**
|
|
13
10
|
* grubcfg
|
|
14
11
|
* - open /etc/default/grub
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
17
|
-
* 's/GRUB_CMDLINE_LINUX_DEFAULT=.*$/GRUB_CMDLINE_LINUX_DEFAULT=/g'
|
|
12
|
+
* - handle BTRFS/LUKS settings
|
|
13
|
+
* - inject enforcing=0 for Fedora/RHEL to allow autorelabel on first boot
|
|
18
14
|
*/
|
|
19
15
|
export default async function grubcfg() {
|
|
20
16
|
const file = `${this.installTarget}/etc/default/grub`;
|
|
17
|
+
if (!fs.existsSync(file)) {
|
|
18
|
+
console.warn(`Warning: ${file} not found. Skipping GRUB config.`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
21
|
let content = '';
|
|
22
22
|
const grubs = fs.readFileSync(file, 'utf8').split('\n');
|
|
23
|
+
// Cache per la verifica della famiglia
|
|
24
|
+
const isRhelFamily = ['fedora', 'rhel', 'centos', 'almalinux', 'rocky'].includes(this.distro.familyId);
|
|
23
25
|
for (let i = 0; i < grubs.length; i++) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
let line = grubs[i];
|
|
27
|
+
// 1. LOGICA ESISTENTE (BTRFS / LUKS)
|
|
28
|
+
// Questa logica riscrive completamente la riga DEFAULT se necessario
|
|
29
|
+
if (line.trim().startsWith('GRUB_CMDLINE_LINUX_DEFAULT=')) {
|
|
26
30
|
if (this.partitions.filesystemType === 'btrfs') {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
const uuid = Utils.uuid(this.devices.swap.name);
|
|
32
|
+
if (this.partitions.installationMode === InstallationMode.Luks) {
|
|
33
|
+
line = `GRUB_CMDLINE_LINUX_DEFAULT="resume=UUID=${uuid}"`;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
line = `GRUB_CMDLINE_LINUX_DEFAULT="quiet splash rootflags=subvol=@"`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// 2. LOGICA SELINUX (RHEL/FEDORA)
|
|
41
|
+
// Applichiamo la modifica sia se la riga è stata appena toccata, sia se è originale.
|
|
42
|
+
// Fedora usa spesso anche GRUB_CMDLINE_LINUX (senza DEFAULT), quindi controlliamo entrambe.
|
|
43
|
+
if (isRhelFamily) {
|
|
44
|
+
if (line.trim().startsWith('GRUB_CMDLINE_LINUX_DEFAULT=') || line.trim().startsWith('GRUB_CMDLINE_LINUX=')) {
|
|
45
|
+
// Se non c'è già il parametro, lo iniettiamo subito dopo la prima virgoletta
|
|
46
|
+
if (!line.includes('enforcing=0')) {
|
|
47
|
+
line = line.replace('="', '="enforcing=0 ');
|
|
48
|
+
console.log(`- GRUB: injected enforcing=0 into ${line.split('=')[0]}`);
|
|
49
|
+
}
|
|
30
50
|
}
|
|
31
51
|
}
|
|
32
|
-
content +=
|
|
52
|
+
content += line + '\n';
|
|
33
53
|
}
|
|
34
54
|
fs.writeFileSync(file, content, 'utf-8');
|
|
35
55
|
}
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
* license: MIT
|
|
7
7
|
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
8
8
|
*/
|
|
9
|
-
import { exec } from '../../../lib/utils.js';
|
|
10
|
-
import shx from "shelljs";
|
|
9
|
+
import { exec, shx } from '../../../lib/utils.js';
|
|
11
10
|
import { InstallationMode, SwapChoice } from '../krill_enums.js';
|
|
12
11
|
/**
|
|
13
12
|
* mkfs
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ./src/krill/modules/unpackfs.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
* email: piero.proietti@gmail.com
|
|
6
|
-
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
4
|
+
* * CLEANED: Just unpacks. SELinux is handled via autorelabel on first boot.
|
|
8
5
|
*/
|
|
9
6
|
import Sequence from '../../classes/sequence.js';
|
|
10
7
|
/**
|
|
11
8
|
* unpackfs
|
|
9
|
+
* Scompatta il filesystem (senza tentare fix SELinux costosi qui)
|
|
12
10
|
*/
|
|
13
11
|
export default function unpackfs(this: Sequence): Promise<void>;
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ./src/krill/modules/unpackfs.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
* email: piero.proietti@gmail.com
|
|
6
|
-
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
4
|
+
* * CLEANED: Just unpacks. SELinux is handled via autorelabel on first boot.
|
|
8
5
|
*/
|
|
9
6
|
import Utils from '../../../classes/utils.js';
|
|
10
7
|
import { exec } from '../../../lib/utils.js';
|
|
11
8
|
import path from 'path';
|
|
12
9
|
/**
|
|
13
10
|
* unpackfs
|
|
11
|
+
* Scompatta il filesystem (senza tentare fix SELinux costosi qui)
|
|
14
12
|
*/
|
|
15
13
|
export default async function unpackfs() {
|
|
16
14
|
const squafsPath = path.join(this.distro.liveMediumPath, this.distro.squashfs);
|
|
15
|
+
// -d: destination
|
|
16
|
+
// -f: force (overwrite)
|
|
17
17
|
const cmd = `unsquashfs -d ${this.installTarget} -f ${squafsPath} ${this.toNull}`;
|
|
18
|
-
|
|
18
|
+
// Usiamo echo false per evitare di intasare il log con migliaia di file
|
|
19
19
|
const echoNo = Utils.setEcho(false);
|
|
20
|
+
console.log('Unpacking filesystem (this may take a while)...');
|
|
21
|
+
// Esecuzione
|
|
20
22
|
await exec(cmd, echoNo);
|
|
23
|
+
console.log('Filesystem unpacked successfully.');
|
|
21
24
|
}
|
|
@@ -19,7 +19,7 @@ import Distro from '../../classes/distro.js';
|
|
|
19
19
|
import Pacman from '../../classes/pacman.js';
|
|
20
20
|
import Utils from '../../classes/utils.js';
|
|
21
21
|
import Xdg from '../../classes/xdg.js';
|
|
22
|
-
import { exec } from '../../lib/utils.js';
|
|
22
|
+
import { exec, spawnSync } from '../../lib/utils.js';
|
|
23
23
|
// Import all modules (unchanged)
|
|
24
24
|
import partition from './sequence.d/partition.js';
|
|
25
25
|
import biosStandard from './sequence.d/partition.d/bios_standard.js';
|
|
@@ -51,7 +51,6 @@ import hostname from './sequence.d/hostname.js';
|
|
|
51
51
|
import CFS from './cfs.js';
|
|
52
52
|
import Title from '../components/title.js';
|
|
53
53
|
import cliCursor from 'cli-cursor';
|
|
54
|
-
import { spawnSync } from 'child_process';
|
|
55
54
|
/**
|
|
56
55
|
* Main Sequence class - Simple Refactoring
|
|
57
56
|
*/
|
|
@@ -339,7 +338,7 @@ export default class Sequence {
|
|
|
339
338
|
await sleep(5000);
|
|
340
339
|
}
|
|
341
340
|
else {
|
|
342
|
-
spawnSync('read _ ', { shell: true, stdio: [0, 1, 2] });
|
|
341
|
+
spawnSync('read _ ', [], { shell: true, stdio: [0, 1, 2] });
|
|
343
342
|
}
|
|
344
343
|
await exec(cmd, { echo: false });
|
|
345
344
|
}
|
|
@@ -14,14 +14,14 @@ const require = createRequire(import.meta.url);
|
|
|
14
14
|
const pjson = require('../../../package.json');
|
|
15
15
|
export default function Title({ title = "", version = "" }) {
|
|
16
16
|
let type = "";
|
|
17
|
-
if (Utils.isAppImage()) {
|
|
18
|
-
type = "
|
|
17
|
+
if (!Utils.isAppImage()) {
|
|
18
|
+
type = " native";
|
|
19
19
|
}
|
|
20
20
|
if (title === "")
|
|
21
21
|
title = `${pjson.name}`;
|
|
22
|
-
let green = ` ${
|
|
22
|
+
let green = ` ${title}`.padEnd(25, " ");
|
|
23
23
|
let white = ` Perri's brewery edition `.padEnd(25, " ");
|
|
24
|
-
let red = ` v${pjson.version} `.padStart(25, " ");
|
|
24
|
+
let red = ` v${pjson.version}${type} `.padStart(25, " ");
|
|
25
25
|
return (React.createElement(React.Fragment, null,
|
|
26
26
|
React.createElement(Box, { flexDirection: "column" },
|
|
27
27
|
React.createElement(Box, null),
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* license: MIT
|
|
7
7
|
*/
|
|
8
8
|
import inquirer from 'inquirer';
|
|
9
|
-
import shx from '
|
|
9
|
+
import { shx } from '../../lib/utils.js';
|
|
10
10
|
export default async function selectInstallationDevice() {
|
|
11
11
|
const drives = shx.exec('lsblk |grep disk|cut -f 1 "-d "', { silent: true }).stdout.trim().split('\n');
|
|
12
12
|
const raid = shx.exec('lsblk -l | grep raid | cut -f 1 "-d "', { silent: true }).stdout.trim().split('\n');
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* license: MIT
|
|
7
7
|
*/
|
|
8
8
|
import inquirer from 'inquirer';
|
|
9
|
-
import shx from '
|
|
9
|
+
import { shx } from '../../lib/utils.js';
|
|
10
10
|
export default async function selectReplacedPartition() {
|
|
11
11
|
const partitions = shx.exec('lsblk -l -o NAME,TYPE | grep part | cut -d" " -f1', { silent: true }).stdout.trim().split('\n');
|
|
12
12
|
let partitionsList = [];
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -5,31 +5,63 @@
|
|
|
5
5
|
* email: piero.proietti@gmail.com
|
|
6
6
|
* license: MIT
|
|
7
7
|
*/
|
|
8
|
+
import { SpawnOptions, SpawnSyncOptions, SpawnSyncReturns, ChildProcess } from 'child_process';
|
|
9
|
+
import { IExec } from '../interfaces/index.js';
|
|
10
|
+
interface ShellExecResult {
|
|
11
|
+
code: number;
|
|
12
|
+
stdout: string;
|
|
13
|
+
stderr: string;
|
|
14
|
+
}
|
|
15
|
+
interface ExecSyncOptions {
|
|
16
|
+
echo?: boolean;
|
|
17
|
+
ignore?: boolean;
|
|
18
|
+
stdio?: 'pipe' | 'ignore' | 'inherit';
|
|
19
|
+
}
|
|
8
20
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* capture: true, to capture and return stdout.
|
|
15
|
-
*
|
|
16
|
-
* @returns {Promise<{code: number, data: string | undefined, error: Object}>}
|
|
17
|
-
*
|
|
18
|
-
* https://github.com/oclif/core/issues/453#issuecomment-1200778612
|
|
19
|
-
* codespool:
|
|
20
|
-
* You could wrap spawn in a promise, listen to exit event, and resolve when it happens. That should play nicely with oclif/core.
|
|
21
|
-
* We are using it here:
|
|
22
|
-
* https://github.com/AstarNetwork/swanky-cli/blob/master/src/commands/compile/index.ts
|
|
21
|
+
* spawnSync (WRAPPER INTELLIGENTE)
|
|
22
|
+
* Supporta:
|
|
23
|
+
* 1. (command, args, options)
|
|
24
|
+
* 2. (command, options) -> args diventa []
|
|
25
|
+
* Pulisce automaticamente l'ambiente.
|
|
23
26
|
*/
|
|
24
|
-
|
|
27
|
+
export declare function spawnSync(command: string, arg2?: string[] | SpawnSyncOptions, arg3?: SpawnSyncOptions): SpawnSyncReturns<string | Buffer>;
|
|
28
|
+
/**
|
|
29
|
+
* spawn (WRAPPER INTELLIGENTE)
|
|
30
|
+
* Supporta:
|
|
31
|
+
* 1. (command, args, options)
|
|
32
|
+
* 2. (command, options) -> args diventa []
|
|
33
|
+
* Pulisce automaticamente l'ambiente.
|
|
34
|
+
*/
|
|
35
|
+
export declare function spawn(command: string, arg2?: readonly string[] | SpawnOptions, arg3?: SpawnOptions): ChildProcess;
|
|
36
|
+
/**
|
|
37
|
+
* shx
|
|
38
|
+
* Sostituto drop-in per shelljs che usa API native e ambiente pulito.
|
|
39
|
+
*/
|
|
40
|
+
export declare const shx: {
|
|
41
|
+
sed: (flag: string, regex: string | RegExp, replacement: string, file: string) => void;
|
|
42
|
+
touch: (file: string) => void;
|
|
43
|
+
cp: (arg1: string, arg2: string, arg3?: string) => void;
|
|
44
|
+
rm: (arg1: string, arg2?: string) => void;
|
|
45
|
+
mkdir: (arg1: string, arg2?: string) => void;
|
|
46
|
+
mv: (src: string, dest: string) => void;
|
|
47
|
+
chmod: (mode: string | number, file: string) => void;
|
|
48
|
+
test: (flag: string, pathToCheck: string) => boolean;
|
|
49
|
+
which: (cmd: string) => string | null;
|
|
50
|
+
ln: (flag: string, target: string, link: string) => void;
|
|
51
|
+
exec: (command: string, options?: {
|
|
52
|
+
silent?: boolean;
|
|
53
|
+
}) => ShellExecResult;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* execSync
|
|
57
|
+
*/
|
|
58
|
+
export declare function execSync(command: string, options?: ExecSyncOptions): string | null;
|
|
25
59
|
/**
|
|
26
|
-
*
|
|
27
|
-
* @param command
|
|
28
|
-
* @param param1
|
|
29
|
-
* @returns
|
|
60
|
+
* exec (Async)
|
|
30
61
|
*/
|
|
31
62
|
export declare function exec(command: string, { echo, ignore, capture }?: {
|
|
32
63
|
echo?: boolean | undefined;
|
|
33
64
|
ignore?: boolean | undefined;
|
|
34
65
|
capture?: boolean | undefined;
|
|
35
66
|
}): Promise<IExec>;
|
|
67
|
+
export {};
|
package/dist/lib/utils.js
CHANGED
|
@@ -5,53 +5,239 @@
|
|
|
5
5
|
* email: piero.proietti@gmail.com
|
|
6
6
|
* license: MIT
|
|
7
7
|
*/
|
|
8
|
-
import
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
// Importiamo con alias per poter wrappare
|
|
11
|
+
import { spawn as nodeSpawn, spawnSync as nodeSpawnSync } from 'child_process';
|
|
9
12
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
|
|
13
|
+
* Pulizia AppImage
|
|
14
|
+
* Variabili d'ambiente da rimuovere per evitare conflitti quando si eseguono
|
|
15
|
+
* comandi di sistema dall'interno di una AppImage.
|
|
16
|
+
*/
|
|
17
|
+
const APPIMAGE_ENV_BLACKLIST = [
|
|
18
|
+
'LD_LIBRARY_PATH', 'LD_PRELOAD', 'PYTHONPATH', 'PERLLIB',
|
|
19
|
+
'GSETTINGS_SCHEMA_DIR', 'QT_PLUGIN_PATH', 'XDG_DATA_DIRS',
|
|
20
|
+
'LIBRARY_PATH', 'PKG_CONFIG_PATH', 'GIO_MODULE_DIR', 'APPIMAGE', 'APPDIR'
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Ottiene un ambiente pulito dalle variabili AppImage
|
|
24
|
+
* @returns Oggetto process.env sanificato
|
|
25
|
+
*/
|
|
26
|
+
function getCleanEnv() {
|
|
27
|
+
const env = { ...process.env };
|
|
28
|
+
if (process.env.APPIMAGE) {
|
|
29
|
+
APPIMAGE_ENV_BLACKLIST.forEach((key) => delete env[key]);
|
|
30
|
+
}
|
|
31
|
+
return env;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* spawnSync (WRAPPER INTELLIGENTE)
|
|
35
|
+
* Supporta:
|
|
36
|
+
* 1. (command, args, options)
|
|
37
|
+
* 2. (command, options) -> args diventa []
|
|
38
|
+
* Pulisce automaticamente l'ambiente.
|
|
39
|
+
*/
|
|
40
|
+
export function spawnSync(command, arg2, arg3) {
|
|
41
|
+
let args = [];
|
|
42
|
+
let options = {};
|
|
43
|
+
// Rilevamento argomenti (Polimorfismo)
|
|
44
|
+
if (Array.isArray(arg2)) {
|
|
45
|
+
args = arg2;
|
|
46
|
+
options = arg3 || {};
|
|
47
|
+
}
|
|
48
|
+
else if (arg2 && typeof arg2 === 'object') {
|
|
49
|
+
// TypeScript fix: cast esplicito per evitare errori di tipo union
|
|
50
|
+
options = arg2;
|
|
51
|
+
}
|
|
52
|
+
const env = getCleanEnv();
|
|
53
|
+
const finalEnv = { ...env, ...(options.env || {}) };
|
|
54
|
+
return nodeSpawnSync(command, args, {
|
|
55
|
+
...options,
|
|
56
|
+
env: finalEnv
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* spawn (WRAPPER INTELLIGENTE)
|
|
61
|
+
* Supporta:
|
|
62
|
+
* 1. (command, args, options)
|
|
63
|
+
* 2. (command, options) -> args diventa []
|
|
64
|
+
* Pulisce automaticamente l'ambiente.
|
|
65
|
+
*/
|
|
66
|
+
export function spawn(command, arg2, arg3) {
|
|
67
|
+
let args = [];
|
|
68
|
+
let options = {};
|
|
69
|
+
// Rilevamento argomenti (Polimorfismo)
|
|
70
|
+
if (Array.isArray(arg2)) {
|
|
71
|
+
args = arg2;
|
|
72
|
+
options = arg3 || {};
|
|
73
|
+
}
|
|
74
|
+
else if (arg2 && typeof arg2 === 'object') {
|
|
75
|
+
// TypeScript fix: cast esplicito
|
|
76
|
+
options = arg2;
|
|
77
|
+
}
|
|
78
|
+
const env = getCleanEnv();
|
|
79
|
+
const finalEnv = { ...env, ...(options.env || {}) };
|
|
80
|
+
return nodeSpawn(command, args, {
|
|
81
|
+
...options,
|
|
82
|
+
env: finalEnv
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* shx
|
|
87
|
+
* Sostituto drop-in per shelljs che usa API native e ambiente pulito.
|
|
88
|
+
*/
|
|
89
|
+
export const shx = {
|
|
90
|
+
sed: (flag, regex, replacement, file) => {
|
|
91
|
+
if (!fs.existsSync(file))
|
|
92
|
+
return;
|
|
93
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
94
|
+
const searchRegex = typeof regex === 'string' ? new RegExp(regex, 'g') : regex;
|
|
95
|
+
const newContent = content.replace(searchRegex, replacement);
|
|
96
|
+
fs.writeFileSync(file, newContent, 'utf8');
|
|
97
|
+
},
|
|
98
|
+
touch: (file) => {
|
|
99
|
+
const time = new Date();
|
|
100
|
+
try {
|
|
101
|
+
fs.utimesSync(file, time, time);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
fs.closeSync(fs.openSync(file, 'w'));
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
cp: (arg1, arg2, arg3) => {
|
|
108
|
+
const src = arg3 ? arg2 : arg1;
|
|
109
|
+
const dest = arg3 ? arg3 : arg2;
|
|
110
|
+
// --- GESTIONE WILDCARD (*) ---
|
|
111
|
+
if (src.endsWith('*')) {
|
|
112
|
+
const srcDir = path.dirname(src);
|
|
113
|
+
if (!fs.existsSync(srcDir))
|
|
114
|
+
return;
|
|
115
|
+
if (!fs.existsSync(dest))
|
|
116
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
117
|
+
const items = fs.readdirSync(srcDir);
|
|
118
|
+
items.forEach(item => {
|
|
119
|
+
const s = path.join(srcDir, item);
|
|
120
|
+
const d = path.join(dest, item);
|
|
121
|
+
fs.cpSync(s, d, { recursive: true, force: true });
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// ----------------------------
|
|
126
|
+
let finalDest = dest;
|
|
127
|
+
if (fs.existsSync(dest) && fs.statSync(dest).isDirectory()) {
|
|
128
|
+
finalDest = path.join(dest, path.basename(src));
|
|
129
|
+
}
|
|
130
|
+
if (fs.existsSync(src)) {
|
|
131
|
+
fs.cpSync(src, finalDest, { recursive: true, force: true });
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
rm: (arg1, arg2) => {
|
|
135
|
+
const target = arg2 ? arg2 : arg1;
|
|
136
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
137
|
+
},
|
|
138
|
+
mkdir: (arg1, arg2) => {
|
|
139
|
+
const dir = arg2 ? arg2 : arg1;
|
|
140
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
141
|
+
},
|
|
142
|
+
mv: (src, dest) => {
|
|
143
|
+
if (!fs.existsSync(src))
|
|
144
|
+
return;
|
|
145
|
+
fs.renameSync(src, dest);
|
|
146
|
+
},
|
|
147
|
+
chmod: (mode, file) => {
|
|
148
|
+
if (!fs.existsSync(file))
|
|
149
|
+
return;
|
|
150
|
+
let finalMode = mode;
|
|
151
|
+
if (mode === '+x')
|
|
152
|
+
finalMode = 0o755;
|
|
153
|
+
if (typeof mode === 'string' && !isNaN(parseInt(mode, 8))) {
|
|
154
|
+
finalMode = parseInt(mode, 8);
|
|
155
|
+
}
|
|
156
|
+
fs.chmodSync(file, finalMode);
|
|
157
|
+
},
|
|
158
|
+
test: (flag, pathToCheck) => {
|
|
159
|
+
try {
|
|
160
|
+
const stats = fs.statSync(pathToCheck);
|
|
161
|
+
if (flag === '-f')
|
|
162
|
+
return stats.isFile();
|
|
163
|
+
if (flag === '-d')
|
|
164
|
+
return stats.isDirectory();
|
|
165
|
+
return true; // -e
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
which: (cmd) => {
|
|
172
|
+
const result = shx.exec(`command -v ${cmd}`, { silent: true });
|
|
173
|
+
return result.code === 0 ? result.stdout.trim() : null;
|
|
174
|
+
},
|
|
175
|
+
ln: (flag, target, link) => {
|
|
176
|
+
if (fs.existsSync(link) || fs.lstatSync(link, { throwIfNoEntry: false })) {
|
|
177
|
+
fs.rmSync(link, { force: true });
|
|
178
|
+
}
|
|
179
|
+
fs.symlinkSync(target, link);
|
|
180
|
+
},
|
|
181
|
+
exec: (command, options = {}) => {
|
|
182
|
+
const env = getCleanEnv();
|
|
183
|
+
const spawnOpts = {
|
|
184
|
+
stdio: options.silent ? 'pipe' : 'inherit',
|
|
185
|
+
env: env,
|
|
186
|
+
shell: '/bin/bash',
|
|
187
|
+
encoding: 'utf-8'
|
|
188
|
+
};
|
|
189
|
+
// Usiamo nodeSpawnSync perché calcoliamo l'env qui sopra
|
|
190
|
+
const result = nodeSpawnSync(command, [], spawnOpts);
|
|
191
|
+
return {
|
|
192
|
+
code: result.status ?? 1,
|
|
193
|
+
stdout: result.stdout ? result.stdout.toString() : '',
|
|
194
|
+
stderr: result.stderr ? result.stderr.toString() : ''
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* execSync
|
|
200
|
+
*/
|
|
201
|
+
export function execSync(command, options = {}) {
|
|
202
|
+
const { echo = false, ignore = false, stdio } = options;
|
|
203
|
+
if (echo)
|
|
204
|
+
console.log(command);
|
|
205
|
+
const isSilent = ignore || stdio === 'ignore';
|
|
206
|
+
const result = shx.exec(command, { silent: isSilent });
|
|
207
|
+
if (result.code !== 0) {
|
|
208
|
+
throw new Error(`Command failed: ${command}\nExit Code: ${result.code}\nStderr: ${result.stderr}`);
|
|
209
|
+
}
|
|
210
|
+
return result.stdout.trim();
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* exec (Async)
|
|
14
214
|
*/
|
|
15
215
|
export async function exec(command, { echo = false, ignore = false, capture = false } = {}) {
|
|
16
216
|
return new Promise((resolve, reject) => {
|
|
17
|
-
if (echo)
|
|
217
|
+
if (echo)
|
|
18
218
|
console.log(command);
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
const
|
|
22
|
-
stdio: ignore ? 'ignore' : capture ? 'pipe' : 'inherit'
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// Clona l'ambiente attuale
|
|
27
|
-
const env = { ...process.env };
|
|
28
|
-
// 1. Rimuovi le variabili che causano conflitti di librerie (Kernel Panic)
|
|
29
|
-
delete env.LD_LIBRARY_PATH;
|
|
30
|
-
delete env.LD_PRELOAD;
|
|
31
|
-
delete env.GSETTINGS_SCHEMA_DIR;
|
|
32
|
-
delete env.PYTHONPATH;
|
|
33
|
-
delete env.MANPATH;
|
|
34
|
-
// 2. FORZA IL PATH DI SISTEMA
|
|
35
|
-
env.PATH = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';
|
|
36
|
-
// Applica l'ambiente pulito alle opzioni di spawn
|
|
37
|
-
spawnOptions.env = env;
|
|
38
|
-
// (Opzionale) Debug visivo per essere sicuri che stia funzionando
|
|
39
|
-
if (echo) {
|
|
40
|
-
console.log(' [AppImage Detected] Environment sanitized for system command.');
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
const child = spawn('bash', ['-c', command], spawnOptions);
|
|
219
|
+
const env = getCleanEnv();
|
|
220
|
+
// Usiamo nodeSpawn direttamente qui per coerenza
|
|
221
|
+
const child = nodeSpawn(command, [], {
|
|
222
|
+
stdio: ignore ? 'ignore' : (capture ? 'pipe' : 'inherit'),
|
|
223
|
+
env: env,
|
|
224
|
+
shell: '/bin/bash'
|
|
225
|
+
});
|
|
44
226
|
let stdout = '';
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
227
|
+
let stderr = '';
|
|
228
|
+
if (capture && child.stdout)
|
|
229
|
+
child.stdout.on('data', d => stdout += d.toString());
|
|
230
|
+
if (capture && child.stderr)
|
|
231
|
+
child.stderr.on('data', d => stderr += d.toString());
|
|
50
232
|
child.on('error', (error) => {
|
|
51
|
-
reject({ code: 1, error });
|
|
233
|
+
reject({ code: 1, error, stderr });
|
|
52
234
|
});
|
|
53
|
-
child.on('
|
|
54
|
-
resolve({
|
|
235
|
+
child.on('close', (code) => {
|
|
236
|
+
resolve({
|
|
237
|
+
code: code || 0,
|
|
238
|
+
data: stdout.trim(),
|
|
239
|
+
error: code !== 0 ? stderr.trim() : undefined
|
|
240
|
+
});
|
|
55
241
|
});
|
|
56
242
|
});
|
|
57
243
|
}
|
|
Binary file
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
7
|
</head>
|
|
8
8
|
<body>
|
|
9
|
-
<h1>eggs(1) -- the reproductive system of penguins: eggs v25.
|
|
9
|
+
<h1>eggs(1) -- the reproductive system of penguins: eggs v25.12.7</h1>
|
|
10
10
|
<h1>SYNOPSIS</h1>
|
|
11
11
|
<p>eggs is a console utility, in active development, who let you to remaster your system and redistribuite it as live ISO image.</p>
|
|
12
12
|
<h1>INSTALL</h1>
|
|
13
13
|
<p>penguins-eggs as an AppImage, it can be installed on all supported distributions. Download it from https://github.com/pieroproietti/penguins-eggs/releases, then run the following commands:</p>
|
|
14
|
-
<pre><code>$ chmod +x penguins-eggs_25.
|
|
14
|
+
<pre><code>$ chmod +x penguins-eggs_25.12.7-1_amd64-x86_64.AppImage
|
|
15
15
|
$ sudo mv /usr/local/bin
|
|
16
16
|
$ sudo eggs setup
|
|
17
17
|
</code></pre>
|
|
@@ -19,30 +19,30 @@ $ sudo eggs setup
|
|
|
19
19
|
<pre><code>$ doas apk add penguins-eggs@testing
|
|
20
20
|
</code></pre>
|
|
21
21
|
<p>AlmaLinux/RockyLinux</p>
|
|
22
|
-
<pre><code>$ sudo dnf install ./penguins-eggs_25.
|
|
22
|
+
<pre><code>$ sudo dnf install ./penguins-eggs_25.12.7-1_amd64-1rocky9.5..x86_64.rpm
|
|
23
23
|
|
|
24
24
|
</code></pre>
|
|
25
25
|
<p>Arch</p>
|
|
26
26
|
<pre><code>$ sudo pacman -S penguins-eggs
|
|
27
|
-
$ sudo pacman -U penguins-eggs_25.
|
|
27
|
+
$ sudo pacman -U penguins-eggs_25.12.7-1_amd64-1-x86_64.pkg.tar.zst
|
|
28
28
|
</code></pre>
|
|
29
29
|
<p>Debian/Devuan/Ubuntu</p>
|
|
30
30
|
<pre><code>$ sudo apt install penguins-eggs
|
|
31
|
-
$ sudo dpkg -i penguins-eggs_25.
|
|
31
|
+
$ sudo dpkg -i penguins-eggs_25.12.7-1_amd64.deb
|
|
32
32
|
</code></pre>
|
|
33
33
|
<p>Fedora</p>
|
|
34
|
-
<pre><code>$ sudo dnf install ./penguins-eggs_25.
|
|
34
|
+
<pre><code>$ sudo dnf install ./penguins-eggs_25.12.7-1_amd64-1fedora.x86_64.rpm
|
|
35
35
|
</code></pre>
|
|
36
36
|
<p>Manjaro</p>
|
|
37
37
|
<pre><code>$ sudo pamac install penguins-eggs
|
|
38
38
|
</code></pre>
|
|
39
39
|
<p>OpenMamba</p>
|
|
40
|
-
<pre><code>$ sudo dnf install ./penguins-eggs_25.
|
|
40
|
+
<pre><code>$ sudo dnf install ./penguins-eggs_25.12.7-1_amd64-1mamba.x86_64.rpm
|
|
41
41
|
</code></pre>
|
|
42
42
|
<h1>USAGE</h1>
|
|
43
43
|
<pre><code>$ eggs (-v|--version|version)
|
|
44
44
|
|
|
45
|
-
penguins-eggs/25.
|
|
45
|
+
penguins-eggs/25.12.7
|
|
46
46
|
$ eggs --help [COMMAND]
|
|
47
47
|
|
|
48
48
|
USAGE
|
|
@@ -79,7 +79,8 @@ sudo eggs dad
|
|
|
79
79
|
<li><a href="#eggs-love"><code>eggs love</code></a></li>
|
|
80
80
|
<li><a href="#eggs-mom"><code>eggs mom</code></a></li>
|
|
81
81
|
<li><a href="#eggs-produce"><code>eggs produce</code></a></li>
|
|
82
|
-
<li><a href="#eggs-setup"><code>eggs setup</code></a></li>
|
|
82
|
+
<li><a href="#eggs-setup-install"><code>eggs setup install</code></a></li>
|
|
83
|
+
<li><a href="#eggs-setup-purge"><code>eggs setup purge</code></a></li>
|
|
83
84
|
<li><a href="#eggs-status"><code>eggs status</code></a></li>
|
|
84
85
|
<li><a href="#eggs-tools-clean"><code>eggs tools clean</code></a></li>
|
|
85
86
|
<li><a href="#eggs-tools-repo"><code>eggs tools repo</code></a></li>
|
|
@@ -444,24 +445,35 @@ EXAMPLES
|
|
|
444
445
|
|
|
445
446
|
sudo eggs produce --basename=colibri
|
|
446
447
|
</code></pre>
|
|
447
|
-
<h2><code>eggs setup</code></h2>
|
|
448
|
+
<h2><code>eggs setup install</code></h2>
|
|
448
449
|
<p>Automatically check and install system prerequisites</p>
|
|
449
450
|
<pre><code>USAGE
|
|
450
|
-
$ eggs setup
|
|
451
|
+
$ eggs setup install
|
|
451
452
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
453
|
+
DESCRIPTION
|
|
454
|
+
Automatically check and install system prerequisites
|
|
455
|
+
|
|
456
|
+
EXAMPLES
|
|
457
|
+
$ eggs setup # this help
|
|
458
|
+
|
|
459
|
+
sudo eggs setup install # install native dependencies, autocomplete, man, etc
|
|
460
|
+
|
|
461
|
+
sudo eggs setup purge # purge all configurations, autocomplete, man, etc installed from penguins-eggs AppImage
|
|
462
|
+
</code></pre>
|
|
463
|
+
<h2><code>eggs setup purge</code></h2>
|
|
464
|
+
<p>Automatically check and install system prerequisites</p>
|
|
465
|
+
<pre><code>USAGE
|
|
466
|
+
$ eggs setup purge
|
|
455
467
|
|
|
456
468
|
DESCRIPTION
|
|
457
469
|
Automatically check and install system prerequisites
|
|
458
470
|
|
|
459
471
|
EXAMPLES
|
|
460
|
-
|
|
472
|
+
$ eggs setup # this help
|
|
461
473
|
|
|
462
|
-
sudo eggs setup
|
|
474
|
+
sudo eggs setup install # install native dependencies, autocomplete, man, etc
|
|
463
475
|
|
|
464
|
-
sudo eggs setup
|
|
476
|
+
sudo eggs setup purge # purge all configurations, autocomplete, man, etc installed from penguins-eggs AppImage
|
|
465
477
|
</code></pre>
|
|
466
478
|
<h2><code>eggs status</code></h2>
|
|
467
479
|
<p>informations about eggs status</p>
|