penguins-eggs 25.10.26 → 25.10.30

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.
Files changed (36) hide show
  1. package/.oclif.manifest.json +1 -1
  2. package/README.md +1 -768
  3. package/addons/eggs/theme/applications/install-system.desktop +8 -6
  4. package/addons/eggs/theme/livecd/generic.grub.theme.cfg +1 -3
  5. package/addons/eggs/theme/livecd/generic.isolinux.theme.cfg +1 -2
  6. package/assets/calamares/io.calamares.calamares.policy +25 -0
  7. package/dist/classes/daddy.js +7 -3
  8. package/dist/classes/incubation/customize/customize-partitions.d.ts +9 -1
  9. package/dist/classes/incubation/customize/customize-partitions.js +10 -2
  10. package/dist/classes/incubation/incubator.d.ts +1 -0
  11. package/dist/classes/incubation/incubator.js +16 -11
  12. package/dist/classes/ovary.d/create-xdg-autostart.js +6 -7
  13. package/dist/classes/ovary.d/luks-get-password.d.ts +1 -1
  14. package/dist/classes/ovary.d/luks-get-password.js +1 -1
  15. package/dist/classes/ovary.d/luks-helpers.d.ts +19 -0
  16. package/dist/classes/ovary.d/luks-helpers.js +73 -0
  17. package/dist/classes/ovary.d/luks-home-support.js +1 -6
  18. package/dist/classes/ovary.d/luks-home.js +7 -34
  19. package/dist/classes/ovary.d/luks-interactive-crypto-config.js +5 -1
  20. package/dist/classes/ovary.d/luks-root-initrd.d.ts +1 -1
  21. package/dist/classes/ovary.d/luks-root-initrd.js +1 -1
  22. package/dist/classes/ovary.d/luks-root.d.ts +1 -1
  23. package/dist/classes/ovary.d/luks-root.js +8 -70
  24. package/dist/classes/ovary.d/make-efi.js +9 -3
  25. package/dist/classes/ovary.d/produce.js +1 -6
  26. package/dist/classes/ovary.d/syslinux.js +5 -1
  27. package/dist/classes/ovary.d/xorriso-command.js +5 -0
  28. package/dist/classes/ovary.d.ts +3 -0
  29. package/dist/classes/ovary.js +3 -0
  30. package/dist/classes/pacman.d/alpine.js +1 -1
  31. package/dist/classes/pacman.d/debian.js +1 -1
  32. package/dist/commands/produce.js +2 -2
  33. package/dist/krill/lib/select_filesystem_type.js +1 -1
  34. package/dracut/dracut.conf.d/50-live.conf +12 -13
  35. package/package.json +5 -5
  36. package/perrisbrewery/template/dependencies.yaml +1 -0
@@ -1,12 +1,14 @@
1
1
  [Desktop Entry]
2
2
  Type=Application
3
3
  Version=1.0
4
- Name=Install system
5
- GenericName=Live Installer
6
- Comment=Install the operating system to disk
7
- Exec=/usr/sbin/install-system.sh
4
+ Name=Install System
5
+ GenericName=System Installer
6
+ Keywords=calamares;system;installer;
7
+ TryExec=calamares
8
+ Exec=sh -c "pkexec calamares"
9
+ Comment=Calamares — System Installer
10
+ Icon=install-system.png
8
11
  Terminal=false
9
12
  StartupNotify=true
10
- Type=Application
11
13
  Categories=Qt;System;
12
- Icon=install-system.png
14
+ X-AppStream-Ignore=true
@@ -1,8 +1,6 @@
1
- # Quirinux GNU/Linux by Charlie Martínez
2
-
3
1
  # Global Property
4
2
  title-color: "blue"
5
- title-text: "Debian live (Trixie)"
3
+ title-text: "LINUX LIVE"
6
4
  title-font: "Sans Regular 16"
7
5
  desktop-color: "blue"
8
6
  desktop-image: "splash.png"
@@ -1,4 +1,3 @@
1
- MENU TITLE Debian live (trixie)
2
1
  MENU CLEAR
3
2
  MENU MARGIN 8
4
3
  MENU ROWS 12
@@ -29,6 +28,6 @@ menu helpmsgendrow -1
29
28
  menu hiddenrow -2
30
29
  menu hshift 0
31
30
  menu vshift 0
32
- menu title Linux live
31
+ menu title LINUX LIVE
33
32
  menu background splash.png
34
33
  menu tabmsg Press ENTER to boot or TAB to edit a menu entry
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- SPDX-FileCopyrightText: no
3
+ SPDX-License-Identifier: CC0-1.0
4
+ -->
5
+ <!DOCTYPE policyconfig PUBLIC
6
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
7
+ "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
8
+ <policyconfig>
9
+
10
+ <vendor>Calamares</vendor>
11
+ <vendor_url>https://calamares.io/</vendor_url>
12
+
13
+ <action id="io.calamares.calamares.pkexec.run">
14
+ <description>Run Installer</description>
15
+ <message>Authentication is required to run the installation program</message>
16
+ <icon_name>drive-harddisk</icon_name>
17
+ <defaults>
18
+ <allow_any>no</allow_any>
19
+ <allow_inactive>no</allow_inactive>
20
+ <allow_active>auth_admin</allow_active>
21
+ </defaults>
22
+ <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/calamares</annotate>
23
+ <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
24
+ </action>
25
+ </policyconfig>
@@ -118,14 +118,18 @@ export default class Daddy {
118
118
  config = this.settings.config;
119
119
  config.compression = 'fast';
120
120
  if (reset || isCustom) {
121
+ // add fstype to snapshot_prefix
121
122
  if (config.snapshot_prefix === '') {
122
123
  let fstype = ((await exec(`findmnt -n -o FSTYPE /`, { capture: true })).data.trim());
123
- if (fstype !== 'ext4') {
124
- fstype += '-';
124
+ if (fstype === 'ext4') {
125
+ fstype = '';
125
126
  }
126
127
  else {
127
- fstype = '';
128
+ // btrfs-, etc
129
+ fstype += '-';
128
130
  }
131
+ // excluded now
132
+ fstype = '';
129
133
  config.snapshot_prefix = Utils.snapshotPrefix(this.settings.distro.distroId, this.settings.distro.codenameId) + fstype;
130
134
  }
131
135
  jsonConf = JSON.stringify(config);
@@ -1,4 +1,12 @@
1
1
  /**
2
- *
2
+ * ./src/classes/incubation/customize/customize-partitions.ts
3
+ * penguins-eggs v.25.7.x / ecmascript 2020
4
+ * author: Piero Proietti
5
+ * email: piero.proietti@gmail.com
6
+ * license: MIT
7
+ */
8
+ /**
9
+ * customize module partition
10
+ * add/remove filesystem available
3
11
  */
4
12
  export declare function customizePartitions(): Promise<void>;
@@ -1,9 +1,17 @@
1
+ /**
2
+ * ./src/classes/incubation/customize/customize-partitions.ts
3
+ * penguins-eggs v.25.7.x / ecmascript 2020
4
+ * author: Piero Proietti
5
+ * email: piero.proietti@gmail.com
6
+ * license: MIT
7
+ */
1
8
  import fs from 'node:fs';
2
9
  import Pacman from '../../pacman.js';
3
10
  import yaml from 'js-yaml';
4
11
  import { exec } from '../../../lib/utils.js';
5
12
  /**
6
- *
13
+ * customize module partition
14
+ * add/remove filesystem available
7
15
  */
8
16
  export async function customizePartitions() {
9
17
  const filePartition = '/etc/calamares/modules/partition.conf';
@@ -15,7 +23,7 @@ export async function customizePartitions() {
15
23
  * Determino i filesystem disponibili
16
24
  */
17
25
  partition.availableFileSystemTypes = ['ext4'];
18
- if (Pacman.packageIsInstalled('btrfs-progs') ||
26
+ if (Pacman.packageIsInstalled('progs') ||
19
27
  Pacman.packageIsInstalled('btrfsprogs')) {
20
28
  partition.availableFileSystemTypes.push('btrfs');
21
29
  }
@@ -43,6 +43,7 @@ export default class Incubator {
43
43
  private createInstallerDirs;
44
44
  /**
45
45
  * soluzione tampone from Glenn
46
+ *
46
47
  */
47
48
  private sudoers;
48
49
  }
@@ -70,7 +70,7 @@ export default class Incubator {
70
70
  Utils.warning(`creating ${installer().name} configuration files on ${installer().configRoot}`);
71
71
  this.createInstallerDirs();
72
72
  this.createBranding();
73
- this.sudoers();
73
+ // this.sudoers()
74
74
  const distroUniqueId = this.distro.distroUniqueId;
75
75
  try {
76
76
  /**
@@ -80,7 +80,7 @@ export default class Incubator {
80
80
  const alpine = new Alpine(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
81
81
  await alpine.create();
82
82
  /**
83
- * Archòomix
83
+ * Archlinux
84
84
  */
85
85
  }
86
86
  else if (distroUniqueId === 'archlinux') {
@@ -321,11 +321,13 @@ export default class Incubator {
321
321
  console.log(`${calamaresBranding} branding not found!`);
322
322
  process.exit();
323
323
  }
324
+ /**
325
+ * install-system.png
326
+ */
324
327
  let calamaresIcon = path.resolve(__dirname, `../../../addons/${this.remix.branding}/theme/artwork/install-system.png`);
325
328
  if (this.theme.includes('/')) {
326
329
  calamaresIcon = `${this.theme}/theme/artwork/install-system.png`;
327
330
  }
328
- // se non esiste non copio la icona
329
331
  if (Pacman.calamaresExists()) {
330
332
  if (fs.existsSync(calamaresIcon)) {
331
333
  shx.cp(calamaresIcon, '/usr/share/icons/');
@@ -335,6 +337,9 @@ export default class Incubator {
335
337
  process.exit();
336
338
  }
337
339
  }
340
+ /**
341
+ * install-system.desktop
342
+ */
338
343
  let calamaresLauncher = path.resolve(__dirname, `../../../addons/${this.remix.branding}/theme/applications/install-system.desktop`);
339
344
  if (this.theme.includes('/')) {
340
345
  calamaresLauncher = `${this.theme}/theme/applications/install-system.desktop`;
@@ -346,22 +351,22 @@ export default class Incubator {
346
351
  console.log(`${calamaresLauncher} launcher not found!`);
347
352
  process.exit();
348
353
  }
349
- // script di avvio
354
+ /**
355
+ * install-system.sh
356
+ */
350
357
  shx.cp(path.resolve(__dirname, '../../../assets/calamares/install-system.sh'), '/usr/sbin/install-system.sh');
351
358
  shx.chmod('+x', '/usr/sbin/install-system.sh');
352
359
  }
353
360
  /**
354
361
  * soluzione tampone from Glenn
362
+ *
355
363
  */
356
364
  sudoers() {
357
- let live = 'live';
358
- let content = `${live} ALL=(ALL) NOPASSWD: /usr/bin/calamares`;
359
- content = `# ${live} ALL=(ALL) NOPASSWD: /usr/bin/calamares`;
365
+ let live = this.user_opt;
366
+ let content = '';
367
+ content += `# grants the live user passwordless permission to run /usr/bin/calamare\n`;
368
+ content += `${live} ALL=(ALL) NOPASSWD: /usr/bin/calamares\n`;
360
369
  let fname = '/etc/sudoers.d/calamares';
361
- // su bionic fa un macello
362
- if (this.distro.distroUniqueId !== 'bionic') {
363
- fs.writeFileSync(fname, content, 'utf-8');
364
- }
365
370
  }
366
371
  }
367
372
  /**
@@ -38,14 +38,13 @@ export async function createXdgAutostart(theme = 'eggs', myAddons, myLinks = [],
38
38
  */
39
39
  let installerLink = 'install-system.desktop';
40
40
  if (Pacman.calamaresExists()) {
41
- /**
42
- * Replace Exec in install-system.desktop per Biglinux e Bigcommunity
43
- */
44
- if (this.settings.distro.distroId === 'Biglinux' || this.settings.distro.distroId === 'Bigcommunity') {
45
- let installSystemDesktop = path.resolve(__dirname, `../../../addons/${theme}/theme/applications/install-system.desktop`);
46
- await exec(`sed -i 's|^Exec=.*|Exec=/usr/bin/calamares_polkit %f|' ${installSystemDesktop}`);
47
- }
41
+ // 1. Copia il lanciatore .desktop STANDARD (quello con pkexec)
48
42
  shx.cp(path.resolve(__dirname, `../../../addons/${theme}/theme/applications/install-system.desktop`), `${this.settings.work_dir.merged}/usr/share/applications/`);
43
+ // 2. Copia la TUA policy Polkit per Calamares
44
+ const policySource = path.resolve(__dirname, '../../../assets/calamares/io.calamares.calamares.policy');
45
+ const policyDest = '/usr/share/polkit-1/actions/';
46
+ shx.cp(policySource, policyDest);
47
+ await exec(`sed -i 's/auth_admin/yes/' ${policyDest}io.calamares.calamares.policy`);
49
48
  }
50
49
  else if (Pacman.packageIsInstalled('live-installer')) {
51
50
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ./src/classes/ovary.d/luks-home.ts
2
+ * ./src/classes/ovary.d/luks-get-password.ts
3
3
  * penguins-eggs v.25.10.x / ecmascript 2020
4
4
  * author: Piero Proietti
5
5
  * email: piero.proietti@gmail.com
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ./src/classes/ovary.d/luks-home.ts
2
+ * ./src/classes/ovary.d/luks-get-password.ts
3
3
  * penguins-eggs v.25.10.x / ecmascript 2020
4
4
  * author: Piero Proietti
5
5
  * email: piero.proietti@gmail.com
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ./src/classes/ovary.d/luks-helpers.ts
3
+ * penguins-eggs v.25.10.x / ecmascript 2020
4
+ * author: Piero Proietti
5
+ * email: piero.proietti@gmail.com
6
+ * license: MIT
7
+ */
8
+ import Ovary from '../ovary.js';
9
+ import { type CryptoConfig } from './luks-interactive-crypto-config.js';
10
+ /**
11
+ * Funzione helper per eseguire comandi esterni in modo asincrono,
12
+ * gestendo lo standard input per passare le password.
13
+ * Restituisce una Promise che si risolve al successo o si rigetta in caso di errore.
14
+ */
15
+ export declare function luksExecuteCommand(this: Ovary, command: string, args: string[], stdinData?: string): Promise<void>;
16
+ /**
17
+ * buildLuksFormatArgs
18
+ */
19
+ export declare function buildLuksFormatArgs(this: Ovary, config: CryptoConfig, luksFile: string): string[];
@@ -0,0 +1,73 @@
1
+ /**
2
+ * ./src/classes/ovary.d/luks-helpers.ts
3
+ * penguins-eggs v.25.10.x / ecmascript 2020
4
+ * author: Piero Proietti
5
+ * email: piero.proietti@gmail.com
6
+ * license: MIT
7
+ */
8
+ import { spawn } from 'node:child_process';
9
+ import Utils from '../utils.js';
10
+ const noop = () => { };
11
+ /**
12
+ * Funzione helper per eseguire comandi esterni in modo asincrono,
13
+ * gestendo lo standard input per passare le password.
14
+ * Restituisce una Promise che si risolve al successo o si rigetta in caso di errore.
15
+ */
16
+ export function luksExecuteCommand(command, args, stdinData) {
17
+ if (!this.hidden) {
18
+ Utils.info(`${command} ${args.join(' ')}`);
19
+ }
20
+ return new Promise((resolve, reject) => {
21
+ // Se passiamo dati a stdin, dobbiamo usare 'pipe'. Altrimenti, 'inherit'.
22
+ const stdioConfig = stdinData ? ['pipe', 'inherit', 'inherit'] : 'inherit';
23
+ const process = spawn(command, args, { stdio: stdioConfig });
24
+ // Se fornito, scriviamo i dati (es. la password) nello stdin del processo.
25
+ if (stdinData && process.stdin) {
26
+ process.stdin.write(stdinData);
27
+ process.stdin.end();
28
+ }
29
+ process.on('error', (err) => {
30
+ reject(new Error(`Error starting command "${command}": ${err.message}`));
31
+ });
32
+ process.on('close', (code) => {
33
+ if (code === 0) {
34
+ resolve(); // Success
35
+ }
36
+ else {
37
+ reject(new Error(`Command "${command} ${args.join(' ')}" ended with error code ${code}`));
38
+ }
39
+ });
40
+ });
41
+ }
42
+ /**
43
+ * buildLuksFormatArgs
44
+ */
45
+ export function buildLuksFormatArgs(config, luksFile) {
46
+ const args = [
47
+ '--batch-mode', // Per saltare la conferma "YES"
48
+ 'luksFormat',
49
+ '--type', 'luks2',
50
+ // Parametri base
51
+ '--cipher', config.cipher,
52
+ '--key-size', config['key-size'].toString(),
53
+ '--hash', config.hash,
54
+ '--sector-size', config['sector-size'].toString(),
55
+ '--pbkdf', config.pbkdf,
56
+ ];
57
+ // Aggiungi i parametri condizionali del PBKDF
58
+ switch (config.pbkdf) {
59
+ case 'argon2id':
60
+ case 'argon2i':
61
+ const argonConfig = config;
62
+ args.push('--pbkdf-memory', argonConfig['pbkdf-memory (KiB)'].toString());
63
+ args.push('--pbkdf-parallel', argonConfig['pbkdf-parallel (threads)'].toString());
64
+ break;
65
+ case 'pbkdf2':
66
+ const pbkdf2Config = config;
67
+ args.push('--iter-time', pbkdf2Config['iter-time (ms)'].toString());
68
+ break;
69
+ }
70
+ // Aggiungi il file di destinazione
71
+ args.push(luksFile);
72
+ return args;
73
+ }
@@ -53,23 +53,18 @@ WantedBy=local-fs.target
53
53
  const servicePath = path.join(squashfsRoot, 'etc/systemd/system/mount-encrypted-home.service');
54
54
  const symlinkDir = path.join(squashfsRoot, 'etc/systemd/system/local-fs.target.wants');
55
55
  const symlinkPath = path.join(symlinkDir, 'mount-encrypted-home.service');
56
- // Crea le directory necessarie
56
+ // Create dirs
57
57
  fs.mkdirSync(path.dirname(scriptPath), { recursive: true });
58
58
  fs.mkdirSync(path.dirname(servicePath), { recursive: true });
59
59
  fs.mkdirSync(symlinkDir, { recursive: true });
60
60
  // Scrivi lo script
61
61
  fs.writeFileSync(scriptPath, bashScript);
62
62
  fs.chmodSync(scriptPath, 0o755);
63
- // console.log(`✓ Created: ${scriptPath}`)
64
63
  // Scrivi il service
65
64
  fs.writeFileSync(servicePath, systemdService);
66
- // console.log(`✓ Created: ${servicePath}`)
67
65
  // Crea il symlink per abilitare il service
68
66
  if (fs.existsSync(symlinkPath)) {
69
67
  fs.unlinkSync(symlinkPath);
70
68
  }
71
69
  fs.symlinkSync('../mount-encrypted-home.service', symlinkPath);
72
- // console.log(`✓ Enabled: mount-encrypted-home.service`)
73
- // console.log('Encrypted home support installed successfully')
74
- // console.log('Logs will be available at: /var/log/mount-encrypted-home.log')
75
70
  }
@@ -7,7 +7,6 @@
7
7
  */
8
8
  // packages
9
9
  import fs from 'fs';
10
- import { spawn } from 'node:child_process';
11
10
  import Utils from '../utils.js';
12
11
  import { exec } from '../../lib/utils.js';
13
12
  const noop = () => { };
@@ -53,11 +52,13 @@ export async function luksHome(clone = false, homecrypt = false) {
53
52
  warning(`homes size: ${bytesToGB(size)}`);
54
53
  warning(`partition LUKS ${this.luksFile} size: ${bytesToGB(luksSize)}`);
55
54
  warning(`creating partition LUKS: ${this.luksFile}`);
56
- await executeCommand('truncate', ['--size', `${luksSize}`, this.luksFile]);
55
+ await this.luksExecuteCommand('truncate', ['--size', `${luksSize}`, this.luksFile]);
57
56
  warning(`formatting ${this.luksFile} as a LUKS volume...`);
58
- await executeCommand('cryptsetup', ['--batch-mode', 'luksFormat', this.luksFile], `${this.luksPassword}\n`);
57
+ //await this.luksExecuteCommand('cryptsetup', ['--batch-mode', 'luksFormat', this.luksFile], `${this.luksPassword}\n`);
58
+ const luksFormatArgs = this.buildLuksFormatArgs(this.luksConfig, this.luksFile);
59
+ await this.luksExecuteCommand('cryptsetup', luksFormatArgs, `${this.luksPassword}\n`);
59
60
  warning(`opening the LUKS volume. It will be mapped to ${this.luksDevice}`);
60
- await executeCommand('cryptsetup', ['luksOpen', this.luksFile, this.luksMappedName], `${this.luksPassword}\n`);
61
+ await this.luksExecuteCommand('cryptsetup', ['luksOpen', this.luksFile, this.luksMappedName], `${this.luksPassword}\n`);
61
62
  warning(`formatting c ext4 `);
62
63
  await exec(`mkfs.ext4 -L live-home ${this.luksDevice}`, this.echo);
63
64
  warning(`mounting ${this.luksDevice} on ${this.luksMountpoint}`);
@@ -97,7 +98,7 @@ export async function luksHome(clone = false, homecrypt = false) {
97
98
  warning(`unmount ${this.luksDevice}`);
98
99
  await exec(`umount ${this.luksMountpoint}`, this.echo);
99
100
  warning(`closing LUKS volume ${this.luksMappedName}.`);
100
- await executeCommand('cryptsetup', ['close', this.luksMappedName]);
101
+ await this.luksExecuteCommand('cryptsetup', ['close', this.luksMappedName]);
101
102
  warning(`moving ${this.luksMappedName} to (ISO)/live/.`);
102
103
  await exec(`mv ${this.luksFile} ${this.settings.iso_work}/live`, this.echo);
103
104
  warning('encryption process successfully completed!');
@@ -114,40 +115,12 @@ export async function luksHome(clone = false, homecrypt = false) {
114
115
  await exec(`umount -lf ${this.luksMountpoint}`).catch(() => { });
115
116
  }
116
117
  if (fs.existsSync(this.luksDevice)) {
117
- await executeCommand('cryptsetup', ['close', this.luksMappedName]).catch(() => { });
118
+ await this.luksExecuteCommand('cryptsetup', ['close', this.luksMappedName]).catch(() => { });
118
119
  }
119
120
  await Utils.pressKeyToExit();
120
121
  process.exit(1);
121
122
  }
122
123
  }
123
- /**
124
- * Funzione helper per eseguire comandi esterni in modo asincrono,
125
- * gestendo lo standard input per passare le password.
126
- * Restituisce una Promise che si risolve al successo o si rigetta in caso di errore.
127
- */
128
- function executeCommand(command, args, stdinData) {
129
- return new Promise((resolve, reject) => {
130
- // Se passiamo dati a stdin, dobbiamo usare 'pipe'. Altrimenti, 'inherit'.
131
- const stdioConfig = stdinData ? ['pipe', 'inherit', 'inherit'] : 'inherit';
132
- const process = spawn(command, args, { stdio: stdioConfig });
133
- // Se fornito, scriviamo i dati (es. la password) nello stdin del processo.
134
- if (stdinData && process.stdin) {
135
- process.stdin.write(stdinData);
136
- process.stdin.end();
137
- }
138
- process.on('error', (err) => {
139
- reject(new Error(`Error starting command "${command}": ${err.message}`));
140
- });
141
- process.on('close', (code) => {
142
- if (code === 0) {
143
- resolve(); // Success
144
- }
145
- else {
146
- reject(new Error(`Command "${command} ${args.join(' ')}" ended with error code ${code}`));
147
- }
148
- });
149
- });
150
- }
151
124
  /**
152
125
  * Converte bytes in gigabytes per la visualizzazione.
153
126
  */
@@ -50,7 +50,7 @@ const questions = [
50
50
  name: 'sector-size',
51
51
  message: 'Choose the sector size:',
52
52
  choices: SECTOR_SIZE_OPTIONS.map(size => ({
53
- name: `${size} bytes ${size === 4096 ? '(Modern SSDs/NVMe)' : '(Legacy default)'}`,
53
+ name: `${size} bytes ${size === 4096 ? '(Modern SSDs/NVMe)' : '(Legacy default/Loop devices'}`,
54
54
  value: size,
55
55
  })),
56
56
  default: 512,
@@ -131,5 +131,9 @@ export async function interactiveCryptoConfig() {
131
131
  const answers = await inquirer.prompt(questions);
132
132
  // Use the double-cast fix to satisfy TypeScript
133
133
  const finalConfig = answers;
134
+ if (finalConfig['sector-size'] === 4096) {
135
+ Utils.warning(`in a loop device - regardless of the hardware - the sector_size will be set to 512`);
136
+ finalConfig['sector-size'] = 512;
137
+ }
134
138
  return finalConfig;
135
139
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ./src/classes/ovary.d/initrd-luks.ts
2
+ * ./src/classes/ovary.d/luks-root-initrd.ts
3
3
  * penguins-eggs v.25.10.x / ecmascript 2020
4
4
  * author: Piero Proietti
5
5
  * email: piero.proietti@gmail.com
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ./src/classes/ovary.d/initrd-luks.ts
2
+ * ./src/classes/ovary.d/luks-root-initrd.ts
3
3
  * penguins-eggs v.25.10.x / ecmascript 2020
4
4
  * author: Piero Proietti
5
5
  * email: piero.proietti@gmail.com
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ./src/classes/ovary.d/encrypt-live-fs.ts
2
+ * ./src/classes/ovary.d/luks-root.ts
3
3
  * penguins-eggs v.25.10.x / ecmascript 2020
4
4
  * author: Piero Proietti
5
5
  * email: piero.proietti@gmail.com
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ./src/classes/ovary.d/encrypt-live-fs.ts
2
+ * ./src/classes/ovary.d/luks-root.ts
3
3
  * penguins-eggs v.25.10.x / ecmascript 2020
4
4
  * author: Piero Proietti
5
5
  * email: piero.proietti@gmail.com
@@ -7,7 +7,6 @@
7
7
  */
8
8
  // packages
9
9
  import fs from 'fs';
10
- import { spawn } from 'node:child_process';
11
10
  import Utils from '../utils.js';
12
11
  import { exec } from '../../lib/utils.js';
13
12
  const noop = () => { };
@@ -29,7 +28,7 @@ export async function luksRoot() {
29
28
  const live_fs = `${this.settings.iso_work}live/filesystem.squashfs`;
30
29
  try {
31
30
  /**
32
- * this.luksMappedName = 'luks.img';
31
+ * this.luksMappedName = 'root.img';
33
32
  * this.luksFile = `/tmp/${luksMappedName}`
34
33
  * this.luksDevice = `/dev/mapper/${luksMappedName}`
35
34
  * this.luksMountpoint = `/tmp/mnt/${luksMappedName}`
@@ -52,13 +51,12 @@ export async function luksRoot() {
52
51
  warning(`filesystem.squashfs size: ${bytesToGB(size)}`);
53
52
  warning(`partition LUKS ${this.luksFile} size: ${bytesToGB(luksSize)}`);
54
53
  warning(`creating partition LUKS: ${this.luksFile}`);
55
- await executeCommand('truncate', ['--size', `${luksSize}`, this.luksFile]);
54
+ await this.luksExecuteCommand('truncate', ['--size', `${luksSize}`, this.luksFile]);
56
55
  warning(`formatting ${this.luksFile} as a LUKS volume...`);
57
- // await executeCommand('cryptsetup', ['--batch-mode', 'luksFormat', this.luksFile], `${this.luksPassword}\n`);
58
- const luksFormatArgs = buildLuksFormatArgs(this.luksConfig, this.luksFile);
59
- await executeCommand('cryptsetup', luksFormatArgs, `${this.luksPassword}\n`);
56
+ const luksFormatArgs = this.buildLuksFormatArgs(this.luksConfig, this.luksFile);
57
+ await this.luksExecuteCommand('cryptsetup', luksFormatArgs, `${this.luksPassword}\n`);
60
58
  warning(`opening the LUKS volume. It will be mapped to ${this.luksDevice}`);
61
- await executeCommand('cryptsetup', ['luksOpen', this.luksFile, this.luksMappedName], `${this.luksPassword}\n`);
59
+ await this.luksExecuteCommand('cryptsetup', ['luksOpen', this.luksFile, this.luksMappedName], `${this.luksPassword}\n`);
62
60
  warning(`formatting ext4 (without journal)...`);
63
61
  await exec(`mkfs.ext4 -O ^has_journal -L live-root ${this.luksDevice}`, this.echo);
64
62
  warning(`mounting ${this.luksDevice} on ${this.luksMountpoint}`);
@@ -92,7 +90,7 @@ export async function luksRoot() {
92
90
  throw umountError;
93
91
  }
94
92
  warning(`closing LUKS volume ${this.luksFile}.`);
95
- await executeCommand('cryptsetup', ['close', this.luksMappedName]);
93
+ await this.luksExecuteCommand('cryptsetup', ['close', this.luksMappedName]);
96
94
  warning(`moving ${this.luksMappedName} on (ISO)/live.`);
97
95
  await exec(`mv ${this.luksFile} ${this.settings.iso_work}/live`, this.echo);
98
96
  }
@@ -108,40 +106,12 @@ export async function luksRoot() {
108
106
  await exec(`umount -lf ${this.luksMountpoint}`).catch(() => { });
109
107
  }
110
108
  if (fs.existsSync(this.luksDevice)) {
111
- await executeCommand('cryptsetup', ['close', this.luksMappedName]).catch(() => { });
109
+ await this.luksExecuteCommand('cryptsetup', ['close', this.luksMappedName]).catch(() => { });
112
110
  }
113
111
  await Utils.pressKeyToExit();
114
112
  process.exit(1);
115
113
  }
116
114
  }
117
- /**
118
- * Funzione helper per eseguire comandi esterni in modo asincrono,
119
- * gestendo lo standard input per passare le password.
120
- * Restituisce una Promise che si risolve al successo o si rigetta in caso di errore.
121
- */
122
- function executeCommand(command, args, stdinData) {
123
- return new Promise((resolve, reject) => {
124
- // Se passiamo dati a stdin, dobbiamo usare 'pipe'. Altrimenti, 'inherit'.
125
- const stdioConfig = stdinData ? ['pipe', 'inherit', 'inherit'] : 'inherit';
126
- const process = spawn(command, args, { stdio: stdioConfig });
127
- // Se fornito, scriviamo i dati (es. la password) nello stdin del processo.
128
- if (stdinData && process.stdin) {
129
- process.stdin.write(stdinData);
130
- process.stdin.end();
131
- }
132
- process.on('error', (err) => {
133
- reject(new Error(`Error starting command "${command}": ${err.message}`));
134
- });
135
- process.on('close', (code) => {
136
- if (code === 0) {
137
- resolve(); // Success
138
- }
139
- else {
140
- reject(new Error(`Command "${command} ${args.join(' ')}" ended with error code ${code}`));
141
- }
142
- });
143
- });
144
- }
145
115
  /**
146
116
  * Converte bytes in gigabytes per la visualizzazione.
147
117
  */
@@ -151,35 +121,3 @@ function bytesToGB(bytes) {
151
121
  const gigabytes = bytes / (1024 * 1024 * 1024);
152
122
  return gigabytes.toFixed(2) + ' GB';
153
123
  }
154
- /**
155
- * buildLuksFormatArgs
156
- */
157
- function buildLuksFormatArgs(config, luksFile) {
158
- const args = [
159
- '--batch-mode', // Per saltare la conferma "YES"
160
- 'luksFormat',
161
- '--type', 'luks2',
162
- // Parametri base
163
- '--cipher', config.cipher,
164
- '--key-size', config['key-size'].toString(),
165
- '--hash', config.hash,
166
- '--sector-size', config['sector-size'].toString(),
167
- '--pbkdf', config.pbkdf,
168
- ];
169
- // Aggiungi i parametri condizionali del PBKDF
170
- switch (config.pbkdf) {
171
- case 'argon2id':
172
- case 'argon2i':
173
- const argonConfig = config;
174
- args.push('--pbkdf-memory', argonConfig['pbkdf-memory (KiB)'].toString());
175
- args.push('--pbkdf-parallel', argonConfig['pbkdf-parallel (threads)'].toString());
176
- break;
177
- case 'pbkdf2':
178
- const pbkdf2Config = config;
179
- args.push('--iter-time', pbkdf2Config['iter-time (ms)'].toString());
180
- break;
181
- }
182
- // Aggiungi il file di destinazione
183
- args.push(luksFile);
184
- return args;
185
- }
@@ -94,9 +94,11 @@ export async function makeEfi(theme = 'eggs') {
94
94
  * create grub.cfg (bridge) on (ISO)/boot/grub/x86_64-efi/grub.cfg
95
95
  */
96
96
  Utils.warning(`creating grub.cfg bridge to main. (ISO)/boot/grub/${Utils.uefiFormat()}`);
97
- let cfgBridge = `${isoDir}/boot/grub/${Utils.uefiFormat()}/grub.cfg`;
97
+ let cfgBridge = path.join(isoDir, '/boot/grub/', Utils.uefiFormat(), '/grub.cfg');
98
98
  let cfgBridgeText = `# grub.cfg bridge\n`;
99
- cfgBridgeText += `# created on ${cfgBridge}\n`;
99
+ if (!this.hidden) {
100
+ cfgBridgeText += `# created on ${cfgBridge}\n`;
101
+ }
100
102
  cfgBridgeText += `\n`;
101
103
  cfgBridgeText += `source /boot/grub/grub.cfg\n`;
102
104
  fs.writeFileSync(cfgBridge, cfgBridgeText);
@@ -235,8 +237,12 @@ export async function makeEfi(theme = 'eggs') {
235
237
  const kernel_parameters = Diversions.kernelParameters(this.familyId, this.volid, this.fullcrypt);
236
238
  const cfgMain = path.join(isoDir, '/boot/grub/grub.cfg');
237
239
  const template = fs.readFileSync(grubTemplate, 'utf8');
240
+ let fullname = this.settings.remix.fullname.toUpperCase();
241
+ if (this.hidden) {
242
+ fullname = "LINUX";
243
+ }
238
244
  const view = {
239
- fullname: this.settings.remix.fullname.toUpperCase(),
245
+ fullname: fullname,
240
246
  initrdImg: `/live/${path.basename(this.initrd)}`,
241
247
  kernel: this.kernel,
242
248
  kernel_parameters,