penguins-eggs 25.11.29 → 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 +1 -1
- package/README.md +72 -110
- package/README.pdf +11041 -10623
- package/conf/derivatives.yaml +2 -1
- package/conf/exclude.list.d/var.list +11 -6
- package/dist/appimage/dependency-manager.js +1 -1
- package/dist/classes/cli-autologin.js +77 -52
- package/dist/classes/compressors.d.ts +7 -10
- package/dist/classes/compressors.js +44 -31
- package/dist/classes/distro.js +2 -2
- package/dist/classes/diversions.js +2 -3
- package/dist/classes/incubation/fisherman-helper/initcpio.d.ts +2 -5
- package/dist/classes/incubation/fisherman-helper/initcpio.js +7 -4
- package/dist/classes/incubation/fisherman-helper/settings.js +1 -1
- package/dist/classes/incubation/fisherman.js +1 -1
- package/dist/classes/incubation/incubator.js +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 +129 -135
- 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.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 +0 -5
- package/dist/classes/pacman.js +3 -16
- 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 +15 -6
- package/dist/classes/utils.js +79 -46
- package/dist/classes/xdg.js +1 -1
- package/dist/classes/yolk.js +2 -4
- 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/install.js +1 -1
- package/dist/commands/setup/purge.js +1 -1
- package/dist/commands/tools/yolk.js +1 -1
- package/dist/commands/update.js +1 -2
- 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 +2 -2
- 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 -20
- package/manpages/doc/man/eggs.1.gz +0 -0
- package/manpages/doc/man/eggs.html +8 -8
- package/package.json +9 -9
- package/perrisbrewery/template/dependencies.yaml +1 -0
- package/scripts/boot-encrypted-root.sh +220 -0
- package/scripts/mount-encrypted-home.sh +324 -0
- 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
|
@@ -1,77 +1,107 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ./src/krill/
|
|
2
|
+
* ./src/krill/classes/secquence.d/add-user.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
4
|
+
* * REFACTORED: Uses "The SysUser Master" class.
|
|
5
|
+
* Replaces chroot/binary dependencies with pure Node.js manipulation.
|
|
8
6
|
*/
|
|
9
|
-
import
|
|
7
|
+
import SysUsers from '../../../classes/sys-users.js';
|
|
8
|
+
import { exec } from '../../../lib/utils.js';
|
|
10
9
|
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
11
|
import yaml from 'js-yaml';
|
|
12
|
-
import { exec } from '../../../lib/utils.js';
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
* @param this
|
|
16
|
-
* @param username
|
|
17
|
-
* @param password
|
|
18
|
-
* @param fullusername
|
|
19
|
-
* @param roomNumber
|
|
20
|
-
* @param workPhone
|
|
21
|
-
* @param homePhone
|
|
22
|
-
*/
|
|
23
12
|
export default async function addUser(username = 'live', password = 'evolution', fullusername = '', roomNumber = '', workPhone = '', homePhone = '') {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
else if (this.distro.familyId === 'opensuse') {
|
|
36
|
-
cmd = `chroot ${this.installTarget} useradd ${username} --create-home --shell /bin/bash --comment "${fullusername},${roomNumber},${workPhone},${homePhone}" ${this.toNull}`;
|
|
13
|
+
const target = this.installTarget;
|
|
14
|
+
const familyId = this.distro.familyId;
|
|
15
|
+
// --- 1. INIZIALIZZAZIONE SYSUSERS ---
|
|
16
|
+
const sysUsers = new SysUsers(target, familyId);
|
|
17
|
+
sysUsers.load(); // Carica passwd, shadow, group in memoria
|
|
18
|
+
console.log(`Creating user ${username} via SysUsers (Safe Mode)...`);
|
|
19
|
+
// --- 2. PREPARAZIONE DATI ---
|
|
20
|
+
// Shell detection (Fallback per Alpine/Minimal)
|
|
21
|
+
let shell = '/bin/bash';
|
|
22
|
+
if (!fs.existsSync(path.join(target, 'bin/bash')) && fs.existsSync(path.join(target, 'bin/ash'))) {
|
|
23
|
+
shell = '/bin/ash';
|
|
37
24
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
// Definizione oggetto utente
|
|
26
|
+
const newUser = {
|
|
27
|
+
username: username,
|
|
28
|
+
password: 'x',
|
|
29
|
+
uid: '1000', // Hardcoded per il primo utente (standard installer)
|
|
30
|
+
gid: '1000',
|
|
31
|
+
gecos: `${fullusername},${roomNumber},${workPhone},${homePhone}`,
|
|
32
|
+
home: `/home/${username}`,
|
|
33
|
+
shell: shell
|
|
34
|
+
};
|
|
35
|
+
// --- 3. MODIFICHE LOGICHE (IN MEMORIA) ---
|
|
36
|
+
// Aggiunge l'utente (gestisce passwd, shadow, group primario, subuid)
|
|
37
|
+
sysUsers.addUser(newUser, password);
|
|
38
|
+
// Aggiungi ai gruppi amministrativi (logica distro)
|
|
39
|
+
let adminGroup = 'wheel';
|
|
40
|
+
if (['debian', 'ubuntu', 'linuxmint', 'pop', 'neon'].includes(familyId)) {
|
|
41
|
+
adminGroup = 'sudo';
|
|
44
42
|
}
|
|
45
|
-
else if (
|
|
46
|
-
|
|
43
|
+
else if (familyId === 'openmamba') {
|
|
44
|
+
adminGroup = 'sysadmin';
|
|
47
45
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// add autologin group in archlinux
|
|
51
|
-
await exec(cmd, this.echo);
|
|
52
|
-
if (this.distro.familyId === 'archlinux') {
|
|
53
|
-
await exec(`chroot ${this.installTarget} getent group autologin || groupadd autologin`);
|
|
54
|
-
await exec(`chroot ${this.installTarget} usermod -aG autologin ${username}`);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* look to calamares/modules/users.conf for groups
|
|
58
|
-
*/
|
|
46
|
+
sysUsers.addUserToGroup(username, adminGroup);
|
|
47
|
+
// Aggiungi ai gruppi definiti in Calamares/Eggs config
|
|
59
48
|
let usersConf = '/etc/calamares/modules/users.conf';
|
|
60
49
|
if (!fs.existsSync(usersConf)) {
|
|
61
50
|
usersConf = '/etc/penguins-eggs.d/krill/modules/users.conf';
|
|
62
51
|
}
|
|
63
52
|
if (fs.existsSync(usersConf)) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
53
|
+
try {
|
|
54
|
+
const content = fs.readFileSync(usersConf, 'utf8');
|
|
55
|
+
const o = yaml.load(content);
|
|
56
|
+
if (o && o.defaultGroups) {
|
|
57
|
+
for (const grp of o.defaultGroups) {
|
|
58
|
+
sysUsers.addUserToGroup(username, grp);
|
|
59
|
+
}
|
|
70
60
|
}
|
|
71
61
|
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
console.error('Warning: Error parsing users.conf, skipping extra groups.', e);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Fix specifico Archlinux (Autologin)
|
|
67
|
+
if (familyId === 'archlinux') {
|
|
68
|
+
sysUsers.addUserToGroup(username, 'autologin');
|
|
69
|
+
}
|
|
70
|
+
// --- 4. SALVATAGGIO ATOMICO SU DISCO ---
|
|
71
|
+
// Scrive tutti i file di config e applica chcon (SELinux) se necessario
|
|
72
|
+
await sysUsers.save();
|
|
73
|
+
// --- 5. CREAZIONE FISICA HOME DIRECTORY ---
|
|
74
|
+
// Queste operazioni toccano il filesystem reale, quindi usiamo exec/fs
|
|
75
|
+
const homeDir = path.join(target, newUser.home);
|
|
76
|
+
// Cleanup preventivo
|
|
77
|
+
await exec(`rm -rf ${homeDir}`, this.echo);
|
|
78
|
+
// Creazione da /etc/skel
|
|
79
|
+
const skelPath = path.join(target, 'etc', 'skel');
|
|
80
|
+
if (fs.existsSync(skelPath)) {
|
|
81
|
+
await exec(`mkdir -p ${homeDir}`, this.echo);
|
|
82
|
+
await exec(`cp -rT ${skelPath} ${homeDir}`, this.echo);
|
|
72
83
|
}
|
|
73
84
|
else {
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
await exec(`mkdir -p ${homeDir}`, this.echo);
|
|
86
|
+
}
|
|
87
|
+
// Permessi e Proprietario
|
|
88
|
+
await exec(`chown -R ${newUser.uid}:${newUser.gid} ${homeDir}`, this.echo);
|
|
89
|
+
// Privacy: 700 è meglio di 755 per la home utente
|
|
90
|
+
await exec(`chmod 700 ${homeDir}`, this.echo);
|
|
91
|
+
// --- 6. FIX SELINUX FINALE (HOME & RELABEL) ---
|
|
92
|
+
// SysUsers ha sistemato /etc/*, ma la home directory è appena stata creata
|
|
93
|
+
// e potrebbe avere contesti errati.
|
|
94
|
+
if (['fedora', 'rhel', 'centos', 'almalinux', 'rocky'].includes(familyId)) {
|
|
95
|
+
try {
|
|
96
|
+
console.log('Applying SELinux contexts to home directory...');
|
|
97
|
+
// Fix contesto home
|
|
98
|
+
await exec(`chcon -R -t user_home_t ${homeDir}`, { echo: false }).catch(() => { });
|
|
99
|
+
// Fix "Nuclear Option": forza relabel al boot se qualcosa fosse sfuggito
|
|
100
|
+
await exec(`touch ${target}/.autorelabel`, { echo: false });
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
console.error('SELinux home fix warning:', e);
|
|
104
|
+
}
|
|
76
105
|
}
|
|
106
|
+
console.log(`User ${username} successfully configured via SysUser Master.`);
|
|
77
107
|
}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* src/krill/modules/change-password.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
4
|
+
* * REFACTORED: Uses "The SysUser Master" class.
|
|
5
|
+
* Changes user password directly in /etc/shadow safely (No binaries, SELinux safe).
|
|
8
6
|
*/
|
|
9
7
|
import Sequence from '../sequence.js';
|
|
10
8
|
/**
|
|
11
9
|
* changePassword
|
|
12
|
-
* @param name
|
|
13
|
-
* @param newPassword
|
|
10
|
+
* @param name - Username to update
|
|
11
|
+
* @param newPassword - New plain text password
|
|
14
12
|
*/
|
|
15
13
|
export default function changePassword(this: Sequence, name?: string, newPassword?: string): Promise<void>;
|
|
@@ -1,18 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* src/krill/modules/change-password.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
4
|
+
* * REFACTORED: Uses "The SysUser Master" class.
|
|
5
|
+
* Changes user password directly in /etc/shadow safely (No binaries, SELinux safe).
|
|
8
6
|
*/
|
|
9
|
-
import
|
|
7
|
+
import SysUsers from '../../../classes/sys-users.js';
|
|
8
|
+
import fs from 'fs';
|
|
10
9
|
/**
|
|
11
10
|
* changePassword
|
|
12
|
-
* @param name
|
|
13
|
-
* @param newPassword
|
|
11
|
+
* @param name - Username to update
|
|
12
|
+
* @param newPassword - New plain text password
|
|
14
13
|
*/
|
|
15
14
|
export default async function changePassword(name = 'live', newPassword = 'evolution') {
|
|
16
|
-
const
|
|
17
|
-
|
|
15
|
+
const target = this.installTarget;
|
|
16
|
+
const familyId = this.distro.familyId;
|
|
17
|
+
console.log(`Changing password for user '${name}' via SysUsers...`);
|
|
18
|
+
// 1. CARICAMENTO
|
|
19
|
+
// Se non esiste il target (caso strano), usciamo
|
|
20
|
+
if (!fs.existsSync(target)) {
|
|
21
|
+
console.error(`Error: Target ${target} not found for password change.`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const sysUsers = new SysUsers(target, familyId);
|
|
25
|
+
sysUsers.load();
|
|
26
|
+
// 2. MODIFICA (In Memoria)
|
|
27
|
+
// La classe SysUsers ha già il metodo setPassword che usa bcryptjs
|
|
28
|
+
// e aggiorna il timestamp di lastChange.
|
|
29
|
+
sysUsers.setPassword(name, newPassword);
|
|
30
|
+
// 3. SALVATAGGIO (Atomico + SELinux Fix)
|
|
31
|
+
await sysUsers.save();
|
|
32
|
+
console.log(`Password updated for '${name}'.`);
|
|
18
33
|
}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* src/krill/classes/sequence.d/del_live_user.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
4
|
+
* * REFACTORED: Uses "The SysUser Master" class.
|
|
5
|
+
* Removes the live user from the installed target safely (SELinux friendly).
|
|
8
6
|
*/
|
|
9
7
|
import Sequence from '../sequence.js';
|
|
10
8
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* delLiveUser
|
|
10
|
+
* Rimuove l'utente live dal sistema installato (target)
|
|
13
11
|
*/
|
|
14
12
|
export default function delLiveUser(this: Sequence): Promise<void>;
|
|
@@ -1,39 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* src/krill/classes/sequence.d/del_live_user.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
4
|
+
* * REFACTORED: Uses "The SysUser Master" class.
|
|
5
|
+
* Removes the live user from the installed target safely (SELinux friendly).
|
|
8
6
|
*/
|
|
7
|
+
import SysUsers from '../../../classes/sys-users.js';
|
|
9
8
|
import Utils from '../../../classes/utils.js';
|
|
10
9
|
import { exec } from '../../../lib/utils.js';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* delLiveUser
|
|
14
|
+
* Rimuove l'utente live dal sistema installato (target)
|
|
14
15
|
*/
|
|
15
16
|
export default async function delLiveUser() {
|
|
17
|
+
// Eseguiamo solo se siamo in modalità live (ovvero stiamo installando da una ISO)
|
|
16
18
|
if (Utils.isLive()) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
// Recuperiamo il nome utente live (default: 'live' o quello impostato in build)
|
|
20
|
+
const liveUsername = this.settings.config.user_opt || 'live';
|
|
21
|
+
const target = this.installTarget;
|
|
22
|
+
const familyId = this.distro.familyId;
|
|
23
|
+
console.log(`Removing live user '${liveUsername}' from target via SysUsers...`);
|
|
24
|
+
// --- 1. CARICAMENTO CONFIGURAZIONE ---
|
|
25
|
+
// Istanziamo il nostro "Master" puntando alla root del sistema installato
|
|
26
|
+
const sysUsers = new SysUsers(target, familyId);
|
|
27
|
+
sysUsers.load();
|
|
28
|
+
// --- 2. RIMOZIONE LOGICA (IN MEMORIA) ---
|
|
29
|
+
// Rimuove l'utente da passwd, shadow, group e dai membri dei gruppi extra
|
|
30
|
+
sysUsers.removeUser(liveUsername);
|
|
31
|
+
// --- 3. SALVATAGGIO ATOMICO ---
|
|
32
|
+
// Scrive i file fisici e ripristina i contesti SELinux in un colpo solo
|
|
33
|
+
await sysUsers.save();
|
|
34
|
+
// --- 4. PULIZIA FILESYSTEM (File non gestiti da SysUsers) ---
|
|
35
|
+
// a) Home Directory
|
|
36
|
+
const homeDir = path.join(target, 'home', liveUsername);
|
|
37
|
+
if (fs.existsSync(homeDir)) {
|
|
38
|
+
await exec(`rm -rf ${homeDir}`, this.echo);
|
|
23
39
|
}
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
// b) File Sudoers (spesso creato in /etc/sudoers.d/)
|
|
41
|
+
const sudoersFile = path.join(target, 'etc', 'sudoers.d', liveUsername);
|
|
42
|
+
if (fs.existsSync(sudoersFile)) {
|
|
43
|
+
fs.unlinkSync(sudoersFile);
|
|
44
|
+
console.log(`Removed sudoers file: ${sudoersFile}`);
|
|
26
45
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
this.distro.familyId === 'fedora' ||
|
|
32
|
-
this.distro.familyId === 'opensuse') {
|
|
33
|
-
cmd = `chroot ${this.installTarget} sudo userdel -r ${user} ${this.toNull}`;
|
|
34
|
-
}
|
|
35
|
-
await exec(cmd, this.echo);
|
|
36
|
-
}
|
|
46
|
+
// c) Mail spool
|
|
47
|
+
const mailFile = path.join(target, 'var', 'mail', liveUsername);
|
|
48
|
+
if (fs.existsSync(mailFile)) {
|
|
49
|
+
fs.unlinkSync(mailFile);
|
|
37
50
|
}
|
|
51
|
+
console.log(`Live user '${liveUsername}' removed successfully via SysUser Master.`);
|
|
38
52
|
}
|
|
39
53
|
}
|
|
@@ -6,7 +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 shx from '
|
|
9
|
+
import { shx } from '../../../lib/utils.js';
|
|
10
10
|
import { InstallationMode } from '../krill_enums.js';
|
|
11
11
|
import Utils from '../../../classes/utils.js';
|
|
12
12
|
import { SwapChoice } from '../krill_enums.js';
|
|
@@ -1,17 +1,13 @@
|
|
|
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 Sequence from '../../classes/sequence.js';
|
|
10
7
|
/**
|
|
11
8
|
* grubcfg
|
|
12
9
|
* - open /etc/default/grub
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
15
|
-
* 's/GRUB_CMDLINE_LINUX_DEFAULT=.*$/GRUB_CMDLINE_LINUX_DEFAULT=/g'
|
|
10
|
+
* - handle BTRFS/LUKS settings
|
|
11
|
+
* - inject enforcing=0 for Fedora/RHEL to allow autorelabel on first boot
|
|
16
12
|
*/
|
|
17
13
|
export default function grubcfg(this: Sequence): Promise<void>;
|
|
@@ -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
|
}
|
|
@@ -15,13 +15,13 @@ const pjson = require('../../../package.json');
|
|
|
15
15
|
export default function Title({ title = "", version = "" }) {
|
|
16
16
|
let type = "";
|
|
17
17
|
if (!Utils.isAppImage()) {
|
|
18
|
-
type = "native";
|
|
18
|
+
type = " native";
|
|
19
19
|
}
|
|
20
20
|
if (title === "")
|
|
21
21
|
title = `${pjson.name}`;
|
|
22
22
|
let green = ` ${title}`.padEnd(25, " ");
|
|
23
23
|
let white = ` Perri's brewery edition `.padEnd(25, " ");
|
|
24
|
-
let red = ` v${pjson.version}
|
|
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 {};
|