penguins-eggs 25.10.6 → 25.10.19
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 +51 -145
- package/README.md +3 -829
- package/addons/eggs/theme/livecd/isolinux.main.simple.cfg +3 -3
- package/conf/distros/trixie/calamares/modules/shellprocess@boot_deploy.yml +3 -4
- package/conf/love.yaml +1 -1
- package/dist/classes/distro.js +9 -2
- package/dist/classes/diversions.d.ts +1 -1
- package/dist/classes/diversions.js +27 -8
- package/dist/classes/incubation/incubator.d/archlinux.js +1 -0
- package/dist/classes/incubation/incubator.d/trixie.js +7 -10
- package/dist/classes/ovary.d/edit-live-fs.d.ts +1 -1
- package/dist/classes/ovary.d/edit-live-fs.js +1 -7
- package/dist/classes/ovary.d/fertilization.js +1 -0
- package/dist/classes/ovary.d/finished.js +1 -5
- package/dist/classes/ovary.d/initrd.d.ts +1 -1
- package/dist/classes/ovary.d/initrd.js +17 -19
- package/dist/classes/ovary.d/live-create-structure.js +1 -4
- package/dist/classes/ovary.d/luks-get-password.d.ts +12 -0
- package/dist/classes/ovary.d/luks-get-password.js +57 -0
- package/dist/classes/ovary.d/luks-home-support.d.ts +12 -0
- package/dist/classes/ovary.d/luks-home-support.js +75 -0
- package/dist/classes/ovary.d/luks-home.d.ts +15 -0
- package/dist/classes/ovary.d/luks-home.js +140 -0
- package/dist/classes/ovary.d/luks-root-bootstrap-builder.d.ts +11 -0
- package/dist/classes/ovary.d/luks-root-bootstrap-builder.js +45 -0
- package/dist/classes/ovary.d/luks-root.d.ts +15 -0
- package/dist/classes/ovary.d/luks-root.js +126 -0
- package/dist/classes/ovary.d/make-efi.js +1 -1
- package/dist/classes/ovary.d/make-squashfs.d.ts +1 -1
- package/dist/classes/ovary.d/make-squashfs.js +7 -3
- package/dist/classes/ovary.d/produce.d.ts +3 -3
- package/dist/classes/ovary.d/produce.js +76 -48
- package/dist/classes/ovary.d/syslinux.js +1 -1
- package/dist/classes/ovary.d/xorriso-command.d.ts +2 -2
- package/dist/classes/ovary.d/xorriso-command.js +27 -29
- package/dist/classes/ovary.d.ts +35 -16
- package/dist/classes/ovary.js +42 -16
- package/dist/classes/utils.d.ts +1 -0
- package/dist/classes/utils.js +3 -0
- package/dist/commands/config.d.ts +1 -1
- package/dist/commands/config.js +2 -2
- package/dist/commands/love.d.ts +3 -0
- package/dist/commands/love.js +40 -2
- package/dist/commands/produce.d.ts +3 -2
- package/dist/commands/produce.js +14 -17
- package/dist/commands/tools/{ppa.d.ts → repo.d.ts} +2 -2
- package/dist/commands/tools/{ppa.js → repo.js} +69 -67
- package/dracut/create-symlink +71 -0
- package/dracut/dracut-log.txt +3 -0
- package/dracut/dracut.conf.d/50-live.conf +24 -6
- package/dracut/dracut.conf.d/README.md +10 -0
- package/dracut/export +4 -0
- package/dracut/export-dracut-analysis +51 -0
- package/dracut/export-dracut-log +2 -0
- package/dracut/mkisofs +10 -0
- package/dracut/modules.d/00debug-shell/debug-hook.sh +13 -0
- package/dracut/modules.d/00debug-shell/module-setup.sh +20 -0
- package/dracut/modules.d/90block/README.md +7 -0
- package/dracut/modules.d/90block/block-cmdline.sh +3 -0
- package/dracut/modules.d/90block/module-setup.sh +15 -0
- package/dracut/modules.d/95iso-scan/README.md +3 -0
- package/dracut/modules.d/95iso-scan/iso-scan-fallback.sh +12 -0
- package/dracut/modules.d/95iso-scan/iso-scan.sh +92 -0
- package/dracut/modules.d/95iso-scan/module-setup.sh +18 -0
- package/dracut/modules.d/95luks-loop/README.md +9 -0
- package/dracut/modules.d/95luks-loop/luks-loop.sh +90 -0
- package/dracut/modules.d/95luks-loop/module-setup.sh +17 -0
- package/dracut/renew-initramfs +17 -0
- package/dracut/sbin2bin +10 -0
- package/dracut/update-dracut-conf-d +2 -0
- package/dracut/update-dracut-modules +62 -0
- package/manpages/doc/man/eggs.1.gz +0 -0
- package/manpages/doc/man/eggs.html +7 -661
- package/package.json +9 -8
- package/perrisbrewery/template/dependencies.yaml +6 -5
- package/scripts/_eggs +16 -31
- package/scripts/eggs.bash +4 -6
- package/scripts/luks-root-bootstrap-create.sh +235 -0
- package/scripts/luks-root-unlock.sh +172 -0
- package/scripts/mount-encrypted-home.sh +223 -0
- package/dist/commands/syncfrom.d.ts +0 -45
- package/dist/commands/syncfrom.js +0 -152
- package/dist/commands/syncto.d.ts +0 -40
- package/dist/commands/syncto.js +0 -175
|
@@ -13,20 +13,20 @@ label Live
|
|
|
13
13
|
say "Booting {{{fullname}}} GNU/Linux (kernel {{{kernel}}})"
|
|
14
14
|
linux {{{vmlinuz}}}
|
|
15
15
|
append initrd={{{initrdImg}}} {{{kernel_parameters}}}
|
|
16
|
-
|
|
16
|
+
# RIMUOVERE O CONTROLLARE evm=off per overlayfs
|
|
17
17
|
|
|
18
18
|
label Safe
|
|
19
19
|
menu label {{{fullname}}} Safe Mode
|
|
20
20
|
say "Booting {{{fullname}}} GNU/Linux (kernel {{{kernel}}})"
|
|
21
21
|
linux {{{vmlinuz}}}
|
|
22
|
-
append initrd={{{initrdImg}}} {{{kernel_parameters}}}
|
|
22
|
+
append initrd={{{initrdImg}}} {{{kernel_parameters}}}
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
label Text
|
|
26
26
|
menu label {{{fullname}}} Text Mode
|
|
27
27
|
say "Booting {{{fullname}}} GNU/Linux (kernel {{{kernel}}})"
|
|
28
28
|
linux {{{vmlinuz}}}
|
|
29
|
-
append initrd={{{initrdImg}}} {{{kernel_parameters}}}
|
|
29
|
+
append initrd={{{initrdImg}}} {{{kernel_parameters}}}
|
|
30
30
|
|
|
31
31
|
label local
|
|
32
32
|
menu label Boot from local disk
|
|
@@ -17,8 +17,7 @@ script:
|
|
|
17
17
|
# Riconfigureremo il kernel nel modulo boot_reconfigure per garantire che gli hook
|
|
18
18
|
# vengano eseguiti secondo necessità.
|
|
19
19
|
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
# debian
|
|
20
|
+
# INITRAMFS = '/run/live/medium/'
|
|
21
|
+
# DRACUT = '/run/initramfs/live/'
|
|
24
22
|
- cp --preserve=timestamps /run/live/medium/live/vmlinuz-`uname -r` ${ROOT}/boot/vmlinuz-`uname -r`
|
|
23
|
+
#- cp --preserve=timestamps /run/initramfs/live/live/vmlinuz-`uname -r` ${ROOT}/boot/vmlinuz-`uname -r`
|
package/conf/love.yaml
CHANGED
package/dist/classes/distro.js
CHANGED
|
@@ -101,7 +101,7 @@ class Distro {
|
|
|
101
101
|
}
|
|
102
102
|
else if (this.distroId === 'Openmamba') {
|
|
103
103
|
this.familyId = 'openmamba';
|
|
104
|
-
this.distroLike = '
|
|
104
|
+
this.distroLike = 'Openmamba';
|
|
105
105
|
this.codenameId = 'rolling'; // viene rimosso dal nome
|
|
106
106
|
this.distroUniqueId = this.familyId; // per krill
|
|
107
107
|
this.liveMediumPath = '/run/initramfs/live/';
|
|
@@ -176,7 +176,14 @@ class Distro {
|
|
|
176
176
|
else if (this.codenameId === 'trixie') {
|
|
177
177
|
this.distroLike = 'Debian';
|
|
178
178
|
this.distroUniqueId = 'trixie';
|
|
179
|
-
this.liveMediumPath = '/run/live/medium/';
|
|
179
|
+
this.liveMediumPath = '/run/live/medium/'; //initramfs
|
|
180
|
+
// this.liveMediumPath = '/run/initramfs/live/' // dracut
|
|
181
|
+
/**
|
|
182
|
+
* dracut su trixie
|
|
183
|
+
if (Pacman.packageIsInstalled('dracut')) {
|
|
184
|
+
this.liveMediumPath = '/run/initramfs/live/'
|
|
185
|
+
}
|
|
186
|
+
*/
|
|
180
187
|
/**
|
|
181
188
|
* Debian 14 forky
|
|
182
189
|
*/
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* license: MIT
|
|
7
7
|
*/
|
|
8
8
|
import Distro from './distro.js';
|
|
9
|
+
import Pacman from './pacman.js';
|
|
9
10
|
export default class Diversions {
|
|
10
11
|
/**
|
|
11
12
|
*
|
|
@@ -66,14 +67,10 @@ export default class Diversions {
|
|
|
66
67
|
* @param volid
|
|
67
68
|
* @returns
|
|
68
69
|
*/
|
|
69
|
-
static kernelParameters(familyId, volid) {
|
|
70
|
+
static kernelParameters(familyId, volid, luksUuid = '') {
|
|
70
71
|
// GRUB_CMDLINE_LINUX='ipv6.disable=1'
|
|
71
72
|
let kp = "";
|
|
72
|
-
if (familyId === '
|
|
73
|
-
kp += `root=live:CDLABEL=${volid} rd.live.image rd.live.dir=/live rd.live.squashimg=filesystem.squashfs selinux=0 rootfstype=auto rd.locale.LANG=en_US.UTF-8 KEYBOARDTYPE=pc rd.vconsole.keymap=us rootflags=defaults,relatime,commit=60 nmi_watchdog=0 rhgb rd_NO_LUKS rd_NO_MD rd_NO_DM`;
|
|
74
|
-
// root=live:CDLABEL=ALDOS6420241128 rootfstype=auto ro liveimg quiet rd.locale.LANG=es_MX.UTF-8 KEYBOARDTYPE=pc SYSFONT=latarcyrheb-sun16 rd.vconsole.keymap=es rootflags=defaults,relatime,commit=60 selinux=0 nmi_watchdog=0 rhgb rd_NO_LUKS rd_NO_MD rd_NO_DM
|
|
75
|
-
}
|
|
76
|
-
else if (familyId === 'alpine') {
|
|
73
|
+
if (familyId === 'alpine') {
|
|
77
74
|
kp += `alpinelivelabel=${volid} alpinelivesquashfs=/mnt/live/filesystem.squashfs`;
|
|
78
75
|
}
|
|
79
76
|
else if (familyId === 'archlinux') {
|
|
@@ -81,14 +78,36 @@ export default class Diversions {
|
|
|
81
78
|
const distroId = this.distro().distroId;
|
|
82
79
|
if (this.isManjaroBased(distroId)) {
|
|
83
80
|
kp += ` misobasedir=manjaro misolabel=${volid}`;
|
|
84
|
-
// shx.exec(`mkdir -p ${this.settings.iso_work}.miso`)
|
|
85
81
|
}
|
|
86
82
|
else {
|
|
87
83
|
kp += ` archisobasedir=arch archisolabel=${volid}`;
|
|
88
84
|
}
|
|
89
85
|
}
|
|
90
86
|
else if (familyId === 'debian') {
|
|
91
|
-
|
|
87
|
+
/**
|
|
88
|
+
* da rivedere dracut/initramfs
|
|
89
|
+
*/
|
|
90
|
+
if (Pacman.packageIsInstalled('dracut')) {
|
|
91
|
+
if (luksUuid !== '') {
|
|
92
|
+
let append = `boot=live \
|
|
93
|
+
root=live:LABEL=${volid} \
|
|
94
|
+
rd.luks.loop=/live/luks.img \
|
|
95
|
+
eggs.luks.uuid=${luksUuid} \
|
|
96
|
+
rd.live.squashimg=filesystem.squashfs \
|
|
97
|
+
rd.live.overlay.overlayfs=1 \
|
|
98
|
+
nomodeset \
|
|
99
|
+
rd.break=pre-mount \
|
|
100
|
+
rd.shell`;
|
|
101
|
+
kp += append.replaceAll(/\s\s+/g, ' ');
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// dracut: rd.live.squashimg
|
|
105
|
+
kp += `root=live:CDLABEL=${volid} rd.live.image rd.live.dir=/live rd.live.squashimg=filesystem.squashfs`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
kp += `boot=live components locales=${process.env.LANG} cow_spacesize=2G`;
|
|
110
|
+
}
|
|
92
111
|
}
|
|
93
112
|
else if (familyId === 'fedora') {
|
|
94
113
|
kp += `root=live:CDLABEL=${volid} rd.live.image rd.live.dir=/live rd.live.squashimg=filesystem.squashfs selinux=0`;
|
|
@@ -59,6 +59,7 @@ export class Archlinux {
|
|
|
59
59
|
await fisherman.buildModule('users', this.theme);
|
|
60
60
|
await fisherman.buildModule('displaymanager');
|
|
61
61
|
await fisherman.buildModule('hwclock');
|
|
62
|
+
await fisherman.shellprocess('disable-grub-btrfs');
|
|
62
63
|
await fisherman.buildModule('grubcfg');
|
|
63
64
|
await fisherman.buildModule('bootloader');
|
|
64
65
|
await fisherman.buildModulePackages(this.distro, this.release);
|
|
@@ -62,24 +62,21 @@ export class Trixie {
|
|
|
62
62
|
await fisherman.buildModule('networkcfg');
|
|
63
63
|
await fisherman.buildModule('hwclock');
|
|
64
64
|
await fisherman.buildModule('services-systemd');
|
|
65
|
+
await fisherman.buildModule('luksbootkeyfile');
|
|
66
|
+
await fisherman.shellprocess('boot_deploy'); // contiene this.liveMediumPath
|
|
65
67
|
await fisherman.buildCalamaresModule('bootloader-config', true);
|
|
66
68
|
await fisherman.buildModule('grubcfg');
|
|
67
69
|
await fisherman.buildModule('bootloader');
|
|
68
|
-
await fisherman.
|
|
69
|
-
await fisherman.buildModule('luksbootkeyfile');
|
|
70
|
-
await fisherman.buildModule('plymouthcfg');
|
|
70
|
+
await fisherman.shellprocess('boot_reconfigure');
|
|
71
71
|
await fisherman.buildModule('initramfscfg');
|
|
72
|
-
await fisherman.
|
|
72
|
+
await fisherman.shellprocess('mkinitramfs');
|
|
73
|
+
await fisherman.buildModule('plymouthcfg');
|
|
74
|
+
await fisherman.buildModulePackages(this.distro, this.release);
|
|
73
75
|
await fisherman.buildCalamaresModule('dpkg-unsafe-io-undo', false);
|
|
74
76
|
await fisherman.buildModuleRemoveuser(this.user_opt);
|
|
75
77
|
await fisherman.buildCalamaresModule('sources-yolk-undo', false);
|
|
76
78
|
await fisherman.buildCalamaresModule('cleanup', true);
|
|
77
|
-
//
|
|
78
|
-
// await fisherman.contextualprocess('before_bootloader_context')
|
|
79
|
-
// shellprocess
|
|
80
|
-
await fisherman.shellprocess('mkinitramfs');
|
|
81
|
-
await fisherman.shellprocess('boot_deploy');
|
|
82
|
-
await fisherman.shellprocess('boot_reconfigure');
|
|
79
|
+
// await fisherman.buildModule('initramfs')
|
|
83
80
|
// libexec recreate
|
|
84
81
|
await exec(`rm -rf /usr/libexec/calamares`);
|
|
85
82
|
await exec(`mkdir -p /usr/libexec/calamares`);
|
|
@@ -17,4 +17,4 @@ import Ovary from '../ovary.js';
|
|
|
17
17
|
* - Add some basic files to /dev
|
|
18
18
|
* - Clear configs from /etc/network/interfaces, wicd and NetworkManager and netman
|
|
19
19
|
*/
|
|
20
|
-
export declare function editLiveFs(this: Ovary, clone?: boolean
|
|
20
|
+
export declare function editLiveFs(this: Ovary, clone?: boolean): Promise<void>;
|
|
@@ -27,7 +27,7 @@ const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
|
27
27
|
* - Add some basic files to /dev
|
|
28
28
|
* - Clear configs from /etc/network/interfaces, wicd and NetworkManager and netman
|
|
29
29
|
*/
|
|
30
|
-
export async function editLiveFs(clone = false
|
|
30
|
+
export async function editLiveFs(clone = false) {
|
|
31
31
|
if (this.verbose) {
|
|
32
32
|
console.log('Ovary: editLiveFs');
|
|
33
33
|
}
|
|
@@ -37,12 +37,6 @@ export async function editLiveFs(clone = false, cryptedclone = false) {
|
|
|
37
37
|
if (clone) {
|
|
38
38
|
await exec(`touch ${this.settings.work_dir.merged}/etc/penguins-eggs.d/is_clone`, this.echo);
|
|
39
39
|
}
|
|
40
|
-
/**
|
|
41
|
-
* /etc/penguins-eggs.d/is_crypted_clone file created on live
|
|
42
|
-
*/
|
|
43
|
-
if (cryptedclone) {
|
|
44
|
-
await exec(`touch ${this.settings.work_dir.merged}/etc/penguins-eggs.d/is_crypted_clone`, this.echo);
|
|
45
|
-
}
|
|
46
40
|
/**
|
|
47
41
|
* /etc/default/epoptes-client created on live
|
|
48
42
|
*/
|
|
@@ -21,6 +21,7 @@ export async function fertilization(snapshot_prefix = '', snapshot_basename = ''
|
|
|
21
21
|
this.familyId = distro.familyId;
|
|
22
22
|
this.distroId = distro.distroId;
|
|
23
23
|
this.distroLike = distro.distroLike;
|
|
24
|
+
this.distroLliveMediumPath = distro.liveMediumPath;
|
|
24
25
|
this.settings = new Settings();
|
|
25
26
|
if (await this.settings.load()) {
|
|
26
27
|
await this.settings.loadRemix(this.theme);
|
|
@@ -8,17 +8,13 @@
|
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
// packages
|
|
10
10
|
import path from 'path';
|
|
11
|
-
// interfaces
|
|
12
|
-
// libraries
|
|
13
|
-
// classes
|
|
14
|
-
import Utils from './../utils.js';
|
|
15
11
|
// _dirname
|
|
16
12
|
/**
|
|
17
13
|
* finished = show the results
|
|
18
14
|
* @param scriptOnly
|
|
19
15
|
*/
|
|
20
16
|
export function finished(scriptOnly = false) {
|
|
21
|
-
Utils.titles('produce')
|
|
17
|
+
// Utils.titles('produce')
|
|
22
18
|
if (scriptOnly) {
|
|
23
19
|
const pathOvarium = path.join(this.settings.config.snapshot_dir, 'ovarium');
|
|
24
20
|
console.log('eggs is finished!\n\nYou can find the scripts to build iso: ' + chalk.cyanBright(this.settings.isoFilename) + '\nin the ovarium: ' + chalk.cyanBright(pathOvarium) + '.');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ./src/classes/ovary.d/initrd
|
|
2
|
+
* ./src/classes/ovary.d/initrd.ts
|
|
3
3
|
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
4
|
* author: Piero Proietti
|
|
5
5
|
* email: piero.proietti@gmail.com
|
|
@@ -21,7 +21,10 @@ export async function initrdAlpine() {
|
|
|
21
21
|
let initrdImg = Utils.initrdImg();
|
|
22
22
|
initrdImg = initrdImg.slice(Math.max(0, initrdImg.lastIndexOf('/') + 1));
|
|
23
23
|
const pathConf = path.resolve(__dirname, `../../../mkinitfs/live.conf`);
|
|
24
|
-
|
|
24
|
+
const prefix = this.settings.config.snapshot_prefix;
|
|
25
|
+
const log = `> ${this.settings.iso_work}${prefix}mkinitfs.log.txt 2>&1`;
|
|
26
|
+
const cmd = `mkinitfs -c ${pathConf} -o ${this.settings.iso_work}live/${initrdImg} ${this.kernel} ${log}`;
|
|
27
|
+
await exec(cmd, this.echo);
|
|
25
28
|
}
|
|
26
29
|
/**
|
|
27
30
|
* initrdArch
|
|
@@ -52,7 +55,9 @@ export async function initrdArch() {
|
|
|
52
55
|
}
|
|
53
56
|
await exec(`cp ${hookSrc} ${hookSaved}`);
|
|
54
57
|
await exec(edit, this.echo);
|
|
55
|
-
|
|
58
|
+
const prefix = this.settings.config.snapshot_prefix;
|
|
59
|
+
const log = `> ${this.settings.iso_work}${prefix}mkinitcpio.log.txt 2>&1`;
|
|
60
|
+
let cmd = `mkinitcpio -c ${fileConf} -g ${this.settings.iso_work}live/${path.basename(this.initrd)} -k ${this.kernel} ${log}`;
|
|
56
61
|
await exec(cmd, this.echo);
|
|
57
62
|
await exec(`rm -f ${hookDest}`);
|
|
58
63
|
if (restore) {
|
|
@@ -65,30 +70,23 @@ export async function initrdArch() {
|
|
|
65
70
|
*/
|
|
66
71
|
export async function initrdDebian(verbose = false) {
|
|
67
72
|
Utils.warning(`creating ${this.initrd} using mkinitramfs on (ISO)/live`);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
await exec(`mkinitramfs -o ${this.settings.iso_work}live/${path.basename(this.initrd)} ${this.kernel} ${this.toNull}`, this.echo);
|
|
74
|
-
if (isCrypted) {
|
|
75
|
-
await exec('mv /etc/crypttab.saved /etc/crypttab', this.echo);
|
|
76
|
-
}
|
|
73
|
+
const prefix = this.settings.config.snapshot_prefix;
|
|
74
|
+
const dest = `${this.settings.iso_work}live/${path.basename(this.initrd)}`;
|
|
75
|
+
const log = `> ${this.settings.iso_work}${prefix}mkinitramfs.log.txt 2>&1`;
|
|
76
|
+
const cmd = `mkinitramfs -o ${dest} ${this.kernel} ${log}`;
|
|
77
|
+
await exec(cmd, this.echo);
|
|
77
78
|
}
|
|
78
79
|
/*
|
|
79
|
-
* initrdDracut) Almalinux/Fedora/Openmamba/Opensuse/Rocky/
|
|
80
|
+
* initrdDracut) Almalinux/Fedora/Openmamba/Opensuse/Rocky/
|
|
80
81
|
*/
|
|
81
82
|
export async function initrdDracut() {
|
|
82
83
|
Utils.warning(`creating ${path.basename(this.initrd)} using dracut on (ISO)/live`);
|
|
83
84
|
const prefix = this.settings.config.snapshot_prefix;
|
|
84
|
-
const confdir = '--confdir ' + path.resolve(__dirname, `../../../dracut/dracut.conf.d`);
|
|
85
|
-
// const dracutdir='--dracutdir /opt/penguins-eggs/dracut'
|
|
86
|
-
const dracutdir = '';
|
|
87
|
-
const dest = `${this.settings.iso_work}live/${path.basename(this.initrd)}`;
|
|
88
85
|
const log = `> ${this.settings.iso_work}${prefix}dracut.log.txt 2>&1`;
|
|
86
|
+
const confdir = '--confdir ' + path.resolve(__dirname, `../../../dracut/dracut.conf.d`);
|
|
89
87
|
const kmoddir = `--kmoddir /lib/modules/${this.kernel}`;
|
|
90
|
-
const
|
|
91
|
-
|
|
88
|
+
const initramfs = `${this.settings.iso_work}live/${path.basename(this.initrd)}`;
|
|
89
|
+
const cmd = `dracut --force ${confdir} ${kmoddir} ${initramfs} ${this.kernel} ${log}`;
|
|
92
90
|
console.log(cmd);
|
|
93
91
|
await exec(cmd, this.echo);
|
|
94
92
|
// clean per btrfs
|
|
@@ -17,10 +17,7 @@ const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
|
17
17
|
* Crea la struttura della workdir
|
|
18
18
|
*/
|
|
19
19
|
export async function liveCreateStructure() {
|
|
20
|
-
|
|
21
|
-
console.log('Ovary: liveCreateStructure');
|
|
22
|
-
}
|
|
23
|
-
Utils.warning(`creating egg in ${this.nest}`);
|
|
20
|
+
Utils.warning(`creating live structure on ${this.nest}`);
|
|
24
21
|
let cmd = '';
|
|
25
22
|
cmd = `# create nest\n`;
|
|
26
23
|
cmd += `mkdir -p ${this.nest}\n`;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ./src/classes/ovary.d/luks-home.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
|
+
* Ottiene la password LUKS dall'utente
|
|
11
|
+
*/
|
|
12
|
+
export declare function luksGetPassword(this: Ovary): Promise<void>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ./src/classes/ovary.d/luks-home.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
|
+
/**
|
|
10
|
+
* Ottiene la password LUKS dall'utente
|
|
11
|
+
*/
|
|
12
|
+
export async function luksGetPassword() {
|
|
13
|
+
const inquirer = (await import('inquirer')).default;
|
|
14
|
+
// Chiedi se usare password di default
|
|
15
|
+
const useDefault = await inquirer.prompt([{
|
|
16
|
+
type: 'confirm',
|
|
17
|
+
name: 'useDefault',
|
|
18
|
+
message: `Use default password "${this.luksPassword}" for LUKS encryption?`,
|
|
19
|
+
default: false
|
|
20
|
+
}]);
|
|
21
|
+
if (useDefault.useDefault) {
|
|
22
|
+
Utils.warning(`Using default password: ${this.luksPassword}`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Chiedi password personalizzata con conferma
|
|
26
|
+
let password = '';
|
|
27
|
+
let confirmed = false;
|
|
28
|
+
while (!confirmed) {
|
|
29
|
+
const answers = await inquirer.prompt([
|
|
30
|
+
{
|
|
31
|
+
type: 'password',
|
|
32
|
+
name: 'password',
|
|
33
|
+
message: 'Enter LUKS encryption password:',
|
|
34
|
+
validate: (input) => {
|
|
35
|
+
if (input.length < 8) {
|
|
36
|
+
return 'Password must be at least 8 characters';
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
type: 'password',
|
|
43
|
+
name: 'confirm',
|
|
44
|
+
message: 'Confirm password:'
|
|
45
|
+
}
|
|
46
|
+
]);
|
|
47
|
+
if (answers.password === answers.confirm) {
|
|
48
|
+
password = answers.password;
|
|
49
|
+
confirmed = true;
|
|
50
|
+
Utils.success('Password confirmed!');
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
Utils.error('Passwords do not match. Please try again.');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
this.luksPassword = password;
|
|
57
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ./src/classes/ovary.d/luks-home-support.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
|
+
* Installa i file necessari per sbloccare home.img LUKS durante il boot
|
|
11
|
+
*/
|
|
12
|
+
export declare function installHomecryptSupport(this: Ovary, squashfsRoot: string, homeImgPath: string): void;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ./src/classes/ovary.d/luks-home-support.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
|
+
// packages
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
import { dirname } from 'path';
|
|
13
|
+
import Utils from '../utils.js';
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname = dirname(__filename);
|
|
16
|
+
/**
|
|
17
|
+
* Installa i file necessari per sbloccare home.img LUKS durante il boot
|
|
18
|
+
*/
|
|
19
|
+
export function installHomecryptSupport(squashfsRoot, homeImgPath) {
|
|
20
|
+
Utils.warning('installing encrypted home support...');
|
|
21
|
+
// console.log("squashfsRoot:", squashfsRoot)
|
|
22
|
+
// console.log("homeImgPath:", homeImgPath)
|
|
23
|
+
// Leggi il template bash
|
|
24
|
+
const templatePath = path.join(__dirname, '../../../scripts/mount-encrypted-home.sh');
|
|
25
|
+
let bashScript = fs.readFileSync(templatePath, 'utf8');
|
|
26
|
+
// Sostituisci il placeholder con il path reale
|
|
27
|
+
bashScript = bashScript.replace('__HOME_IMG_PATH__', homeImgPath);
|
|
28
|
+
// Systemd service
|
|
29
|
+
const systemdService = `[Unit]
|
|
30
|
+
Description=Unlock and mount encrypted home.img
|
|
31
|
+
DefaultDependencies=no
|
|
32
|
+
After=systemd-udev-settle.service local-fs-pre.target
|
|
33
|
+
Before=local-fs.target display-manager.service
|
|
34
|
+
ConditionPathExists=${homeImgPath}
|
|
35
|
+
|
|
36
|
+
[Service]
|
|
37
|
+
Type=oneshot
|
|
38
|
+
RemainAfterExit=yes
|
|
39
|
+
StandardInput=tty
|
|
40
|
+
StandardOutput=journal+console
|
|
41
|
+
StandardError=journal+console
|
|
42
|
+
TTYPath=/dev/console
|
|
43
|
+
TTYReset=yes
|
|
44
|
+
TTYVHangup=yes
|
|
45
|
+
ExecStart=/usr/local/bin/mount-encrypted-home.sh
|
|
46
|
+
ExecStop=/bin/bash -c 'umount /home && cryptsetup close live-home'
|
|
47
|
+
|
|
48
|
+
[Install]
|
|
49
|
+
WantedBy=local-fs.target
|
|
50
|
+
`;
|
|
51
|
+
// Percorsi di destinazione
|
|
52
|
+
const scriptPath = path.join(squashfsRoot, 'usr/local/bin/mount-encrypted-home.sh');
|
|
53
|
+
const servicePath = path.join(squashfsRoot, 'etc/systemd/system/mount-encrypted-home.service');
|
|
54
|
+
const symlinkDir = path.join(squashfsRoot, 'etc/systemd/system/local-fs.target.wants');
|
|
55
|
+
const symlinkPath = path.join(symlinkDir, 'mount-encrypted-home.service');
|
|
56
|
+
// Crea le directory necessarie
|
|
57
|
+
fs.mkdirSync(path.dirname(scriptPath), { recursive: true });
|
|
58
|
+
fs.mkdirSync(path.dirname(servicePath), { recursive: true });
|
|
59
|
+
fs.mkdirSync(symlinkDir, { recursive: true });
|
|
60
|
+
// Scrivi lo script
|
|
61
|
+
fs.writeFileSync(scriptPath, bashScript);
|
|
62
|
+
fs.chmodSync(scriptPath, 0o755);
|
|
63
|
+
// console.log(`✓ Created: ${scriptPath}`)
|
|
64
|
+
// Scrivi il service
|
|
65
|
+
fs.writeFileSync(servicePath, systemdService);
|
|
66
|
+
// console.log(`✓ Created: ${servicePath}`)
|
|
67
|
+
// Crea il symlink per abilitare il service
|
|
68
|
+
if (fs.existsSync(symlinkPath)) {
|
|
69
|
+
fs.unlinkSync(symlinkPath);
|
|
70
|
+
}
|
|
71
|
+
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
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ./src/classes/ovary.d/luks-home.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
|
+
* luksHome()
|
|
11
|
+
*
|
|
12
|
+
* create a container LUKS with the entire
|
|
13
|
+
* filesystem.squashfs
|
|
14
|
+
*/
|
|
15
|
+
export declare function luksHome(this: Ovary, clone?: boolean, homecrypt?: boolean): Promise<void>;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ./src/classes/ovary.d/luks-home.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
|
+
// packages
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import Utils from '../utils.js';
|
|
12
|
+
import { exec } from '../../lib/utils.js';
|
|
13
|
+
/**
|
|
14
|
+
* luksHome()
|
|
15
|
+
*
|
|
16
|
+
* create a container LUKS with the entire
|
|
17
|
+
* filesystem.squashfs
|
|
18
|
+
*/
|
|
19
|
+
export async function luksHome(clone = false, homecrypt = false) {
|
|
20
|
+
try {
|
|
21
|
+
/**
|
|
22
|
+
* this.luksName = 'home.img';
|
|
23
|
+
* this.luksFile = `/tmp/${luksName}`
|
|
24
|
+
* this.luksDevice = `/dev/mapper/${luksName}`
|
|
25
|
+
* this.luksMappedName = this.luksName
|
|
26
|
+
* this.luksMountpoint = `/tmp/mnt/${luksName}`
|
|
27
|
+
* this.luksPassword = 'evolution'
|
|
28
|
+
*/
|
|
29
|
+
console.log();
|
|
30
|
+
console.log('====================================');
|
|
31
|
+
console.log(` Creating ${this.luksName}`);
|
|
32
|
+
console.log('====================================');
|
|
33
|
+
// Utils.warning('1. Calculation of space requirements...')
|
|
34
|
+
let sizeString = (await exec('du -sb --exclude=/home/eggs /home', { capture: true })).data.trim().split(/\s+/)[0];
|
|
35
|
+
let size = Number.parseInt(sizeString, 10);
|
|
36
|
+
// const fsOverhead = Math.max(size * 0.1, 100 * 1024 * 1024)
|
|
37
|
+
// const luksSize = size + fsOverhead + (size * 0.2) // +20% di sicurezza
|
|
38
|
+
const luksSize = Math.ceil(size * 2);
|
|
39
|
+
Utils.warning(`homes size: ${bytesToGB(size)}`);
|
|
40
|
+
Utils.warning(`partition LUKS ${this.luksFile} size: ${bytesToGB(luksSize)}`);
|
|
41
|
+
Utils.warning(`creating partition LUKS: ${this.luksFile}`);
|
|
42
|
+
await executeCommand('truncate', ['--size', `${luksSize}`, this.luksFile]);
|
|
43
|
+
Utils.warning(`formatting ${this.luksFile} as a LUKS volume...`);
|
|
44
|
+
await executeCommand('cryptsetup', ['--batch-mode', 'luksFormat', this.luksFile], `${this.luksPassword}\n`);
|
|
45
|
+
this.luksUuid = (await exec(`cryptsetup luksUUID ${this.luksFile}`, { capture: true, echo: false })).data.trim();
|
|
46
|
+
Utils.warning(`LUKS uuid: ${this.luksUuid}`);
|
|
47
|
+
Utils.warning(`opening the LUKS volume. It will be mapped to ${this.luksDevice}`);
|
|
48
|
+
await executeCommand('cryptsetup', ['luksOpen', this.luksFile, this.luksMappedName], `${this.luksPassword}\n`);
|
|
49
|
+
Utils.warning(`formatting c ext4 `);
|
|
50
|
+
await exec(`mkfs.ext4 -L live-home ${this.luksDevice}`, this.echo);
|
|
51
|
+
Utils.warning(`mounting ${this.luksDevice} on ${this.luksMountpoint}`);
|
|
52
|
+
if (fs.existsSync(this.luksMountpoint)) {
|
|
53
|
+
if (!Utils.isMountpoint(this.luksMountpoint)) {
|
|
54
|
+
await exec(`rm -rf ${this.luksMountpoint}`, this.echo);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
throw new Error(`${this.luksMountpoint} is already mounted, process will abort!`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
await exec(`mkdir -p ${this.luksMountpoint}`, this.echo);
|
|
61
|
+
await exec(`mount /dev/mapper/${this.luksName} ${this.luksMountpoint}`, this.echo);
|
|
62
|
+
Utils.warning(`copying /home on ${this.luksMountpoint}`);
|
|
63
|
+
await exec(`rsync -ah --exclude='eggs' /home/ ${this.luksMountpoint}`, this.echo);
|
|
64
|
+
Utils.warning(`saving user accounts info...`);
|
|
65
|
+
// Crea directory per backup system files
|
|
66
|
+
await exec(`mkdir -p ${this.luksMountpoint}/.system-backup`, this.echo);
|
|
67
|
+
// Filtra solo utenti con UID >= 1000
|
|
68
|
+
await exec(`awk -F: '$3 >= 1000 {print}' /etc/passwd > ${this.luksMountpoint}/.system-backup/passwd`, this.echo);
|
|
69
|
+
await exec(`awk -F: '$3 >= 1000 {print}' /etc/shadow > ${this.luksMountpoint}/.system-backup/shadow`, this.echo);
|
|
70
|
+
// Per i gruppi: salva TUTTI (non filtrare per GID)
|
|
71
|
+
// Gli utenti possono appartenere a gruppi di sistema (sudo, audio, video, etc.)
|
|
72
|
+
await exec(`cp /etc/group ${this.luksMountpoint}/.system-backup/group`, this.echo);
|
|
73
|
+
await exec(`cp /etc/gshadow ${this.luksMountpoint}/.system-backup/gshadow`, this.echo);
|
|
74
|
+
Utils.warning(`unmount ${this.luksDevice}`);
|
|
75
|
+
await exec(`umount ${this.luksMountpoint}`, this.echo);
|
|
76
|
+
Utils.warning(`closing LUKS volume ${this.luksMappedName}.`);
|
|
77
|
+
await executeCommand('cryptsetup', ['close', this.luksMappedName]);
|
|
78
|
+
Utils.warning(`moving ${this.luksName} to (ISO)/live/.`);
|
|
79
|
+
await exec(`mv ${this.luksFile} ${this.settings.iso_work}/live`, this.echo);
|
|
80
|
+
Utils.warning('encryption process successfully completed!');
|
|
81
|
+
/**
|
|
82
|
+
* YOU MUST! unlink the key on production
|
|
83
|
+
*/
|
|
84
|
+
// fs.unlinkSync(`${this.settings.iso_work}/live/home.key`)
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (error instanceof Error) {
|
|
88
|
+
Utils.error(`ERROR: ${error.message}`);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
Utils.error(`An unknown error has occurred.`);
|
|
92
|
+
}
|
|
93
|
+
Utils.warning('Cleaning performed following the error...');
|
|
94
|
+
if (fs.existsSync(this.luksMountpoint)) {
|
|
95
|
+
await exec(`umount -lf ${this.luksMountpoint}`).catch(() => { });
|
|
96
|
+
}
|
|
97
|
+
if (fs.existsSync(this.luksDevice)) {
|
|
98
|
+
await executeCommand('cryptsetup', ['luksClose', this.luksName]).catch(() => { });
|
|
99
|
+
}
|
|
100
|
+
await Utils.pressKeyToExit();
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Funzione helper per eseguire comandi esterni in modo asincrono,
|
|
106
|
+
* gestendo lo standard input per passare le password.
|
|
107
|
+
* Restituisce una Promise che si risolve al successo o si rigetta in caso di errore.
|
|
108
|
+
*/
|
|
109
|
+
function executeCommand(command, args, stdinData) {
|
|
110
|
+
return new Promise((resolve, reject) => {
|
|
111
|
+
// Se passiamo dati a stdin, dobbiamo usare 'pipe'. Altrimenti, 'inherit'.
|
|
112
|
+
const stdioConfig = stdinData ? ['pipe', 'inherit', 'inherit'] : 'inherit';
|
|
113
|
+
const process = spawn(command, args, { stdio: stdioConfig });
|
|
114
|
+
// Se fornito, scriviamo i dati (es. la password) nello stdin del processo.
|
|
115
|
+
if (stdinData && process.stdin) {
|
|
116
|
+
process.stdin.write(stdinData);
|
|
117
|
+
process.stdin.end();
|
|
118
|
+
}
|
|
119
|
+
process.on('error', (err) => {
|
|
120
|
+
reject(new Error(`Error starting command "${command}": ${err.message}`));
|
|
121
|
+
});
|
|
122
|
+
process.on('close', (code) => {
|
|
123
|
+
if (code === 0) {
|
|
124
|
+
resolve(); // Success
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
reject(new Error(`Command "${command} ${args.join(' ')}" ended with error code ${code}`));
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Converte bytes in gigabytes per la visualizzazione.
|
|
134
|
+
*/
|
|
135
|
+
function bytesToGB(bytes) {
|
|
136
|
+
if (bytes === 0)
|
|
137
|
+
return '0.00 GB';
|
|
138
|
+
const gigabytes = bytes / (1024 * 1024 * 1024);
|
|
139
|
+
return gigabytes.toFixed(2) + ' GB';
|
|
140
|
+
}
|