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.
Files changed (84) hide show
  1. package/.oclif.manifest.json +51 -145
  2. package/README.md +3 -829
  3. package/addons/eggs/theme/livecd/isolinux.main.simple.cfg +3 -3
  4. package/conf/distros/trixie/calamares/modules/shellprocess@boot_deploy.yml +3 -4
  5. package/conf/love.yaml +1 -1
  6. package/dist/classes/distro.js +9 -2
  7. package/dist/classes/diversions.d.ts +1 -1
  8. package/dist/classes/diversions.js +27 -8
  9. package/dist/classes/incubation/incubator.d/archlinux.js +1 -0
  10. package/dist/classes/incubation/incubator.d/trixie.js +7 -10
  11. package/dist/classes/ovary.d/edit-live-fs.d.ts +1 -1
  12. package/dist/classes/ovary.d/edit-live-fs.js +1 -7
  13. package/dist/classes/ovary.d/fertilization.js +1 -0
  14. package/dist/classes/ovary.d/finished.js +1 -5
  15. package/dist/classes/ovary.d/initrd.d.ts +1 -1
  16. package/dist/classes/ovary.d/initrd.js +17 -19
  17. package/dist/classes/ovary.d/live-create-structure.js +1 -4
  18. package/dist/classes/ovary.d/luks-get-password.d.ts +12 -0
  19. package/dist/classes/ovary.d/luks-get-password.js +57 -0
  20. package/dist/classes/ovary.d/luks-home-support.d.ts +12 -0
  21. package/dist/classes/ovary.d/luks-home-support.js +75 -0
  22. package/dist/classes/ovary.d/luks-home.d.ts +15 -0
  23. package/dist/classes/ovary.d/luks-home.js +140 -0
  24. package/dist/classes/ovary.d/luks-root-bootstrap-builder.d.ts +11 -0
  25. package/dist/classes/ovary.d/luks-root-bootstrap-builder.js +45 -0
  26. package/dist/classes/ovary.d/luks-root.d.ts +15 -0
  27. package/dist/classes/ovary.d/luks-root.js +126 -0
  28. package/dist/classes/ovary.d/make-efi.js +1 -1
  29. package/dist/classes/ovary.d/make-squashfs.d.ts +1 -1
  30. package/dist/classes/ovary.d/make-squashfs.js +7 -3
  31. package/dist/classes/ovary.d/produce.d.ts +3 -3
  32. package/dist/classes/ovary.d/produce.js +76 -48
  33. package/dist/classes/ovary.d/syslinux.js +1 -1
  34. package/dist/classes/ovary.d/xorriso-command.d.ts +2 -2
  35. package/dist/classes/ovary.d/xorriso-command.js +27 -29
  36. package/dist/classes/ovary.d.ts +35 -16
  37. package/dist/classes/ovary.js +42 -16
  38. package/dist/classes/utils.d.ts +1 -0
  39. package/dist/classes/utils.js +3 -0
  40. package/dist/commands/config.d.ts +1 -1
  41. package/dist/commands/config.js +2 -2
  42. package/dist/commands/love.d.ts +3 -0
  43. package/dist/commands/love.js +40 -2
  44. package/dist/commands/produce.d.ts +3 -2
  45. package/dist/commands/produce.js +14 -17
  46. package/dist/commands/tools/{ppa.d.ts → repo.d.ts} +2 -2
  47. package/dist/commands/tools/{ppa.js → repo.js} +69 -67
  48. package/dracut/create-symlink +71 -0
  49. package/dracut/dracut-log.txt +3 -0
  50. package/dracut/dracut.conf.d/50-live.conf +24 -6
  51. package/dracut/dracut.conf.d/README.md +10 -0
  52. package/dracut/export +4 -0
  53. package/dracut/export-dracut-analysis +51 -0
  54. package/dracut/export-dracut-log +2 -0
  55. package/dracut/mkisofs +10 -0
  56. package/dracut/modules.d/00debug-shell/debug-hook.sh +13 -0
  57. package/dracut/modules.d/00debug-shell/module-setup.sh +20 -0
  58. package/dracut/modules.d/90block/README.md +7 -0
  59. package/dracut/modules.d/90block/block-cmdline.sh +3 -0
  60. package/dracut/modules.d/90block/module-setup.sh +15 -0
  61. package/dracut/modules.d/95iso-scan/README.md +3 -0
  62. package/dracut/modules.d/95iso-scan/iso-scan-fallback.sh +12 -0
  63. package/dracut/modules.d/95iso-scan/iso-scan.sh +92 -0
  64. package/dracut/modules.d/95iso-scan/module-setup.sh +18 -0
  65. package/dracut/modules.d/95luks-loop/README.md +9 -0
  66. package/dracut/modules.d/95luks-loop/luks-loop.sh +90 -0
  67. package/dracut/modules.d/95luks-loop/module-setup.sh +17 -0
  68. package/dracut/renew-initramfs +17 -0
  69. package/dracut/sbin2bin +10 -0
  70. package/dracut/update-dracut-conf-d +2 -0
  71. package/dracut/update-dracut-modules +62 -0
  72. package/manpages/doc/man/eggs.1.gz +0 -0
  73. package/manpages/doc/man/eggs.html +7 -661
  74. package/package.json +9 -8
  75. package/perrisbrewery/template/dependencies.yaml +6 -5
  76. package/scripts/_eggs +16 -31
  77. package/scripts/eggs.bash +4 -6
  78. package/scripts/luks-root-bootstrap-create.sh +235 -0
  79. package/scripts/luks-root-unlock.sh +172 -0
  80. package/scripts/mount-encrypted-home.sh +223 -0
  81. package/dist/commands/syncfrom.d.ts +0 -45
  82. package/dist/commands/syncfrom.js +0 -152
  83. package/dist/commands/syncto.d.ts +0 -40
  84. package/dist/commands/syncto.js +0 -175
@@ -0,0 +1,223 @@
1
+ #!/bin/bash
2
+ # Script per sbloccare e montare home.img LUKS cifrato
3
+ # Con logging robusto e gestione errori
4
+
5
+ set -e
6
+
7
+ # Configurazione
8
+ HOME_IMG="__HOME_IMG_PATH__"
9
+ LUKS_NAME="live-home"
10
+ MOUNT_POINT="/home"
11
+ LOG_FILE="/var/log/mount-encrypted-home.log"
12
+
13
+ # Funzione di logging
14
+ log() {
15
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
16
+ }
17
+
18
+ log_error() {
19
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" | tee -a "$LOG_FILE" >&2
20
+ }
21
+
22
+ # Cleanup in caso di errore
23
+ cleanup() {
24
+ log "Cleanup in progress..."
25
+ if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
26
+ umount "$MOUNT_POINT" 2>/dev/null || true
27
+ fi
28
+ if [ -e "/dev/mapper/$LUKS_NAME" ]; then
29
+ cryptsetup close "$LUKS_NAME" 2>/dev/null || true
30
+ fi
31
+ }
32
+
33
+ trap cleanup EXIT
34
+
35
+ log "=== Starting encrypted home mount process ==="
36
+
37
+ # Verifica memoria disponibile
38
+ AVAILABLE_MEM=$(free -m | awk '/^Mem:/{print $7}')
39
+ log "Available memory: ${AVAILABLE_MEM}MB"
40
+
41
+ if [ "$AVAILABLE_MEM" -lt 1024 ]; then
42
+ log_error "Low memory warning: only ${AVAILABLE_MEM}MB available"
43
+ log "This might cause issues with LUKS operations"
44
+ fi
45
+
46
+ # Attendi che il media sia disponibile (max 30 secondi)
47
+ log "Waiting for live media to be available..."
48
+ COUNTER=0
49
+ while [ ! -f "$HOME_IMG" ] && [ $COUNTER -lt 30 ]; do
50
+ sleep 1
51
+ COUNTER=$((COUNTER + 1))
52
+ done
53
+
54
+ if [ ! -f "$HOME_IMG" ]; then
55
+ log_error "home.img not found at $HOME_IMG after 30 seconds"
56
+ log "Available mounts:"
57
+ mount | grep live | tee -a "$LOG_FILE"
58
+ exit 0
59
+ fi
60
+
61
+ log "Found home.img at $HOME_IMG"
62
+
63
+ # Copia in RAM se è su media read-only
64
+ TEMP_HOME_IMG="/var/tmp/home.img" # /var/tmp è su overlay, non tmpfs
65
+ log "Copying home.img to RAM..."
66
+ cp "$HOME_IMG" "$TEMP_HOME_IMG"
67
+ HOME_IMG="$TEMP_HOME_IMG"
68
+ log "home.img copied to $HOME_IMG"
69
+
70
+ # Verifica dimensione file
71
+ IMG_SIZE=$(stat -c %s "$HOME_IMG")
72
+ log "home.img size: $((IMG_SIZE / 1024 / 1024))MB"
73
+
74
+ # Verifica dimensione file
75
+ IMG_SIZE=$(stat -c %s "$HOME_IMG")
76
+ log "home.img size: $((IMG_SIZE / 1024 / 1024))MB"
77
+
78
+ # Verifica se è un volume LUKS
79
+ if ! cryptsetup isLuks "$HOME_IMG" 2>&1 | tee -a "$LOG_FILE"; then
80
+ log_error "$HOME_IMG is not a valid LUKS volume"
81
+ exit 1
82
+ fi
83
+
84
+ log "Verified: home.img is a valid LUKS volume"
85
+
86
+ # Mostra prompt per la passphrase
87
+ echo ""
88
+ echo "╔════════════════════════════════════════╗"
89
+ echo "║ Encrypted Home Directory Detected ║"
90
+ echo "╚════════════════════════════════════════╝"
91
+ echo ""
92
+ echo "Please enter your passphrase to unlock your home directory"
93
+ echo "(Press Ctrl+C to skip and continue with temporary home)"
94
+ echo ""
95
+
96
+ echo "(Press Ctrl+C to skip and continue with temporary home)"
97
+ echo ""
98
+
99
+ # Aspetta che il TTY sia completamente inizializzato
100
+ sleep 2
101
+
102
+ # Prima del while loop dei tentativi
103
+ if [ -e "/dev/mapper/$LUKS_NAME" ]; then
104
+ log "LUKS device already exists, closing it first..."
105
+ cryptsetup close "$LUKS_NAME" 2>&1 | tee -a "$LOG_FILE" || true
106
+ fi
107
+
108
+ # Tentativi multipli per la passphrase
109
+ MAX_ATTEMPTS=3
110
+ ATTEMPT=1
111
+
112
+ while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
113
+ log "Unlock attempt $ATTEMPT of $MAX_ATTEMPTS"
114
+
115
+ if cryptsetup open "$HOME_IMG" "$LUKS_NAME" 2>&1 | tee -a "$LOG_FILE"; then
116
+ log "LUKS volume unlocked successfully"
117
+ break
118
+ else
119
+ log_error "Failed to unlock LUKS volume (attempt $ATTEMPT)"
120
+
121
+ if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
122
+ log_error "Maximum attempts reached. Continuing without encrypted home."
123
+ echo ""
124
+ echo "╔════════════════════════════════════════╗"
125
+ echo "║ Failed to unlock encrypted home ║"
126
+ echo "║ System will continue with default ║"
127
+ echo "╚════════════════════════════════════════╝"
128
+ echo ""
129
+ sleep 3
130
+ exit 0
131
+ fi
132
+
133
+ ATTEMPT=$((ATTEMPT + 1))
134
+ echo "Incorrect passphrase. Please try again ($ATTEMPT/$MAX_ATTEMPTS)"
135
+ echo ""
136
+ fi
137
+ done
138
+
139
+ # Verifica che il device mapper esista
140
+ if [ ! -e "/dev/mapper/$LUKS_NAME" ]; then
141
+ log_error "Device /dev/mapper/$LUKS_NAME not found after unlock"
142
+ exit 1
143
+ fi
144
+
145
+ log "LUKS device available at /dev/mapper/$LUKS_NAME"
146
+
147
+ # Crea mount point
148
+ mkdir -p "$MOUNT_POINT"
149
+
150
+ # Monta il filesystem
151
+ log "Mounting decrypted volume to $MOUNT_POINT"
152
+ if mount "/dev/mapper/$LUKS_NAME" "$MOUNT_POINT" 2>&1 | tee -a "$LOG_FILE"; then
153
+ log "Home directory mounted successfully"
154
+ else
155
+ log_error "Failed to mount decrypted volume"
156
+ cryptsetup close "$LUKS_NAME"
157
+ exit 1
158
+ fi
159
+
160
+ # Ripristina gli utenti se esistono
161
+ if [ -d "$MOUNT_POINT/.system-backup" ]; then
162
+ log "Restoring user accounts..."
163
+
164
+ # Rimuovi utente live temporaneo
165
+ if id live >/dev/null 2>&1; then
166
+ log "Removing temporary 'live' user"
167
+ userdel -r live 2>&1 | tee -a "$LOG_FILE" || true
168
+ fi
169
+
170
+ # Ripristina gli utenti
171
+ if [ -f "$MOUNT_POINT/.system-backup/passwd" ]; then
172
+ cat "$MOUNT_POINT/.system-backup/passwd" >> /etc/passwd
173
+ log "Restored $(wc -l < "$MOUNT_POINT/.system-backup/passwd") user entries"
174
+ fi
175
+
176
+ if [ -f "$MOUNT_POINT/.system-backup/shadow" ]; then
177
+ cat "$MOUNT_POINT/.system-backup/shadow" >> /etc/shadow
178
+ fi
179
+
180
+ # Ripristina gli utenti
181
+ if [ -f "$MOUNT_POINT/.system-backup/passwd" ]; then
182
+ cat "$MOUNT_POINT/.system-backup/passwd" >> /etc/passwd
183
+ log "Restored $(wc -l < "$MOUNT_POINT/.system-backup/passwd") user entries"
184
+ fi
185
+
186
+ if [ -f "$MOUNT_POINT/.system-backup/shadow" ]; then
187
+ cat "$MOUNT_POINT/.system-backup/shadow" >> /etc/shadow
188
+ fi
189
+
190
+ # Ripristina i gruppi (sostituisci completamente)
191
+ if [ -f "$MOUNT_POINT/.system-backup/group" ]; then
192
+ cp "$MOUNT_POINT/.system-backup/group" /etc/group
193
+ log "Restored group memberships"
194
+ fi
195
+
196
+ if [ -f "$MOUNT_POINT/.system-backup/gshadow" ]; then
197
+ cp "$MOUNT_POINT/.system-backup/gshadow" /etc/gshadow
198
+ fi
199
+
200
+ log "User accounts restored successfully"
201
+
202
+ # Riavvia display manager per ricaricare gli utenti
203
+ log "Restarting display manager..."
204
+ if systemctl is-active --quiet gdm; then
205
+ systemctl restart gdm 2>&1 | tee -a "$LOG_FILE"
206
+ log "GDM restarted"
207
+ elif systemctl is-active --quiet lightdm; then
208
+ systemctl restart lightdm 2>&1 | tee -a "$LOG_FILE"
209
+ log "LightDM restarted"
210
+ elif systemctl is-active --quiet sddm; then
211
+ systemctl restart sddm 2>&1 | tee -a "$LOG_FILE"
212
+ log "SDDM restarted"
213
+ else
214
+ log "No active display manager found to restart"
215
+ fi
216
+ fi
217
+
218
+ log "=== Encrypted home mount completed successfully ==="
219
+
220
+ # Non fare cleanup al successo
221
+ trap - EXIT
222
+
223
+ exit 0
@@ -1,45 +0,0 @@
1
- /**
2
- * ./src/commands/syncfrom.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
- import { Command } from '@oclif/core';
9
- import { IRemix } from '../interfaces/index.js';
10
- /**
11
- *
12
- */
13
- export default class Syncfrom extends Command {
14
- static description: string;
15
- static examples: string[];
16
- static flags: {
17
- delete: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
- file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
- help: import("@oclif/core/interfaces").BooleanFlag<void>;
20
- rootdir: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
21
- verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
22
- };
23
- echo: {};
24
- luksName: string;
25
- luksDevice: string;
26
- luksFile: string;
27
- luksMountpoint: string;
28
- remix: IRemix;
29
- rootDir: string;
30
- verbose: boolean;
31
- /**
32
- *
33
- */
34
- luksClose(): Promise<void>;
35
- /**
36
- *
37
- */
38
- luksOpen(): Promise<void>;
39
- run(): Promise<void>;
40
- /**
41
- *
42
- * @param verbose
43
- */
44
- private restorePrivateData;
45
- }
@@ -1,152 +0,0 @@
1
- /**
2
- * ./src/commands/syncfrom.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
- import { Command, Flags } from '@oclif/core';
9
- import fs from 'node:fs';
10
- import path from 'node:path';
11
- import Distro from '../classes/distro.js';
12
- import Utils from '../classes/utils.js';
13
- import { exec } from '../lib/utils.js';
14
- /**
15
- *
16
- */
17
- export default class Syncfrom extends Command {
18
- static description = 'restore users and user data from a LUKS volumes';
19
- static examples = ['sudo eggs syncfrom', 'sudo eggs syncfrom --file /path/to/luks-volume'];
20
- static flags = {
21
- delete: Flags.string({ description: 'rsync --delete delete extraneous files from dest dirs' }),
22
- file: Flags.string({ char: 'f', description: 'file containing luks-volume encrypted' }),
23
- help: Flags.help({ char: 'h' }),
24
- rootdir: Flags.string({ char: 'r', description: 'rootdir of the installed system, when used from live' }),
25
- verbose: Flags.boolean({ char: 'v', description: 'verbose' })
26
- };
27
- echo = {};
28
- luksName = 'luks-volume';
29
- luksDevice = `/dev/mapper/${this.luksName}`;
30
- luksFile = '';
31
- luksMountpoint = `/tmp/mnt/${this.luksName}`;
32
- remix = {};
33
- rootDir = '/';
34
- verbose = false;
35
- /**
36
- *
37
- */
38
- async luksClose() {
39
- if (Utils.isMountpoint(this.luksMountpoint)) {
40
- await exec(`umount ${this.luksMountpoint}`, this.echo);
41
- }
42
- if (fs.existsSync(this.luksDevice)) {
43
- Utils.warning(`LUKS close volume: ${this.luksName}`);
44
- await exec(`cryptsetup luksClose ${this.luksName}`, this.echo);
45
- }
46
- }
47
- /**
48
- *
49
- */
50
- async luksOpen() {
51
- if (fs.existsSync(this.luksDevice)) {
52
- Utils.warning(`LUKS volume: ${this.luksName} already open`);
53
- }
54
- else {
55
- Utils.warning(`LUKS open volume: ${this.luksName}`);
56
- await exec(`cryptsetup luksOpen --type luks2 ${this.luksFile} ${this.luksName}`, Utils.setEcho(true));
57
- }
58
- if (!fs.existsSync(this.luksMountpoint)) {
59
- await exec(`mkdir -p ${this.luksMountpoint}`, this.echo);
60
- }
61
- if (Utils.isMountpoint(this.luksMountpoint)) {
62
- Utils.warning(`mount volume: ${this.luksDevice} already mounted on ${this.luksMountpoint}`);
63
- }
64
- else {
65
- Utils.warning(`mount volume: ${this.luksDevice} on ${this.luksMountpoint}`);
66
- await exec(`mount ${this.luksDevice} ${this.luksMountpoint}`, this.echo);
67
- }
68
- }
69
- async run() {
70
- const { flags } = await this.parse(Syncfrom);
71
- if (flags.verbose) {
72
- this.verbose = true;
73
- }
74
- this.echo = Utils.setEcho(this.verbose);
75
- let fileVolume = '';
76
- if (flags.file) {
77
- fileVolume = flags.file;
78
- }
79
- let destDelete = false;
80
- if (flags.delete) {
81
- destDelete = true;
82
- }
83
- if (Utils.isLive()) {
84
- if (flags.rootdir) {
85
- this.rootDir = flags.rootdir;
86
- }
87
- else {
88
- Utils.pressKeyToExit('Argument --rootdir is mandatory, when running live! Process will terminate');
89
- }
90
- }
91
- if (Utils.isRoot()) {
92
- if (fileVolume === '') {
93
- const distro = new Distro();
94
- fileVolume = `${distro.liveMediumPath}live/${this.luksName}`;
95
- }
96
- if (Utils.isLive()) {
97
- /**
98
- * WORKING FROM LIVE
99
- */
100
- this.luksName = path.basename(fileVolume);
101
- this.luksFile = fileVolume;
102
- this.luksDevice = `/dev/mapper/${this.luksName}`;
103
- this.luksMountpoint = `/tmp/${this.luksName}`;
104
- await this.restorePrivateData();
105
- }
106
- else {
107
- /**
108
- * WORKING FROM INSTALLED
109
- */
110
- if (fs.existsSync(fileVolume)) {
111
- this.luksName = path.basename(fileVolume);
112
- this.luksFile = fileVolume;
113
- this.luksDevice = `/dev/mapper/${this.luksName}`;
114
- this.luksMountpoint = `/tmp/${this.luksName}`;
115
- await this.restorePrivateData();
116
- if (await Utils.customConfirm('Your system was updated! Press a key to reboot')) {
117
- await exec('reboot');
118
- }
119
- }
120
- else {
121
- Utils.pressKeyToExit(`Can't find ${this.luksFile}`);
122
- }
123
- }
124
- }
125
- else {
126
- Utils.useRoot(this.id);
127
- }
128
- }
129
- /**
130
- *
131
- * @param verbose
132
- */
133
- async restorePrivateData(destDelete = false) {
134
- if (!fs.existsSync(this.luksMountpoint)) {
135
- await exec(`mkdir ${this.luksMountpoint}`, this.echo);
136
- }
137
- await this.luksOpen();
138
- if (Utils.isLive() && this.rootDir !== '/') {
139
- Utils.warning('Restoring crypted data');
140
- // Rimozione dei file esistenti
141
- await exec(`rm -rf ${this.rootDir}/etc/lightdm/lightdm.conf`, this.echo);
142
- await exec(`rm -rf ${this.rootDir}/etc/passwd`, this.echo);
143
- await exec(`rm -rf ${this.rootDir}/etc/group`, this.echo);
144
- await exec(`rm -rf ${this.rootDir}/etc/shadow`, this.echo);
145
- await exec(`rm -rf ${this.rootDir}/home/*`, this.echo);
146
- // unsquashfs
147
- const cmd = `unsquashfs -d ${this.rootDir} -f ${this.luksMountpoint}/private.squashfs`;
148
- await exec(cmd, Utils.setEcho(true));
149
- }
150
- await this.luksClose();
151
- }
152
- }
@@ -1,40 +0,0 @@
1
- /**
2
- * ./src/commands/syncto.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
- import { Command } from '@oclif/core';
9
- import Settings from '../classes/settings.js';
10
- /**
11
- *
12
- */
13
- export default class Syncto extends Command {
14
- static description: string;
15
- static examples: string[];
16
- static flags: {
17
- excludes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
- file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
- help: import("@oclif/core/interfaces").BooleanFlag<void>;
20
- verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
21
- };
22
- echo: {};
23
- exclude: boolean;
24
- excludeHome: string;
25
- luksName: string;
26
- luksDevice: string;
27
- luksFile: string;
28
- luksMountpoint: string;
29
- privateSquashfs: string;
30
- settings: Settings;
31
- verbose: boolean;
32
- /**
33
- *
34
- */
35
- luksCreate(): Promise<void>;
36
- /**
37
- *
38
- */
39
- run(): Promise<void>;
40
- }
@@ -1,175 +0,0 @@
1
- /**
2
- * ./src/commands/syncto.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
- // https://gist.github.com/ansemjo/6f1cf9d9b8f7ce8f70813f52c63b74a6
9
- import { Command, Flags } from '@oclif/core';
10
- import fs from 'node:fs';
11
- import Compressors from '../classes/compressors.js';
12
- import Settings from '../classes/settings.js';
13
- import Utils from '../classes/utils.js';
14
- import { exec } from '../lib/utils.js';
15
- /**
16
- *
17
- */
18
- export default class Syncto extends Command {
19
- static description = "Save users and users' data ENCRYPTED";
20
- static examples = ['sudo eggs syncto', 'sudo eggs syncto --file /path/to/luks-volume', 'sudo eggs syncto --excludes'];
21
- static flags = {
22
- excludes: Flags.boolean({ char: 'e', description: 'use: exclude.list.d/home.list' }),
23
- file: Flags.string({ char: 'f', description: 'file luks-volume encrypted' }),
24
- help: Flags.help({ char: 'h' }),
25
- verbose: Flags.boolean({ char: 'v', description: 'verbose' })
26
- };
27
- echo = {};
28
- exclude = false;
29
- excludeHome = '/etc/penguins-eggs.d/exclude.list.d/home.list';
30
- luksName = 'luks-volume';
31
- luksDevice = `/dev/mapper/${this.luksName}`;
32
- luksFile = `/tmp/${this.luksName}`;
33
- luksMountpoint = `/tmp/mnt/${this.luksName}`;
34
- privateSquashfs = `private.squashfs`;
35
- settings = {};
36
- verbose = false;
37
- /**
38
- *
39
- */
40
- async luksCreate() {
41
- await exec(`rm -rf ${this.luksFile}`);
42
- // ==========================================================================
43
- // Create squashfs
44
- // ==========================================================================
45
- Utils.warning(`Creating private.squashfs`);
46
- const compressors = new Compressors();
47
- await compressors.populate();
48
- // comp
49
- let comp = '';
50
- this.settings = new Settings();
51
- if (await this.settings.load()) {
52
- let compression = compressors.fast();
53
- if (this.settings.config.compression == `max`) {
54
- compression = compressors.max();
55
- }
56
- else if (this.settings.config.compression == `standard`) {
57
- compression = compressors.standard();
58
- }
59
- comp = `-comp ${compression}`;
60
- }
61
- // exclude /home/eggs
62
- let exclude_nest = '';
63
- if (fs.existsSync(this.settings.work_dir.workdir)) {
64
- exclude_nest = `-e ${this.settings.config.snapshot_dir}`;
65
- }
66
- // exclude file
67
- let exclude_home = '';
68
- if (this.exclude) {
69
- exclude_home = `-ef ${this.excludeHome}`;
70
- }
71
- // creato dummyfs per /etc/
72
- await exec(`mkdir -p /tmp/dummyfs/etc`, this.echo);
73
- await exec(`cp -a /etc/passwd /tmp/dummyfs/etc`, this.echo);
74
- await exec(`cp -a /etc/group /tmp/dummyfs/etc`, this.echo);
75
- await exec(`cp -a /etc/shadow /tmp/dummyfs/etc`, this.echo);
76
- await exec(`mkdir -p /tmp/dummyfs/etc/lightdm`, this.echo); // lightdm
77
- await exec(`cp -a /etc/lightdm/lightdm.conf /tmp/dummyfs/etc/lightdm/`, this.echo); // lightdm
78
- let mkPrivateSquashfs = `mksquashfs \
79
- /tmp/dummyfs/etc \
80
- /home \
81
- /tmp/${this.privateSquashfs} \
82
- ${comp} \
83
- ${exclude_nest} \
84
- ${exclude_home} \
85
- -keep-as-directory \
86
- -noappend`;
87
- mkPrivateSquashfs = mkPrivateSquashfs.replaceAll(/\s\s+/g, ` `);
88
- await exec(mkPrivateSquashfs, Utils.setEcho(true));
89
- // remove dummyfs
90
- await exec(`rm /tmp/dummyfs/ -rf`, this.echo);
91
- // ==========================================================================
92
- // Create LUKS volume
93
- // ==========================================================================
94
- Utils.titles('Creating LUKS Volume');
95
- // calcolo size
96
- const sizeString = (await exec(`unsquashfs -s /tmp/${this.privateSquashfs} | grep "Filesystem size" | sed -e 's/.*size //' -e 's/ .*//'`, { capture: true, echo: false })).data;
97
- let size = Number.parseInt(sizeString) + 2048;
98
- console.log('size private.squashfs:', bytesToGB(size), size);
99
- const luksBlockSize = 512;
100
- const luksBlocks = Math.ceil(size / luksBlockSize);
101
- size = luksBlockSize * luksBlocks;
102
- // Aggiungo un 20% in più per ottenere luksSize
103
- const luksSize = Math.ceil(size * 1.2);
104
- console.log('luksSize:', bytesToGB(luksSize), luksSize);
105
- // truncate * 2048 è cruciale
106
- const truncateAt = luksSize * 2048;
107
- Utils.warning(`Preparing file ${this.luksFile} for ${this.luksDevice}, size ${truncateAt}`);
108
- await exec(`truncate --size ${luksSize} ${this.luksFile}`, this.echo);
109
- Utils.warning(`Creating LUKS Volume on ${this.luksFile}`);
110
- await exec(`cryptsetup --batch-mode luksFormat ${this.luksFile}`, Utils.setEcho(true));
111
- console.log('');
112
- // open LUKS volume temp
113
- Utils.warning(`Opening LUKS Volume on ${this.luksFile}`);
114
- const { code } = await exec(`cryptsetup luksOpen ${this.luksFile} ${this.luksName}`, Utils.setEcho(true));
115
- if (code != 0) {
116
- Utils.error(`cryptsetup luksOpen ${this.luksFile} ${this.luksName} failed`);
117
- process.exit(code);
118
- }
119
- await exec('udevadm settle', this.echo);
120
- // formatta ext4 il volume
121
- await exec(`mkfs.ext4 ${this.luksDevice}`, this.echo);
122
- console.log('');
123
- // mount LUKS volume
124
- if (!fs.existsSync(`this.luksMountpoint)`)) {
125
- Utils.warning(`creating mountpoint ${this.luksMountpoint}`);
126
- await exec(`mkdir -p ${this.luksMountpoint}`, this.echo);
127
- }
128
- if (!Utils.isMountpoint(`${this.luksMountpoint}`)) {
129
- Utils.warning(`mounting volume: ${this.luksDevice} on ${this.luksMountpoint}`);
130
- const { code } = await exec(`mount ${this.luksDevice} ${this.luksMountpoint}`, Utils.setEcho(true));
131
- if (code != 0) {
132
- Utils.error(`mount ${this.luksDevice} ${this.luksMountpoint} failed`);
133
- process.exit(code);
134
- }
135
- }
136
- // copy private.squashfs
137
- Utils.warning(`moving /tmp/${this.privateSquashfs} to ${this.luksMountpoint}`);
138
- await exec(`mv /tmp/${this.privateSquashfs} ${this.luksMountpoint}`, this.echo);
139
- Utils.warning(`Umounting ${this.luksMountpoint}`);
140
- await exec(`umount ${this.luksMountpoint}`, this.echo);
141
- Utils.warning(`Vlosing ${this.luksMountpoint}`);
142
- await exec(`cryptsetup luksClose ${this.luksName}`, this.echo);
143
- }
144
- /**
145
- *
146
- */
147
- async run() {
148
- Utils.titles(this.id + ' ' + this.argv);
149
- const { flags } = await this.parse(Syncto);
150
- if (flags.verbose) {
151
- this.verbose = true;
152
- }
153
- this.echo = Utils.setEcho(this.verbose);
154
- let fileLuks = '';
155
- if (flags.file) {
156
- fileLuks = flags.file;
157
- }
158
- if (flags.excludes) {
159
- this.exclude = true;
160
- }
161
- if (Utils.isRoot()) {
162
- await this.luksCreate();
163
- }
164
- else {
165
- Utils.useRoot(this.id);
166
- }
167
- }
168
- }
169
- /**
170
- * Convert bytes to gigabytes
171
- */
172
- function bytesToGB(bytes) {
173
- const gigabytes = bytes / 1_073_741_824;
174
- return gigabytes.toFixed(2) + ' GB';
175
- }