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.
- package/.oclif.manifest.json +53 -41
- package/README.md +80 -36
- package/README.pdf +21575 -3241
- package/addons/eggs/theme/livecd/full.grub.main.cfg +39 -4
- package/addons/eggs/theme/livecd/full.isolinux.main.cfg +47 -4
- package/bin/run.js +11 -0
- package/conf/derivatives.yaml +4 -2
- package/conf/exclude.list.d/var.list +11 -6
- package/dist/appimage/dependency-manager.d.ts +31 -0
- package/dist/appimage/dependency-manager.js +292 -0
- package/dist/appimage/first-run-check.js +3 -3
- package/dist/bin/run.js +11 -0
- package/dist/classes/cli-autologin.js +78 -53
- package/dist/classes/compressors.d.ts +7 -10
- package/dist/classes/compressors.js +44 -31
- package/dist/classes/daddy.js +11 -11
- package/dist/classes/distro.js +2 -2
- package/dist/classes/diversions.js +2 -3
- package/dist/classes/incubation/fisherman-helper/initcpio.d.ts +4 -0
- package/dist/classes/incubation/fisherman-helper/initcpio.js +14 -4
- package/dist/classes/incubation/fisherman-helper/settings.js +1 -1
- package/dist/classes/incubation/fisherman.js +1 -3
- package/dist/classes/incubation/incubator.js +1 -1
- package/dist/classes/network.d.ts +1 -1
- package/dist/classes/ovary.d/create-xdg-autostart.js +1 -1
- package/dist/classes/ovary.d/edit-live-fs.d.ts +1 -12
- package/dist/classes/ovary.d/edit-live-fs.js +216 -186
- package/dist/classes/ovary.d/fertilization.js +1 -1
- package/dist/classes/ovary.d/make-dot-disk.js +1 -1
- package/dist/classes/ovary.d/produce.js +1 -1
- package/dist/classes/ovary.d/user-create-live.d.ts +4 -10
- package/dist/classes/ovary.d/user-create-live.js +82 -84
- package/dist/classes/ovary.d/users-remove.d.ts +5 -6
- package/dist/classes/ovary.d/users-remove.js +61 -31
- package/dist/classes/ovary.d/xorriso-command.js +1 -5
- package/dist/classes/ovary.d.ts +2 -2
- package/dist/classes/ovary.js +2 -2
- package/dist/classes/pacman.d/alpine.js +2 -2
- package/dist/classes/pacman.d/archlinux.js +2 -2
- package/dist/classes/pacman.d/debian.js +2 -3
- package/dist/classes/pacman.d/fedora.js +2 -3
- package/dist/classes/pacman.d/openmamba.js +2 -3
- package/dist/classes/pacman.d/opensuse.js +2 -3
- package/dist/classes/pacman.d.ts +21 -12
- package/dist/classes/pacman.js +55 -47
- package/dist/classes/pve-live.js +1 -1
- package/dist/classes/settings.js +1 -1
- package/dist/classes/sys-users.d.ts +76 -0
- package/dist/classes/sys-users.js +206 -0
- package/dist/classes/utils.d/kernel.js +3 -3
- package/dist/classes/utils.d.ts +16 -11
- package/dist/classes/utils.js +92 -56
- package/dist/classes/xdg.js +1 -1
- package/dist/classes/yolk.js +2 -4
- package/dist/commands/config.js +3 -14
- package/dist/commands/cuckoo.js +1 -1
- package/dist/commands/export/appimage.js +3 -3
- package/dist/commands/export/pkg.js +3 -3
- package/dist/commands/export/tarballs.js +3 -3
- package/dist/commands/krill.js +1 -1
- package/dist/commands/produce.js +9 -4
- package/dist/commands/{setup.d.ts → setup/install.d.ts} +1 -5
- package/dist/commands/setup/install.js +71 -0
- package/dist/commands/setup/purge.d.ts +17 -0
- package/dist/commands/setup/purge.js +71 -0
- package/dist/commands/tools/yolk.js +1 -1
- package/dist/commands/update.d.ts +15 -0
- package/dist/commands/update.js +74 -7
- package/dist/interfaces/i-exec.d.ts +1 -0
- package/dist/krill/classes/prepare.d/location.js +1 -1
- package/dist/krill/classes/prepare.d/partitions.js +1 -1
- package/dist/krill/classes/prepare.d/users.js +2 -2
- package/dist/krill/classes/prepare.js +5 -5
- package/dist/krill/classes/sequence.d/add_user.d.ts +3 -15
- package/dist/krill/classes/sequence.d/add_user.js +87 -57
- package/dist/krill/classes/sequence.d/change_password.d.ts +5 -7
- package/dist/krill/classes/sequence.d/change_password.js +25 -10
- package/dist/krill/classes/sequence.d/del_live_user.d.ts +5 -7
- package/dist/krill/classes/sequence.d/del_live_user.js +39 -25
- package/dist/krill/classes/sequence.d/fstab.js +1 -1
- package/dist/krill/classes/sequence.d/grubcfg.d.ts +3 -7
- package/dist/krill/classes/sequence.d/grubcfg.js +33 -13
- package/dist/krill/classes/sequence.d/mkfs.js +1 -2
- package/dist/krill/classes/sequence.d/unpackfs.d.ts +2 -4
- package/dist/krill/classes/sequence.d/unpackfs.js +8 -5
- package/dist/krill/classes/sequence.js +2 -3
- package/dist/krill/components/title.js +4 -4
- package/dist/krill/lib/select_installation_device.js +1 -1
- package/dist/krill/lib/select_replaced_partition.js +1 -1
- package/dist/lib/utils.d.ts +51 -19
- package/dist/lib/utils.js +225 -39
- package/manpages/doc/man/eggs.1.gz +0 -0
- package/manpages/doc/man/eggs.html +29 -17
- package/package.json +13 -14
- package/perrisbrewery/template/dependencies.yaml +1 -0
- package/scripts/_eggs +35 -7
- package/scripts/boot-encrypted-root.sh +220 -0
- package/scripts/eggs.bash +2 -1
- package/scripts/mount-encrypted-home.sh +324 -0
- package/dist/appimage/prerequisites.d.ts +0 -34
- package/dist/appimage/prerequisites.js +0 -350
- package/dist/commands/setup.js +0 -90
- package/dracut/create-symlink +0 -71
- package/dracut/dracut-log.txt +0 -3
- package/dracut/export +0 -4
- package/dracut/export-dracut-analysis +0 -51
- package/dracut/export-dracut-log +0 -2
- package/dracut/mkisofs +0 -10
- package/dracut/renew-initramfs +0 -17
- package/dracut/sbin2bin +0 -10
- package/dracut/update-dracut-conf-d +0 -2
- package/dracut/update-dracut-modules +0 -62
- package/scripts/appimage-build.sh +0 -152
- package/scripts/appimage-install.sh +0 -43
package/dist/classes/pacman.js
CHANGED
|
@@ -5,11 +5,10 @@
|
|
|
5
5
|
* email: piero.proietti@gmail.com
|
|
6
6
|
* license: MIT
|
|
7
7
|
*/
|
|
8
|
-
import { execSync } from '
|
|
8
|
+
import { shx, execSync } from '../lib/utils.js';
|
|
9
9
|
import fs from 'node:fs';
|
|
10
10
|
// _dirname
|
|
11
11
|
import path from 'node:path';
|
|
12
|
-
import shx from 'shelljs';
|
|
13
12
|
import { exec } from '../lib/utils.js';
|
|
14
13
|
import Distro from './distro.js';
|
|
15
14
|
import Diversions from './diversions.js';
|
|
@@ -33,24 +32,35 @@ export default class Pacman {
|
|
|
33
32
|
distro = {};
|
|
34
33
|
remix = {};
|
|
35
34
|
/**
|
|
36
|
-
*
|
|
35
|
+
* autocompleteInstall()
|
|
37
36
|
* @param verbose
|
|
38
37
|
*/
|
|
39
|
-
static async autocompleteInstall(
|
|
38
|
+
static async autocompleteInstall() {
|
|
40
39
|
if (Pacman.packageIsInstalled('bash-completion')) {
|
|
41
40
|
if (fs.existsSync('/usr/share/bash-completion/completions/')) {
|
|
42
41
|
await exec(`cp ${__dirname}/../../scripts/eggs.bash /usr/share/bash-completion/completions/`);
|
|
43
42
|
}
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
}
|
|
44
|
+
// Su arch è ok, su debian God know
|
|
45
|
+
if (Pacman.packageIsInstalled('zsh-completions')) {
|
|
46
|
+
if (fs.existsSync('/usr/share/zsh/site-functions')) {
|
|
47
|
+
await exec(`cp ${__dirname}/../../scripts/_eggs /usr/share/zsh/site-functions/`);
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* autocompleteRemove
|
|
53
|
+
* @param verbose
|
|
54
|
+
*/
|
|
55
|
+
static async autocompleteRemove(verbose = false) {
|
|
56
|
+
await exec(`rm -f /usr/share/bash-completion/completions/eggs.bash`);
|
|
57
|
+
await exec(`rm -f /usr/share/zsh/site-functions/._eggs`);
|
|
58
|
+
}
|
|
49
59
|
/**
|
|
50
60
|
* return true if calamares is installed
|
|
51
61
|
*/
|
|
52
62
|
static calamaresExists() {
|
|
53
|
-
return
|
|
63
|
+
return Utils.commandExists('calamares');
|
|
54
64
|
}
|
|
55
65
|
/**
|
|
56
66
|
*
|
|
@@ -133,19 +143,6 @@ export default class Pacman {
|
|
|
133
143
|
}
|
|
134
144
|
return retVal;
|
|
135
145
|
}
|
|
136
|
-
/**
|
|
137
|
-
*
|
|
138
|
-
* @param cmd
|
|
139
|
-
*/
|
|
140
|
-
static commandIsInstalled(cmd) {
|
|
141
|
-
let installed = false;
|
|
142
|
-
// if (shx.exec(`command -V ${cmd} &>/dev/null`).code == 0) {
|
|
143
|
-
// remove output
|
|
144
|
-
if (shx.exec(`command -V ${cmd} >/dev/null 2>&1`).code == 0) {
|
|
145
|
-
installed = true;
|
|
146
|
-
}
|
|
147
|
-
return installed;
|
|
148
|
-
}
|
|
149
146
|
/**
|
|
150
147
|
* Restituisce VERO se i file di configurazione SONO presenti
|
|
151
148
|
*/
|
|
@@ -186,7 +183,7 @@ export default class Pacman {
|
|
|
186
183
|
/**
|
|
187
184
|
* Salvo la configurazione di eggs.yaml
|
|
188
185
|
*/
|
|
189
|
-
config.machine_id = Utils.machineId()
|
|
186
|
+
config.machine_id = ''; //Utils.machineId()
|
|
190
187
|
config.vmlinuz = Utils.vmlinuz();
|
|
191
188
|
config.initrd_img = Utils.initrdImg();
|
|
192
189
|
const settings = new Settings();
|
|
@@ -222,7 +219,6 @@ export default class Pacman {
|
|
|
222
219
|
execSync(`rm -rf ${init}`);
|
|
223
220
|
}
|
|
224
221
|
execSync(`mkdir -p ${init}`);
|
|
225
|
-
shx.ln('-s', path.resolve(__dirname, '../../addons'), addons);
|
|
226
222
|
shx.cp(path.resolve(__dirname, '../../conf/README.md'), confRoot);
|
|
227
223
|
shx.cp(path.resolve(__dirname, '../../conf/derivatives.yaml'), confRoot);
|
|
228
224
|
shx.cp(path.resolve(__dirname, '../../conf/derivatives_fedora.yaml'), confRoot);
|
|
@@ -240,6 +236,21 @@ export default class Pacman {
|
|
|
240
236
|
shx.cp(path.resolve(__dirname, '../../conf/exclude.list.d/*'), '/etc/penguins-eggs.d/exclude.list.d');
|
|
241
237
|
await this.configurationFresh();
|
|
242
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Rimozione dei file di configurazione
|
|
241
|
+
*/
|
|
242
|
+
static async configurationRemove(verbose = false) {
|
|
243
|
+
const echo = Utils.setEcho(verbose);
|
|
244
|
+
if (fs.existsSync('/etc/penguins-eggs.d')) {
|
|
245
|
+
await exec('rm /etc/penguins-eggs.d -rf', echo);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* No remove calamares more
|
|
249
|
+
*/
|
|
250
|
+
// if (fs.existsSync('/etc/calamares')) {
|
|
251
|
+
// await exec('rm /etc/calamares -rf', echo)
|
|
252
|
+
// }
|
|
253
|
+
}
|
|
243
254
|
/**
|
|
244
255
|
* Ritorna vero se machine-id è uguale
|
|
245
256
|
*/
|
|
@@ -252,18 +263,6 @@ export default class Pacman {
|
|
|
252
263
|
}
|
|
253
264
|
return result;
|
|
254
265
|
}
|
|
255
|
-
/**
|
|
256
|
-
* Rimozione dei file di configurazione
|
|
257
|
-
*/
|
|
258
|
-
static async configurationRemove(verbose = true) {
|
|
259
|
-
const echo = Utils.setEcho(verbose);
|
|
260
|
-
if (fs.existsSync('/etc/penguins-eggs.d')) {
|
|
261
|
-
await exec('rm /etc/penguins-eggs.d -rf', echo);
|
|
262
|
-
}
|
|
263
|
-
if (fs.existsSync('/etc/calamares')) {
|
|
264
|
-
await exec('rm /etc/calamares -rf', echo);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
266
|
/**
|
|
268
267
|
*
|
|
269
268
|
* @returns
|
|
@@ -591,22 +590,26 @@ export default class Pacman {
|
|
|
591
590
|
/**
|
|
592
591
|
* Installa manPage
|
|
593
592
|
*/
|
|
594
|
-
static async
|
|
595
|
-
const
|
|
596
|
-
if (fs.existsSync(
|
|
597
|
-
const
|
|
598
|
-
if (!fs.existsSync(
|
|
599
|
-
exec(`mkdir ${
|
|
600
|
-
}
|
|
601
|
-
exec(`cp ${manPageSrc} ${manPageDest}`);
|
|
602
|
-
if (shx.exec('which mandb', { silent: true }).stdout.trim() !== '') {
|
|
603
|
-
await exec('mandb > /dev/null');
|
|
604
|
-
if (verbose) {
|
|
605
|
-
console.log('manPage eggs installed...');
|
|
606
|
-
}
|
|
593
|
+
static async manpageInstall() {
|
|
594
|
+
const manpageSrc = path.resolve(__dirname, '../../manpages/doc/man/eggs.1.gz');
|
|
595
|
+
if (fs.existsSync(manpageSrc)) {
|
|
596
|
+
const manpageDest = `/usr/share/man/man1`;
|
|
597
|
+
if (!fs.existsSync(manpageDest)) {
|
|
598
|
+
await exec(`mkdir ${manpageDest} -p`);
|
|
607
599
|
}
|
|
600
|
+
await exec(`cp ${manpageSrc} ${manpageDest}`);
|
|
601
|
+
// if (shx.exec('which mandb', { silent: true }).stdout.trim() !== '') {
|
|
602
|
+
// await exec('mandb > /dev/null')
|
|
603
|
+
// }
|
|
608
604
|
}
|
|
609
605
|
}
|
|
606
|
+
/**
|
|
607
|
+
* manpageRemove
|
|
608
|
+
*/
|
|
609
|
+
static async manpageRemove() {
|
|
610
|
+
const manpageEggs = `/usr/share/man/man1/eggs.1.gz`;
|
|
611
|
+
await exec(`rm -rf ${manpageEggs}`);
|
|
612
|
+
}
|
|
610
613
|
/**
|
|
611
614
|
*
|
|
612
615
|
* @param debPackage
|
|
@@ -674,6 +677,11 @@ export default class Pacman {
|
|
|
674
677
|
}
|
|
675
678
|
return installed;
|
|
676
679
|
}
|
|
680
|
+
/**
|
|
681
|
+
*
|
|
682
|
+
* @param packageNpm
|
|
683
|
+
* @returns
|
|
684
|
+
*/
|
|
677
685
|
static async packageNpmLast(packageNpm = 'penguins-eggs') {
|
|
678
686
|
return shx.exec('npm show ' + packageNpm + ' version', { silent: true }).stdout.trim();
|
|
679
687
|
}
|
package/dist/classes/pve-live.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* This will remove the symbolic link that indicated that the service should be started automatically.
|
|
15
15
|
*/
|
|
16
16
|
import path from 'node:path';
|
|
17
|
-
import shx from '
|
|
17
|
+
import { shx } from '../lib/utils.js';
|
|
18
18
|
import Systemctl from './systemctl.js';
|
|
19
19
|
// _dirname
|
|
20
20
|
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
package/dist/classes/settings.js
CHANGED
|
@@ -10,7 +10,7 @@ import yaml from 'js-yaml';
|
|
|
10
10
|
// packages
|
|
11
11
|
import fs from 'node:fs';
|
|
12
12
|
import os from 'node:os';
|
|
13
|
-
import shx from '
|
|
13
|
+
import { shx } from '../lib/utils.js';
|
|
14
14
|
// pjson
|
|
15
15
|
import { createRequire } from 'node:module';
|
|
16
16
|
const require = createRequire(import.meta.url);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/classes/sys-users.ts
|
|
3
|
+
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
+
* * "THE SYSUSER MASTER"
|
|
5
|
+
* Gestione pura Node.js per utenti e gruppi di sistema.
|
|
6
|
+
* Sostituisce i binari (useradd/usermod/deluser) per garantire operazioni atomiche
|
|
7
|
+
* e compatibilità SELinux (Fedora/RHEL) scrivendo file puliti.
|
|
8
|
+
*/
|
|
9
|
+
export interface IPasswdEntry {
|
|
10
|
+
username: string;
|
|
11
|
+
password: string;
|
|
12
|
+
uid: string;
|
|
13
|
+
gid: string;
|
|
14
|
+
gecos: string;
|
|
15
|
+
home: string;
|
|
16
|
+
shell: string;
|
|
17
|
+
}
|
|
18
|
+
export interface IShadowEntry {
|
|
19
|
+
username: string;
|
|
20
|
+
hash: string;
|
|
21
|
+
lastChange: string;
|
|
22
|
+
min: string;
|
|
23
|
+
max: string;
|
|
24
|
+
warn: string;
|
|
25
|
+
inactive: string;
|
|
26
|
+
expire: string;
|
|
27
|
+
}
|
|
28
|
+
export interface IGroupEntry {
|
|
29
|
+
groupName: string;
|
|
30
|
+
password: string;
|
|
31
|
+
gid: string;
|
|
32
|
+
members: string[];
|
|
33
|
+
}
|
|
34
|
+
export default class SysUsers {
|
|
35
|
+
private targetRoot;
|
|
36
|
+
private distroFamily;
|
|
37
|
+
private passwd;
|
|
38
|
+
private shadow;
|
|
39
|
+
private group;
|
|
40
|
+
private gshadowLines;
|
|
41
|
+
private subuidLines;
|
|
42
|
+
private subgidLines;
|
|
43
|
+
constructor(targetRoot: string, distroFamily: string);
|
|
44
|
+
/**
|
|
45
|
+
* Carica tutti i file di configurazione in memoria
|
|
46
|
+
*/
|
|
47
|
+
load(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Salva lo stato della memoria su disco e applica SELinux fix
|
|
50
|
+
*/
|
|
51
|
+
save(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Crea un nuovo utente completo
|
|
54
|
+
*/
|
|
55
|
+
addUser(user: IPasswdEntry, cleanPassword: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Rimuove completamente un utente
|
|
58
|
+
*/
|
|
59
|
+
removeUser(username: string): void;
|
|
60
|
+
/**
|
|
61
|
+
* Aggiunge utente a un gruppo supplementare
|
|
62
|
+
*/
|
|
63
|
+
addUserToGroup(username: string, groupName: string): void;
|
|
64
|
+
/**
|
|
65
|
+
* Cambia password utente
|
|
66
|
+
*/
|
|
67
|
+
setPassword(username: string, password: string): void;
|
|
68
|
+
private readFile;
|
|
69
|
+
private writeFile;
|
|
70
|
+
private parsePasswd;
|
|
71
|
+
private serializePasswd;
|
|
72
|
+
private parseShadow;
|
|
73
|
+
private serializeShadow;
|
|
74
|
+
private parseGroup;
|
|
75
|
+
private serializeGroup;
|
|
76
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/classes/sys-users.ts
|
|
3
|
+
* penguins-eggs v.25.7.x / ecmascript 2020
|
|
4
|
+
* * "THE SYSUSER MASTER"
|
|
5
|
+
* Gestione pura Node.js per utenti e gruppi di sistema.
|
|
6
|
+
* Sostituisce i binari (useradd/usermod/deluser) per garantire operazioni atomiche
|
|
7
|
+
* e compatibilità SELinux (Fedora/RHEL) scrivendo file puliti.
|
|
8
|
+
*/
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import * as bcrypt from 'bcryptjs';
|
|
12
|
+
import { exec } from '../lib/utils.js';
|
|
13
|
+
export default class SysUsers {
|
|
14
|
+
targetRoot;
|
|
15
|
+
distroFamily;
|
|
16
|
+
// Cache in memoria
|
|
17
|
+
passwd = [];
|
|
18
|
+
shadow = [];
|
|
19
|
+
group = [];
|
|
20
|
+
// File "minori" gestiti a righe raw per semplicità
|
|
21
|
+
gshadowLines = [];
|
|
22
|
+
subuidLines = [];
|
|
23
|
+
subgidLines = [];
|
|
24
|
+
constructor(targetRoot, distroFamily) {
|
|
25
|
+
this.targetRoot = targetRoot;
|
|
26
|
+
this.distroFamily = distroFamily;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Carica tutti i file di configurazione in memoria
|
|
30
|
+
*/
|
|
31
|
+
load() {
|
|
32
|
+
this.passwd = this.parsePasswd(this.readFile('etc/passwd'));
|
|
33
|
+
this.shadow = this.parseShadow(this.readFile('etc/shadow'));
|
|
34
|
+
this.group = this.parseGroup(this.readFile('etc/group'));
|
|
35
|
+
this.gshadowLines = this.readFile('etc/gshadow');
|
|
36
|
+
this.subuidLines = this.readFile('etc/subuid');
|
|
37
|
+
this.subgidLines = this.readFile('etc/subgid');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Salva lo stato della memoria su disco e applica SELinux fix
|
|
41
|
+
*/
|
|
42
|
+
async save() {
|
|
43
|
+
// Serializzazione
|
|
44
|
+
const passwdContent = this.serializePasswd(this.passwd);
|
|
45
|
+
const shadowContent = this.serializeShadow(this.shadow);
|
|
46
|
+
const groupContent = this.serializeGroup(this.group);
|
|
47
|
+
// Scrittura Atomica + Fix SELinux
|
|
48
|
+
await this.writeFile('etc/passwd', passwdContent, 'passwd_file_t');
|
|
49
|
+
await this.writeFile('etc/shadow', shadowContent, 'shadow_t');
|
|
50
|
+
await this.writeFile('etc/group', groupContent, 'passwd_file_t');
|
|
51
|
+
// File raw
|
|
52
|
+
if (this.gshadowLines.length > 0)
|
|
53
|
+
await this.writeFile('etc/gshadow', this.gshadowLines.join('\n'), 'shadow_t');
|
|
54
|
+
if (this.subuidLines.length > 0)
|
|
55
|
+
await this.writeFile('etc/subuid', this.subuidLines.join('\n'), 'passwd_file_t');
|
|
56
|
+
if (this.subgidLines.length > 0)
|
|
57
|
+
await this.writeFile('etc/subgid', this.subgidLines.join('\n'), 'passwd_file_t');
|
|
58
|
+
}
|
|
59
|
+
// =========================================================================
|
|
60
|
+
// API PUBBLICA
|
|
61
|
+
// =========================================================================
|
|
62
|
+
/**
|
|
63
|
+
* Crea un nuovo utente completo
|
|
64
|
+
*/
|
|
65
|
+
addUser(user, cleanPassword) {
|
|
66
|
+
// Rimuovi se esiste (idempotenza)
|
|
67
|
+
this.removeUser(user.username);
|
|
68
|
+
// 1. Passwd
|
|
69
|
+
this.passwd.push(user);
|
|
70
|
+
// 2. Shadow (Hash Password)
|
|
71
|
+
const salt = bcrypt.genSaltSync(10);
|
|
72
|
+
const hash = bcrypt.hashSync(cleanPassword, salt);
|
|
73
|
+
this.shadow.push({
|
|
74
|
+
username: user.username,
|
|
75
|
+
hash: hash,
|
|
76
|
+
lastChange: '19700', // Data approssimativa
|
|
77
|
+
min: '0',
|
|
78
|
+
max: '99999',
|
|
79
|
+
warn: '7',
|
|
80
|
+
inactive: '',
|
|
81
|
+
expire: ''
|
|
82
|
+
});
|
|
83
|
+
// 3. Gruppo Primario
|
|
84
|
+
// Solo se non esiste già un gruppo con quel nome
|
|
85
|
+
if (!this.group.find(g => g.groupName === user.username)) {
|
|
86
|
+
this.group.push({
|
|
87
|
+
groupName: user.username,
|
|
88
|
+
password: 'x',
|
|
89
|
+
gid: user.gid,
|
|
90
|
+
members: []
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// 4. GShadow (placeholder)
|
|
94
|
+
this.gshadowLines.push(`${user.username}:!::`);
|
|
95
|
+
// 5. SubUID/SubGID (Podman rootless)
|
|
96
|
+
// Calcolo offset standard: 100000 + (UID-1000)*65536
|
|
97
|
+
const uidNum = parseInt(user.uid);
|
|
98
|
+
if (!isNaN(uidNum) && uidNum >= 1000) {
|
|
99
|
+
const startUid = 100000 + (uidNum - 1000) * 65536;
|
|
100
|
+
const subEntry = `${user.username}:${startUid}:65536`;
|
|
101
|
+
this.subuidLines.push(subEntry);
|
|
102
|
+
this.subgidLines.push(subEntry);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Rimuove completamente un utente
|
|
107
|
+
*/
|
|
108
|
+
removeUser(username) {
|
|
109
|
+
this.passwd = this.passwd.filter(u => u.username !== username);
|
|
110
|
+
this.shadow = this.shadow.filter(s => s.username !== username);
|
|
111
|
+
this.group = this.group.filter(g => g.groupName !== username);
|
|
112
|
+
// Rimuovi dai membri di altri gruppi
|
|
113
|
+
this.group.forEach(g => {
|
|
114
|
+
g.members = g.members.filter(m => m !== username);
|
|
115
|
+
});
|
|
116
|
+
this.gshadowLines = this.gshadowLines.filter(l => !l.startsWith(`${username}:`));
|
|
117
|
+
this.subuidLines = this.subuidLines.filter(l => !l.startsWith(`${username}:`));
|
|
118
|
+
this.subgidLines = this.subgidLines.filter(l => !l.startsWith(`${username}:`));
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Aggiunge utente a un gruppo supplementare
|
|
122
|
+
*/
|
|
123
|
+
addUserToGroup(username, groupName) {
|
|
124
|
+
const grp = this.group.find(g => g.groupName === groupName);
|
|
125
|
+
if (grp) {
|
|
126
|
+
if (!grp.members.includes(username)) {
|
|
127
|
+
grp.members.push(username);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Se il gruppo non esiste, lo ignoriamo silenziosamente o potremmo crearlo
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Cambia password utente
|
|
134
|
+
*/
|
|
135
|
+
setPassword(username, password) {
|
|
136
|
+
const entry = this.shadow.find(s => s.username === username);
|
|
137
|
+
if (entry) {
|
|
138
|
+
const salt = bcrypt.genSaltSync(10);
|
|
139
|
+
entry.hash = bcrypt.hashSync(password, salt);
|
|
140
|
+
entry.lastChange = '19700';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// =========================================================================
|
|
144
|
+
// IMPLEMENTAZIONE FILE (Privata)
|
|
145
|
+
// =========================================================================
|
|
146
|
+
readFile(relativePath) {
|
|
147
|
+
const fullPath = path.join(this.targetRoot, relativePath);
|
|
148
|
+
if (fs.existsSync(fullPath)) {
|
|
149
|
+
return fs.readFileSync(fullPath, 'utf8').split('\n').filter(l => l.trim().length > 0);
|
|
150
|
+
}
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
async writeFile(relativePath, content, contextType) {
|
|
154
|
+
const fullPath = path.join(this.targetRoot, relativePath);
|
|
155
|
+
// Crea dir se manca (es. /etc/sudoers.d/ o simili)
|
|
156
|
+
const dir = path.dirname(fullPath);
|
|
157
|
+
if (!fs.existsSync(dir))
|
|
158
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
159
|
+
try {
|
|
160
|
+
// 1. Scrittura
|
|
161
|
+
fs.writeFileSync(fullPath, content + '\n');
|
|
162
|
+
// 2. Fix SELinux (Solo RHEL Family)
|
|
163
|
+
if (['fedora', 'rhel', 'centos', 'almalinux', 'rocky'].includes(this.distroFamily)) {
|
|
164
|
+
// await exec, echo false per non sporcare i log
|
|
165
|
+
await exec(`chcon -t ${contextType} ${fullPath}`, { echo: false }).catch(() => { });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
console.error(`SysUsers Error writing ${relativePath}:`, e);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// --- PARSERS & SERIALIZERS ---
|
|
173
|
+
parsePasswd(lines) {
|
|
174
|
+
return lines.map(line => {
|
|
175
|
+
const p = line.split(':');
|
|
176
|
+
if (p.length < 7)
|
|
177
|
+
return null;
|
|
178
|
+
return { username: p[0], password: p[1], uid: p[2], gid: p[3], gecos: p[4], home: p[5], shell: p[6] };
|
|
179
|
+
}).filter((u) => u !== null);
|
|
180
|
+
}
|
|
181
|
+
serializePasswd(entries) {
|
|
182
|
+
return entries.map(u => `${u.username}:${u.password}:${u.uid}:${u.gid}:${u.gecos}:${u.home}:${u.shell}`).join('\n');
|
|
183
|
+
}
|
|
184
|
+
parseShadow(lines) {
|
|
185
|
+
return lines.map(line => {
|
|
186
|
+
const p = line.split(':');
|
|
187
|
+
if (p.length < 2)
|
|
188
|
+
return null;
|
|
189
|
+
return { username: p[0], hash: p[1], lastChange: p[2] || '', min: p[3] || '', max: p[4] || '', warn: p[5] || '', inactive: p[6] || '', expire: p[7] || '' };
|
|
190
|
+
}).filter((u) => u !== null);
|
|
191
|
+
}
|
|
192
|
+
serializeShadow(entries) {
|
|
193
|
+
return entries.map(s => `${s.username}:${s.hash}:${s.lastChange}:${s.min}:${s.max}:${s.warn}:${s.inactive}:${s.expire}:`).join('\n');
|
|
194
|
+
}
|
|
195
|
+
parseGroup(lines) {
|
|
196
|
+
return lines.map(line => {
|
|
197
|
+
const p = line.split(':');
|
|
198
|
+
if (p.length < 3)
|
|
199
|
+
return null;
|
|
200
|
+
return { groupName: p[0], password: p[1], gid: p[2], members: p[3] && p[3].trim() ? p[3].split(',') : [] };
|
|
201
|
+
}).filter((g) => g !== null);
|
|
202
|
+
}
|
|
203
|
+
serializeGroup(entries) {
|
|
204
|
+
return entries.map(g => `${g.groupName}:${g.password}:${g.gid}:${g.members.join(',')}`).join('\n');
|
|
205
|
+
}
|
|
206
|
+
}
|
|
@@ -8,7 +8,7 @@ import fs from 'node:fs';
|
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import Distro from '../distro.js';
|
|
10
10
|
import Utils from '../utils.js';
|
|
11
|
-
import { execSync } from '
|
|
11
|
+
import { execSync } from '../../lib/utils.js';
|
|
12
12
|
/**
|
|
13
13
|
* Kernel utilities for managing vmlinuz and initramfs paths
|
|
14
14
|
*/
|
|
@@ -55,7 +55,7 @@ export default class Kernel {
|
|
|
55
55
|
Utils.warning("Non è possibile determinare il kernel in un container.");
|
|
56
56
|
process.exit(1);
|
|
57
57
|
}
|
|
58
|
-
targetKernel = execSync('uname -r')
|
|
58
|
+
targetKernel = (execSync('uname -r', { stdio: 'ignore' }) || '').trim();
|
|
59
59
|
}
|
|
60
60
|
const kernelVersionShort = targetKernel.split('.').slice(0, 2).join('.');
|
|
61
61
|
const bootDir = '/boot';
|
|
@@ -138,7 +138,7 @@ export default class Kernel {
|
|
|
138
138
|
* debian, fedora, opensuse, rasberry
|
|
139
139
|
*/
|
|
140
140
|
static vmlinuzFromUname() {
|
|
141
|
-
let kernelVersion = execSync('uname -r')
|
|
141
|
+
let kernelVersion = (execSync('uname -r', { stdio: 'ignore' }) || '').trim();
|
|
142
142
|
// Try 1: path standard (es. Debian, Ubuntu, Fedora)
|
|
143
143
|
let standardPath = `/boot/vmlinuz-${kernelVersion}`;
|
|
144
144
|
if (fs.existsSync(standardPath)) {
|
package/dist/classes/utils.d.ts
CHANGED
|
@@ -62,7 +62,7 @@ export default class Utils {
|
|
|
62
62
|
*/
|
|
63
63
|
static isOpenRc(): boolean;
|
|
64
64
|
/**
|
|
65
|
-
*
|
|
65
|
+
* Usata da pacman e config credo non serva affatto
|
|
66
66
|
*/
|
|
67
67
|
static machineId(): string;
|
|
68
68
|
/**
|
|
@@ -140,7 +140,7 @@ export default class Utils {
|
|
|
140
140
|
*
|
|
141
141
|
* @param volid
|
|
142
142
|
*/
|
|
143
|
-
static
|
|
143
|
+
static VolidTrim(volid?: string): string;
|
|
144
144
|
/**
|
|
145
145
|
* Return postfix
|
|
146
146
|
* @param basename
|
|
@@ -153,11 +153,10 @@ export default class Utils {
|
|
|
153
153
|
*/
|
|
154
154
|
static getUsedSpace(): number;
|
|
155
155
|
/**
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
*/
|
|
156
|
+
* Estimate the linuxfs dimension
|
|
157
|
+
* (Refactored to use native FS instead of dd/od)
|
|
158
|
+
* @returns {number} GB
|
|
159
|
+
*/
|
|
161
160
|
static getLiveRootSpace(type?: string): number;
|
|
162
161
|
/**
|
|
163
162
|
* Return true if i686 architecture
|
|
@@ -247,10 +246,6 @@ export default class Utils {
|
|
|
247
246
|
* cidr
|
|
248
247
|
*/
|
|
249
248
|
static cidr(): string;
|
|
250
|
-
/**
|
|
251
|
-
*
|
|
252
|
-
* broadcast
|
|
253
|
-
*/
|
|
254
249
|
static broadcast(): string;
|
|
255
250
|
/**
|
|
256
251
|
* dns
|
|
@@ -331,4 +326,14 @@ export default class Utils {
|
|
|
331
326
|
static wardrobe(): Promise<string>;
|
|
332
327
|
static getOsRelease(): IOsRelease;
|
|
333
328
|
static sleep(ms?: number): Promise<void>;
|
|
329
|
+
/**
|
|
330
|
+
* chpasswdPath
|
|
331
|
+
* @returns
|
|
332
|
+
*/
|
|
333
|
+
static chpasswdPath(): string;
|
|
334
|
+
/**
|
|
335
|
+
*
|
|
336
|
+
* @param cmd
|
|
337
|
+
*/
|
|
338
|
+
static commandExists(cmd: string): boolean;
|
|
334
339
|
}
|