penguins-eggs 25.10.19 → 25.10.24
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 +17 -3
- package/README.md +769 -2
- package/README.pdf +1705 -1747
- package/addons/eggs/theme/livecd/{grub.theme.cfg → full.grub.theme.cfg} +1 -1
- package/addons/eggs/theme/livecd/{isolinux.theme.cfg → full.isolinux.theme.cfg} +1 -1
- package/addons/eggs/theme/livecd/generic-splash.png +0 -0
- package/addons/eggs/theme/livecd/generic.grub.main.cfg +29 -0
- package/addons/eggs/theme/livecd/generic.grub.theme.cfg +67 -0
- package/addons/eggs/theme/livecd/generic.isolinux.main.cfg +34 -0
- package/addons/eggs/theme/livecd/generic.isolinux.theme.cfg +34 -0
- package/addons/eggs/theme/livecd/simple.grub.main.cfg +29 -0
- package/addons/eggs/theme/livecd/simple.grub.theme.cfg +67 -0
- package/addons/eggs/theme/livecd/{isolinux.main.simple.cfg → simple.isolinux.main.cfg} +1 -2
- package/addons/eggs/theme/livecd/simple.isolinux.theme.cfg +47 -0
- package/dist/classes/diversions.d.ts +1 -1
- package/dist/classes/diversions.js +4 -25
- package/dist/classes/ovary.d/bind-live-fs.js +1 -1
- package/dist/classes/ovary.d/initrd.js +3 -2
- package/dist/classes/ovary.d/luks-get-password.js +1 -0
- package/dist/classes/ovary.d/luks-home.js +41 -29
- package/dist/classes/ovary.d/luks-root-initrd.d.ts +17 -0
- package/dist/classes/ovary.d/luks-root-initrd.js +213 -0
- package/dist/classes/ovary.d/luks-root.js +60 -35
- package/dist/classes/ovary.d/make-dot-disk.js +10 -1
- package/dist/classes/ovary.d/make-efi.js +59 -43
- package/dist/classes/ovary.d/make-squashfs.d.ts +1 -1
- package/dist/classes/ovary.d/make-squashfs.js +2 -5
- package/dist/classes/ovary.d/merged.js +1 -1
- package/dist/classes/ovary.d/produce.d.ts +2 -2
- package/dist/classes/ovary.d/produce.js +45 -44
- package/dist/classes/ovary.d/syslinux.js +47 -34
- package/dist/classes/ovary.d/xorriso-command.js +1 -2
- package/dist/classes/ovary.d.ts +3 -4
- package/dist/classes/ovary.js +6 -6
- package/dist/classes/utils.d.ts +2 -0
- package/dist/classes/utils.js +13 -3
- package/dist/commands/love.d.ts +1 -0
- package/dist/commands/love.js +9 -2
- package/dist/commands/produce.d.ts +2 -1
- package/dist/commands/produce.js +18 -4
- package/dist/krill/classes/sequence.d.ts +1 -1
- package/dist/krill/classes/sequence.js +3 -3
- package/package.json +4 -4
- package/scripts/_eggs +3 -1
- package/scripts/boot-encrypted-root.sh +177 -0
- package/scripts/eggs.bash +2 -2
- package/scripts/mount-encrypted-home.sh +92 -56
- package/dist/classes/ovary.d/luks-root-bootstrap-builder.d.ts +0 -11
- package/dist/classes/ovary.d/luks-root-bootstrap-builder.js +0 -45
- package/scripts/luks-root-bootstrap-create.sh +0 -235
- package/scripts/luks-root-unlock.sh +0 -172
- /package/addons/eggs/theme/livecd/{grub.main.cfg → full.grub.main.cfg} +0 -0
- /package/addons/eggs/theme/livecd/{isolinux.main.full.cfg → full.isolinux.main.cfg} +0 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ./src/classes/ovary.d/initrd-luks.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
|
+
// packages
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
// classes
|
|
12
|
+
import { exec } from '../../lib/utils.js';
|
|
13
|
+
import Utils from '../utils.js';
|
|
14
|
+
// _dirname
|
|
15
|
+
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
16
|
+
const noop = () => { };
|
|
17
|
+
/**
|
|
18
|
+
* Creates a streamlined initrd image for Debian/Ubuntu with LUKS support using mkinitramfs within a temporary chroot.
|
|
19
|
+
* Copies the necessary unlock script, ensures losetup is included via a hook, and wraps /scripts/live for debugging.
|
|
20
|
+
* Assumes live-boot and cryptsetup packages are installed in the chroot.
|
|
21
|
+
* No cleanup of /etc modifications is performed as the chroot is temporary.
|
|
22
|
+
* @param this - Ovary instance context
|
|
23
|
+
* @param verbose - Whether to show verbose output
|
|
24
|
+
*/
|
|
25
|
+
export async function luksRootInitrd(verbose = false) {
|
|
26
|
+
const loggers = {
|
|
27
|
+
log: this.hidden ? noop : console.log,
|
|
28
|
+
warning: this.hidden ? noop : Utils.warning,
|
|
29
|
+
success: this.hidden ? noop : Utils.success,
|
|
30
|
+
info: this.hidden ? noop : Utils.info,
|
|
31
|
+
};
|
|
32
|
+
const { log, warning, success, info } = loggers;
|
|
33
|
+
if (this.hidden) {
|
|
34
|
+
Utils.warning("intentionally blank. System is working, please wait");
|
|
35
|
+
}
|
|
36
|
+
log();
|
|
37
|
+
log('===========================================================================');
|
|
38
|
+
log(`Creating ${this.initrd} for LUKS using mkinitramfs`);
|
|
39
|
+
log('===========================================================================');
|
|
40
|
+
// --- Core Paths & Config ---
|
|
41
|
+
const chrootPath = path.join(this.dotMnt, 'filesystem.squashfs');
|
|
42
|
+
const kernelVersion = this.kernel;
|
|
43
|
+
const initrdBaseName = path.basename(this.initrd);
|
|
44
|
+
const logBaseName = `${this.settings.config.snapshot_prefix}mkinitramfs.log.txt`;
|
|
45
|
+
const finalInitrdDestPath = path.join(this.settings.iso_work, 'live', initrdBaseName); // Define final destination early for logging
|
|
46
|
+
try {
|
|
47
|
+
// --- 2. Prepare Chroot Environment ---
|
|
48
|
+
warning("Preparing chroot environment...");
|
|
49
|
+
// --- 2.1 Copy boot-encrypted-root.sh
|
|
50
|
+
{
|
|
51
|
+
const bootEncryptedRootName = 'boot-encrypted-root.sh'; // Corrected to lowercase zz-
|
|
52
|
+
const srcbootEncryptedRootPath = path.join(__dirname, '../../../scripts', bootEncryptedRootName);
|
|
53
|
+
const chrootbootEncryptedRootDir = '/etc/initramfs-tools/scripts/live-premount';
|
|
54
|
+
const chrootbootEncryptedRootPath = path.join(chrootbootEncryptedRootDir, bootEncryptedRootName);
|
|
55
|
+
const hostDestbootEncryptedRootDir = path.join(chrootPath, chrootbootEncryptedRootDir);
|
|
56
|
+
const hostDestbootEncryptedRootPath = path.join(chrootPath, chrootbootEncryptedRootPath);
|
|
57
|
+
if (!fs.existsSync(srcbootEncryptedRootPath)) {
|
|
58
|
+
throw new Error(`Unlock script source not found: ${srcbootEncryptedRootPath}`);
|
|
59
|
+
}
|
|
60
|
+
await exec(`mkdir -p "${hostDestbootEncryptedRootDir}"`);
|
|
61
|
+
await exec(`cp "${srcbootEncryptedRootPath}" "${hostDestbootEncryptedRootPath}"`);
|
|
62
|
+
await exec(`chmod +x "${hostDestbootEncryptedRootPath}"`);
|
|
63
|
+
success(`Copied ${bootEncryptedRootName} script to ${hostDestbootEncryptedRootDir}`);
|
|
64
|
+
}
|
|
65
|
+
// --- 2.2 Create dummy /etc/crypttab if needed ---
|
|
66
|
+
{
|
|
67
|
+
const chrootCrypttabPath = '/etc/crypttab';
|
|
68
|
+
const hostCrypttabPath = path.join(chrootPath, chrootCrypttabPath);
|
|
69
|
+
if (!fs.existsSync(hostCrypttabPath)) {
|
|
70
|
+
const crypttabContent = "# Dummy entry to ensure cryptsetup is included\ncryptroot UUID=none none luks\n";
|
|
71
|
+
fs.writeFileSync(hostCrypttabPath, crypttabContent, 'utf-8');
|
|
72
|
+
success(`Created crypttab on ${path.dirname(hostCrypttabPath)}`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
info(`${hostCrypttabPath} already exists.`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// --- 2.3 Add hook ---
|
|
79
|
+
// Utils.warning(`Generating required hook scripts`)
|
|
80
|
+
await addHook('/usr/sbin/losetup', chrootPath, loggers);
|
|
81
|
+
await addHook('/usr/bin/rsync', chrootPath, loggers);
|
|
82
|
+
// --- 2.4 Add modules ---
|
|
83
|
+
// addModules('overlay', chrootPath)
|
|
84
|
+
// --- 3. Execute mkinitramfs INSIDE Chroot ---
|
|
85
|
+
{
|
|
86
|
+
warning(`Running mkinitramfs for kernel ${kernelVersion} inside chroot...`);
|
|
87
|
+
const chrootTmpInitrdPath = `/tmp/${initrdBaseName}`;
|
|
88
|
+
let logFilePath = path.join(this.settings.iso_work, logBaseName);
|
|
89
|
+
if (this.hidden) {
|
|
90
|
+
logFilePath = '/dev/null';
|
|
91
|
+
}
|
|
92
|
+
const mkinitramfsCmd = `mkinitramfs -v -o "${chrootTmpInitrdPath}" ${kernelVersion}`;
|
|
93
|
+
const chrootCmd = `chroot "${chrootPath}" /bin/bash -c "${mkinitramfsCmd}" > "${logFilePath}" 2>&1`;
|
|
94
|
+
await exec(chrootCmd, this.echo);
|
|
95
|
+
success(`mkinitramfs completed. Log: ${logFilePath}`);
|
|
96
|
+
}
|
|
97
|
+
// --- 4. Move Result ---
|
|
98
|
+
{
|
|
99
|
+
const chrootTmpInitrdPath = `/tmp/${initrdBaseName}`; // Re-declare for scope
|
|
100
|
+
const hostTmpInitrdPath = path.join(chrootPath, chrootTmpInitrdPath);
|
|
101
|
+
if (fs.existsSync(hostTmpInitrdPath)) {
|
|
102
|
+
info(`Moving generated initrd to ${finalInitrdDestPath}`);
|
|
103
|
+
await exec(`mv "${hostTmpInitrdPath}" "${finalInitrdDestPath}"`);
|
|
104
|
+
success(`Initrd moved successfully.`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
Utils.error(`Generated initrd not found at ${hostTmpInitrdPath}. Build failed!`);
|
|
108
|
+
throw new Error("mkinitramfs did not produce the expected output file.");
|
|
109
|
+
}
|
|
110
|
+
// process.exit()
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
Utils.error(`Error during LUKS initrd generation: ${error}`);
|
|
115
|
+
const logFilePath = path.join(this.settings.iso_work, logBaseName); // Re-declare for scope
|
|
116
|
+
if (error instanceof Error && error.message.includes('mkinitramfs inside chroot failed')) {
|
|
117
|
+
Utils.warning(`Check mkinitramfs log: ${logFilePath}`);
|
|
118
|
+
}
|
|
119
|
+
throw error; // Re-throw error
|
|
120
|
+
}
|
|
121
|
+
success(`Finished creating LUKS initrd: ${finalInitrdDestPath}`);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Genera e installa uno script hook di initramfs-tools nel chroot.
|
|
125
|
+
* Copia il comando specificato nella sua directory di destinazione
|
|
126
|
+
* standard (/bin o /sbin) all'interno dell'initramfs.
|
|
127
|
+
* @param cmdPath Path assoluto del comando da copiare *nel chroot* (es. '/usr/sbin/losetup')
|
|
128
|
+
* @param chrootPath Path assoluto alla radice del chroot
|
|
129
|
+
*/
|
|
130
|
+
async function addHook(cmdPath, chrootPath, loggers) {
|
|
131
|
+
const { log, warning, success, info } = loggers;
|
|
132
|
+
const chrootHooksDirPath = '/etc/initramfs-tools/hooks';
|
|
133
|
+
const hostHooksDirPath = path.join(chrootPath, chrootHooksDirPath);
|
|
134
|
+
const cmd = path.basename(cmdPath); // es. 'losetup'
|
|
135
|
+
const hookScriptName = `add-${cmd}-hook.sh`; // es. 'add-losetup-hook.sh'
|
|
136
|
+
const hostHookPath = path.join(hostHooksDirPath, hookScriptName);
|
|
137
|
+
if (!fs.existsSync(cmdPath)) {
|
|
138
|
+
Utils.error(`Dont' exists ${cmdPath}`);
|
|
139
|
+
process.exit();
|
|
140
|
+
}
|
|
141
|
+
let destDir = "/sbin"; // Default a /sbin per i comandi di amministrazione
|
|
142
|
+
// Determina la destinazione corretta
|
|
143
|
+
if (cmdPath.includes('/usr/bin') || cmdPath.includes('/bin')) {
|
|
144
|
+
destDir = "/bin"; // Comandi utente
|
|
145
|
+
}
|
|
146
|
+
else if (cmdPath.includes('/usr/sbin') || cmdPath.includes('/sbin')) {
|
|
147
|
+
destDir = "/sbin"; // Comandi amministrativi
|
|
148
|
+
}
|
|
149
|
+
// Crea la riga di comando per l'hook
|
|
150
|
+
const copyLine = `copy_exec ${cmdPath} ${destDir} || echo "WARNING: Failed to copy ${cmdPath} to ${destDir}" >&2`;
|
|
151
|
+
// Crea il contenuto boilerplate dello script hook
|
|
152
|
+
const hookContent = `#!/bin/sh
|
|
153
|
+
# Hook: ${hookScriptName}
|
|
154
|
+
# Generato automaticamente da penguins-eggs
|
|
155
|
+
# Copia ${cmdPath} in ${destDir}
|
|
156
|
+
|
|
157
|
+
PREREQ=""
|
|
158
|
+
case $1 in prereqs) echo "\${PREREQ}"; exit 0;; esac
|
|
159
|
+
|
|
160
|
+
. /usr/share/initramfs-tools/hook-functions
|
|
161
|
+
|
|
162
|
+
echo "EGGS-HOOK: Esecuzione hook ${hookScriptName}..."
|
|
163
|
+
${copyLine}
|
|
164
|
+
|
|
165
|
+
exit 0
|
|
166
|
+
`;
|
|
167
|
+
try {
|
|
168
|
+
await exec(`mkdir -p "${hostHooksDirPath}"`);
|
|
169
|
+
// Scrive il file e lo rende eseguibile (mode 0o755)
|
|
170
|
+
fs.writeFileSync(hostHookPath, hookContent, { mode: 0o755, encoding: 'utf-8' });
|
|
171
|
+
// console.log(hookContent)
|
|
172
|
+
success(`Generated and set executable hook: ${hookScriptName}`);
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
Utils.error(`Failed to write hook script ${hostHookPath}: ${err.message}`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
throw err; // Lancia l'errore per fermare il processo
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
*
|
|
182
|
+
* @param module
|
|
183
|
+
* @param chrootPath
|
|
184
|
+
*/
|
|
185
|
+
function addModules(module, chrootPath, loggers) {
|
|
186
|
+
const { log, warning, success, info } = loggers;
|
|
187
|
+
const chrootModulesFilePath = '/etc/initramfs-tools/modules'; // Relative inside chroot
|
|
188
|
+
const hostModulesFilePath = path.join(chrootPath, chrootModulesFilePath); // Absolute on host fs
|
|
189
|
+
let modulesContent = '';
|
|
190
|
+
let needsUpdate = false;
|
|
191
|
+
if (fs.existsSync(hostModulesFilePath)) {
|
|
192
|
+
modulesContent = fs.readFileSync(hostModulesFilePath, 'utf-8');
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// inizializzazione modules
|
|
196
|
+
modulesContent = '\n';
|
|
197
|
+
}
|
|
198
|
+
if (modulesContent.includes(`\n${module}\n`)) {
|
|
199
|
+
info(`'${module}' module already present.`);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
info(`Added '${module}' module on ${hostModulesFilePath}`);
|
|
203
|
+
if (!modulesContent.endsWith('\n')) {
|
|
204
|
+
modulesContent += '\n';
|
|
205
|
+
}
|
|
206
|
+
modulesContent += `${module}\n`;
|
|
207
|
+
needsUpdate = true;
|
|
208
|
+
}
|
|
209
|
+
if (needsUpdate) {
|
|
210
|
+
fs.writeFileSync(hostModulesFilePath, modulesContent, 'utf-8');
|
|
211
|
+
success(`Updated ${hostModulesFilePath} with 'overlay'.`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -10,6 +10,7 @@ import fs from 'fs';
|
|
|
10
10
|
import { spawn } from 'node:child_process';
|
|
11
11
|
import Utils from '../utils.js';
|
|
12
12
|
import { exec } from '../../lib/utils.js';
|
|
13
|
+
const noop = () => { };
|
|
13
14
|
/**
|
|
14
15
|
* luksRoot()
|
|
15
16
|
*
|
|
@@ -17,39 +18,48 @@ import { exec } from '../../lib/utils.js';
|
|
|
17
18
|
* filesystem.squashfs
|
|
18
19
|
*/
|
|
19
20
|
export async function luksRoot() {
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
const loggers = {
|
|
22
|
+
log: this.hidden ? noop : console.log,
|
|
23
|
+
warning: this.hidden ? noop : Utils.warning,
|
|
24
|
+
success: this.hidden ? noop : Utils.success,
|
|
25
|
+
info: this.hidden ? noop : Utils.info,
|
|
26
|
+
};
|
|
27
|
+
const { log, warning, success, info } = loggers;
|
|
28
|
+
// filesystem.squashfs
|
|
29
|
+
const live_fs = `${this.settings.iso_work}live/filesystem.squashfs`;
|
|
22
30
|
try {
|
|
23
31
|
/**
|
|
24
|
-
* this.
|
|
25
|
-
* this.luksFile = `/tmp/${
|
|
26
|
-
* this.luksDevice = `/dev/mapper/${
|
|
27
|
-
* this.
|
|
28
|
-
* this.
|
|
29
|
-
* this.luksPassword = 'evolution'
|
|
32
|
+
* this.luksMappedName = 'luks.img';
|
|
33
|
+
* this.luksFile = `/tmp/${luksMappedName}`
|
|
34
|
+
* this.luksDevice = `/dev/mapper/${luksMappedName}`
|
|
35
|
+
* this.luksMountpoint = `/tmp/mnt/${luksMappedName}`
|
|
36
|
+
* this.luksPassword = '0'
|
|
30
37
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
if (this.hidden) {
|
|
39
|
+
Utils.warning("intentionally blank. System is working, please wait");
|
|
40
|
+
}
|
|
41
|
+
log();
|
|
42
|
+
log('====================================');
|
|
43
|
+
log(` Creating ${this.luksMappedName}`);
|
|
44
|
+
log('====================================');
|
|
45
|
+
if (!fs.existsSync(live_fs)) {
|
|
46
|
+
throw new Error(`filesystem.squashfs not found at: ${live_fs}`);
|
|
47
|
+
}
|
|
48
|
+
const stats = fs.statSync(live_fs);
|
|
49
|
+
let size = stats.size; // Dimensione REALE del file in Byte
|
|
50
|
+
// Add overhead * 1.25 per più sicurezza con file grandi
|
|
51
|
+
const luksSize = Math.ceil(size * 1.25);
|
|
52
|
+
warning(`filesystem.squashfs size: ${bytesToGB(size)}`);
|
|
53
|
+
warning(`partition LUKS ${this.luksFile} size: ${bytesToGB(luksSize)}`);
|
|
54
|
+
warning(`creating partition LUKS: ${this.luksFile}`);
|
|
43
55
|
await executeCommand('truncate', ['--size', `${luksSize}`, this.luksFile]);
|
|
44
|
-
|
|
56
|
+
warning(`formatting ${this.luksFile} as a LUKS volume...`);
|
|
45
57
|
await executeCommand('cryptsetup', ['--batch-mode', 'luksFormat', this.luksFile], `${this.luksPassword}\n`);
|
|
46
|
-
|
|
47
|
-
Utils.warning(`LUKS uuid: ${this.luksUuid}`);
|
|
48
|
-
Utils.warning(`opening the LUKS volume. It will be mapped to ${this.luksDevice}`);
|
|
58
|
+
warning(`opening the LUKS volume. It will be mapped to ${this.luksDevice}`);
|
|
49
59
|
await executeCommand('cryptsetup', ['luksOpen', this.luksFile, this.luksMappedName], `${this.luksPassword}\n`);
|
|
50
|
-
|
|
51
|
-
await exec(`mkfs.ext4 -L live-root ${this.luksDevice}`, this.echo);
|
|
52
|
-
|
|
60
|
+
warning(`formatting ext4 (without journal)...`);
|
|
61
|
+
await exec(`mkfs.ext4 -O ^has_journal -L live-root ${this.luksDevice}`, this.echo);
|
|
62
|
+
warning(`mounting ${this.luksDevice} on ${this.luksMountpoint}`);
|
|
53
63
|
if (fs.existsSync(this.luksMountpoint)) {
|
|
54
64
|
if (!Utils.isMountpoint(this.luksMountpoint)) {
|
|
55
65
|
await exec(`rm -rf ${this.luksMountpoint}`, this.echo);
|
|
@@ -59,14 +69,29 @@ export async function luksRoot() {
|
|
|
59
69
|
}
|
|
60
70
|
}
|
|
61
71
|
await exec(`mkdir -p ${this.luksMountpoint}`, this.echo);
|
|
62
|
-
await exec(`mount /dev/mapper/${this.
|
|
63
|
-
|
|
64
|
-
await exec(`mv
|
|
65
|
-
|
|
66
|
-
await exec(
|
|
67
|
-
|
|
72
|
+
await exec(`mount /dev/mapper/${this.luksMappedName} ${this.luksMountpoint}`, this.echo);
|
|
73
|
+
warning(`moving ${live_fs} ${this.luksMountpoint}/filesystem.squashfs`);
|
|
74
|
+
await exec(`mv ${live_fs} ${this.luksMountpoint}/filesystem.squashfs`, this.echo);
|
|
75
|
+
warning(`Syncing filesystem on ${this.luksMountpoint}...`);
|
|
76
|
+
await exec('sync', this.echo); // Forza scrittura dati su disco
|
|
77
|
+
warning(`Attempting unmount ${this.luksMountpoint}...`);
|
|
78
|
+
try {
|
|
79
|
+
await exec(`umount ${this.luksMountpoint}`, this.echo);
|
|
80
|
+
success(`Unmounted ${this.luksMountpoint} successfully.`);
|
|
81
|
+
}
|
|
82
|
+
catch (umountError) {
|
|
83
|
+
Utils.error(`Failed to unmount ${this.luksMountpoint}! Trying force unmount...`);
|
|
84
|
+
// Tenta un unmount forzato/lazy come ultima risorsa
|
|
85
|
+
await exec(`umount -lf ${this.luksMountpoint}`).catch((forceError) => {
|
|
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}.`);
|
|
68
93
|
await executeCommand('cryptsetup', ['close', this.luksMappedName]);
|
|
69
|
-
|
|
94
|
+
warning(`moving ${this.luksMappedName} on (ISO)/live.`);
|
|
70
95
|
await exec(`mv ${this.luksFile} ${this.settings.iso_work}/live`, this.echo);
|
|
71
96
|
}
|
|
72
97
|
catch (error) {
|
|
@@ -81,7 +106,7 @@ export async function luksRoot() {
|
|
|
81
106
|
await exec(`umount -lf ${this.luksMountpoint}`).catch(() => { });
|
|
82
107
|
}
|
|
83
108
|
if (fs.existsSync(this.luksDevice)) {
|
|
84
|
-
await executeCommand('cryptsetup', ['
|
|
109
|
+
await executeCommand('cryptsetup', ['close', this.luksMappedName]).catch(() => { });
|
|
85
110
|
}
|
|
86
111
|
await Utils.pressKeyToExit();
|
|
87
112
|
process.exit(1);
|
|
@@ -28,7 +28,16 @@ export function makeDotDisk(info = '', mksquashfs = '', mkisofs = '') {
|
|
|
28
28
|
* write volid .disk/info
|
|
29
29
|
* Required
|
|
30
30
|
*/
|
|
31
|
-
let volidContent =
|
|
31
|
+
let volidContent = "Linux live";
|
|
32
|
+
if (this.hidden) {
|
|
33
|
+
fs.writeFileSync(path.join(dotDisk, 'info'), volidContent, 'utf-8');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* write volid .disk/info
|
|
38
|
+
* Complete
|
|
39
|
+
*/
|
|
40
|
+
volidContent = this.settings.isoFilename;
|
|
32
41
|
fs.writeFileSync(path.join(dotDisk, 'info'), volidContent, 'utf-8');
|
|
33
42
|
/**
|
|
34
43
|
* A readme now replace the old .disk/info
|
|
@@ -172,53 +172,67 @@ export async function makeEfi(theme = 'eggs') {
|
|
|
172
172
|
* creating grub.cfg (4) on (ISO)/boot/grub
|
|
173
173
|
*/
|
|
174
174
|
Utils.warning("creating grub.cfg main on (ISO)/boot/grub");
|
|
175
|
-
//
|
|
175
|
+
// splash.png
|
|
176
|
+
let splashSrc = '';
|
|
176
177
|
const splashDest = `${efiWorkDir}/boot/grub/splash.png`;
|
|
177
|
-
let
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
let themeSrc = '';
|
|
179
|
+
const themeDest = `${isoDir}/boot/grub/theme.cfg`;
|
|
180
|
+
let grubTemplate = '';
|
|
181
|
+
if (this.hidden) {
|
|
182
|
+
splashSrc = path.resolve(__dirname, `../../../addons/${theme}/theme/livecd/generic-splash.png`);
|
|
183
|
+
grubTemplate = path.resolve(__dirname, '../../../addons/eggs/theme/livecd/generic.grub.main.cfg');
|
|
184
|
+
themeSrc = path.resolve(__dirname, '../../../addons/eggs/theme/livecd/generic.grub.theme.cfg');
|
|
180
185
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
186
|
+
else {
|
|
187
|
+
// copy splash to efiWorkDir
|
|
188
|
+
splashSrc = path.resolve(__dirname, `../../../addons/${theme}/theme/livecd/splash.png`);
|
|
189
|
+
if (this.theme.includes('/')) {
|
|
190
|
+
splashSrc = `${theme}/theme/livecd/splash.png`;
|
|
191
|
+
}
|
|
192
|
+
if (!fs.existsSync(splashSrc)) {
|
|
193
|
+
Utils.warning(`warning: ${splashSrc} does not exists`);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
// select themeSrc
|
|
197
|
+
themeSrc = path.resolve(__dirname, `../../../addons/${theme}/theme/livecd/grub.theme.cfg`);
|
|
198
|
+
if (this.theme.includes('/')) {
|
|
199
|
+
themeSrc = `${theme}/theme/livecd/grub.theme.cfg`;
|
|
200
|
+
}
|
|
201
|
+
// copy theme
|
|
202
|
+
if (!fs.existsSync(themeSrc)) {
|
|
203
|
+
Utils.error(`error: ${themeSrc} does not exist`);
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
// selecting available fonts
|
|
207
|
+
if (fs.existsSync('/usr/share/grub/font.pf2')) {
|
|
208
|
+
await exec(`cp /usr/share/grub/font.pf2 ${efiWorkDir}boot/grub/font.pf2`, this.echo);
|
|
209
|
+
}
|
|
210
|
+
else if (fs.existsSync('/usr/share/grub/unicode.pf2')) {
|
|
211
|
+
await exec(`cp /usr/share/grub/unicode.pf2 ${efiWorkDir}boot/grub/font.pf2`, this.echo);
|
|
212
|
+
}
|
|
213
|
+
else if (fs.existsSync('/usr/share/grub/ascii.pf2')) {
|
|
214
|
+
await exec(`cp /usr/share/grub/ascii.pf2 ${efiWorkDir}boot/grub/font.pf2`, this.echo);
|
|
215
|
+
}
|
|
216
|
+
// Copy workdir files to ISO/boot
|
|
217
|
+
await exec(`rsync -avx ${efiWorkDir}/boot ${isoDir}/`, this.echo);
|
|
218
|
+
/**
|
|
219
|
+
* prepare main grub.cfg from grub.main.cfg
|
|
220
|
+
*/
|
|
221
|
+
grubTemplate = `${theme}/theme/livecd/grub.main.cfg`;
|
|
222
|
+
if (!fs.existsSync(grubTemplate)) {
|
|
223
|
+
grubTemplate = path.resolve(__dirname, '../../../addons/eggs/theme/livecd/grub.main.cfg');
|
|
224
|
+
}
|
|
225
|
+
if (!fs.existsSync(grubTemplate)) {
|
|
226
|
+
Utils.error(`error: ${grubTemplate} does not exist`);
|
|
227
|
+
process.exit(1);
|
|
228
|
+
}
|
|
184
229
|
}
|
|
230
|
+
// splash.png
|
|
185
231
|
await exec(`cp ${splashSrc} ${splashDest}`, this.echo);
|
|
186
|
-
//
|
|
187
|
-
let themeSrc = path.resolve(__dirname, `../../../addons/${theme}/theme/livecd/grub.theme.cfg`);
|
|
188
|
-
if (this.theme.includes('/')) {
|
|
189
|
-
themeSrc = `${theme}/theme/livecd/grub.theme.cfg`;
|
|
190
|
-
}
|
|
191
|
-
// copy theme
|
|
192
|
-
const themeDest = `${isoDir}/boot/grub/theme.cfg`;
|
|
193
|
-
if (!fs.existsSync(themeSrc)) {
|
|
194
|
-
Utils.error(`error: ${themeSrc} does not exist`);
|
|
195
|
-
process.exit(1);
|
|
196
|
-
}
|
|
232
|
+
// grub.theme.png
|
|
197
233
|
fs.copyFileSync(themeSrc, themeDest);
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
await exec(`cp /usr/share/grub/font.pf2 ${efiWorkDir}boot/grub/font.pf2`, this.echo);
|
|
201
|
-
}
|
|
202
|
-
else if (fs.existsSync('/usr/share/grub/unicode.pf2')) {
|
|
203
|
-
await exec(`cp /usr/share/grub/unicode.pf2 ${efiWorkDir}boot/grub/font.pf2`, this.echo);
|
|
204
|
-
}
|
|
205
|
-
else if (fs.existsSync('/usr/share/grub/ascii.pf2')) {
|
|
206
|
-
await exec(`cp /usr/share/grub/ascii.pf2 ${efiWorkDir}boot/grub/font.pf2`, this.echo);
|
|
207
|
-
}
|
|
208
|
-
// Copy workdir files to ISO/boot
|
|
209
|
-
await exec(`rsync -avx ${efiWorkDir}/boot ${isoDir}/`, this.echo);
|
|
210
|
-
/**
|
|
211
|
-
* prepare main grub.cfg from grub.main.cfg
|
|
212
|
-
*/
|
|
213
|
-
let grubTemplate = `${theme}/theme/livecd/grub.main.cfg`;
|
|
214
|
-
if (!fs.existsSync(grubTemplate)) {
|
|
215
|
-
grubTemplate = path.resolve(__dirname, '../../../addons/eggs/theme/livecd/grub.main.cfg');
|
|
216
|
-
}
|
|
217
|
-
if (!fs.existsSync(grubTemplate)) {
|
|
218
|
-
Utils.error(`error: ${grubTemplate} does not exist`);
|
|
219
|
-
process.exit(1);
|
|
220
|
-
}
|
|
221
|
-
const kernel_parameters = Diversions.kernelParameters(this.familyId, this.volid, this.luksUuid); // this.kernelParameters()
|
|
234
|
+
// grub.main.png
|
|
235
|
+
const kernel_parameters = Diversions.kernelParameters(this.familyId, this.volid, this.fullcrypt);
|
|
222
236
|
const cfgMain = path.join(isoDir, '/boot/grub/grub.cfg');
|
|
223
237
|
const template = fs.readFileSync(grubTemplate, 'utf8');
|
|
224
238
|
const view = {
|
|
@@ -230,7 +244,9 @@ export async function makeEfi(theme = 'eggs') {
|
|
|
230
244
|
};
|
|
231
245
|
let cfgMainText = '';
|
|
232
246
|
cfgMainText += `# grub.cfg (4) main\n`;
|
|
233
|
-
|
|
247
|
+
if (!this.hidden) {
|
|
248
|
+
cfgMainText += `# created on ${cfgMain}`;
|
|
249
|
+
}
|
|
234
250
|
cfgMainText += `\n`;
|
|
235
251
|
cfgMainText += mustache.render(template, view);
|
|
236
252
|
fs.writeFileSync(cfgMain, cfgMainText);
|
|
@@ -9,7 +9,7 @@ import Ovary from '../ovary.js';
|
|
|
9
9
|
/**
|
|
10
10
|
* squashFs: crea in live filesystem.squashfs
|
|
11
11
|
*/
|
|
12
|
-
export declare function makeSquashfs(this: Ovary, scriptOnly?: boolean,
|
|
12
|
+
export declare function makeSquashfs(this: Ovary, scriptOnly?: boolean, includeRootHome?: boolean): Promise<string>;
|
|
13
13
|
/**
|
|
14
14
|
* Add or remove exclusion
|
|
15
15
|
* @param add {boolean} true = add, false remove
|
|
@@ -16,7 +16,7 @@ const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
|
16
16
|
/**
|
|
17
17
|
* squashFs: crea in live filesystem.squashfs
|
|
18
18
|
*/
|
|
19
|
-
export async function makeSquashfs(scriptOnly = false,
|
|
19
|
+
export async function makeSquashfs(scriptOnly = false, includeRootHome = false) {
|
|
20
20
|
if (this.verbose) {
|
|
21
21
|
console.log('Ovary: makeSquashfs');
|
|
22
22
|
}
|
|
@@ -57,7 +57,7 @@ export async function makeSquashfs(scriptOnly = false, includeRoot = false) {
|
|
|
57
57
|
/**
|
|
58
58
|
* secure
|
|
59
59
|
*/
|
|
60
|
-
if (!
|
|
60
|
+
if (!includeRootHome) {
|
|
61
61
|
this.addExclusion(`root/*`);
|
|
62
62
|
this.addExclusion(`root/.*`);
|
|
63
63
|
}
|
|
@@ -82,9 +82,6 @@ export async function makeSquashfs(scriptOnly = false, includeRoot = false) {
|
|
|
82
82
|
* [-e list of exclude dirs/files]
|
|
83
83
|
*/
|
|
84
84
|
let sfsName = "filesystem.squashfs";
|
|
85
|
-
if (this.fullcrypt) {
|
|
86
|
-
sfsName = "filesystem.squashfs.real";
|
|
87
|
-
}
|
|
88
85
|
let cmd = `mksquashfs ${this.settings.work_dir.merged} ${this.settings.iso_work}live/${sfsName} ${compression} ${limit} -no-xattrs -wildcards -ef ${this.settings.config.snapshot_excludes} ${this.settings.session_excludes}`;
|
|
89
86
|
cmd = cmd.replaceAll(/\s\s+/g, ' ');
|
|
90
87
|
Utils.writeX(`${this.settings.work_dir.ovarium}mksquashfs`, cmd);
|
|
@@ -17,7 +17,7 @@ import Ovary from './../ovary.js';
|
|
|
17
17
|
* @param myAddons
|
|
18
18
|
* @param nointeractive
|
|
19
19
|
* @param noicons
|
|
20
|
-
* @param
|
|
20
|
+
* @param includeRootHome
|
|
21
21
|
* @param verbose
|
|
22
22
|
*/
|
|
23
|
-
export declare function produce(this: Ovary, kernel: string | undefined, clone: boolean | undefined, homecrypt: boolean | undefined, fullcrypt: boolean | undefined, scriptOnly: boolean | undefined, yolkRenew: boolean | undefined, release: boolean | undefined, myAddons: IAddons, myLinks: string[], excludes: IExcludes, nointeractive?: boolean, noicons?: boolean,
|
|
23
|
+
export declare function produce(this: Ovary, kernel: string | undefined, clone: boolean | undefined, homecrypt: boolean | undefined, fullcrypt: boolean | undefined, hidden: boolean | undefined, scriptOnly: boolean | undefined, yolkRenew: boolean | undefined, release: boolean | undefined, myAddons: IAddons, myLinks: string[], excludes: IExcludes, nointeractive?: boolean, noicons?: boolean, includeRootHome?: boolean, verbose?: boolean): Promise<void>;
|