penguins-eggs 25.12.15 → 26.1.3
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 +192 -192
- package/README.md +109 -489
- package/README.pdf +3174 -19913
- package/addons/eggs/theme/applications/install-system.desktop +3 -9
- package/assets/calamares/install-system.sh +23 -22
- package/assets/penguins-krill.desktop +5 -23
- package/dist/classes/distro.js +2 -1
- package/dist/classes/incubation/incubator.js +21 -8
- package/dist/classes/ovary.d/create-xdg-autostart.d.ts +3 -3
- package/dist/classes/ovary.d/create-xdg-autostart.js +139 -149
- package/dist/classes/ovary.d/luks-home-support-systemd.d.ts +12 -0
- package/dist/classes/ovary.d/luks-home-support-systemd.js +70 -0
- package/dist/classes/ovary.d/luks-home-support.d.ts +1 -0
- package/dist/classes/ovary.d/luks-home-support.js +101 -24
- package/dist/classes/ovary.d/produce.js +2 -2
- package/dist/classes/ovary.d/user-create-live.js +6 -1
- package/dist/classes/ovary.d/xorriso-command.js +11 -21
- package/dist/classes/utils.js +3 -0
- package/dist/classes/xdg.d.ts +6 -1
- package/dist/classes/xdg.js +119 -108
- package/dist/commands/export/appimage.js +2 -1
- package/dist/commands/export/pkg.js +16 -8
- package/dist/commands/update.js +1 -1
- package/dist/krill/classes/prepare.d/users.js +6 -6
- package/dist/krill/classes/prepare.js +6 -2
- package/dist/krill/classes/sequence.d/remove-homecrypt-hack.d.ts +13 -0
- package/dist/krill/classes/sequence.d/remove-homecrypt-hack.js +65 -0
- package/dist/krill/classes/sequence.d.ts +2 -0
- package/dist/krill/classes/sequence.js +7 -2
- package/dist/krill/components/users.js +4 -4
- package/dist/krill/lib/get_userfullname.js +1 -1
- package/dist/krill/lib/get_username.js +3 -3
- package/package.json +16 -15
- package/perrisbrewery/template/dependencies.yaml +3 -0
|
@@ -15,18 +15,23 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
15
15
|
const __dirname = dirname(__filename);
|
|
16
16
|
/**
|
|
17
17
|
* Installa i file necessari per sbloccare home.img LUKS durante il boot
|
|
18
|
+
* Supporta sia Systemd (Debian/Ubuntu) che SysVinit (Devuan)
|
|
18
19
|
*/
|
|
19
20
|
export function installHomecryptSupport(squashfsRoot, homeImgPath) {
|
|
20
21
|
Utils.warning('installing encrypted home support...');
|
|
21
|
-
//
|
|
22
|
-
// console.log("homeImgPath:", homeImgPath)
|
|
23
|
-
// Leggi il template bash
|
|
22
|
+
// 1. PREPARAZIONE SCRIPT DI MONTAGGIO (Il "Motore")
|
|
24
23
|
const templatePath = path.join(__dirname, '../../../scripts/mount-encrypted-home.sh');
|
|
25
24
|
let bashScript = fs.readFileSync(templatePath, 'utf8');
|
|
26
|
-
// Sostituisci il placeholder con il path reale
|
|
27
25
|
bashScript = bashScript.replace('__HOME_IMG_PATH__', homeImgPath);
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
const mountScriptPath = path.join(squashfsRoot, 'usr/local/bin/mount-encrypted-home.sh');
|
|
27
|
+
fs.mkdirSync(path.dirname(mountScriptPath), { recursive: true });
|
|
28
|
+
fs.writeFileSync(mountScriptPath, bashScript);
|
|
29
|
+
fs.chmodSync(mountScriptPath, 0o755);
|
|
30
|
+
// ---------------------------------------------------------
|
|
31
|
+
// RAMO SYSTEMD (Invariato - funziona bene con i .service)
|
|
32
|
+
// ---------------------------------------------------------
|
|
33
|
+
if (Utils.isSystemd()) {
|
|
34
|
+
const systemdService = `[Unit]
|
|
30
35
|
Description=Unlock and mount encrypted home.img
|
|
31
36
|
DefaultDependencies=no
|
|
32
37
|
After=systemd-udev-settle.service local-fs-pre.target
|
|
@@ -48,23 +53,95 @@ ExecStop=/bin/bash -c 'umount /home && cryptsetup close live-home'
|
|
|
48
53
|
[Install]
|
|
49
54
|
WantedBy=local-fs.target
|
|
50
55
|
`;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
56
|
+
const servicePath = path.join(squashfsRoot, 'etc/systemd/system/mount-encrypted-home.service');
|
|
57
|
+
const symlinkDir = path.join(squashfsRoot, 'etc/systemd/system/local-fs.target.wants');
|
|
58
|
+
const symlinkPath = path.join(symlinkDir, 'mount-encrypted-home.service');
|
|
59
|
+
fs.mkdirSync(path.dirname(servicePath), { recursive: true });
|
|
60
|
+
fs.mkdirSync(symlinkDir, { recursive: true });
|
|
61
|
+
fs.writeFileSync(servicePath, systemdService);
|
|
62
|
+
if (fs.existsSync(symlinkPath))
|
|
63
|
+
fs.unlinkSync(symlinkPath);
|
|
64
|
+
fs.symlinkSync('../mount-encrypted-home.service', symlinkPath);
|
|
65
|
+
}
|
|
66
|
+
// ---------------------------------------------------------
|
|
67
|
+
// RAMO SYSVINIT (DEVUAN) - METODO INITTAB HIJACK
|
|
68
|
+
// ---------------------------------------------------------
|
|
69
|
+
else if (Utils.isSysvinit()) {
|
|
70
|
+
Utils.warning('Configuring SysVinit via /etc/inittab hijacking (Persistent Method)...');
|
|
71
|
+
// A. Creiamo un Wrapper Script che fa: Sblocco -> Poi lancia Login
|
|
72
|
+
// Questo script prenderà il posto di 'agetty' su tty1
|
|
73
|
+
const wrapperScript = `#!/bin/sh
|
|
74
|
+
# Wrapper per sbloccare la home prima del login su TTY1
|
|
75
|
+
|
|
76
|
+
# 1. Setup ambiente minimale
|
|
77
|
+
export TERM=linux
|
|
78
|
+
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
|
79
|
+
|
|
80
|
+
# 2. Pulizia schermo e stop Plymouth
|
|
81
|
+
clear
|
|
82
|
+
if [ -x /bin/plymouth ] && /bin/plymouth --ping; then
|
|
83
|
+
/bin/plymouth quit
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# 3. Attesa dispositivi (importante per USB)
|
|
87
|
+
echo "Waiting for devices..."
|
|
88
|
+
/sbin/udevadm settle
|
|
89
|
+
|
|
90
|
+
# 4. Esecuzione script di sblocco
|
|
91
|
+
echo "------------------------------------------------"
|
|
92
|
+
echo " CHECKING ENCRYPTED HOME STORAGE"
|
|
93
|
+
echo "------------------------------------------------"
|
|
94
|
+
/usr/local/bin/mount-encrypted-home.sh
|
|
95
|
+
|
|
96
|
+
# 5. Controllo esito (visivo)
|
|
97
|
+
if mountpoint -q /home; then
|
|
98
|
+
echo ">> Home mounted successfully."
|
|
99
|
+
sleep 1
|
|
100
|
+
else
|
|
101
|
+
echo ">> Home NOT mounted. Continuing unencrypted..."
|
|
102
|
+
sleep 2
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# 6. LANCIO DEL VERO LOGIN (Sostituisce questo processo)
|
|
106
|
+
# Nota: --noclear evita di cancellare i messaggi di errore precedenti
|
|
107
|
+
exec /sbin/agetty --noclear tty1 linux
|
|
108
|
+
`;
|
|
109
|
+
const wrapperPath = path.join(squashfsRoot, 'usr/local/bin/tty1-unlock-wrapper.sh');
|
|
110
|
+
fs.writeFileSync(wrapperPath, wrapperScript);
|
|
111
|
+
fs.chmodSync(wrapperPath, 0o755);
|
|
112
|
+
// B. Modifichiamo /etc/inittab per usare il nostro wrapper
|
|
113
|
+
const inittabPath = path.join(squashfsRoot, 'etc/inittab');
|
|
114
|
+
if (fs.existsSync(inittabPath)) {
|
|
115
|
+
let content = fs.readFileSync(inittabPath, 'utf8');
|
|
116
|
+
// La riga standard è solitamente: 1:2345:respawn:/sbin/getty 38400 tty1
|
|
117
|
+
// Oppure su Devuan: 1:2345:respawn:/sbin/agetty --noclear tty1 linux
|
|
118
|
+
// Cerchiamo qualsiasi riga che inizia con "1:" (tty1)
|
|
119
|
+
const regexTTY1 = /^1:.*$/m;
|
|
120
|
+
// La nuova riga che lancia il nostro wrapper invece di agetty diretto
|
|
121
|
+
const newLine = `1:2345:respawn:/usr/local/bin/tty1-unlock-wrapper.sh`;
|
|
122
|
+
if (regexTTY1.test(content)) {
|
|
123
|
+
content = content.replace(regexTTY1, newLine);
|
|
124
|
+
Utils.warning('Patched /etc/inittab to run home unlock on TTY1');
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// Se non la trova, la aggiungiamo in fondo (caso raro ma possibile)
|
|
128
|
+
content += `\n${newLine}\n`;
|
|
129
|
+
}
|
|
130
|
+
fs.writeFileSync(inittabPath, content);
|
|
131
|
+
}
|
|
132
|
+
// C. Pulizia vecchi tentativi (Rimuoviamo script init.d se presenti per evitare conflitti)
|
|
133
|
+
const badSymlinks = [
|
|
134
|
+
path.join(squashfsRoot, 'etc/rcS.d/S05mount-encrypted-home'),
|
|
135
|
+
path.join(squashfsRoot, 'etc/rcS.d/S20mount-encrypted-home'),
|
|
136
|
+
path.join(squashfsRoot, 'etc/rc2.d/S02mount-encrypted-home')
|
|
137
|
+
];
|
|
138
|
+
badSymlinks.forEach(link => {
|
|
139
|
+
if (fs.existsSync(link))
|
|
140
|
+
fs.unlinkSync(link);
|
|
141
|
+
});
|
|
142
|
+
// Rimuoviamo anche lo script init.d stesso se esiste, non serve più
|
|
143
|
+
const initdFile = path.join(squashfsRoot, 'etc/init.d/mount-encrypted-home');
|
|
144
|
+
if (fs.existsSync(initdFile))
|
|
145
|
+
fs.unlinkSync(initdFile);
|
|
68
146
|
}
|
|
69
|
-
fs.symlinkSync('../mount-encrypted-home.service', symlinkPath);
|
|
70
147
|
}
|
|
@@ -231,7 +231,7 @@ export async function produce(kernel = '', clone = false, homecrypt = false, ful
|
|
|
231
231
|
// mistero della Fede
|
|
232
232
|
await this.editLiveFs();
|
|
233
233
|
/**
|
|
234
|
-
* Autologin
|
|
234
|
+
* Autologin solo se per non clone
|
|
235
235
|
*/
|
|
236
236
|
if (!(this.clone || this.homecrypt || this.fullcrypt)) {
|
|
237
237
|
await this.usersRemove();
|
|
@@ -246,7 +246,7 @@ export async function produce(kernel = '', clone = false, homecrypt = false, ful
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
/**
|
|
249
|
-
* configurazione
|
|
249
|
+
* configurazione homecrypt
|
|
250
250
|
*/
|
|
251
251
|
if (this.homecrypt) {
|
|
252
252
|
// Occorre forzare il login CLI
|
|
@@ -22,7 +22,7 @@ export default async function userCreateLive() {
|
|
|
22
22
|
sysUsers.load();
|
|
23
23
|
// 2. DEFINIZIONE UTENTE LIVE
|
|
24
24
|
const username = this.settings.config.user_opt || 'live';
|
|
25
|
-
const password = 'evolution';
|
|
25
|
+
const password = this.settings.config.user_opt_passwd || 'evolution';
|
|
26
26
|
// Shell detection
|
|
27
27
|
let shell = '/bin/bash';
|
|
28
28
|
if (!fs.existsSync(path.join(target, 'bin/bash')) && fs.existsSync(path.join(target, 'bin/ash'))) {
|
|
@@ -92,4 +92,9 @@ export default async function userCreateLive() {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
console.log(`Live user '${username}' created successfully via SysUser Master.`);
|
|
95
|
+
// Importante: la password di root
|
|
96
|
+
const rootPassword = this.settings.config.root_passwd || 'evolution';
|
|
97
|
+
sysUsers.setPassword('root', rootPassword);
|
|
98
|
+
await sysUsers.save();
|
|
99
|
+
console.log(`Password of root updated successfully.`);
|
|
95
100
|
}
|
|
@@ -43,11 +43,9 @@ export async function xorrisoCommand(clone = false, homecrypt = false, fullcrypt
|
|
|
43
43
|
console.log('isoFilename:', this.settings.isoFilename);
|
|
44
44
|
const output = this.settings.config.snapshot_mnt + this.settings.isoFilename;
|
|
45
45
|
let command = '';
|
|
46
|
-
//
|
|
47
|
-
// const publisher = `-publisher "${this.settings.distro.distroId}/${this.settings.distro.codenameId}" `
|
|
48
|
-
// const preparer = '-preparer "prepared by eggs <https://penguins-eggs.net>" '
|
|
46
|
+
// Isohybrid MBR: solo se non siamo su arm64 o riscv64
|
|
49
47
|
let isoHybridMbr = '';
|
|
50
|
-
if (this.settings.config.make_isohybrid) {
|
|
48
|
+
if (this.settings.config.make_isohybrid && process.arch !== 'arm64' && process.arch !== 'riscv64') {
|
|
51
49
|
const bootloaders = Diversions.bootloaders(this.familyId);
|
|
52
50
|
const isohybridFile = path.resolve(bootloaders, `ISOLINUX/isohdpfx.bin`);
|
|
53
51
|
if (fs.existsSync(isohybridFile)) {
|
|
@@ -58,18 +56,15 @@ export async function xorrisoCommand(clone = false, homecrypt = false, fullcrypt
|
|
|
58
56
|
process.exit();
|
|
59
57
|
}
|
|
60
58
|
}
|
|
61
|
-
//
|
|
59
|
+
// Gestione parametri Bootloader x86
|
|
62
60
|
let isolinuxBin = '';
|
|
63
61
|
let isolinuxCat = '';
|
|
64
|
-
let
|
|
65
|
-
|
|
66
|
-
let bootinfotable = '';
|
|
67
|
-
if (process.arch !== 'arm64') {
|
|
62
|
+
let x86_boot_params = '';
|
|
63
|
+
if (process.arch !== 'arm64' && process.arch !== 'riscv64') {
|
|
68
64
|
isolinuxBin = `-b isolinux/isolinux.bin`;
|
|
69
65
|
isolinuxCat = `-c isolinux/boot.cat`;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
bootinfotable = '-boot-info-table';
|
|
66
|
+
// Questi sono i parametri che su RISC-V causano il fallimento di xorriso
|
|
67
|
+
x86_boot_params = '-no-emul-boot -boot-load-size 4 -boot-info-table';
|
|
73
68
|
}
|
|
74
69
|
if (Pacman.packageIsInstalled('xorriso')) {
|
|
75
70
|
let uefi_elToritoAltBoot = '';
|
|
@@ -82,14 +77,10 @@ export async function xorrisoCommand(clone = false, homecrypt = false, fullcrypt
|
|
|
82
77
|
uefi_isohybridGptBasdat = '-isohybrid-gpt-basdat';
|
|
83
78
|
uefi_noEmulBoot = '-no-emul-boot';
|
|
84
79
|
}
|
|
85
|
-
|
|
86
|
-
let luksPartitionParam = ''; // Inizializziamo la variabile per il parametro LUKS
|
|
80
|
+
let luksPartitionParam = '';
|
|
87
81
|
if (fullcrypt) {
|
|
88
|
-
// Costruiamo il percorso del file luks.img all'interno della directory di build
|
|
89
82
|
const luksImagePath = path.join(this.settings.iso_work, 'live', this.luksMappedName);
|
|
90
|
-
// Verifichiamo che il file esista prima di aggiungerlo
|
|
91
83
|
if (fs.existsSync(luksImagePath)) {
|
|
92
|
-
// Costruiamo il parametro per aggiungere la partizione 3
|
|
93
84
|
luksPartitionParam = `-append_partition 3 0x80 ${luksImagePath}`;
|
|
94
85
|
}
|
|
95
86
|
else {
|
|
@@ -97,7 +88,7 @@ export async function xorrisoCommand(clone = false, homecrypt = false, fullcrypt
|
|
|
97
88
|
process.exit();
|
|
98
89
|
}
|
|
99
90
|
}
|
|
100
|
-
//
|
|
91
|
+
// Il comando ora usa x86_boot_params che sarà vuoto su RISC-V
|
|
101
92
|
command = `xorriso -as mkisofs \
|
|
102
93
|
-J \
|
|
103
94
|
-joliet-long \
|
|
@@ -108,13 +99,12 @@ export async function xorrisoCommand(clone = false, homecrypt = false, fullcrypt
|
|
|
108
99
|
-V ${this.volid} \
|
|
109
100
|
${isolinuxBin} \
|
|
110
101
|
${isolinuxCat} \
|
|
111
|
-
|
|
112
|
-
-boot-load-size 4 \
|
|
113
|
-
-boot-info-table \
|
|
102
|
+
${x86_boot_params} \
|
|
114
103
|
${uefi_elToritoAltBoot} \
|
|
115
104
|
${uefi_e} \
|
|
116
105
|
${uefi_isohybridGptBasdat} \
|
|
117
106
|
${uefi_noEmulBoot} \
|
|
107
|
+
${luksPartitionParam} \
|
|
118
108
|
-o ${output} ${this.settings.iso_work}`;
|
|
119
109
|
}
|
|
120
110
|
return command;
|
package/dist/classes/utils.js
CHANGED
package/dist/classes/xdg.d.ts
CHANGED
|
@@ -16,7 +16,12 @@ export default class Xdg {
|
|
|
16
16
|
* @param newuser
|
|
17
17
|
* @param chroot
|
|
18
18
|
*/
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Forza l'autologin per il nuovo utente (live) su diversi Display Manager
|
|
21
|
+
* @param newuser Nome dell'utente live da loggare automaticamente
|
|
22
|
+
* @param chroot Percorso della root (default '/')
|
|
23
|
+
*/
|
|
24
|
+
static autologin(newuser: string, chroot?: string): Promise<void>;
|
|
20
25
|
/**
|
|
21
26
|
*
|
|
22
27
|
* @param user
|
package/dist/classes/xdg.js
CHANGED
|
@@ -25,128 +25,139 @@ export default class Xdg {
|
|
|
25
25
|
* @param newuser
|
|
26
26
|
* @param chroot
|
|
27
27
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Forza l'autologin per il nuovo utente (live) su diversi Display Manager
|
|
30
|
+
* @param newuser Nome dell'utente live da loggare automaticamente
|
|
31
|
+
* @param chroot Percorso della root (default '/')
|
|
32
|
+
*/
|
|
33
|
+
static async autologin(newuser, chroot = '/') {
|
|
34
|
+
if (!Pacman.isInstalledGui())
|
|
35
|
+
return;
|
|
36
|
+
/**
|
|
37
|
+
* SLIM & SLIMSKI
|
|
38
|
+
*/
|
|
39
|
+
let slimConf = '';
|
|
40
|
+
if (Pacman.packageIsInstalled('slim')) {
|
|
41
|
+
slimConf = fs.existsSync(`${chroot}/etc/slim.local.conf`) ? 'slim.local.conf' : 'slim.conf';
|
|
42
|
+
}
|
|
43
|
+
else if (Pacman.packageIsInstalled('slimski')) {
|
|
44
|
+
slimConf = fs.existsSync(`${chroot}/etc/slimski.local.conf`) ? 'slimski.local.conf' : 'slimski.conf';
|
|
45
|
+
}
|
|
46
|
+
if (slimConf !== '') {
|
|
47
|
+
let content = fs.readFileSync(`${chroot}/etc/${slimConf}`, 'utf8');
|
|
48
|
+
content = content.replace(/^#?auto_login\s+.*/m, 'auto_login yes');
|
|
49
|
+
content = content.replace(/^#?default_user\s+.*/m, `default_user ${newuser}`);
|
|
50
|
+
fs.writeFileSync(`${chroot}/etc/${slimConf}`, content, 'utf8');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* LIGHTDM
|
|
54
|
+
*/
|
|
55
|
+
else if (Pacman.packageIsInstalled('lightdm')) {
|
|
56
|
+
const confPath = `${chroot}/etc/lightdm/lightdm.conf`;
|
|
57
|
+
if (fs.existsSync(confPath)) {
|
|
58
|
+
let content = fs.readFileSync(confPath, 'utf8');
|
|
59
|
+
if (!content.includes('[Seat:*]')) {
|
|
60
|
+
content += '\n[Seat:*]\n';
|
|
39
61
|
}
|
|
62
|
+
// Rimuove eventuali righe esistenti e le aggiunge pulite sotto [Seat:*]
|
|
63
|
+
content = content.replace(/^autologin-user=.*/gm, '');
|
|
64
|
+
content = content.replace(/^autologin-user-timeout=.*/gm, '');
|
|
65
|
+
content = content.replace('[Seat:*]', `[Seat:*]\nautologin-user=${newuser}\nautologin-user-timeout=0`);
|
|
66
|
+
fs.writeFileSync(confPath, content.replace(/\n\n+/g, '\n\n'), 'utf8');
|
|
40
67
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* LXDM
|
|
71
|
+
*/
|
|
72
|
+
else if (Pacman.packageIsInstalled('lxdm')) {
|
|
73
|
+
const lxdmConf = `${chroot}/etc/lxdm/lxdm.conf`;
|
|
74
|
+
if (fs.existsSync(lxdmConf)) {
|
|
75
|
+
let content = fs.readFileSync(lxdmConf, 'utf8');
|
|
76
|
+
content = content.replace(/^#?\s*autologin=.*/m, `autologin=${newuser}`);
|
|
77
|
+
fs.writeFileSync(lxdmConf, content, 'utf8');
|
|
46
78
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
* LIGHTDM
|
|
56
|
-
*/
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* SDDM (Modern approach con file dedicato)
|
|
82
|
+
*/
|
|
83
|
+
else if (Pacman.packageIsInstalled('sddm')) {
|
|
84
|
+
const confDir = `${chroot}/etc/sddm.conf.d`;
|
|
85
|
+
if (!fs.existsSync(confDir)) {
|
|
86
|
+
fs.mkdirSync(confDir, { recursive: true });
|
|
57
87
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
for (const elem of files) {
|
|
62
|
-
const curFile = dc + elem;
|
|
63
|
-
if (!fs.statSync(`/${curFile}`).isDirectory()) {
|
|
64
|
-
let content = fs.readFileSync(curFile, 'utf8');
|
|
65
|
-
const find = '[Seat:*]';
|
|
66
|
-
if (content.includes(find)) {
|
|
67
|
-
const regex = new RegExp(`autologin-user\\s*=\\s*${olduser}`, 'g'); // remove spaces
|
|
68
|
-
content = content.replace(regex, `autologin-user=${newuser}`);
|
|
69
|
-
fs.writeFileSync(curFile, content, 'utf8');
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
88
|
+
let session = 'plasma';
|
|
89
|
+
if (Pacman.isInstalledWayland()) {
|
|
90
|
+
session = fs.existsSync(`${chroot}/usr/share/wayland-sessions/cosmic.desktop`) ? 'cosmic' : 'plasma-wayland';
|
|
73
91
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
92
|
+
const content = `[Autologin]\nUser=${newuser}\nSession=${session}\n`;
|
|
93
|
+
fs.writeFileSync(`${confDir}/eggs-autologin.conf`, content, 'utf8');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* GDM / GDM3 (Pop!_OS, Ubuntu, Debian)
|
|
97
|
+
*/
|
|
98
|
+
else if (Pacman.packageIsInstalled('gdm') || Pacman.packageIsInstalled('gdm3')) {
|
|
99
|
+
let gdmFile = '';
|
|
100
|
+
const possiblePaths = [
|
|
101
|
+
`${chroot}/etc/gdm3/daemon.conf`,
|
|
102
|
+
`${chroot}/etc/gdm3/custom.conf`,
|
|
103
|
+
`${chroot}/etc/gdm/custom.conf`
|
|
104
|
+
];
|
|
105
|
+
for (const p of possiblePaths) {
|
|
106
|
+
if (fs.existsSync(p)) {
|
|
107
|
+
gdmFile = p;
|
|
108
|
+
break;
|
|
81
109
|
}
|
|
82
110
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
let content = fs.readFileSync(curFile, 'utf8');
|
|
91
|
-
const find = '[Autologin]';
|
|
92
|
-
if (content.includes(find)) {
|
|
93
|
-
const regex = new RegExp(`User\\s*=\\s*${olduser}`, 'g'); // replace space
|
|
94
|
-
content = content.replace(regex, `User=${newuser}`);
|
|
95
|
-
fs.writeFileSync(curFile, content, 'utf8');
|
|
96
|
-
sddmChanged = true;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (!sddmChanged) {
|
|
100
|
-
const dc = `${chroot}/etc/sddm.conf.d/`;
|
|
101
|
-
if (fs.existsSync(dc)) {
|
|
102
|
-
const files = fs.readdirSync(dc);
|
|
103
|
-
for (const elem of files) {
|
|
104
|
-
const curFile = dc + elem;
|
|
105
|
-
let content = fs.readFileSync(curFile, 'utf8');
|
|
106
|
-
const find = '[Autologin]';
|
|
107
|
-
if (content.includes(find)) {
|
|
108
|
-
const regex = new RegExp(`User\\s*=\\s*${olduser}`, 'g'); // replace space
|
|
109
|
-
content = content.replace(regex, `User=${newuser}`);
|
|
110
|
-
fs.writeFileSync(curFile, content, 'utf8');
|
|
111
|
-
sddmChanged = true;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
111
|
+
if (gdmFile) {
|
|
112
|
+
let content = fs.readFileSync(gdmFile, 'utf8');
|
|
113
|
+
if (!content.includes('[daemon]'))
|
|
114
|
+
content = "[daemon]\n" + content;
|
|
115
|
+
// Abilitazione chirurgica
|
|
116
|
+
if (content.match(/^#?AutomaticLoginEnable=.*/m)) {
|
|
117
|
+
content = content.replace(/^#?AutomaticLoginEnable=.*/m, 'AutomaticLoginEnable=true');
|
|
115
118
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
let session = 'plasma';
|
|
119
|
-
if (Pacman.isInstalledWayland()) {
|
|
120
|
-
session = 'plasma-wayland';
|
|
121
|
-
}
|
|
122
|
-
const content = `[Autologin]\nUser=${newuser}\nSession=${session}\n`;
|
|
123
|
-
const curFile = `${chroot}/etc/sddm.conf`;
|
|
124
|
-
fs.writeFileSync(curFile, content, 'utf8');
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
else if (Pacman.packageIsInstalled('gdm') || Pacman.packageIsInstalled('gdm3')) {
|
|
128
|
-
/**
|
|
129
|
-
* GDM/GDM3
|
|
130
|
-
* in manjaro è /etc/gdm/custom.conf
|
|
131
|
-
*/
|
|
132
|
-
let gdmConf = `${chroot}/etc/gdm3`;
|
|
133
|
-
if (Pacman.packageIsInstalled('gdm3')) {
|
|
134
|
-
gdmConf = `${chroot}/etc/gdm3`;
|
|
119
|
+
else {
|
|
120
|
+
content = content.replace('[daemon]', '[daemon]\nAutomaticLoginEnable=true');
|
|
135
121
|
}
|
|
136
|
-
|
|
137
|
-
|
|
122
|
+
if (content.match(/^#?AutomaticLogin=.*/m)) {
|
|
123
|
+
content = content.replace(/^#?AutomaticLogin=.*/m, `AutomaticLogin=${newuser}`);
|
|
138
124
|
}
|
|
139
|
-
|
|
140
|
-
|
|
125
|
+
else {
|
|
126
|
+
content = content.replace('AutomaticLoginEnable=true', `AutomaticLoginEnable=true\nAutomaticLogin=${newuser}`);
|
|
141
127
|
}
|
|
142
|
-
|
|
143
|
-
|
|
128
|
+
fs.writeFileSync(gdmFile, content, 'utf8');
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* GREETD / COSMIC (Pop!_OS COSMIC)
|
|
132
|
+
*/
|
|
133
|
+
}
|
|
134
|
+
else if (Pacman.packageIsInstalled('greetd')) {
|
|
135
|
+
const greetdPath = `${chroot}/etc/greetd/cosmic-greeter.toml`;
|
|
136
|
+
// Se esiste la configurazione specifica di COSMIC
|
|
137
|
+
if (fs.existsSync(greetdPath)) {
|
|
138
|
+
let content = fs.readFileSync(greetdPath, 'utf8');
|
|
139
|
+
// Se la sezione [initial_session] esiste già, la aggiorniamo, altrimenti la aggiungiamo
|
|
140
|
+
const initialSessionRegex = /\[initial_session\][^\[]*/;
|
|
141
|
+
const newInitialSession = `[initial_session]\ncommand = "start-cosmic"\nuser = "${newuser}"\n\n`;
|
|
142
|
+
if (initialSessionRegex.test(content)) {
|
|
143
|
+
content = content.replace(initialSessionRegex, newInitialSession);
|
|
144
144
|
}
|
|
145
145
|
else {
|
|
146
|
-
|
|
146
|
+
// La aggiungiamo in testa o dopo la sezione general
|
|
147
|
+
content = newInitialSession + content;
|
|
148
|
+
}
|
|
149
|
+
fs.writeFileSync(greetdPath, content, 'utf8');
|
|
150
|
+
}
|
|
151
|
+
// Fallback per greetd standard (config.toml) se non è COSMIC specifico
|
|
152
|
+
else if (fs.existsSync(`${chroot}/etc/greetd/config.toml`)) {
|
|
153
|
+
const configPath = `${chroot}/etc/greetd/config.toml`;
|
|
154
|
+
let content = fs.readFileSync(configPath, 'utf8');
|
|
155
|
+
// Configurazione per il login automatico su greetd generico
|
|
156
|
+
const autologinConfig = `[initial_session]\ncommand = "start-cosmic"\nuser = "${newuser}"\n`;
|
|
157
|
+
if (!content.includes('[initial_session]')) {
|
|
158
|
+
content = autologinConfig + content;
|
|
159
|
+
fs.writeFileSync(configPath, content, 'utf8');
|
|
147
160
|
}
|
|
148
|
-
const content = `[daemon]\nAutomaticLoginEnable=true\nAutomaticLogin=${newuser}\n`;
|
|
149
|
-
Utils.write(gdmConf, content);
|
|
150
161
|
}
|
|
151
162
|
}
|
|
152
163
|
}
|
|
@@ -46,7 +46,8 @@ export default class ExportAppimage extends Command {
|
|
|
46
46
|
const remoteMountpoint = `/tmp/eggs-${(Math.random() + 1).toString(36).slice(7)}`;
|
|
47
47
|
let localPath = "$HOME/penguins-eggs";
|
|
48
48
|
let remotePath = "/eggs/";
|
|
49
|
-
let filter = `penguins-eggs
|
|
49
|
+
let filter = `penguins-eggs-+([0-9.])-*.AppImage`;
|
|
50
|
+
//let filter = `penguins-eggs-[0-9][0-9].[0-9]*.[0-9]*-*.AppImage`
|
|
50
51
|
let cmd = `#!/bin/bash\n`;
|
|
51
52
|
cmd += `set -e\n`;
|
|
52
53
|
cmd += 'shopt -s extglob\n';
|
|
@@ -63,7 +63,8 @@ export default class ExportPkg extends Command {
|
|
|
63
63
|
Utils.warning(`exporting Alpine APK packages`);
|
|
64
64
|
localPath = `/home/${this.user}/packages/aports/${arch}`;
|
|
65
65
|
remotePath = `${this.Tu.config.remotePathPackages}/alpine/${arch}`;
|
|
66
|
-
filter = `penguins-eggs
|
|
66
|
+
filter = `penguins-eggs-+([0-9.])-*.apk`;
|
|
67
|
+
// filter = `penguins-eggs-*[0-9][0-9].@([0-9]|[0-1][0-9]).@([0-9]|[0-3][0-9])-*.apk`
|
|
67
68
|
/**
|
|
68
69
|
* Arch/Manjaro
|
|
69
70
|
*/
|
|
@@ -76,7 +77,8 @@ export default class ExportPkg extends Command {
|
|
|
76
77
|
Utils.warning(`exporting Manjaro .pkg.tar.zst packages`);
|
|
77
78
|
localPath = `/home/${this.user}/penguins-packs/manjaro/penguins-eggs`;
|
|
78
79
|
remotePath = this.Tu.config.remotePathPackages + "/manjaro";
|
|
79
|
-
filter = `penguins-eggs
|
|
80
|
+
filter = `penguins-eggs-+([0-9.])-*-any.pkg.tar.*`;
|
|
81
|
+
// filter = `penguins-eggs-[0-9][0-9].@([0-9]|[0-1][0-9]).@([0-9]|[0-3][0-9])-*-any.pkg.tar.*`
|
|
80
82
|
/**
|
|
81
83
|
* Arch
|
|
82
84
|
*/
|
|
@@ -85,7 +87,8 @@ export default class ExportPkg extends Command {
|
|
|
85
87
|
Utils.warning(`exporting Arch .pkg.tar.zst packages`);
|
|
86
88
|
localPath = `/home/${this.user}/penguins-packs/aur/penguins-eggs`;
|
|
87
89
|
remotePath = this.Tu.config.remotePathPackages + "/aur";
|
|
88
|
-
filter = `penguins-eggs
|
|
90
|
+
filter = `penguins-eggs-+([0-9.])-*-any.pkg.tar.zst`;
|
|
91
|
+
//filter = `penguins-eggs-[0-9][0-9].@([0-9]|[0-1][0-9]).@([0-9]|[0-3][0-9])-*-any.pkg.tar.zst`
|
|
89
92
|
}
|
|
90
93
|
/**
|
|
91
94
|
* Debian
|
|
@@ -99,7 +102,8 @@ export default class ExportPkg extends Command {
|
|
|
99
102
|
if (this.all) {
|
|
100
103
|
arch = '*';
|
|
101
104
|
}
|
|
102
|
-
filter = `penguins-eggs_[0-9][0-9].@([0-9]|[0-1][0-9]).@([0-9]|[0-3][0-9])-*_${arch}.deb
|
|
105
|
+
//filter = `penguins-eggs_[0-9][0-9].@([0-9]|[0-1][0-9]).@([0-9]|[0-3][0-9])-*_${arch}.deb`
|
|
106
|
+
filter = `penguins-eggs-+([0-9.])-*${arch}.deb`;
|
|
103
107
|
/**
|
|
104
108
|
* fedora
|
|
105
109
|
*/
|
|
@@ -111,12 +115,13 @@ export default class ExportPkg extends Command {
|
|
|
111
115
|
if (distro.distroId !== 'Fedora') {
|
|
112
116
|
repo = 'el9';
|
|
113
117
|
ftype = `el?`;
|
|
114
|
-
warning = `exporting Almalinux/Rocky RPM packages`;
|
|
118
|
+
warning = `exporting Almalinux/RHEL/Rocky RPM packages`;
|
|
115
119
|
}
|
|
116
|
-
filter = `penguins-eggs-[0-9][0-9].[0-9]*.[0-9]*-*.${ftype}.x86_64.rpm`;
|
|
117
120
|
Utils.warning(warning);
|
|
118
121
|
localPath = `/home/${this.user}/rpmbuild/RPMS/x86_64`;
|
|
119
122
|
remotePath = this.Tu.config.remotePathPackages + `/` + repo;
|
|
123
|
+
filter = `penguins-eggs-+([0-9.])-*.${ftype}.x86_64.rpm`;
|
|
124
|
+
//filter = `penguins-eggs-[0-9][0-9].[0-9]*.[0-9]*-*.${ftype}.x86_64.rpm`
|
|
120
125
|
/**
|
|
121
126
|
* openmamba
|
|
122
127
|
*/
|
|
@@ -125,7 +130,8 @@ export default class ExportPkg extends Command {
|
|
|
125
130
|
Utils.warning(`exporting Openmamba RPM packages`);
|
|
126
131
|
localPath = `/home/${this.user}/rpmbuild/RPMS/x86_64`;
|
|
127
132
|
remotePath = this.Tu.config.remotePathPackages + "/openmamba";
|
|
128
|
-
filter = `penguins-eggs
|
|
133
|
+
filter = `penguins-eggs-+([0-9.])-*.mamba.*.rpm`;
|
|
134
|
+
// filter = `penguins-eggs-[0-9][0-9].@([0-9]|[0-1][0-9]).@([0-9]|[0-3][0-9])-*mamba.*.rpm`
|
|
129
135
|
/**
|
|
130
136
|
* opensuse
|
|
131
137
|
*/
|
|
@@ -134,7 +140,8 @@ export default class ExportPkg extends Command {
|
|
|
134
140
|
Utils.warning(`exporting OpenSuSE RPM packages`);
|
|
135
141
|
localPath = `/home/${this.user}/rpmbuild/RPMS/x86_64`;
|
|
136
142
|
remotePath = this.Tu.config.remotePathPackages + "/opensuse";
|
|
137
|
-
filter = `penguins-eggs
|
|
143
|
+
filter = `penguins-eggs-+([0-9.])-*.rpm`;
|
|
144
|
+
// filter = `penguins-eggs-[0-9][0-9].[0-9]*.[0-9]*-*.opensuse.x86_64.rpm`
|
|
138
145
|
}
|
|
139
146
|
let cmd = `#!/bin/bash\n`;
|
|
140
147
|
cmd += `set -e\n`;
|
|
@@ -154,6 +161,7 @@ export default class ExportPkg extends Command {
|
|
|
154
161
|
cmd += `rm -f ${remoteMountpoint}/${archDest}${filter}\n`;
|
|
155
162
|
}
|
|
156
163
|
cmd += `# Export packages\n`;
|
|
164
|
+
cmd += `shopt -s extglob\n`;
|
|
157
165
|
cmd += `cp ${localPath}/${filter} ${remoteMountpoint}\n`;
|
|
158
166
|
cmd += 'sync\n';
|
|
159
167
|
cmd += `\n`;
|
package/dist/commands/update.js
CHANGED
|
@@ -167,7 +167,7 @@ export default class Update extends Command {
|
|
|
167
167
|
}
|
|
168
168
|
else if (this.distro.familyId === "debian") {
|
|
169
169
|
repo = 'debs';
|
|
170
|
-
filter = `penguins-
|
|
170
|
+
filter = `penguins-eggs-??.*.*-?_${Utils.uefiArch()}.deb`;
|
|
171
171
|
copy = `scp ${Tu.config.remoteUser}@${Tu.config.remoteHost}:${Tu.config.remotePathPackages}/${repo}/${filter} /tmp`;
|
|
172
172
|
install = `apt reinstall /tmp/${filter}`;
|
|
173
173
|
/**
|