penguins-eggs 25.11.29 → 25.12.15
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 +118 -127
- package/README.pdf +10950 -11893
- package/addons/eggs/theme/livecd/simple.grub.main.cfg +3 -3
- package/conf/derivatives.yaml +2 -1
- package/conf/distros/buster/calamares/calamares-modules/cleanup/cleanup.sh +1 -1
- package/conf/distros/focal/calamares/calamares-modules/cleanup/cleanup.sh +1 -1
- package/conf/distros/noble/calamares/calamares-modules/cleanup/cleanup.sh +1 -1
- package/conf/distros/noble/calamares/libexec/calamares-l10n-helper.sh +2 -1
- package/conf/distros/noble/calamares/settings.yml +1 -0
- package/conf/distros/trixie/calamares/calamares-modules/cleanup/cleanup.sh +1 -1
- package/conf/exclude.list.d/var.list +11 -6
- package/dist/appimage/dependency-manager.js +1 -1
- package/dist/classes/cli-autologin.d.ts +37 -4
- package/dist/classes/cli-autologin.js +153 -115
- package/dist/classes/compressors.d.ts +7 -10
- package/dist/classes/compressors.js +44 -31
- package/dist/classes/daddy.js +4 -1
- package/dist/classes/distro.js +2 -2
- package/dist/classes/diversions.js +2 -3
- package/dist/classes/incubation/fisherman-helper/initcpio.d.ts +3 -5
- package/dist/classes/incubation/fisherman-helper/initcpio.js +28 -20
- package/dist/classes/incubation/fisherman-helper/settings.js +1 -1
- package/dist/classes/incubation/fisherman.js +1 -1
- package/dist/classes/incubation/incubator.d/manjaro.js +1 -0
- 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 +2 -13
- package/dist/classes/ovary.d/edit-live-fs.js +33 -146
- package/dist/classes/ovary.d/fertilization.js +1 -1
- package/dist/classes/ovary.d/luks-home.js +33 -19
- package/dist/classes/ovary.d/luks-root.d.ts +1 -2
- package/dist/classes/ovary.d/luks-root.js +46 -27
- package/dist/classes/ovary.d/luks-shrink.d.ts +14 -0
- package/dist/classes/ovary.d/luks-shrink.js +86 -0
- package/dist/classes/ovary.d/make-dot-disk.js +1 -1
- package/dist/classes/ovary.d/produce.js +64 -22
- 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 +5 -3
- package/dist/classes/ovary.js +5 -3
- 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 +80 -47
- package/dist/classes/xdg.js +1 -1
- package/dist/classes/yolk.js +3 -5
- 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 +14 -5
- 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/calamares/i-calamares-branding.d.ts +56 -38
- package/dist/interfaces/calamares/i-calamares-branding.js +10 -0
- 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 +2 -2
- 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 +2 -3
- 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.d.ts +1 -5
- package/dist/krill/classes/sequence.js +28 -32
- package/dist/krill/components/finished.js +2 -2
- package/dist/krill/components/install.js +2 -2
- package/dist/krill/components/keyboard.js +2 -2
- package/dist/krill/components/location.js +2 -2
- package/dist/krill/components/network.js +2 -2
- package/dist/krill/components/partitions.js +2 -2
- package/dist/krill/components/summary.js +2 -2
- package/dist/krill/components/title.js +2 -2
- package/dist/krill/components/users.js +2 -2
- package/dist/krill/components/welcome.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 +52 -19
- package/dist/lib/utils.js +271 -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/scripts/restore_homecrypt_krill.sh +93 -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
|
@@ -27,7 +27,7 @@ export async function luksHome(clone = false, homecrypt = false) {
|
|
|
27
27
|
try {
|
|
28
28
|
/**
|
|
29
29
|
* this.luksMappedName = 'home.img';
|
|
30
|
-
* this.luksFile = `/tmp/${luksMappedName}`
|
|
30
|
+
* this.luksFile = `/var/tmp/${luksMappedName}`
|
|
31
31
|
* this.luksDevice = `/dev/mapper/${luksMappedName}`
|
|
32
32
|
* this.luksMountpoint = `/tmp/mnt/${luksMappedName}`
|
|
33
33
|
* this.luksPassword = '0'
|
|
@@ -42,15 +42,21 @@ export async function luksHome(clone = false, homecrypt = false) {
|
|
|
42
42
|
// Utils.warning('1. Calculation of space requirements...')
|
|
43
43
|
let sizeString = (await exec('du -sb --exclude=/home/eggs /home', { capture: true })).data.trim().split(/\s+/)[0];
|
|
44
44
|
let size = Number.parseInt(sizeString, 10);
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
const fsOverhead = Math.ceil(size * 0.05);
|
|
46
|
+
const luksHeader = 32 * 1024 * 1024;
|
|
47
|
+
const safetyBuffer = 100 * 1024 * 1024;
|
|
48
|
+
let calculatedSize = size + fsOverhead + luksHeader + safetyBuffer;
|
|
49
|
+
const minSize = 64 * 1024 * 1024;
|
|
50
|
+
if (calculatedSize < minSize)
|
|
51
|
+
calculatedSize = minSize;
|
|
52
|
+
const alignment = 4 * 1024 * 1024;
|
|
53
|
+
const luksSize = Math.ceil(calculatedSize / alignment) * alignment;
|
|
54
|
+
warning(`------------------------------------------`);
|
|
55
|
+
warning(`HOME CRYPT CALCULATION (Read-Only):`);
|
|
56
|
+
warning(` Data Payload: ${bytesToGB(size)}`);
|
|
57
|
+
warning(` Overhead+Buf: ${bytesToGB(luksSize - size)}`);
|
|
58
|
+
warning(` TOTAL SIZE: ${bytesToGB(luksSize)}`);
|
|
59
|
+
warning(`------------------------------------------`);
|
|
54
60
|
warning(`creating partition LUKS: ${this.luksFile}`);
|
|
55
61
|
await this.luksExecuteCommand('truncate', ['--size', `${luksSize}`, this.luksFile]);
|
|
56
62
|
warning(`formatting ${this.luksFile} as a LUKS volume...`);
|
|
@@ -59,7 +65,7 @@ export async function luksHome(clone = false, homecrypt = false) {
|
|
|
59
65
|
await this.luksExecuteCommand('cryptsetup', luksFormatArgs, `${this.luksPassword}\n`);
|
|
60
66
|
warning(`opening the LUKS volume. It will be mapped to ${this.luksDevice}`);
|
|
61
67
|
await this.luksExecuteCommand('cryptsetup', ['luksOpen', this.luksFile, this.luksMappedName], `${this.luksPassword}\n`);
|
|
62
|
-
warning(`formatting
|
|
68
|
+
warning(`formatting ext4 `);
|
|
63
69
|
await exec(`mkfs.ext4 -L live-home ${this.luksDevice}`, this.echo);
|
|
64
70
|
warning(`mounting ${this.luksDevice} on ${this.luksMountpoint}`);
|
|
65
71
|
if (fs.existsSync(this.luksMountpoint)) {
|
|
@@ -74,17 +80,21 @@ export async function luksHome(clone = false, homecrypt = false) {
|
|
|
74
80
|
await exec(`mount /dev/mapper/${this.luksMappedName} ${this.luksMountpoint}`, this.echo);
|
|
75
81
|
warning(`copying /home on ${this.luksMountpoint}`);
|
|
76
82
|
await exec(`rsync -ah --exclude='eggs' /home/ ${this.luksMountpoint}`, this.echo);
|
|
83
|
+
/**
|
|
84
|
+
* utenti e gruppi in .system-backup
|
|
85
|
+
*/
|
|
77
86
|
warning(`saving user accounts info...`);
|
|
78
|
-
// Crea directory per backup system files
|
|
79
87
|
await exec(`mkdir -p ${this.luksMountpoint}/.system-backup`, this.echo);
|
|
80
|
-
//
|
|
88
|
+
// passwd/shadow: solo utenti con UID >= 1000
|
|
81
89
|
await exec(`awk -F: '$3 >= 1000 {print}' /etc/passwd > ${this.luksMountpoint}/.system-backup/passwd`, this.echo);
|
|
82
90
|
await exec(`awk -F: '$3 >= 1000 {print}' /etc/shadow > ${this.luksMountpoint}/.system-backup/shadow`, this.echo);
|
|
83
|
-
//
|
|
91
|
+
// group/gshadow TUTTI
|
|
84
92
|
// Gli utenti possono appartenere a gruppi di sistema (sudo, audio, video, etc.)
|
|
85
93
|
await exec(`cp /etc/group ${this.luksMountpoint}/.system-backup/group`, this.echo);
|
|
86
94
|
await exec(`cp /etc/gshadow ${this.luksMountpoint}/.system-backup/gshadow`, this.echo);
|
|
87
|
-
|
|
95
|
+
/**
|
|
96
|
+
* saving display manager (autologin) configs...
|
|
97
|
+
*/
|
|
88
98
|
warning(`saving display manager configuration...`);
|
|
89
99
|
// GDM (gdm3 è comune su Debian/Ubuntu)
|
|
90
100
|
await exec(`[ -e /etc/gdm3 ] && cp -a /etc/gdm3 ${this.luksMountpoint}/.system-backup/`, this.echo);
|
|
@@ -95,10 +105,10 @@ export async function luksHome(clone = false, homecrypt = false) {
|
|
|
95
105
|
// SDDM (sia file .conf che directory .conf.d)
|
|
96
106
|
await exec(`[ -e /etc/sddm.conf ] && cp -a /etc/sddm.conf ${this.luksMountpoint}/.system-backup/`, this.echo);
|
|
97
107
|
await exec(`[ -e /etc/sddm.conf.d ] && cp -a /etc/sddm.conf.d ${this.luksMountpoint}/.system-backup/`, this.echo);
|
|
98
|
-
warning(`
|
|
99
|
-
await exec(
|
|
100
|
-
|
|
101
|
-
await this.
|
|
108
|
+
warning(`Syncing filesystem on ${this.luksMountpoint}...`);
|
|
109
|
+
await exec('sync', this.echo); // Forza scrittura dati su disco
|
|
110
|
+
// Shrink()
|
|
111
|
+
await this.luksShrink();
|
|
102
112
|
warning(`moving ${this.luksMappedName} to (ISO)/live/.`);
|
|
103
113
|
await exec(`mv ${this.luksFile} ${this.settings.iso_work}/live`, this.echo);
|
|
104
114
|
warning('encryption process successfully completed!');
|
|
@@ -117,6 +127,10 @@ export async function luksHome(clone = false, homecrypt = false) {
|
|
|
117
127
|
if (fs.existsSync(this.luksDevice)) {
|
|
118
128
|
await this.luksExecuteCommand('cryptsetup', ['close', this.luksMappedName]).catch(() => { });
|
|
119
129
|
}
|
|
130
|
+
if (fs.existsSync(this.luksFile)) {
|
|
131
|
+
Utils.warning(`Removing temporary container: ${this.luksFile}`);
|
|
132
|
+
fs.unlinkSync(this.luksFile);
|
|
133
|
+
}
|
|
120
134
|
await Utils.pressKeyToExit();
|
|
121
135
|
process.exit(1);
|
|
122
136
|
}
|
|
@@ -12,8 +12,7 @@ import { exec } from '../../lib/utils.js';
|
|
|
12
12
|
const noop = () => { };
|
|
13
13
|
/**
|
|
14
14
|
* luksRoot()
|
|
15
|
-
*
|
|
16
|
-
* create a container LUKS with the entire
|
|
15
|
+
* * create a container LUKS with the entire
|
|
17
16
|
* filesystem.squashfs
|
|
18
17
|
*/
|
|
19
18
|
export async function luksRoot() {
|
|
@@ -29,7 +28,7 @@ export async function luksRoot() {
|
|
|
29
28
|
try {
|
|
30
29
|
/**
|
|
31
30
|
* this.luksMappedName = 'root.img';
|
|
32
|
-
* this.luksFile = `/tmp/${luksMappedName}`
|
|
31
|
+
* this.luksFile = `/var/tmp/${luksMappedName}`
|
|
33
32
|
* this.luksDevice = `/dev/mapper/${luksMappedName}`
|
|
34
33
|
* this.luksMountpoint = `/tmp/mnt/${luksMappedName}`
|
|
35
34
|
* this.luksPassword = '0'
|
|
@@ -45,11 +44,29 @@ export async function luksRoot() {
|
|
|
45
44
|
throw new Error(`filesystem.squashfs not found at: ${live_fs}`);
|
|
46
45
|
}
|
|
47
46
|
const stats = fs.statSync(live_fs);
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
const size = stats.size; // Dimensione REALE del file in Byte
|
|
48
|
+
// -------------------------------------------------------------
|
|
49
|
+
// CALCOLO DIMENSIONE OTTIMIZZATA (No shrink, safe allocation)
|
|
50
|
+
// -------------------------------------------------------------
|
|
51
|
+
// 1. Overhead Ext4: Inode, bitmap, superblocchi. ~3-4% è standard senza journal.
|
|
52
|
+
const fsOverhead = Math.ceil(size * 0.04);
|
|
53
|
+
// 2. Header LUKS: Solitamente 16MB per LUKS2, usiamo 32MB per sicurezza.
|
|
54
|
+
const luksHeader = 32 * 1024 * 1024;
|
|
55
|
+
// 3. Margine di sicurezza (Buffer): 120MB fissi.
|
|
56
|
+
// Questo spazio evita errori di "Disk full" durante la copia dei metadati.
|
|
57
|
+
// Viene compensato dall'uso di "-m 0" nella formattazione.
|
|
58
|
+
const safetyBuffer = 120 * 1024 * 1024;
|
|
59
|
+
// 4. Somma totale
|
|
60
|
+
let calculatedSize = size + fsOverhead + luksHeader + safetyBuffer;
|
|
61
|
+
// 5. Allineamento a 4MB (Performance storage)
|
|
62
|
+
const alignment = 4 * 1024 * 1024;
|
|
63
|
+
const luksSize = Math.ceil(calculatedSize / alignment) * alignment;
|
|
64
|
+
warning(`------------------------------------------`);
|
|
65
|
+
warning(`SAFE SIZE CALCULATION (No Shrink):`);
|
|
66
|
+
warning(` Payload (SquashFS): ${bytesToGB(size)}`);
|
|
67
|
+
warning(` Calc. Overhead: ${bytesToGB(luksSize - size)}`);
|
|
68
|
+
warning(` TOTAL CONTAINER: ${bytesToGB(luksSize)}`);
|
|
69
|
+
warning(`------------------------------------------`);
|
|
53
70
|
warning(`creating partition LUKS: ${this.luksFile}`);
|
|
54
71
|
await this.luksExecuteCommand('truncate', ['--size', `${luksSize}`, this.luksFile]);
|
|
55
72
|
warning(`formatting ${this.luksFile} as a LUKS volume...`);
|
|
@@ -57,8 +74,13 @@ export async function luksRoot() {
|
|
|
57
74
|
await this.luksExecuteCommand('cryptsetup', luksFormatArgs, `${this.luksPassword}\n`);
|
|
58
75
|
warning(`opening the LUKS volume. It will be mapped to ${this.luksDevice}`);
|
|
59
76
|
await this.luksExecuteCommand('cryptsetup', ['luksOpen', this.luksFile, this.luksMappedName], `${this.luksPassword}\n`);
|
|
60
|
-
|
|
61
|
-
|
|
77
|
+
// -------------------------------------------------------------
|
|
78
|
+
// FORMATTAZIONE EXT4
|
|
79
|
+
// -m 0 : Imposta i blocchi riservati a 0% (recupera spazio)
|
|
80
|
+
// -O ^has_journal : Disabilita il journal (risparmia spazio e scritture)
|
|
81
|
+
// -------------------------------------------------------------
|
|
82
|
+
warning(`formatting ext4 (without journal, 0% reserved)...`);
|
|
83
|
+
await exec(`mkfs.ext4 -m 0 -O ^has_journal -L live-root ${this.luksDevice}`, this.echo);
|
|
62
84
|
warning(`mounting ${this.luksDevice} on ${this.luksMountpoint}`);
|
|
63
85
|
if (fs.existsSync(this.luksMountpoint)) {
|
|
64
86
|
if (!Utils.isMountpoint(this.luksMountpoint)) {
|
|
@@ -74,25 +96,18 @@ export async function luksRoot() {
|
|
|
74
96
|
await exec(`mv ${live_fs} ${this.luksMountpoint}/filesystem.squashfs`, this.echo);
|
|
75
97
|
warning(`Syncing filesystem on ${this.luksMountpoint}...`);
|
|
76
98
|
await exec('sync', this.echo); // Forza scrittura dati su disco
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Utils.error(`Force unmount also failed: ${forceError}`);
|
|
87
|
-
// Considera se lanciare un errore qui per fermare il processo
|
|
88
|
-
});
|
|
89
|
-
// Lancia comunque l'errore originale per segnalare il problema
|
|
90
|
-
throw umountError;
|
|
91
|
-
}
|
|
92
|
-
warning(`closing LUKS volume ${this.luksFile}.`);
|
|
99
|
+
/**
|
|
100
|
+
* SHRINK DISABILITATO
|
|
101
|
+
* Non eseguiamo this.luksShrink() per evitare corruzione dati.
|
|
102
|
+
* Abbiamo calcolato la dimensione corretta all'inizio.
|
|
103
|
+
*/
|
|
104
|
+
// Procedura di chiusura manuale (sostituisce quella dentro shrink)
|
|
105
|
+
warning(`Unmounting ${this.luksMountpoint}...`);
|
|
106
|
+
await exec(`umount ${this.luksMountpoint}`, this.echo);
|
|
107
|
+
warning(`Closing LUKS volume ${this.luksMappedName}...`);
|
|
93
108
|
await this.luksExecuteCommand('cryptsetup', ['close', this.luksMappedName]);
|
|
94
109
|
warning(`moving ${this.luksMappedName} on (ISO)/live.`);
|
|
95
|
-
await exec(`mv ${this.luksFile} ${this.settings.iso_work}/live`, this.echo);
|
|
110
|
+
await exec(`mv ${this.luksFile} ${this.settings.iso_work}/live/root.img`, this.echo);
|
|
96
111
|
}
|
|
97
112
|
catch (error) {
|
|
98
113
|
if (error instanceof Error) {
|
|
@@ -108,6 +123,10 @@ export async function luksRoot() {
|
|
|
108
123
|
if (fs.existsSync(this.luksDevice)) {
|
|
109
124
|
await this.luksExecuteCommand('cryptsetup', ['close', this.luksMappedName]).catch(() => { });
|
|
110
125
|
}
|
|
126
|
+
if (fs.existsSync(this.luksFile)) {
|
|
127
|
+
Utils.warning(`Removing temporary container: ${this.luksFile}`);
|
|
128
|
+
fs.unlinkSync(this.luksFile);
|
|
129
|
+
}
|
|
111
130
|
await Utils.pressKeyToExit();
|
|
112
131
|
process.exit(1);
|
|
113
132
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ./src/classes/ovary.d/luks-shrink.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
|
+
/**
|
|
10
|
+
* luksShrink
|
|
11
|
+
* Riduce in sicurezza un volume LUKS (root o home) minimizzando lo spazio
|
|
12
|
+
* ma garantendo l'integrità dei dati e l'allineamento dei blocchi.
|
|
13
|
+
*/
|
|
14
|
+
export declare function luksShrink(this: Ovary): Promise<void>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ./src/classes/ovary.d/luks-shrink.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 Utils from '../utils.js';
|
|
9
|
+
import { exec } from '../../lib/utils.js';
|
|
10
|
+
const noop = () => { };
|
|
11
|
+
/**
|
|
12
|
+
* luksShrink
|
|
13
|
+
* Riduce in sicurezza un volume LUKS (root o home) minimizzando lo spazio
|
|
14
|
+
* ma garantendo l'integrità dei dati e l'allineamento dei blocchi.
|
|
15
|
+
*/
|
|
16
|
+
export async function luksShrink() {
|
|
17
|
+
const loggers = {
|
|
18
|
+
log: this.hidden ? noop : console.log,
|
|
19
|
+
warning: this.hidden ? noop : Utils.warning,
|
|
20
|
+
success: this.hidden ? noop : Utils.success,
|
|
21
|
+
info: this.hidden ? noop : Utils.info,
|
|
22
|
+
};
|
|
23
|
+
const { log, warning, success, info } = loggers;
|
|
24
|
+
warning(`Unmounting ${this.luksMountpoint} to perform shrinking...`);
|
|
25
|
+
// Usa -l (lazy) se necessario, ma meglio umount pulito
|
|
26
|
+
await exec(`umount ${this.luksMountpoint}`, this.echo);
|
|
27
|
+
// 1. Controllo integrità (CRUCIALE per homecrypt: ripara eventuali errori prima di ridimensionare)
|
|
28
|
+
warning(`Checking filesystem integrity...`);
|
|
29
|
+
await exec(`e2fsck -f -y ${this.luksDevice}`, this.echo);
|
|
30
|
+
// 2. Riduzione del filesystem al minimo
|
|
31
|
+
warning(`Shrinking filesystem to minimum size...`);
|
|
32
|
+
// resize2fs -M è sicuro se poi lasciamo margine nel contenitore
|
|
33
|
+
await exec(`resize2fs -M ${this.luksDevice}`, this.echo);
|
|
34
|
+
// 3. Calcolo della nuova dimensione del filesystem
|
|
35
|
+
warning(`Calculating new sizes...`);
|
|
36
|
+
const tuneOutput = (await exec(`tune2fs -l ${this.luksDevice}`, { capture: true })).data;
|
|
37
|
+
const blockSizeMatch = tuneOutput.match(/Block size:\s+(\d+)/);
|
|
38
|
+
const blockCountMatch = tuneOutput.match(/Block count:\s+(\d+)/);
|
|
39
|
+
if (!blockSizeMatch || !blockCountMatch) {
|
|
40
|
+
throw new Error("Could not determine filesystem size from tune2fs");
|
|
41
|
+
}
|
|
42
|
+
const blockSize = parseInt(blockSizeMatch[1], 10);
|
|
43
|
+
const blockCount = parseInt(blockCountMatch[1], 10);
|
|
44
|
+
const fsSizeBytes = blockSize * blockCount;
|
|
45
|
+
warning(`Actual Ext4 payload size: ${bytesToGB(fsSizeBytes)}`);
|
|
46
|
+
// 4. Calcolo dell'offset LUKS (Header size)
|
|
47
|
+
const statusOutput = (await exec(`cryptsetup status ${this.luksMappedName}`, { capture: true })).data;
|
|
48
|
+
const offsetMatch = statusOutput.match(/offset:\s+(\d+)\s+sectors/);
|
|
49
|
+
let luksHeaderBytes = 0;
|
|
50
|
+
if (offsetMatch && offsetMatch[1]) {
|
|
51
|
+
luksHeaderBytes = parseInt(offsetMatch[1], 10) * 512;
|
|
52
|
+
warning(`Detected LUKS header: ${bytesToGB(luksHeaderBytes)}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
luksHeaderBytes = 32 * 1024 * 1024; // Fallback 32MB
|
|
56
|
+
warning(`Could not detect LUKS offset, using safe fallback: 32MB`);
|
|
57
|
+
}
|
|
58
|
+
// 5. Calcolo dimensione finale SICURA
|
|
59
|
+
// Usiamo 200MB di margine. Su una ISO da 4GB è il 5%, un prezzo onesto per la stabilità.
|
|
60
|
+
// Questo spazio extra protegge sia lo squashfs (root) che i metadati sparsi (home).
|
|
61
|
+
const safetyMargin = 200 * 1024 * 1024;
|
|
62
|
+
let rawFinalSize = fsSizeBytes + luksHeaderBytes + safetyMargin;
|
|
63
|
+
// ALLINEAMENTO A 1MB: Fondamentale per evitare errori di I/O su device fisici o loop
|
|
64
|
+
const alignBlock = 1024 * 1024;
|
|
65
|
+
const finalFileSize = Math.ceil(rawFinalSize / alignBlock) * alignBlock;
|
|
66
|
+
warning(`------------------------------------------------`);
|
|
67
|
+
warning(`SAFE SHRINK CALCULATION:`);
|
|
68
|
+
warning(` FS Payload: ${bytesToGB(fsSizeBytes)}`);
|
|
69
|
+
warning(` LUKS Header: ${bytesToGB(luksHeaderBytes)}`);
|
|
70
|
+
warning(` SafetyMargin: ${bytesToGB(safetyMargin)}`);
|
|
71
|
+
warning(` Alignment: 1 MB`);
|
|
72
|
+
warning(` FINAL SIZE: ${bytesToGB(finalFileSize)}`);
|
|
73
|
+
warning(`------------------------------------------------`);
|
|
74
|
+
// 6. Chiusura volume
|
|
75
|
+
warning(`Closing LUKS volume ${this.luksMappedName}...`);
|
|
76
|
+
await this.luksExecuteCommand('cryptsetup', ['close', this.luksMappedName]);
|
|
77
|
+
// 7. Truncate finale
|
|
78
|
+
warning(`Truncating ${this.luksFile} to release unused space...`);
|
|
79
|
+
await exec(`truncate -s ${finalFileSize} ${this.luksFile}`, this.echo);
|
|
80
|
+
}
|
|
81
|
+
function bytesToGB(bytes) {
|
|
82
|
+
if (bytes === 0)
|
|
83
|
+
return '0.00 GB';
|
|
84
|
+
const gigabytes = bytes / (1024 * 1024 * 1024);
|
|
85
|
+
return gigabytes.toFixed(2) + ' GB';
|
|
86
|
+
}
|
|
@@ -9,7 +9,7 @@ import chalk from 'chalk';
|
|
|
9
9
|
import mustache from 'mustache';
|
|
10
10
|
// packages
|
|
11
11
|
import fs from 'node:fs';
|
|
12
|
-
import shx from '
|
|
12
|
+
import { shx } from '../../lib/utils.js';
|
|
13
13
|
import path from 'path';
|
|
14
14
|
// libraries
|
|
15
15
|
import { exec } from '../../lib/utils.js';
|
|
@@ -58,7 +58,7 @@ export async function produce(kernel = '', clone = false, homecrypt = false, ful
|
|
|
58
58
|
else if (this.fullcrypt) {
|
|
59
59
|
this.luksMappedName = 'root.img';
|
|
60
60
|
}
|
|
61
|
-
this.luksFile = `/tmp/${this.luksMappedName}`;
|
|
61
|
+
this.luksFile = `/var/tmp/${this.luksMappedName}`;
|
|
62
62
|
this.luksMappedName = this.luksMappedName;
|
|
63
63
|
this.luksMountpoint = `/tmp/mnt/${this.luksMappedName}`;
|
|
64
64
|
this.luksDevice = `/dev/mapper/${this.luksMappedName}`;
|
|
@@ -131,8 +131,6 @@ export async function produce(kernel = '', clone = false, homecrypt = false, ful
|
|
|
131
131
|
* homecrypt/fullcrypt/clone/standard
|
|
132
132
|
*/
|
|
133
133
|
if (this.homecrypt) {
|
|
134
|
-
this.settings.config.user_opt = 'live'; // patch for humans
|
|
135
|
-
this.settings.config.user_opt_passwd = 'evolution';
|
|
136
134
|
Utils.warning("eggs will SAVE users and users' data ENCRYPTED on the live (ISO)/live/home.img");
|
|
137
135
|
}
|
|
138
136
|
else if (this.fullcrypt) {
|
|
@@ -195,10 +193,10 @@ export async function produce(kernel = '', clone = false, homecrypt = false, ful
|
|
|
195
193
|
/**
|
|
196
194
|
* installer
|
|
197
195
|
*/
|
|
198
|
-
this.incubator = new Incubator(this.settings.remix, this.settings.distro, this.settings.config.user_opt, this.theme, this.clone || this.fullcrypt, verbose);
|
|
196
|
+
this.incubator = new Incubator(this.settings.remix, this.settings.distro, this.settings.config.user_opt, this.theme, this.clone || this.fullcrypt || this.homecrypt, verbose);
|
|
199
197
|
await this.incubator.config(release);
|
|
200
|
-
//
|
|
201
|
-
await Utils.sleep(5000);
|
|
198
|
+
// 5 secondi di sleep
|
|
199
|
+
await Utils.sleep(5000);
|
|
202
200
|
await this.bindLiveFs();
|
|
203
201
|
await this.bindVfs();
|
|
204
202
|
/**
|
|
@@ -228,36 +226,80 @@ export async function produce(kernel = '', clone = false, homecrypt = false, ful
|
|
|
228
226
|
await this.initrdDracut();
|
|
229
227
|
}
|
|
230
228
|
}
|
|
231
|
-
// We
|
|
229
|
+
// We don't need more
|
|
232
230
|
await this.ubindVfs();
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
231
|
+
// mistero della Fede
|
|
232
|
+
await this.editLiveFs();
|
|
233
|
+
/**
|
|
234
|
+
* Autologin solse per non clone
|
|
235
|
+
*/
|
|
236
|
+
if (!(this.clone || this.homecrypt || this.fullcrypt)) {
|
|
238
237
|
await this.usersRemove();
|
|
239
238
|
await this.userCreateLive();
|
|
240
239
|
if (Pacman.isInstalledGui()) {
|
|
240
|
+
// add GUI autologin
|
|
241
241
|
await this.createXdgAutostart(this.settings.config.theme, myAddons, myLinks, noicons);
|
|
242
|
-
/**
|
|
243
|
-
* GUI installed but NOT Desktop Manager: just create motd and issue
|
|
244
|
-
*/
|
|
245
|
-
// if (displaymanager().length > 0) {
|
|
246
|
-
// this.cliAutologin.addIssue(this.settings.distro.distroId, this.settings.distro.codenameId, this.settings.config.user_opt, this.settings.config.user_opt_passwd, this.settings.config.root_passwd, this.settings.work_dir.merged)
|
|
247
|
-
// this.cliAutologin.addMotd(this.settings.distro.distroId, this.settings.distro.codenameId, this.settings.config.user_opt, this.settings.config.user_opt_passwd, this.settings.config.root_passwd, this.settings.work_dir.merged)
|
|
248
|
-
// }
|
|
249
242
|
}
|
|
250
243
|
else {
|
|
244
|
+
// add cli-autologin
|
|
251
245
|
this.cliAutologin.add(this.settings.distro.distroId, this.settings.distro.codenameId, this.settings.config.user_opt, this.settings.config.user_opt_passwd, this.settings.config.root_passwd, this.settings.work_dir.merged);
|
|
252
246
|
}
|
|
253
247
|
}
|
|
254
|
-
|
|
248
|
+
/**
|
|
249
|
+
* configurazione homecrytp
|
|
250
|
+
*/
|
|
255
251
|
if (this.homecrypt) {
|
|
252
|
+
// Occorre forzare il login CLI
|
|
253
|
+
if (Utils.isSystemd()) {
|
|
254
|
+
const systemdDir = `${this.settings.work_dir.merged}/etc/systemd/system`;
|
|
255
|
+
// remove eventuali autologin
|
|
256
|
+
if (fs.existsSync(`${systemdDir}/getty@tty1.service.d`)) {
|
|
257
|
+
await exec(`rm -rf ${systemdDir}/getty@tty1.service.d/*`);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
await exec(`mkdir -p ${systemdDir}/getty@tty1.service.d`);
|
|
261
|
+
}
|
|
262
|
+
let content = ``;
|
|
263
|
+
content += `[Service]\n`;
|
|
264
|
+
content += `ExecStart=\n`;
|
|
265
|
+
content += `ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I \$TERM\n`;
|
|
266
|
+
fs.writeFileSync(`${systemdDir}/getty@tty1.service.d/no-autologin.conf`, content);
|
|
267
|
+
}
|
|
268
|
+
else if (Utils.isSysvinit()) {
|
|
269
|
+
const inittabPath = `${this.settings.work_dir.merged}/etc/inittab`;
|
|
270
|
+
if (fs.existsSync(inittabPath)) {
|
|
271
|
+
// Non funziona per Devuan
|
|
272
|
+
let content = fs.readFileSync(inittabPath, 'utf-8');
|
|
273
|
+
// La riga standard per Devuan/Debian SysVinit.
|
|
274
|
+
// 1: ID
|
|
275
|
+
// 2345: Runlevels in cui attivarlo (Nota che il tuo boot è in runlevel 2)
|
|
276
|
+
// respawn: Riavvia getty se muore
|
|
277
|
+
// /sbin/getty 38400 tty1: Il comando
|
|
278
|
+
const tty1Line = '1:2345:respawn:/sbin/agetty --noclear tty1 linux';
|
|
279
|
+
// Rimuoviamo vecchie definizioni di tty1 (anche se commentate o diverse)
|
|
280
|
+
// Cerca righe che iniziano con "1:"
|
|
281
|
+
const regex = /^1:.*$/gm;
|
|
282
|
+
if (regex.test(content)) {
|
|
283
|
+
// Sostituisce la riga esistente
|
|
284
|
+
content = content.replace(regex, tty1Line);
|
|
285
|
+
console.log('Fixed tty1 in inittab (replaced)');
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
// Se non c'è, la aggiunge in fondo (dopo i commenti iniziali)
|
|
289
|
+
content += `\n${tty1Line}\n`;
|
|
290
|
+
console.log('Fixed tty1 in inittab (appended)');
|
|
291
|
+
}
|
|
292
|
+
// FIX CRITICO PER --cryptedhome / LIVE:
|
|
293
|
+
// A volte le live commentano tutte le tty per usare i propri hook.
|
|
294
|
+
// Assicurati che non ci siano altre righe strane che confliggono.
|
|
295
|
+
fs.writeFileSync(inittabPath, content);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
256
298
|
/**
|
|
257
299
|
* homecrypt: installa il supporto
|
|
258
300
|
*/
|
|
259
301
|
const squashfsRoot = this.settings.work_dir.merged;
|
|
260
|
-
const homeImgPath = this.
|
|
302
|
+
const homeImgPath = this.distroLiveMediumPath + 'live/home.img';
|
|
261
303
|
this.installHomecryptSupport(squashfsRoot, homeImgPath);
|
|
262
304
|
}
|
|
263
305
|
mksquashfsCmd = await this.makeSquashfs(scriptOnly, includeRootHome);
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* src/classes/ovary.d/user-create-live.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* license: MIT
|
|
4
|
+
* * REFACTORED: Uses "The SysUser Master" class.
|
|
5
|
+
* Creates the live user directly in the merged filesystem safely.
|
|
7
6
|
*/
|
|
8
7
|
import Ovary from '../ovary.js';
|
|
9
|
-
|
|
10
|
-
* list degli utenti: grep -E 1[0-9]{3} /etc/passwd | sed s/:/\ / | awk '{print $1}'
|
|
11
|
-
* create la home per user_opt
|
|
12
|
-
* @param verbose
|
|
13
|
-
*/
|
|
14
|
-
export declare function userCreateLive(this: Ovary): Promise<void>;
|
|
8
|
+
export default function userCreateLive(this: Ovary): Promise<void>;
|