penguins-eggs 10.0.60 → 10.1.1
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 +62 -1
- package/README.md +145 -75
- package/addons/eggs/theme/calamares/modules/{_users.yml → users.yml} +3 -3
- package/addons/eggs/theme/livecd/grub.main.full.cfg +1 -1
- package/addons/eggs/theme/livecd/grub.main.simple.cfg +1 -1
- package/conf/derivatives.yaml +4 -3
- package/conf/derivatives_fedora.yaml +6 -0
- package/conf/distros/alpine/calamares/modules/users.yml +3 -3
- package/conf/distros/bionic/calamares/calamares-modules/grubcfg/grubcfg.yml +1 -1
- package/conf/distros/bionic/calamares/modules/users.yml +3 -3
- package/conf/distros/buster/calamares/modules/users.yml +4 -3
- package/conf/distros/fedora/calamares/modules/users.yml +3 -3
- package/conf/distros/noble/calamares/modules/focal-jammy/users.yml +3 -3
- package/conf/distros/noble/calamares/modules/users.yml +1 -0
- package/conf/distros/opensuse/calamares/modules/users.yml +3 -3
- package/conf/distros/rolling/calamares/modules/users.yml +3 -3
- package/conf/eggs.yaml +1 -1
- package/conf/love.yaml +4 -4
- package/dist/classes/compressors.js +1 -1
- package/dist/classes/distro.d.ts +27 -3
- package/dist/classes/distro.js +361 -289
- package/dist/classes/ovary.d/bind-live-fs.js +22 -30
- package/dist/classes/ovary.d/edit-live-fs.d.ts +1 -0
- package/dist/classes/ovary.d/edit-live-fs.js +9 -13
- package/dist/classes/ovary.d/fertilization.js +6 -1
- package/dist/classes/ovary.d/initrd.js +11 -15
- package/dist/classes/ovary.d/kernel-copy.js +2 -16
- package/dist/classes/ovary.d/make-efi.js +8 -5
- package/dist/classes/ovary.d/make-squashfs.d.ts +1 -1
- package/dist/classes/ovary.d/make-squashfs.js +17 -24
- package/dist/classes/ovary.d/merged.d.ts +9 -13
- package/dist/classes/ovary.d/merged.js +38 -48
- package/dist/classes/ovary.d/produce.d.ts +1 -1
- package/dist/classes/ovary.d/produce.js +38 -32
- package/dist/classes/ovary.d/syslinux.js +4 -4
- package/dist/classes/ovary.d/user-create-live.js +12 -5
- package/dist/classes/ovary.d.ts +8 -3
- package/dist/classes/ovary.js +8 -3
- package/dist/classes/pacman.d/archlinux.js +1 -5
- package/dist/classes/pacman.js +2 -1
- package/dist/classes/systemctl.d.ts +1 -1
- package/dist/classes/systemctl.js +1 -1
- package/dist/classes/tailor.js +2 -1
- package/dist/classes/utils.d/architecture.d.ts +41 -0
- package/dist/classes/utils.d/architecture.js +87 -0
- package/dist/classes/utils.d/console-output.d.ts +26 -0
- package/dist/classes/utils.d/console-output.js +46 -0
- package/dist/classes/utils.d/filesystem.d.ts +53 -0
- package/dist/classes/utils.d/filesystem.js +152 -0
- package/dist/classes/utils.d/formatters.d.ts +32 -0
- package/dist/classes/utils.d/formatters.js +64 -0
- package/dist/classes/utils.d/kernel.d.ts +83 -0
- package/dist/classes/utils.d/kernel.js +288 -0
- package/dist/classes/utils.d/network.d.ts +43 -0
- package/dist/classes/utils.d/network.js +133 -0
- package/dist/classes/utils.d/package-info.d.ts +55 -0
- package/dist/classes/utils.d/package-info.js +137 -0
- package/dist/classes/utils.d/snapshot.d.ts +44 -0
- package/dist/classes/utils.d/snapshot.js +102 -0
- package/dist/classes/utils.d/system.d.ts +63 -0
- package/dist/classes/utils.d/system.js +200 -0
- package/dist/classes/utils.d/user-interaction.d.ts +39 -0
- package/dist/classes/utils.d/user-interaction.js +104 -0
- package/dist/classes/utils.d.ts +90 -322
- package/dist/classes/utils.js +105 -1013
- package/dist/commands/dad.d.ts +1 -0
- package/dist/commands/dad.js +1 -0
- package/dist/commands/export/pkg.js +6 -6
- package/dist/commands/export/tarballs.js +11 -16
- package/dist/commands/kill.js +1 -1
- package/dist/commands/love.d.ts +1 -0
- package/dist/commands/love.js +21 -7
- package/dist/commands/pods.d.ts +22 -0
- package/dist/commands/pods.js +92 -0
- package/dist/commands/produce.d.ts +1 -0
- package/dist/commands/produce.js +21 -1
- package/dist/commands/update.js +2 -2
- package/dist/index.d.ts +6 -52
- package/dist/index.js +6 -145
- package/dist/krill/classes/krill_enums.d.ts +14 -1
- package/dist/krill/classes/krill_enums.js +16 -1
- package/dist/krill/classes/prepare.d/partitions.js +3 -3
- package/dist/krill/classes/prepare.d.ts +46 -21
- package/dist/krill/classes/prepare.js +187 -187
- package/dist/krill/classes/sequence.d/add_user.js +21 -3
- package/dist/krill/classes/sequence.d/partition.js +2 -2
- package/dist/krill/classes/sequence.d.ts +18 -21
- package/dist/krill/classes/sequence.js +156 -423
- package/dist/krill/components/information.js +13 -7
- package/dist/{krill/lib → lib}/kill_me_softly.js +2 -2
- package/dist/penguins-eggs_10.1.1-0_amd64.deb +0 -0
- package/dist/penguins-eggs_10.1.1-0_amd64.deb.sha256 +1 -0
- package/package.json +32 -27
- package/perrisbrewery/scripts/postinst +98 -0
- package/perrisbrewery/scripts/postrm +82 -0
- package/perrisbrewery/scripts/preinst +40 -0
- package/perrisbrewery/scripts/prerm +47 -0
- package/perrisbrewery/template/control.template +17 -0
- package/perrisbrewery/template/dependencies-bionic.yaml +33 -0
- package/perrisbrewery/template/dependencies.yaml +37 -0
- package/perrisbrewery/template/man.template.md +110 -0
- package/pods/README.md +14 -0
- package/pods/almalinux.sh +10 -0
- package/pods/archlinux.sh +10 -0
- package/pods/ci/README.md +5 -0
- package/pods/ci/kernel-overlay-install.sh +114 -0
- package/pods/ci/minimal/almalinux-container2host.sh +165 -0
- package/pods/ci/minimal/archlinux-container2host.sh +125 -0
- package/pods/ci/minimal/debian-container2host.sh +173 -0
- package/pods/ci/minimal/fedora-container2host.sh +170 -0
- package/pods/ci/minimal/manjaro-container2host.sh +123 -0
- package/pods/ci/minimal/opensuse-container2host.sh +143 -0
- package/pods/ci/penguins-eggs-execute.sh +22 -0
- package/pods/ci/penguins-eggs-install.sh +115 -0
- package/pods/ci/run +34 -0
- package/pods/ci/run-on-almalinux.sh +50 -0
- package/pods/ci/run-on-archlinux.sh +64 -0
- package/pods/ci/run-on-debian.sh +51 -0
- package/pods/ci/run-on-devuan.sh +48 -0
- package/pods/ci/run-on-fedora.sh +51 -0
- package/pods/ci/run-on-manjaro.sh +61 -0
- package/pods/ci/run-on-opensuse.sh +58 -0
- package/pods/ci/run-on-rockylinux.sh +51 -0
- package/pods/ci/run-on-ubuntu.sh +52 -0
- package/pods/debian.sh +23 -0
- package/pods/devuan.sh +26 -0
- package/pods/fedora.sh +12 -0
- package/pods/lmde.sh +22 -0
- package/pods/manjaro.sh +10 -0
- package/pods/opensuse.sh +12 -0
- package/pods/podman.command.sh +85 -0
- package/pods/rocky.sh +12 -0
- package/pods/run-build-packages-debs.sh +45 -0
- package/pods/run-create-debs.sh +23 -0
- package/pods/ubuntu.sh +24 -0
- package/scripts/_eggs +14 -5
- package/scripts/eggs.bash +5 -4
- /package/dist/{krill/lib → lib}/kill_me_softly.d.ts +0 -0
|
@@ -34,7 +34,7 @@ export async function partitions(installationDevice = "", crypted = false, pve =
|
|
|
34
34
|
let knownInstallationModes = Object.values(InstallationMode);
|
|
35
35
|
let knownSwapChoices = Object.values(SwapChoice);
|
|
36
36
|
if (!knownInstallationModes.includes(installationMode)) {
|
|
37
|
-
installationMode = InstallationMode.
|
|
37
|
+
installationMode = InstallationMode.EraseDisk;
|
|
38
38
|
}
|
|
39
39
|
if (crypted) {
|
|
40
40
|
installationMode = InstallationMode.Luks;
|
|
@@ -54,7 +54,7 @@ export async function partitions(installationDevice = "", crypted = false, pve =
|
|
|
54
54
|
}
|
|
55
55
|
else {
|
|
56
56
|
installationDevice = driveList[0]; // Solo per selezionare il default
|
|
57
|
-
installationMode = InstallationMode.
|
|
57
|
+
installationMode = InstallationMode.EraseDisk;
|
|
58
58
|
if (crypted) {
|
|
59
59
|
installationMode = InstallationMode.Luks;
|
|
60
60
|
}
|
|
@@ -65,7 +65,7 @@ export async function partitions(installationDevice = "", crypted = false, pve =
|
|
|
65
65
|
filesystemType = await selectFileSystemType();
|
|
66
66
|
userSwapChoice = SwapChoice.File;
|
|
67
67
|
}
|
|
68
|
-
else if (installationMode === InstallationMode.
|
|
68
|
+
else if (installationMode === InstallationMode.EraseDisk) {
|
|
69
69
|
replacedPartition = "";
|
|
70
70
|
filesystemType = await selectFileSystemType();
|
|
71
71
|
userSwapChoice = await selectUserSwapChoice(userSwapChoice);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Krill Installer - Simplified Refactoring
|
|
3
|
+
* ./src/krill/prepare.ts
|
|
3
4
|
* penguins-eggs v.10.0.0 / ecmascript 2020
|
|
4
5
|
* author: Piero Proietti
|
|
5
6
|
* email: piero.proietti@gmail.com
|
|
6
7
|
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
8
8
|
*/
|
|
9
9
|
import { IKrillConfig } from '../interfaces/i_krill_config.js';
|
|
10
10
|
import Keyboards from '../../classes/keyboards.js';
|
|
@@ -17,7 +17,7 @@ import { users } from './prepare.d/users.js';
|
|
|
17
17
|
import { network } from './prepare.d/network.js';
|
|
18
18
|
import { summary } from './prepare.d/summary.js';
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Main Krill installer class - Simplified refactoring
|
|
21
21
|
*/
|
|
22
22
|
export default class Krill {
|
|
23
23
|
welcome: typeof welcome;
|
|
@@ -35,30 +35,55 @@ export default class Krill {
|
|
|
35
35
|
chroot: boolean;
|
|
36
36
|
halt: boolean;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
* @param unattended
|
|
40
|
-
* @param nointeractive
|
|
41
|
-
* @param halt
|
|
38
|
+
* Constructor
|
|
42
39
|
*/
|
|
43
40
|
constructor(unattended?: boolean, nointeractive?: boolean, halt?: boolean, chroot?: boolean);
|
|
44
41
|
/**
|
|
45
|
-
*
|
|
46
|
-
* @param krillConfig
|
|
47
|
-
* @param ip
|
|
48
|
-
* @param random
|
|
49
|
-
* @param domain
|
|
50
|
-
* @param suspend
|
|
51
|
-
* @param small
|
|
52
|
-
* @param none
|
|
53
|
-
* @param crypted
|
|
54
|
-
* @param pve
|
|
55
|
-
* @param btrfs
|
|
56
|
-
* @param testing
|
|
57
|
-
* @param verbose
|
|
42
|
+
* Main prepare method - Simplified and cleaner
|
|
58
43
|
*/
|
|
59
44
|
prepare(krillConfig?: IKrillConfig, ip?: boolean, random?: boolean, domain?: string, suspend?: boolean, small?: boolean, none?: boolean, crypted?: boolean, pve?: boolean, btrfs?: boolean, testing?: boolean, verbose?: boolean): Promise<void>;
|
|
60
45
|
/**
|
|
61
|
-
*
|
|
46
|
+
* Check system requirements (disks, LVM)
|
|
47
|
+
*/
|
|
48
|
+
private checkSystemRequirements;
|
|
49
|
+
/**
|
|
50
|
+
* Setup configuration files and auto-configure timezone
|
|
51
|
+
*/
|
|
52
|
+
private setupConfiguration;
|
|
53
|
+
/**
|
|
54
|
+
* Auto-configure timezone from internet
|
|
55
|
+
*/
|
|
56
|
+
private autoConfigureTimezone;
|
|
57
|
+
/**
|
|
58
|
+
* Stop system services
|
|
59
|
+
*/
|
|
60
|
+
private stopSystemServices;
|
|
61
|
+
/**
|
|
62
|
+
* Build default configurations
|
|
63
|
+
*/
|
|
64
|
+
private buildConfigurations;
|
|
65
|
+
/**
|
|
66
|
+
* Generate hostname based on options
|
|
67
|
+
*/
|
|
68
|
+
private generateHostname;
|
|
69
|
+
/**
|
|
70
|
+
* Apply options for unattended installation
|
|
71
|
+
*/
|
|
72
|
+
private applyUnattendedOptions;
|
|
73
|
+
/**
|
|
74
|
+
* Run interactive mode with UI
|
|
75
|
+
*/
|
|
76
|
+
private runInteractiveMode;
|
|
77
|
+
/**
|
|
78
|
+
* Perform installation or testing
|
|
79
|
+
*/
|
|
80
|
+
private performInstallation;
|
|
81
|
+
/**
|
|
82
|
+
* Create script to remove LVM partitions
|
|
83
|
+
*/
|
|
84
|
+
private createLvmRemovalScript;
|
|
85
|
+
/**
|
|
86
|
+
* Check if Physical Volumes exist
|
|
62
87
|
*/
|
|
63
88
|
private pvExist;
|
|
64
89
|
}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Krill Installer - Simplified Refactoring
|
|
3
|
+
* ./src/krill/prepare.ts
|
|
3
4
|
* penguins-eggs v.10.0.0 / ecmascript 2020
|
|
4
5
|
* author: Piero Proietti
|
|
5
6
|
* email: piero.proietti@gmail.com
|
|
6
7
|
* license: MIT
|
|
7
|
-
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
8
8
|
*/
|
|
9
9
|
import os from 'os';
|
|
10
|
-
import axios from 'axios';
|
|
11
|
-
import shx from 'shelljs';
|
|
12
10
|
import fs from 'fs';
|
|
11
|
+
import shx from 'shelljs';
|
|
12
|
+
import axios from 'axios';
|
|
13
|
+
import { SwapChoice, InstallationMode, FsType } from './krill_enums.js';
|
|
13
14
|
import Keyboards from '../../classes/keyboards.js';
|
|
14
15
|
import Locales from '../../classes/locales.js';
|
|
15
16
|
import Systemctl from '../../classes/systemctl.js';
|
|
16
17
|
import Utils from '../../classes/utils.js';
|
|
17
|
-
// libraries
|
|
18
18
|
import { exec } from '../../lib/utils.js';
|
|
19
|
+
import Sequence from './sequence.js';
|
|
20
|
+
// UI Components
|
|
19
21
|
import { welcome } from './prepare.d/welcome.js';
|
|
20
22
|
import { location } from './prepare.d/location.js';
|
|
21
23
|
import { keyboard } from './prepare.d/keyboard.js';
|
|
@@ -23,13 +25,12 @@ import { partitions } from './prepare.d/partitions.js';
|
|
|
23
25
|
import { users } from './prepare.d/users.js';
|
|
24
26
|
import { network } from './prepare.d/network.js';
|
|
25
27
|
import { summary } from './prepare.d/summary.js';
|
|
26
|
-
import Sequence from './sequence.js';
|
|
27
|
-
import { SwapChoice, InstallationMode } from './krill_enums.js';
|
|
28
28
|
const config_file = '/etc/penguins-eggs.d/krill.yaml';
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* Main Krill installer class - Simplified refactoring
|
|
31
31
|
*/
|
|
32
32
|
export default class Krill {
|
|
33
|
+
// UI Components
|
|
33
34
|
welcome = welcome;
|
|
34
35
|
location = location;
|
|
35
36
|
keyboard = keyboard;
|
|
@@ -37,18 +38,17 @@ export default class Krill {
|
|
|
37
38
|
users = users;
|
|
38
39
|
network = network;
|
|
39
40
|
summary = summary;
|
|
41
|
+
// Configuration
|
|
40
42
|
krillConfig = {};
|
|
41
43
|
locales = new Locales();
|
|
42
44
|
keyboards = new Keyboards();
|
|
45
|
+
// Installation flags
|
|
43
46
|
unattended = false;
|
|
44
47
|
nointeractive = false;
|
|
45
48
|
chroot = false;
|
|
46
49
|
halt = false;
|
|
47
50
|
/**
|
|
48
|
-
*
|
|
49
|
-
* @param unattended
|
|
50
|
-
* @param nointeractive
|
|
51
|
-
* @param halt
|
|
51
|
+
* Constructor
|
|
52
52
|
*/
|
|
53
53
|
constructor(unattended = false, nointeractive = false, halt = false, chroot = false) {
|
|
54
54
|
this.unattended = unattended;
|
|
@@ -57,129 +57,146 @@ export default class Krill {
|
|
|
57
57
|
this.halt = halt;
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @param krillConfig
|
|
62
|
-
* @param ip
|
|
63
|
-
* @param random
|
|
64
|
-
* @param domain
|
|
65
|
-
* @param suspend
|
|
66
|
-
* @param small
|
|
67
|
-
* @param none
|
|
68
|
-
* @param crypted
|
|
69
|
-
* @param pve
|
|
70
|
-
* @param btrfs
|
|
71
|
-
* @param testing
|
|
72
|
-
* @param verbose
|
|
60
|
+
* Main prepare method - Simplified and cleaner
|
|
73
61
|
*/
|
|
74
62
|
async prepare(krillConfig = {}, ip = false, random = false, domain = '', suspend = false, small = false, none = false, crypted = false, pve = false, btrfs = false, testing = false, verbose = false) {
|
|
63
|
+
try {
|
|
64
|
+
// System validation
|
|
65
|
+
await this.checkSystemRequirements();
|
|
66
|
+
// Configuration setup
|
|
67
|
+
this.krillConfig = krillConfig;
|
|
68
|
+
await this.setupConfiguration();
|
|
69
|
+
// Stop services
|
|
70
|
+
await this.stopSystemServices(verbose, testing);
|
|
71
|
+
// Build configurations
|
|
72
|
+
const configs = await this.buildConfigurations(ip, random, suspend, small, none);
|
|
73
|
+
// Interactive or unattended mode
|
|
74
|
+
const finalConfigs = this.unattended
|
|
75
|
+
? this.applyUnattendedOptions(configs, crypted, pve, btrfs)
|
|
76
|
+
: await this.runInteractiveMode(crypted, pve, btrfs);
|
|
77
|
+
// Install
|
|
78
|
+
await this.performInstallation(finalConfigs, domain, testing, verbose);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
await Utils.pressKeyToExit(`${error.message}\nkrill installer refuses to continue`);
|
|
82
|
+
process.exit();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Check system requirements (disks, LVM)
|
|
87
|
+
*/
|
|
88
|
+
async checkSystemRequirements() {
|
|
75
89
|
// Check disk presence
|
|
76
90
|
const drives = shx.exec('lsblk |grep disk|cut -f 1 "-d "', { silent: true }).stdout.trim().split('\n');
|
|
77
91
|
if (drives[0] === '') {
|
|
78
|
-
|
|
79
|
-
process.exit();
|
|
92
|
+
throw new Error('No disk to install the system in this machine.');
|
|
80
93
|
}
|
|
81
|
-
// Check
|
|
94
|
+
// Check LVM presence
|
|
82
95
|
if (await this.pvExist()) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
let cmds = "#!/bin/bash\n";
|
|
86
|
-
cmds += `# remove LV (Logical Volumes)\n`;
|
|
87
|
-
cmds += `vg=$(vgs --noheadings -o vg_name| awk '{$1=$1};1')\n`;
|
|
88
|
-
cmds += `lvs -o lv_name --noheadings | awk '{$1=$1};1' | while read -r lv; do\n`;
|
|
89
|
-
cmds += ` lvremove -y /dev/mapper/$vg-$lv\n`;
|
|
90
|
-
cmds += `done\n`;
|
|
91
|
-
cmds += `\n`;
|
|
92
|
-
cmds += `# remove VG (Volume groups)\n`;
|
|
93
|
-
cmds += `vgremove --force $(vgs --noheadings -o vg_name $vg)\n`;
|
|
94
|
-
cmds += `\n`;
|
|
95
|
-
cmds += `# remove PV (Phisical Volumes) \n`;
|
|
96
|
-
cmds += `pv=$(pvs --noheading -o pv_name | awk '{$1=$1};1')\n`;
|
|
97
|
-
cmds += `pvremove --force --force $pv\n`;
|
|
98
|
-
cmds += `# wipe PV (Phisical Volumes) \n`;
|
|
99
|
-
cmds += `wipefs -a $pv\n`;
|
|
100
|
-
cmds += `# clean device\n`;
|
|
101
|
-
cmds += `sgdisk --zap-all $pv\n`;
|
|
102
|
-
cmds += `dd if=/dev/zero of=$pv bs=1M count=10\n`;
|
|
103
|
-
fs.writeFileSync(scriptName, cmds);
|
|
104
|
-
await exec(`chmod +x ${scriptName}`);
|
|
105
|
-
await Utils.pressKeyToExit(`There is a lvm2 volume in the system, remove it manually before installation.\nkrill installer refuses to continue`);
|
|
106
|
-
process.exit();
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* stop udisks2.service
|
|
110
|
-
*/
|
|
111
|
-
const systemdCtl = new Systemctl(verbose);
|
|
112
|
-
if (await systemdCtl.isActive('udisks2.service') && !testing) {
|
|
113
|
-
await systemdCtl.stop('udisks2.service');
|
|
96
|
+
await this.createLvmRemovalScript();
|
|
97
|
+
throw new Error('There is a lvm2 volume in the system, remove it manually before installation.');
|
|
114
98
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* load default values
|
|
123
|
-
*/
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Setup configuration files and auto-configure timezone
|
|
102
|
+
*/
|
|
103
|
+
async setupConfiguration() {
|
|
104
|
+
// Check config file
|
|
124
105
|
if (!fs.existsSync(config_file)) {
|
|
125
|
-
|
|
126
|
-
process.exit(1);
|
|
106
|
+
throw new Error(`Cannot find configuration file ${config_file}`);
|
|
127
107
|
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* test calamares/krill configuration presence
|
|
131
|
-
*/
|
|
108
|
+
// Check calamares/krill configuration
|
|
132
109
|
let configRoot = '/etc/penguins-eggs.d/krill/';
|
|
133
110
|
if (fs.existsSync('/etc/calamares/settings.conf')) {
|
|
134
111
|
configRoot = '/etc/calamares/';
|
|
135
112
|
}
|
|
136
113
|
if (!fs.existsSync(configRoot + 'settings.conf')) {
|
|
137
|
-
|
|
138
|
-
console.log(`sudo eggs calamares`);
|
|
139
|
-
process.exit(1);
|
|
114
|
+
throw new Error('Cannot find calamares/krill configuration file, please create it running: sudo eggs calamares');
|
|
140
115
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
116
|
+
// Auto-configure timezone
|
|
117
|
+
await this.autoConfigureTimezone();
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Auto-configure timezone from internet
|
|
121
|
+
*/
|
|
122
|
+
async autoConfigureTimezone() {
|
|
144
123
|
try {
|
|
145
|
-
const response = await axios.get(
|
|
124
|
+
const response = await axios.get('https://geoip.kde.org/v1/calamares');
|
|
146
125
|
if (response.statusText === 'OK') {
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
this.krillConfig.
|
|
150
|
-
this.krillConfig.zone = obj.time_zone.substring(obj.time_zone.indexOf('/') + 1);
|
|
126
|
+
const timeZone = response.data.time_zone;
|
|
127
|
+
this.krillConfig.region = timeZone.substring(0, timeZone.indexOf('/'));
|
|
128
|
+
this.krillConfig.zone = timeZone.substring(timeZone.indexOf('/') + 1);
|
|
151
129
|
}
|
|
152
130
|
}
|
|
153
131
|
catch (error) {
|
|
154
|
-
console.error('
|
|
132
|
+
console.error('Error auto-configuring timezone:', error);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Stop system services
|
|
137
|
+
*/
|
|
138
|
+
async stopSystemServices(verbose, testing) {
|
|
139
|
+
const systemdCtl = new Systemctl(verbose);
|
|
140
|
+
if (await systemdCtl.isActive('udisks2.service') && !testing) {
|
|
141
|
+
await systemdCtl.stop('udisks2.service');
|
|
155
142
|
}
|
|
156
|
-
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Build default configurations
|
|
146
|
+
*/
|
|
147
|
+
async buildConfigurations(ip, random, suspend, small, none) {
|
|
148
|
+
// Generate hostname
|
|
149
|
+
const hostname = this.generateHostname(ip, random);
|
|
150
|
+
// Build configuration objects
|
|
151
|
+
const oWelcome = { language: this.krillConfig.language };
|
|
152
|
+
const oLocation = {
|
|
157
153
|
language: this.krillConfig.language,
|
|
158
154
|
region: this.krillConfig.region,
|
|
159
155
|
zone: this.krillConfig.zone
|
|
160
156
|
};
|
|
161
|
-
oKeyboard = {
|
|
157
|
+
const oKeyboard = {
|
|
162
158
|
keyboardModel: this.krillConfig.keyboardModel,
|
|
163
159
|
keyboardLayout: this.krillConfig.keyboardLayout,
|
|
164
160
|
keyboardVariant: this.krillConfig.keyboardVariant,
|
|
165
161
|
keyboardOption: this.krillConfig.keyboardOption
|
|
166
162
|
};
|
|
167
|
-
|
|
163
|
+
let userSwapChoice = this.krillConfig.userSwapChoice;
|
|
164
|
+
if (suspend)
|
|
165
|
+
userSwapChoice = SwapChoice.Suspend;
|
|
166
|
+
else if (small)
|
|
167
|
+
userSwapChoice = SwapChoice.Small;
|
|
168
|
+
else if (none)
|
|
169
|
+
userSwapChoice = SwapChoice.None;
|
|
170
|
+
const oPartitions = {
|
|
168
171
|
installationDevice: this.krillConfig.installationDevice,
|
|
169
172
|
installationMode: this.krillConfig.installationMode,
|
|
170
173
|
filesystemType: this.krillConfig.filesystemType,
|
|
171
|
-
userSwapChoice
|
|
174
|
+
userSwapChoice,
|
|
172
175
|
replacedPartition: this.krillConfig.replacedPartition
|
|
173
176
|
};
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
177
|
+
const oUsers = {
|
|
178
|
+
username: this.krillConfig.name,
|
|
179
|
+
fullname: this.krillConfig.fullname,
|
|
180
|
+
password: this.krillConfig.password,
|
|
181
|
+
rootPassword: this.krillConfig.rootPassword,
|
|
182
|
+
autologin: this.krillConfig.autologin,
|
|
183
|
+
hostname
|
|
184
|
+
};
|
|
185
|
+
const oNetwork = {
|
|
186
|
+
iface: await Utils.iface(),
|
|
187
|
+
addressType: this.krillConfig.addressType,
|
|
188
|
+
address: Utils.address(),
|
|
189
|
+
netmask: Utils.netmask(),
|
|
190
|
+
gateway: Utils.gateway(),
|
|
191
|
+
dns: Utils.getDns(),
|
|
192
|
+
domain: Utils.getDomain()
|
|
193
|
+
};
|
|
194
|
+
return { oWelcome, oLocation, oKeyboard, oPartitions, oUsers, oNetwork };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Generate hostname based on options
|
|
198
|
+
*/
|
|
199
|
+
generateHostname(ip, random) {
|
|
183
200
|
let hostname = this.krillConfig.hostname;
|
|
184
201
|
if (hostname === '') {
|
|
185
202
|
hostname = shx.exec('cat /etc/hostname', { silent: true }).trim();
|
|
@@ -193,89 +210,50 @@ export default class Krill {
|
|
|
193
210
|
const sl = shx.exec(`tr -dc a-z </dev/urandom | head -c 2 ; echo ''`, { silent: true }).trim();
|
|
194
211
|
hostname = `${os.hostname()}-${fl}${n}${sl}`;
|
|
195
212
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
netmask: Utils.netmask(),
|
|
210
|
-
gateway: Utils.gateway(),
|
|
211
|
-
dns: Utils.getDns(),
|
|
212
|
-
domain: Utils.getDomain()
|
|
213
|
-
};
|
|
214
|
-
/**
|
|
215
|
-
* Defaults
|
|
216
|
-
*/
|
|
217
|
-
/**
|
|
218
|
-
* random = false,
|
|
219
|
-
* domain = '',
|
|
220
|
-
* pve = false
|
|
221
|
-
* */
|
|
222
|
-
if (ip) {
|
|
223
|
-
oUsers.hostname = 'ip-' + Utils.address().replaceAll('.', '-');
|
|
224
|
-
}
|
|
225
|
-
// Luks
|
|
226
|
-
if (crypted) {
|
|
227
|
-
oPartitions.installationMode = InstallationMode.Luks;
|
|
228
|
-
}
|
|
229
|
-
// fs
|
|
230
|
-
if (btrfs) {
|
|
231
|
-
oPartitions.filesystemType = 'btrfs';
|
|
232
|
-
}
|
|
233
|
-
// swap
|
|
234
|
-
if (none) {
|
|
235
|
-
oPartitions.userSwapChoice = SwapChoice.None;
|
|
236
|
-
}
|
|
237
|
-
if (small) {
|
|
238
|
-
oPartitions.userSwapChoice = SwapChoice.Small;
|
|
239
|
-
}
|
|
240
|
-
if (suspend) {
|
|
241
|
-
oPartitions.userSwapChoice = SwapChoice.Suspend;
|
|
242
|
-
}
|
|
243
|
-
if (pve) {
|
|
213
|
+
return hostname;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Apply options for unattended installation
|
|
217
|
+
*/
|
|
218
|
+
applyUnattendedOptions(configs, crypted, pve, btrfs) {
|
|
219
|
+
const { oPartitions, oUsers } = configs;
|
|
220
|
+
// Set defaults for unattended
|
|
221
|
+
oPartitions.installationMode = InstallationMode.EraseDisk;
|
|
222
|
+
// Apply options
|
|
223
|
+
if (btrfs)
|
|
224
|
+
oPartitions.filesystemType = FsType.btrfs;
|
|
225
|
+
if (crypted || pve)
|
|
244
226
|
oPartitions.installationMode = InstallationMode.Luks;
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
oPartitions = await this.partitions(this.krillConfig.installationDevice, crypted, pve, btrfs);
|
|
254
|
-
oUsers = await this.users();
|
|
255
|
-
oNetwork = await this.network();
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
/**
|
|
259
|
-
* this variables ALWAYS need to be initializated
|
|
260
|
-
*/
|
|
261
|
-
// oPartitions.installationDevice
|
|
262
|
-
if (oPartitions.installationDevice === '') {
|
|
263
|
-
// No RAID considerated
|
|
264
|
-
const drives = shx.exec('lsblk |grep disk|cut -f 1 "-d "', { silent: true }).stdout.trim().split('\n');
|
|
265
|
-
if (drives.length > 0) {
|
|
266
|
-
oPartitions.installationDevice = `/dev/` + drives[0];
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
console.log("Unable to find installation drive");
|
|
270
|
-
process.exit(1);
|
|
271
|
-
}
|
|
227
|
+
// Set default installation device if empty
|
|
228
|
+
if (oPartitions.installationDevice === '') {
|
|
229
|
+
const drives = shx.exec('lsblk |grep disk|cut -f 1 "-d "', { silent: true }).stdout.trim().split('\n');
|
|
230
|
+
if (drives.length > 0) {
|
|
231
|
+
oPartitions.installationDevice = `/dev/` + drives[0];
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
throw new Error("Unable to find installation drive");
|
|
272
235
|
}
|
|
273
236
|
}
|
|
237
|
+
return configs;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Run interactive mode with UI
|
|
241
|
+
*/
|
|
242
|
+
async runInteractiveMode(crypted, pve, btrfs) {
|
|
243
|
+
const oWelcome = await this.welcome();
|
|
244
|
+
const oLocation = await this.location(oWelcome.language);
|
|
245
|
+
const oKeyboard = await this.keyboard();
|
|
246
|
+
const oPartitions = await this.partitions(this.krillConfig.installationDevice, crypted, pve, btrfs);
|
|
247
|
+
const oUsers = await this.users();
|
|
248
|
+
const oNetwork = await this.network();
|
|
249
|
+
return { oWelcome, oLocation, oKeyboard, oPartitions, oUsers, oNetwork };
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Perform installation or testing
|
|
253
|
+
*/
|
|
254
|
+
async performInstallation(configs, domain, testing, verbose) {
|
|
255
|
+
const { oLocation, oKeyboard, oPartitions, oUsers, oNetwork } = configs;
|
|
274
256
|
await this.summary(oLocation, oKeyboard, oPartitions, oUsers);
|
|
275
|
-
/**
|
|
276
|
-
* INSTALL
|
|
277
|
-
*/
|
|
278
|
-
const sequence = new Sequence(oLocation, oKeyboard, oPartitions, oUsers, oNetwork);
|
|
279
257
|
if (testing) {
|
|
280
258
|
console.log();
|
|
281
259
|
Utils.titles("install --testing");
|
|
@@ -285,30 +263,52 @@ export default class Krill {
|
|
|
285
263
|
process.exit();
|
|
286
264
|
}
|
|
287
265
|
else {
|
|
266
|
+
const sequence = new Sequence(oLocation, oKeyboard, oPartitions, oUsers, oNetwork);
|
|
288
267
|
await sequence.start(domain, this.unattended, this.nointeractive, this.chroot, this.halt, verbose);
|
|
289
268
|
}
|
|
290
269
|
}
|
|
291
270
|
/**
|
|
292
|
-
*
|
|
271
|
+
* Create script to remove LVM partitions
|
|
272
|
+
*/
|
|
273
|
+
async createLvmRemovalScript() {
|
|
274
|
+
const scriptName = "removeLvmPartitions";
|
|
275
|
+
let cmds = "#!/bin/bash\n";
|
|
276
|
+
cmds += `# remove LV (Logical Volumes)\n`;
|
|
277
|
+
cmds += `vg=$(vgs --noheadings -o vg_name| awk '{$1=$1};1')\n`;
|
|
278
|
+
cmds += `lvs -o lv_name --noheadings | awk '{$1=$1};1' | while read -r lv; do\n`;
|
|
279
|
+
cmds += ` lvremove -y /dev/mapper/$vg-$lv\n`;
|
|
280
|
+
cmds += `done\n`;
|
|
281
|
+
cmds += `\n`;
|
|
282
|
+
cmds += `# remove VG (Volume groups)\n`;
|
|
283
|
+
cmds += `vgremove --force $(vgs --noheadings -o vg_name $vg)\n`;
|
|
284
|
+
cmds += `\n`;
|
|
285
|
+
cmds += `# remove PV (Physical Volumes) \n`;
|
|
286
|
+
cmds += `pv=$(pvs --noheading -o pv_name | awk '{$1=$1};1')\n`;
|
|
287
|
+
cmds += `pvremove --force --force $pv\n`;
|
|
288
|
+
cmds += `# wipe PV (Physical Volumes) \n`;
|
|
289
|
+
cmds += `wipefs -a $pv\n`;
|
|
290
|
+
cmds += `# clean device\n`;
|
|
291
|
+
cmds += `sgdisk --zap-all $pv\n`;
|
|
292
|
+
cmds += `dd if=/dev/zero of=$pv bs=1M count=10\n`;
|
|
293
|
+
fs.writeFileSync(scriptName, cmds);
|
|
294
|
+
await exec(`chmod +x ${scriptName}`);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Check if Physical Volumes exist
|
|
293
298
|
*/
|
|
294
299
|
async pvExist() {
|
|
295
|
-
let exist = false;
|
|
296
300
|
const check = `#!/bin/sh\npvdisplay |grep "PV Name" >/dev/null && echo 1|| echo 0`;
|
|
297
|
-
|
|
298
|
-
exist = true;
|
|
299
|
-
}
|
|
300
|
-
return exist;
|
|
301
|
+
return shx.exec(check, { silent: true }).stdout.trim() === '1';
|
|
301
302
|
}
|
|
302
303
|
}
|
|
303
304
|
/**
|
|
304
|
-
*
|
|
305
|
-
* @param mask
|
|
305
|
+
* Utility function for netmask conversion
|
|
306
306
|
*/
|
|
307
307
|
function netmask2CIDR(mask) {
|
|
308
308
|
const countCharOccurences = (string, char) => string.split(char).length - 1;
|
|
309
309
|
const decimalToBinary = (dec) => (dec >>> 0).toString(2);
|
|
310
310
|
const getNetMaskParts = (nmask) => nmask.split('.').map(Number);
|
|
311
|
-
|
|
311
|
+
return countCharOccurences(getNetMaskParts(mask)
|
|
312
312
|
.map(part => decimalToBinary(part))
|
|
313
313
|
.join(''), '1');
|
|
314
314
|
}
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* license: MIT
|
|
7
7
|
* https://stackoverflow.com/questions/23876782/how-do-i-split-a-typescript-class-into-multiple-files
|
|
8
8
|
*/
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import yaml from 'js-yaml';
|
|
9
11
|
import { exec } from '../../../lib/utils.js';
|
|
10
12
|
/**
|
|
11
13
|
*
|
|
@@ -35,10 +37,26 @@ export default async function addUser(name = 'live', password = 'evolution', ful
|
|
|
35
37
|
await exec(cmd, this.echo);
|
|
36
38
|
let group = 'wheel';
|
|
37
39
|
if (this.distro.familyId === 'debian') {
|
|
38
|
-
|
|
40
|
+
/**
|
|
41
|
+
* look to calamares/modules/users.yml for groups
|
|
42
|
+
*/
|
|
43
|
+
let usersConf = '/etc/calamares/modules/users.conf';
|
|
44
|
+
if (!fs.existsSync(usersConf)) {
|
|
45
|
+
usersConf = '/etc/penguins-eggs.d/krill/modules/users.conf';
|
|
46
|
+
}
|
|
47
|
+
if (fs.existsSync(usersConf)) {
|
|
48
|
+
const o = yaml.load(fs.readFileSync(usersConf, 'utf8'));
|
|
49
|
+
for (const group of o.defaultGroups) {
|
|
50
|
+
cmd = `chroot ${this.installTarget} usermod -aG ${group} ${name} ${this.toNull}`;
|
|
51
|
+
await exec(cmd, this.echo);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
group = 'sudo';
|
|
56
|
+
}
|
|
57
|
+
cmd = `chroot ${this.installTarget} usermod -aG ${group} ${name} ${this.toNull}`;
|
|
58
|
+
await exec(cmd, this.echo);
|
|
39
59
|
}
|
|
40
|
-
cmd = `chroot ${this.installTarget} usermod -aG ${group} ${name} ${this.toNull}`;
|
|
41
|
-
await exec(cmd, this.echo);
|
|
42
60
|
// add autologin group in archlinux
|
|
43
61
|
await exec(cmd, this.echo);
|
|
44
62
|
if (this.distro.familyId === 'archlinux') {
|
|
@@ -54,13 +54,13 @@ export default async function partition() {
|
|
|
54
54
|
if (installationMode === InstallationMode.Replace) {
|
|
55
55
|
retVal = true;
|
|
56
56
|
}
|
|
57
|
-
else if (installationMode === InstallationMode.
|
|
57
|
+
else if (installationMode === InstallationMode.EraseDisk && !this.efi) {
|
|
58
58
|
retVal = await this.partitionBiosStandard(installDevice, p);
|
|
59
59
|
}
|
|
60
60
|
else if (installationMode === InstallationMode.Luks && !this.efi) {
|
|
61
61
|
retVal = await this.partitionBiosLuks(installDevice, p);
|
|
62
62
|
}
|
|
63
|
-
else if (installationMode === InstallationMode.
|
|
63
|
+
else if (installationMode === InstallationMode.EraseDisk && this.efi) {
|
|
64
64
|
retVal = await this.partitionUefiStandard(installDevice, p);
|
|
65
65
|
}
|
|
66
66
|
else if (installationMode === InstallationMode.Luks && this.efi) {
|