penguins-eggs 25.11.21 → 25.12.7

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 (114) hide show
  1. package/.oclif.manifest.json +53 -41
  2. package/README.md +80 -36
  3. package/README.pdf +21575 -3241
  4. package/addons/eggs/theme/livecd/full.grub.main.cfg +39 -4
  5. package/addons/eggs/theme/livecd/full.isolinux.main.cfg +47 -4
  6. package/bin/run.js +11 -0
  7. package/conf/derivatives.yaml +4 -2
  8. package/conf/exclude.list.d/var.list +11 -6
  9. package/dist/appimage/dependency-manager.d.ts +31 -0
  10. package/dist/appimage/dependency-manager.js +292 -0
  11. package/dist/appimage/first-run-check.js +3 -3
  12. package/dist/bin/run.js +11 -0
  13. package/dist/classes/cli-autologin.js +78 -53
  14. package/dist/classes/compressors.d.ts +7 -10
  15. package/dist/classes/compressors.js +44 -31
  16. package/dist/classes/daddy.js +11 -11
  17. package/dist/classes/distro.js +2 -2
  18. package/dist/classes/diversions.js +2 -3
  19. package/dist/classes/incubation/fisherman-helper/initcpio.d.ts +4 -0
  20. package/dist/classes/incubation/fisherman-helper/initcpio.js +14 -4
  21. package/dist/classes/incubation/fisherman-helper/settings.js +1 -1
  22. package/dist/classes/incubation/fisherman.js +1 -3
  23. package/dist/classes/incubation/incubator.js +1 -1
  24. package/dist/classes/network.d.ts +1 -1
  25. package/dist/classes/ovary.d/create-xdg-autostart.js +1 -1
  26. package/dist/classes/ovary.d/edit-live-fs.d.ts +1 -12
  27. package/dist/classes/ovary.d/edit-live-fs.js +216 -186
  28. package/dist/classes/ovary.d/fertilization.js +1 -1
  29. package/dist/classes/ovary.d/make-dot-disk.js +1 -1
  30. package/dist/classes/ovary.d/produce.js +1 -1
  31. package/dist/classes/ovary.d/user-create-live.d.ts +4 -10
  32. package/dist/classes/ovary.d/user-create-live.js +82 -84
  33. package/dist/classes/ovary.d/users-remove.d.ts +5 -6
  34. package/dist/classes/ovary.d/users-remove.js +61 -31
  35. package/dist/classes/ovary.d/xorriso-command.js +1 -5
  36. package/dist/classes/ovary.d.ts +2 -2
  37. package/dist/classes/ovary.js +2 -2
  38. package/dist/classes/pacman.d/alpine.js +2 -2
  39. package/dist/classes/pacman.d/archlinux.js +2 -2
  40. package/dist/classes/pacman.d/debian.js +2 -3
  41. package/dist/classes/pacman.d/fedora.js +2 -3
  42. package/dist/classes/pacman.d/openmamba.js +2 -3
  43. package/dist/classes/pacman.d/opensuse.js +2 -3
  44. package/dist/classes/pacman.d.ts +21 -12
  45. package/dist/classes/pacman.js +55 -47
  46. package/dist/classes/pve-live.js +1 -1
  47. package/dist/classes/settings.js +1 -1
  48. package/dist/classes/sys-users.d.ts +76 -0
  49. package/dist/classes/sys-users.js +206 -0
  50. package/dist/classes/utils.d/kernel.js +3 -3
  51. package/dist/classes/utils.d.ts +16 -11
  52. package/dist/classes/utils.js +92 -56
  53. package/dist/classes/xdg.js +1 -1
  54. package/dist/classes/yolk.js +2 -4
  55. package/dist/commands/config.js +3 -14
  56. package/dist/commands/cuckoo.js +1 -1
  57. package/dist/commands/export/appimage.js +3 -3
  58. package/dist/commands/export/pkg.js +3 -3
  59. package/dist/commands/export/tarballs.js +3 -3
  60. package/dist/commands/krill.js +1 -1
  61. package/dist/commands/produce.js +9 -4
  62. package/dist/commands/{setup.d.ts → setup/install.d.ts} +1 -5
  63. package/dist/commands/setup/install.js +71 -0
  64. package/dist/commands/setup/purge.d.ts +17 -0
  65. package/dist/commands/setup/purge.js +71 -0
  66. package/dist/commands/tools/yolk.js +1 -1
  67. package/dist/commands/update.d.ts +15 -0
  68. package/dist/commands/update.js +74 -7
  69. package/dist/interfaces/i-exec.d.ts +1 -0
  70. package/dist/krill/classes/prepare.d/location.js +1 -1
  71. package/dist/krill/classes/prepare.d/partitions.js +1 -1
  72. package/dist/krill/classes/prepare.d/users.js +2 -2
  73. package/dist/krill/classes/prepare.js +5 -5
  74. package/dist/krill/classes/sequence.d/add_user.d.ts +3 -15
  75. package/dist/krill/classes/sequence.d/add_user.js +87 -57
  76. package/dist/krill/classes/sequence.d/change_password.d.ts +5 -7
  77. package/dist/krill/classes/sequence.d/change_password.js +25 -10
  78. package/dist/krill/classes/sequence.d/del_live_user.d.ts +5 -7
  79. package/dist/krill/classes/sequence.d/del_live_user.js +39 -25
  80. package/dist/krill/classes/sequence.d/fstab.js +1 -1
  81. package/dist/krill/classes/sequence.d/grubcfg.d.ts +3 -7
  82. package/dist/krill/classes/sequence.d/grubcfg.js +33 -13
  83. package/dist/krill/classes/sequence.d/mkfs.js +1 -2
  84. package/dist/krill/classes/sequence.d/unpackfs.d.ts +2 -4
  85. package/dist/krill/classes/sequence.d/unpackfs.js +8 -5
  86. package/dist/krill/classes/sequence.js +2 -3
  87. package/dist/krill/components/title.js +4 -4
  88. package/dist/krill/lib/select_installation_device.js +1 -1
  89. package/dist/krill/lib/select_replaced_partition.js +1 -1
  90. package/dist/lib/utils.d.ts +51 -19
  91. package/dist/lib/utils.js +225 -39
  92. package/manpages/doc/man/eggs.1.gz +0 -0
  93. package/manpages/doc/man/eggs.html +29 -17
  94. package/package.json +13 -14
  95. package/perrisbrewery/template/dependencies.yaml +1 -0
  96. package/scripts/_eggs +35 -7
  97. package/scripts/boot-encrypted-root.sh +220 -0
  98. package/scripts/eggs.bash +2 -1
  99. package/scripts/mount-encrypted-home.sh +324 -0
  100. package/dist/appimage/prerequisites.d.ts +0 -34
  101. package/dist/appimage/prerequisites.js +0 -350
  102. package/dist/commands/setup.js +0 -90
  103. package/dracut/create-symlink +0 -71
  104. package/dracut/dracut-log.txt +0 -3
  105. package/dracut/export +0 -4
  106. package/dracut/export-dracut-analysis +0 -51
  107. package/dracut/export-dracut-log +0 -2
  108. package/dracut/mkisofs +0 -10
  109. package/dracut/renew-initramfs +0 -17
  110. package/dracut/sbin2bin +0 -10
  111. package/dracut/update-dracut-conf-d +0 -2
  112. package/dracut/update-dracut-modules +0 -62
  113. package/scripts/appimage-build.sh +0 -152
  114. package/scripts/appimage-install.sh +0 -43
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * ./src/classes/ovary.d/edit-live-fs.ts
3
- * penguins-eggs v.25.7.x / ecmascript 2020
3
+ * penguins-eggs v.25.12.5 / ecmascript 2020
4
4
  * author: Piero Proietti
5
5
  * email: piero.proietti@gmail.com
6
6
  * license: MIT
@@ -9,231 +9,261 @@
9
9
  import fs from 'fs';
10
10
  import os from 'os';
11
11
  import path from 'node:path';
12
- import shx from 'shelljs';
12
+ import { shx } from '../../lib/utils.js';
13
13
  import Utils from '../utils.js';
14
14
  import Pacman from '../pacman.js';
15
15
  import Systemctl from '../systemctl.js';
16
16
  import { exec } from '../../lib/utils.js';
17
17
  // _dirname
18
18
  const __dirname = path.dirname(new URL(import.meta.url).pathname);
19
- /**
20
- * editLiveFs
21
- * - Mark if is_clone or is_clone_crypted
22
- * - Truncate logs, remove archived log
23
- * - Allow all fixed drives to be mounted with pmount
24
- * - Enable or disable password login trhough ssh for users (not root)
25
- * - Create an empty /etc/fstab
26
- * - Blanck /etc/machine-id
27
- * - Add some basic files to /dev
28
- * - Clear configs from /etc/network/interfaces, wicd and NetworkManager and netman
29
- */
30
19
  export async function editLiveFs(clone = false) {
31
- if (this.verbose) {
20
+ if (this.verbose)
32
21
  console.log('Ovary: editLiveFs');
33
- }
34
- /**
35
- * /etc/penguins-eggs.d/is_clone file created on live
36
- */
22
+ const workDir = this.settings.work_dir.merged;
37
23
  if (clone) {
38
- await exec(`touch ${this.settings.work_dir.merged}/etc/penguins-eggs.d/is_clone`, this.echo);
24
+ await exec(`touch ${workDir}/etc/penguins-eggs.d/is_clone`, this.echo);
39
25
  }
40
- /**
41
- * /etc/default/epoptes-client created on live
42
- */
43
26
  if (Pacman.packageIsInstalled('epoptes')) {
44
- const file = `${this.settings.work_dir.merged}/etc/default/epoptes-client`;
27
+ const file = `${workDir}/etc/default/epoptes-client`;
45
28
  const text = `SERVER=${os.hostname}.local\n`;
46
29
  fs.writeFileSync(file, text);
47
30
  }
48
31
  if (this.familyId === 'debian') {
49
- // Aggiungo UMASK=0077 in /etc/initramfs-tools/conf.d/calamares-safe-initramfs.conf
50
32
  const text = 'UMASK=0077\n';
51
33
  const file = '/etc/initramfs-tools/conf.d/eggs-safe-initramfs.conf';
52
34
  Utils.write(file, text);
53
35
  }
54
- // Truncate logs, remove archived logs.
55
- let cmd = `find ${this.settings.work_dir.merged}/var/log -name "*gz" -print0 | xargs -0r rm -f`;
36
+ // Truncate logs
37
+ let cmd = `find ${workDir}/var/log -name "*gz" -print0 | xargs -0r rm -f`;
56
38
  await exec(cmd, this.echo);
57
- cmd = `find ${this.settings.work_dir.merged}/var/log/ -type f -exec truncate -s 0 {} \\;`;
39
+ cmd = `find ${workDir}/var/log/ -type f -exec truncate -s 0 {} \\;`;
58
40
  await exec(cmd, this.echo);
59
- // Allow all fixed drives to be mounted with pmount
60
- if (this.settings.config.pmount_fixed && fs.existsSync(`${this.settings.work_dir.merged}/etc/pmount.allow`)) {
61
- // MX aggiunto /etc
62
- await exec(`sed -i 's:#/dev/sd\[a-z\]:/dev/sd\[a-z\]:' ${this.settings.work_dir.merged}/etc/pmount.allow`, this.echo);
63
- }
64
- // Remove obsolete live-config file
65
- if (fs.existsSync(`${this.settings.work_dir.merged}lib/live/config/1161-openssh-server`)) {
66
- await exec(`rm -f ${this.settings.work_dir.merged}/lib/live/config/1161-openssh-server`, this.echo);
67
- }
68
- if (fs.existsSync(`${this.settings.work_dir.merged}/etc/ssh/sshd_config`)) {
69
- /**
70
- * enable/disable SSH root/users password login
71
- */
72
- await exec(`sed -i '/PermitRootLogin/d' ${this.settings.work_dir.merged}/etc/ssh/sshd_config`);
73
- await exec(`sed -i '/PasswordAuthentication/d' ${this.settings.work_dir.merged}/etc/ssh/sshd_config`);
41
+ // =========================================================================
42
+ // FIX DEFINITIVO PER DEVUAN/SYSVINIT (Init Script Hardening)
43
+ // =========================================================================
44
+ if (Utils.isSysvinit()) {
45
+ if (this.verbose)
46
+ console.log('SysVinit detected: Hardening init scripts...');
47
+ await patchInitScripts(workDir, this.verbose);
48
+ }
49
+ // =========================================================================
50
+ // Fix Symlinks /var/run e /var/lock
51
+ const varRun = `${workDir}/var/run`;
52
+ if (fs.existsSync(varRun) && !fs.lstatSync(varRun).isSymbolicLink()) {
53
+ if (this.verbose)
54
+ console.log('Fixing /var/run symlink...');
55
+ await exec(`rm -rf ${varRun}`, this.echo);
56
+ await exec(`ln -s /run ${varRun}`, this.echo);
57
+ }
58
+ const varLock = `${workDir}/var/lock`;
59
+ if (fs.existsSync(varLock) && !fs.lstatSync(varLock).isSymbolicLink()) {
60
+ if (this.verbose)
61
+ console.log('Fixing /var/lock symlink...');
62
+ await exec(`rm -rf ${varLock}`, this.echo);
63
+ await exec(`ln -s /run/lock ${varLock}`, this.echo);
64
+ }
65
+ // Altri fix standard
66
+ if (this.settings.config.pmount_fixed && fs.existsSync(`${workDir}/etc/pmount.allow`)) {
67
+ await exec(`sed -i 's:#/dev/sd\[a-z\]:/dev/sd\[a-z\]:' ${workDir}/etc/pmount.allow`, this.echo);
68
+ }
69
+ if (fs.existsSync(`${workDir}lib/live/config/1161-openssh-server`)) {
70
+ await exec(`rm -f ${workDir}/lib/live/config/1161-openssh-server`, this.echo);
71
+ }
72
+ if (fs.existsSync(`${workDir}/etc/ssh/sshd_config`)) {
73
+ await exec(`sed -i '/PermitRootLogin/d' ${workDir}/etc/ssh/sshd_config`);
74
+ await exec(`sed -i '/PasswordAuthentication/d' ${workDir}/etc/ssh/sshd_config`);
74
75
  if (this.settings.config.ssh_pass) {
75
- await exec(`echo 'PasswordAuthentication yes' | tee -a ${this.settings.work_dir.merged}/etc/ssh/sshd_config`, this.echo);
76
+ await exec(`echo 'PasswordAuthentication yes' | tee -a ${workDir}/etc/ssh/sshd_config`, this.echo);
76
77
  }
77
78
  else {
78
- await exec(`echo 'PermitRootLogin prohibit-password' | tee -a ${this.settings.work_dir.merged}/etc/ssh/sshd_config`, this.echo);
79
- await exec(`echo 'PasswordAuthentication no' | tee -a ${this.settings.work_dir.merged}/etc/ssh/sshd_config`, this.echo);
79
+ await exec(`echo 'PermitRootLogin prohibit-password' | tee -a ${workDir}/etc/ssh/sshd_config`, this.echo);
80
+ await exec(`echo 'PasswordAuthentication no' | tee -a ${workDir}/etc/ssh/sshd_config`, this.echo);
80
81
  }
81
82
  }
82
- /**
83
- * ufw --force reset
84
- */
85
- // if (Pacman.packageIsInstalled('ufw')) {
86
- // await exec('ufw --force reset')
87
- // }
88
- /**
89
- * /etc/fstab should exist, even if it's empty,
90
- * to prevent error messages at boot
91
- */
92
- await exec(`rm ${this.settings.work_dir.merged}/etc/fstab`, this.echo);
93
- await exec(`touch ${this.settings.work_dir.merged}/etc/fstab`, this.echo);
94
- /**
95
- * Remove crypttab if exists
96
- * this is crucial for tpm systems.
97
- */
98
- if (fs.existsSync(`${this.settings.work_dir.merged}/etc/crypttab`)) {
99
- await exec(`rm ${this.settings.work_dir.merged}/etc/crypttab`, this.echo);
100
- }
101
- /**
102
- * Blank out systemd machine id.
103
- * If it does not exist, systemd-journald will fail,
104
- * but if it exists and is empty, systemd will automatically
105
- * set up a new unique ID.
106
- */
107
- if (fs.existsSync(`${this.settings.work_dir.merged}/etc/machine-id`)) {
108
- await exec(`rm ${this.settings.work_dir.merged}/etc/machine-id`, this.echo);
109
- await exec(`touch ${this.settings.work_dir.merged}/etc/machine-id`, this.echo);
110
- Utils.write(`${this.settings.work_dir.merged}/etc/machine-id`, ':');
111
- }
112
- /**
113
- * LMDE4: utilizza UbuntuMono16.pf2
114
- * aggiungo un link a /boot/grub/fonts/UbuntuMono16.pf2
115
- */
116
- if (fs.existsSync(`${this.settings.work_dir.merged}/boot/grub/fonts/unicode.pf2`)) {
117
- shx.cp(`${this.settings.work_dir.merged}/boot/grub/fonts/unicode.pf2`, `${this.settings.work_dir.merged}/boot/grub/fonts/UbuntuMono16.pf2`);
118
- }
119
- /**
120
- * cleaning /etc/resolv.conf
121
- */
122
- const resolvFile = `${this.settings.work_dir.merged}/etc/resolv.conf`;
123
- shx.rm(resolvFile);
124
- /**
125
- * Per tutte le distro systemd
126
- */
83
+ await exec(`rm ${workDir}/etc/fstab`, this.echo);
84
+ await exec(`touch ${workDir}/etc/fstab`, this.echo);
85
+ if (fs.existsSync(`${workDir}/etc/crypttab`)) {
86
+ await exec(`rm ${workDir}/etc/crypttab`, this.echo);
87
+ }
88
+ // 🔧 [MODIFICA 1] Machine ID cleanup
89
+ // Cancelliamo SEMPRE il machine-id, anche su SysVinit.
90
+ // Questo garantisce che lo script patchato (dbus) trovi il file mancante e lo rigeneri.
91
+ if (fs.existsSync(`${workDir}/etc/machine-id`)) {
92
+ await exec(`rm ${workDir}/etc/machine-id`, this.echo);
93
+ await exec(`touch ${workDir}/etc/machine-id`, this.echo); // Lo ricreiamo vuoto
94
+ }
95
+ // Rimuoviamo anche quello in /var/lib/dbus per forzare la rigenerazione
96
+ if (fs.existsSync(`${workDir}/var/lib/dbus/machine-id`)) {
97
+ await exec(`rm ${workDir}/var/lib/dbus/machine-id`, this.echo);
98
+ }
99
+ if (fs.existsSync(`${workDir}/boot/grub/fonts/unicode.pf2`)) {
100
+ shx.cp(`${workDir}/boot/grub/fonts/unicode.pf2`, `${workDir}/boot/grub/fonts/UbuntuMono16.pf2`);
101
+ }
102
+ shx.rm(`${workDir}/etc/resolv.conf`);
103
+ // Systemd cleanup
127
104
  if (Utils.isSystemd()) {
128
105
  const systemdctl = new Systemctl(this.verbose);
129
- /*
130
- * Arch: /ci/minimal/arch-minimal.sh:
131
- * systemctl set-default multi-user.target
132
- * systemctl enable getty@tty1.service
133
- * systemctl enable systemd-networkd.service
134
- * systemctl enable 'systemd-resolved.service
135
- */
136
- if (await systemdctl.isEnabled('remote-cryptsetup.target')) {
137
- await systemdctl.disable('remote-cryptsetup.target', this.settings.work_dir.merged, true);
138
- }
139
- if (await systemdctl.isEnabled('speech-dispatcherd.service')) {
140
- await systemdctl.disable('speech-dispatcherd.service', this.settings.work_dir.merged, true);
141
- }
142
- if (await systemdctl.isEnabled('wpa_supplicant-nl80211@.service')) {
143
- await systemdctl.disable('wpa_supplicant-nl80211@.service', this.settings.work_dir.merged, true);
144
- }
145
- if (await systemdctl.isEnabled('wpa_supplicant@.service')) {
146
- await systemdctl.disable('wpa_supplicant@.service', this.settings.work_dir.merged, true);
147
- }
148
- if (await systemdctl.isEnabled('wpa_supplicant-wired@.service')) {
149
- await systemdctl.disable('wpa_supplicant-wired@.service', this.settings.work_dir.merged, true);
150
- }
151
- /**
152
- * All systemd distros
153
- */
154
- await exec(`rm -f ${this.settings.work_dir.merged}/var/lib/wicd/configurations/*`, this.echo);
155
- await exec(`rm -f ${this.settings.work_dir.merged}/etc/wicd/wireless-settings.conf`, this.echo);
156
- await exec(`rm -f ${this.settings.work_dir.merged}/etc/NetworkManager/system-connections/*`, this.echo);
157
- await exec(`rm -f ${this.settings.work_dir.merged}/etc/network/wifi/*`, this.echo);
158
- /**
159
- * removing from /etc/network/:
160
- * if-down.d if-post-down.d if-pre-up.d if-up.d interfaces interfaces.d
161
- */
106
+ if (await systemdctl.isEnabled('remote-cryptsetup.target'))
107
+ await systemdctl.disable('remote-cryptsetup.target', workDir, true);
108
+ if (await systemdctl.isEnabled('speech-dispatcherd.service'))
109
+ await systemdctl.disable('speech-dispatcherd.service', workDir, true);
110
+ if (await systemdctl.isEnabled('wpa_supplicant-nl80211@.service'))
111
+ await systemdctl.disable('wpa_supplicant-nl80211@.service', workDir, true);
112
+ if (await systemdctl.isEnabled('wpa_supplicant@.service'))
113
+ await systemdctl.disable('wpa_supplicant@.service', workDir, true);
114
+ if (await systemdctl.isEnabled('wpa_supplicant-wired@.service'))
115
+ await systemdctl.disable('wpa_supplicant-wired@.service', workDir, true);
116
+ await exec(`rm -f ${workDir}/var/lib/wicd/configurations/*`, this.echo);
117
+ await exec(`rm -f ${workDir}/etc/wicd/wireless-settings.conf`, this.echo);
118
+ await exec(`rm -f ${workDir}/etc/NetworkManager/system-connections/*`, this.echo);
119
+ await exec(`rm -f ${workDir}/etc/network/wifi/*`, this.echo);
162
120
  const cleanDirs = ['if-down.d', 'if-post-down.d', 'if-pre-up.d', 'if-up.d', 'interfaces.d'];
163
- let cleanDir = '';
164
- for (cleanDir of cleanDirs) {
165
- await exec(`rm -f ${this.settings.work_dir.merged}/etc/network/${cleanDir}/wpasupplicant`, this.echo);
121
+ for (const cleanDir of cleanDirs) {
122
+ await exec(`rm -f ${workDir}/etc/network/${cleanDir}/wpasupplicant`, this.echo);
166
123
  }
167
124
  }
168
- /**
169
- * Clear configs from /etc/network/interfaces, wicd and NetworkManager
170
- * and netman, so they aren't stealthily included in the snapshot.
171
- */
172
125
  if (this.familyId === 'debian') {
173
- if (fs.existsSync(`${this.settings.work_dir.merged}/etc/network/interfaces`)) {
174
- await exec(`rm -f ${this.settings.work_dir.merged}/etc/network/interfaces`, this.echo);
175
- Utils.write(`${this.settings.work_dir.merged}/etc/network/interfaces`, 'auto lo\niface lo inet loopback');
176
- }
177
- /**
178
- * add some basic files to /dev
179
- */
180
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/console`)) {
181
- await exec(`mknod -m 622 ${this.settings.work_dir.merged}/dev/console c 5 1`, this.echo);
182
- }
183
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/null`)) {
184
- await exec(`mknod -m 666 ${this.settings.work_dir.merged}/dev/null c 1 3`, this.echo);
185
- }
186
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/zero`)) {
187
- await exec(`mknod -m 666 ${this.settings.work_dir.merged}/dev/zero c 1 5`, this.echo);
188
- }
189
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/ptmx`)) {
190
- await exec(`mknod -m 666 ${this.settings.work_dir.merged}/dev/ptmx c 5 2`, this.echo);
191
- }
192
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/tty`)) {
193
- await exec(`mknod -m 666 ${this.settings.work_dir.merged}/dev/tty c 5 0`, this.echo);
194
- }
195
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/random`)) {
196
- await exec(`mknod -m 444 ${this.settings.work_dir.merged}/dev/random c 1 8`, this.echo);
197
- }
198
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/urandom`)) {
199
- await exec(`mknod -m 444 ${this.settings.work_dir.merged}/dev/urandom c 1 9`, this.echo);
126
+ if (fs.existsSync(`${workDir}/etc/network/interfaces`)) {
127
+ await exec(`rm -f ${workDir}/etc/network/interfaces`, this.echo);
128
+ Utils.write(`${workDir}/etc/network/interfaces`, 'auto lo\niface lo inet loopback');
200
129
  }
201
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/{console,ptmx,tty}`)) {
202
- await exec(`chown -v root:tty ${this.settings.work_dir.merged}/dev/{console,ptmx,tty}`, this.echo);
130
+ const devNodes = [
131
+ { path: 'console', m: '622', type: 'c', major: 5, minor: 1 },
132
+ { path: 'null', m: '666', type: 'c', major: 1, minor: 3 },
133
+ { path: 'zero', m: '666', type: 'c', major: 1, minor: 5 },
134
+ { path: 'ptmx', m: '666', type: 'c', major: 5, minor: 2 },
135
+ { path: 'tty', m: '666', type: 'c', major: 5, minor: 0 },
136
+ { path: 'random', m: '444', type: 'c', major: 1, minor: 8 },
137
+ { path: 'urandom', m: '444', type: 'c', major: 1, minor: 9 },
138
+ ];
139
+ for (const node of devNodes) {
140
+ if (!fs.existsSync(`${workDir}/dev/${node.path}`)) {
141
+ await exec(`mknod -m ${node.m} ${workDir}/dev/${node.path} ${node.type} ${node.major} ${node.minor}`, this.echo);
142
+ }
203
143
  }
204
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/fd`)) {
205
- await exec(`ln -sv /proc/self/fd ${this.settings.work_dir.merged}/dev/fd`, this.echo);
144
+ if (!fs.existsSync(`${workDir}/dev/console`)) {
145
+ await exec(`chown -v root:tty ${workDir}/dev/{console,ptmx,tty}`, this.echo);
206
146
  }
207
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/stdin`)) {
208
- await exec(`ln -sv /proc/self/fd/0 ${this.settings.work_dir.merged}/dev/stdin`, this.echo);
147
+ const links = [
148
+ { src: '/proc/self/fd', dest: 'fd' },
149
+ { src: '/proc/self/fd/0', dest: 'stdin' },
150
+ { src: '/proc/self/fd/1', dest: 'stdout' },
151
+ { src: '/proc/self/fd/2', dest: 'stderr' },
152
+ { src: '/proc/kcore', dest: 'core' }
153
+ ];
154
+ for (const link of links) {
155
+ if (!fs.existsSync(`${workDir}/dev/${link.dest}`)) {
156
+ await exec(`ln -sv ${link.src} ${workDir}/dev/${link.dest}`, this.echo);
157
+ }
209
158
  }
210
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/stdout`)) {
211
- await exec(`ln -sv /proc/self/fd/1 ${this.settings.work_dir.merged}/dev/stdout`, this.echo);
212
- }
213
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/stderr`)) {
214
- await exec(`ln -sv /proc/self/fd/2 ${this.settings.work_dir.merged}/dev/stderr`, this.echo);
215
- }
216
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/core`)) {
217
- await exec(`ln -sv /proc/kcore ${this.settings.work_dir.merged}/dev/core`, this.echo);
159
+ if (!fs.existsSync(`${workDir}/dev/shm`))
160
+ await exec(`mkdir -v ${workDir}/dev/shm`, this.echo);
161
+ if (!fs.existsSync(`${workDir}/dev/pts`))
162
+ await exec(`mkdir -v ${workDir}/dev/pts`, this.echo);
163
+ await exec(`chmod 1777 ${workDir}/dev/shm`, this.echo);
164
+ if (!fs.existsSync(`${workDir}/tmp`))
165
+ await exec(`mkdir ${workDir}/tmp`, this.echo);
166
+ await exec(`chmod 1777 ${workDir}/tmp`, this.echo);
167
+ }
168
+ }
169
+ /**
170
+ * Patcha direttamente gli script di init in /etc/init.d/
171
+ */
172
+ async function patchInitScripts(workDir, verbose) {
173
+ // 1. PATCH DBUS (Il più importante)
174
+ const dbusScript = `${workDir}/etc/init.d/dbus`;
175
+ if (fs.existsSync(dbusScript)) {
176
+ if (verbose)
177
+ console.log(`Patching ${dbusScript} to fix missing directories and RO fs...`);
178
+ let content = fs.readFileSync(dbusScript, 'utf8');
179
+ let modified = false;
180
+ // PATCH A: Header con gestione Ramdisk Fallback e Mount Proc
181
+ // Questa intestazione viene inserita all'inizio e prova a montare tmpfs se non può scrivere
182
+ const dbusFix = `
183
+ ### EGGS-FIX-START
184
+ # 1. Assicuriamoci che /proc sia montato (necessario per leggere uuid kernel)
185
+ if ! mountpoint -q /proc/; then
186
+ mount -t proc proc /proc
187
+ fi
188
+
189
+ # 2. Gestione Filesystem Read-Only (RO)
190
+ # Se non possiamo scrivere in /var/lib/dbus, montiamo un tmpfs (RAM) sopra.
191
+ # Questo bypassa il blocco dell'overlayfs non ancora pronto tipico delle build AppImage.
192
+ if ! mkdir -p /var/lib/dbus 2>/dev/null || ! touch /var/lib/dbus/.rw_check 2>/dev/null; then
193
+ echo "EGGS-DEBUG: Filesystem Read-Only detected! Mounting tmpfs on /var/lib/dbus" > /dev/console
194
+ mount -t tmpfs -o size=1m tmpfs /var/lib/dbus
195
+ fi
196
+ rm -f /var/lib/dbus/.rw_check
197
+
198
+ # 3. Creazione Directory Runtime
199
+ mkdir -p /var/run/dbus /var/lib/dbus
200
+ chmod 755 /var/run/dbus /var/lib/dbus
201
+
202
+ # 4. Generazione Machine ID (Non-Blocking Strategy)
203
+ # Se il file non esiste (o è vuoto), lo creiamo.
204
+ if [ ! -s /var/lib/dbus/machine-id ]; then
205
+ # Prova A: Usa UUID del kernel (Istantaneo, non blocca)
206
+ if [ -f /proc/sys/kernel/random/uuid ]; then
207
+ cat /proc/sys/kernel/random/uuid | tr -d '-' > /var/lib/dbus/machine-id
208
+ # Prova B: Fallback statico
209
+ else
210
+ echo "00000000000000000000000000000001" > /var/lib/dbus/machine-id
211
+ fi
212
+ chmod 644 /var/lib/dbus/machine-id
213
+ fi
214
+
215
+ # 5. Sync /etc/machine-id (Best effort, ignora errori se /etc è RO)
216
+ if [ ! -s /etc/machine-id ] && [ -s /var/lib/dbus/machine-id ]; then
217
+ cp /var/lib/dbus/machine-id /etc/machine-id 2>/dev/null || true
218
+ fi
219
+ ### EGGS-FIX-END
220
+ `;
221
+ if (!content.includes('EGGS-FIX-START')) {
222
+ content = content.replace('#!/bin/sh', `#!/bin/sh\n${dbusFix}`);
223
+ modified = true;
218
224
  }
219
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/shm`)) {
220
- await exec(`mkdir -v ${this.settings.work_dir.merged}/dev/shm`, this.echo);
225
+ // PATCH B: SABOTAGE PREVENTION (Questa è quella che mancava!)
226
+ // Impediamo che create_machineid cancelli il file che abbiamo appena creato
227
+ // perché l'uptime è basso.
228
+ if (content.includes('rm -f "${MACHINEID}"')) {
229
+ if (verbose)
230
+ console.log('Patching dbus: disabling auto-delete of machine-id on boot');
231
+ content = content.replace('rm -f "${MACHINEID}"', ': # EGGS-PATCH: Prevent deletion of valid machine-id');
232
+ modified = true;
221
233
  }
222
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/pts`)) {
223
- await exec(`mkdir -v ${this.settings.work_dir.merged}/dev/pts`, this.echo);
234
+ if (modified) {
235
+ fs.writeFileSync(dbusScript, content, 'utf8');
224
236
  }
225
- if (!fs.existsSync(`${this.settings.work_dir.merged}/dev/shm`)) {
226
- await exec(`chmod 1777 ${this.settings.work_dir.merged}/dev/shm`, this.echo);
237
+ }
238
+ // 2. PATCH RSYSLOG
239
+ const rsyslogScript = `${workDir}/etc/init.d/rsyslog`;
240
+ if (fs.existsSync(rsyslogScript)) {
241
+ let content = fs.readFileSync(rsyslogScript, 'utf8');
242
+ const fix = `
243
+ ### EGGS-FIX-START
244
+ mkdir -p /var/spool/rsyslog
245
+ chmod 755 /var/spool/rsyslog
246
+ ### EGGS-FIX-END
247
+ `;
248
+ if (!content.includes('EGGS-FIX-START')) {
249
+ content = content.replace('#!/bin/sh', `#!/bin/sh\n${fix}`);
250
+ fs.writeFileSync(rsyslogScript, content, 'utf8');
227
251
  }
228
- /**
229
- * creo /tmp
230
- */
231
- if (!fs.existsSync(`${this.settings.work_dir.merged}/tmp`)) {
232
- await exec(`mkdir ${this.settings.work_dir.merged}/tmp`, this.echo);
252
+ }
253
+ // 3. PATCH CRON
254
+ const cronScript = `${workDir}/etc/init.d/cron`;
255
+ if (fs.existsSync(cronScript)) {
256
+ let content = fs.readFileSync(cronScript, 'utf8');
257
+ const fix = `
258
+ ### EGGS-FIX-START
259
+ mkdir -p /var/spool/cron/crontabs
260
+ chmod 1730 /var/spool/cron/crontabs
261
+ chown root:crontab /var/spool/cron/crontabs 2>/dev/null || true
262
+ ### EGGS-FIX-END
263
+ `;
264
+ if (!content.includes('EGGS-FIX-START')) {
265
+ content = content.replace('#!/bin/sh', `#!/bin/sh\n${fix}`);
266
+ fs.writeFileSync(cronScript, content, 'utf8');
233
267
  }
234
- /**
235
- * Assegno 1777 a /tmp creava problemi con MXLINUX
236
- */
237
- await exec(`chmod 1777 ${this.settings.work_dir.merged}/tmp`, this.echo);
238
268
  }
239
269
  }
@@ -25,7 +25,7 @@ export async function fertilization(snapshot_prefix = '', snapshot_basename = ''
25
25
  this.settings = new Settings();
26
26
  if (await this.settings.load()) {
27
27
  await this.settings.loadRemix(this.theme);
28
- this.volid = Utils.getVolid(this.settings.remix.name);
28
+ this.volid = Utils.VolidTrim(this.settings.remix.name);
29
29
  this.uuid = Utils.uuidGen();
30
30
  //this.familyId = this.settings.distro.familyId
31
31
  this.nest = this.settings.config.snapshot_mnt;
@@ -7,7 +7,7 @@
7
7
  */
8
8
  // packages
9
9
  import fs from 'node:fs';
10
- import shx from 'shelljs';
10
+ import { shx } from '../../lib/utils.js';
11
11
  import path from 'path';
12
12
  // interfaces
13
13
  // libraries
@@ -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 'shelljs';
12
+ import { shx } from '../../lib/utils.js';
13
13
  import path from 'path';
14
14
  // libraries
15
15
  import { exec } from '../../lib/utils.js';
@@ -1,14 +1,8 @@
1
1
  /**
2
- * ./src/classes/ovary.d/create-user-live.ts
2
+ * src/classes/ovary.d/user-create-live.ts
3
3
  * penguins-eggs v.25.7.x / ecmascript 2020
4
- * author: Piero Proietti
5
- * email: piero.proietti@gmail.com
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>;