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.
Files changed (138) hide show
  1. package/.oclif.manifest.json +62 -1
  2. package/README.md +145 -75
  3. package/addons/eggs/theme/calamares/modules/{_users.yml → users.yml} +3 -3
  4. package/addons/eggs/theme/livecd/grub.main.full.cfg +1 -1
  5. package/addons/eggs/theme/livecd/grub.main.simple.cfg +1 -1
  6. package/conf/derivatives.yaml +4 -3
  7. package/conf/derivatives_fedora.yaml +6 -0
  8. package/conf/distros/alpine/calamares/modules/users.yml +3 -3
  9. package/conf/distros/bionic/calamares/calamares-modules/grubcfg/grubcfg.yml +1 -1
  10. package/conf/distros/bionic/calamares/modules/users.yml +3 -3
  11. package/conf/distros/buster/calamares/modules/users.yml +4 -3
  12. package/conf/distros/fedora/calamares/modules/users.yml +3 -3
  13. package/conf/distros/noble/calamares/modules/focal-jammy/users.yml +3 -3
  14. package/conf/distros/noble/calamares/modules/users.yml +1 -0
  15. package/conf/distros/opensuse/calamares/modules/users.yml +3 -3
  16. package/conf/distros/rolling/calamares/modules/users.yml +3 -3
  17. package/conf/eggs.yaml +1 -1
  18. package/conf/love.yaml +4 -4
  19. package/dist/classes/compressors.js +1 -1
  20. package/dist/classes/distro.d.ts +27 -3
  21. package/dist/classes/distro.js +361 -289
  22. package/dist/classes/ovary.d/bind-live-fs.js +22 -30
  23. package/dist/classes/ovary.d/edit-live-fs.d.ts +1 -0
  24. package/dist/classes/ovary.d/edit-live-fs.js +9 -13
  25. package/dist/classes/ovary.d/fertilization.js +6 -1
  26. package/dist/classes/ovary.d/initrd.js +11 -15
  27. package/dist/classes/ovary.d/kernel-copy.js +2 -16
  28. package/dist/classes/ovary.d/make-efi.js +8 -5
  29. package/dist/classes/ovary.d/make-squashfs.d.ts +1 -1
  30. package/dist/classes/ovary.d/make-squashfs.js +17 -24
  31. package/dist/classes/ovary.d/merged.d.ts +9 -13
  32. package/dist/classes/ovary.d/merged.js +38 -48
  33. package/dist/classes/ovary.d/produce.d.ts +1 -1
  34. package/dist/classes/ovary.d/produce.js +38 -32
  35. package/dist/classes/ovary.d/syslinux.js +4 -4
  36. package/dist/classes/ovary.d/user-create-live.js +12 -5
  37. package/dist/classes/ovary.d.ts +8 -3
  38. package/dist/classes/ovary.js +8 -3
  39. package/dist/classes/pacman.d/archlinux.js +1 -5
  40. package/dist/classes/pacman.js +2 -1
  41. package/dist/classes/systemctl.d.ts +1 -1
  42. package/dist/classes/systemctl.js +1 -1
  43. package/dist/classes/tailor.js +2 -1
  44. package/dist/classes/utils.d/architecture.d.ts +41 -0
  45. package/dist/classes/utils.d/architecture.js +87 -0
  46. package/dist/classes/utils.d/console-output.d.ts +26 -0
  47. package/dist/classes/utils.d/console-output.js +46 -0
  48. package/dist/classes/utils.d/filesystem.d.ts +53 -0
  49. package/dist/classes/utils.d/filesystem.js +152 -0
  50. package/dist/classes/utils.d/formatters.d.ts +32 -0
  51. package/dist/classes/utils.d/formatters.js +64 -0
  52. package/dist/classes/utils.d/kernel.d.ts +83 -0
  53. package/dist/classes/utils.d/kernel.js +288 -0
  54. package/dist/classes/utils.d/network.d.ts +43 -0
  55. package/dist/classes/utils.d/network.js +133 -0
  56. package/dist/classes/utils.d/package-info.d.ts +55 -0
  57. package/dist/classes/utils.d/package-info.js +137 -0
  58. package/dist/classes/utils.d/snapshot.d.ts +44 -0
  59. package/dist/classes/utils.d/snapshot.js +102 -0
  60. package/dist/classes/utils.d/system.d.ts +63 -0
  61. package/dist/classes/utils.d/system.js +200 -0
  62. package/dist/classes/utils.d/user-interaction.d.ts +39 -0
  63. package/dist/classes/utils.d/user-interaction.js +104 -0
  64. package/dist/classes/utils.d.ts +90 -322
  65. package/dist/classes/utils.js +105 -1013
  66. package/dist/commands/dad.d.ts +1 -0
  67. package/dist/commands/dad.js +1 -0
  68. package/dist/commands/export/pkg.js +6 -6
  69. package/dist/commands/export/tarballs.js +11 -16
  70. package/dist/commands/kill.js +1 -1
  71. package/dist/commands/love.d.ts +1 -0
  72. package/dist/commands/love.js +21 -7
  73. package/dist/commands/pods.d.ts +22 -0
  74. package/dist/commands/pods.js +92 -0
  75. package/dist/commands/produce.d.ts +1 -0
  76. package/dist/commands/produce.js +21 -1
  77. package/dist/commands/update.js +2 -2
  78. package/dist/index.d.ts +6 -52
  79. package/dist/index.js +6 -145
  80. package/dist/krill/classes/krill_enums.d.ts +14 -1
  81. package/dist/krill/classes/krill_enums.js +16 -1
  82. package/dist/krill/classes/prepare.d/partitions.js +3 -3
  83. package/dist/krill/classes/prepare.d.ts +46 -21
  84. package/dist/krill/classes/prepare.js +187 -187
  85. package/dist/krill/classes/sequence.d/add_user.js +21 -3
  86. package/dist/krill/classes/sequence.d/partition.js +2 -2
  87. package/dist/krill/classes/sequence.d.ts +18 -21
  88. package/dist/krill/classes/sequence.js +156 -423
  89. package/dist/krill/components/information.js +13 -7
  90. package/dist/{krill/lib → lib}/kill_me_softly.js +2 -2
  91. package/dist/penguins-eggs_10.1.1-0_amd64.deb +0 -0
  92. package/dist/penguins-eggs_10.1.1-0_amd64.deb.sha256 +1 -0
  93. package/package.json +32 -27
  94. package/perrisbrewery/scripts/postinst +98 -0
  95. package/perrisbrewery/scripts/postrm +82 -0
  96. package/perrisbrewery/scripts/preinst +40 -0
  97. package/perrisbrewery/scripts/prerm +47 -0
  98. package/perrisbrewery/template/control.template +17 -0
  99. package/perrisbrewery/template/dependencies-bionic.yaml +33 -0
  100. package/perrisbrewery/template/dependencies.yaml +37 -0
  101. package/perrisbrewery/template/man.template.md +110 -0
  102. package/pods/README.md +14 -0
  103. package/pods/almalinux.sh +10 -0
  104. package/pods/archlinux.sh +10 -0
  105. package/pods/ci/README.md +5 -0
  106. package/pods/ci/kernel-overlay-install.sh +114 -0
  107. package/pods/ci/minimal/almalinux-container2host.sh +165 -0
  108. package/pods/ci/minimal/archlinux-container2host.sh +125 -0
  109. package/pods/ci/minimal/debian-container2host.sh +173 -0
  110. package/pods/ci/minimal/fedora-container2host.sh +170 -0
  111. package/pods/ci/minimal/manjaro-container2host.sh +123 -0
  112. package/pods/ci/minimal/opensuse-container2host.sh +143 -0
  113. package/pods/ci/penguins-eggs-execute.sh +22 -0
  114. package/pods/ci/penguins-eggs-install.sh +115 -0
  115. package/pods/ci/run +34 -0
  116. package/pods/ci/run-on-almalinux.sh +50 -0
  117. package/pods/ci/run-on-archlinux.sh +64 -0
  118. package/pods/ci/run-on-debian.sh +51 -0
  119. package/pods/ci/run-on-devuan.sh +48 -0
  120. package/pods/ci/run-on-fedora.sh +51 -0
  121. package/pods/ci/run-on-manjaro.sh +61 -0
  122. package/pods/ci/run-on-opensuse.sh +58 -0
  123. package/pods/ci/run-on-rockylinux.sh +51 -0
  124. package/pods/ci/run-on-ubuntu.sh +52 -0
  125. package/pods/debian.sh +23 -0
  126. package/pods/devuan.sh +26 -0
  127. package/pods/fedora.sh +12 -0
  128. package/pods/lmde.sh +22 -0
  129. package/pods/manjaro.sh +10 -0
  130. package/pods/opensuse.sh +12 -0
  131. package/pods/podman.command.sh +85 -0
  132. package/pods/rocky.sh +12 -0
  133. package/pods/run-build-packages-debs.sh +45 -0
  134. package/pods/run-create-debs.sh +23 -0
  135. package/pods/ubuntu.sh +24 -0
  136. package/scripts/_eggs +14 -5
  137. package/scripts/eggs.bash +5 -4
  138. /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.Standard;
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.Standard;
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.Standard) {
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
- * ./src/krill/prepare.tsx
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
- * constructor
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
- * return true if pv exist
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
- * ./src/krill/prepare.tsx
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
- * constructor
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
- await Utils.pressKeyToExit(`No disk to install the system in this machine.\nkrill installer refuses to continue`);
79
- process.exit();
92
+ throw new Error('No disk to install the system in this machine.');
80
93
  }
81
- // Check Lvm2 presence
94
+ // Check LVM presence
82
95
  if (await this.pvExist()) {
83
- // Create removeLvmPartitions
84
- let scriptName = "removeLvmPartitions";
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
- let oWelcome = {};
116
- let oLocation = {};
117
- let oKeyboard = {};
118
- let oPartitions = {};
119
- let oUsers = {};
120
- let oNetwork = {};
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
- console.log(`cannot find configuration file ${config_file},`);
126
- process.exit(1);
106
+ throw new Error(`Cannot find configuration file ${config_file}`);
127
107
  }
128
- this.krillConfig = krillConfig;
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
- console.log(`Cannot find calamares/krill configuration file, please create it running:`);
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
- oWelcome = { language: this.krillConfig.language };
142
- // Try to auto-configure timezone by internet
143
- const url = `https://geoip.kde.org/v1/calamares`;
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(url);
124
+ const response = await axios.get('https://geoip.kde.org/v1/calamares');
146
125
  if (response.statusText === 'OK') {
147
- const data = JSON.stringify(response.data);
148
- const obj = JSON.parse(data);
149
- this.krillConfig.region = obj.time_zone.substring(0, obj.time_zone.indexOf('/'));
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('error: ' + 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
- oLocation = {
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
- oPartitions = {
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: this.krillConfig.userSwapChoice,
174
+ userSwapChoice,
172
175
  replacedPartition: this.krillConfig.replacedPartition
173
176
  };
174
- if (suspend) {
175
- oPartitions.userSwapChoice = SwapChoice.Suspend;
176
- }
177
- else if (small) {
178
- oPartitions.userSwapChoice = SwapChoice.Small;
179
- }
180
- else if (none) {
181
- oPartitions.userSwapChoice = SwapChoice.None;
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
- oUsers = {
197
- username: this.krillConfig.name,
198
- fullname: this.krillConfig.fullname,
199
- password: this.krillConfig.password,
200
- rootPassword: this.krillConfig.rootPassword,
201
- autologin: this.krillConfig.autologin,
202
- hostname: hostname
203
- };
204
- oNetwork =
205
- {
206
- iface: await Utils.iface(),
207
- addressType: this.krillConfig.addressType,
208
- address: Utils.address(),
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
- * interactive
248
- */
249
- if (!this.unattended) {
250
- oWelcome = await this.welcome();
251
- oLocation = await this.location(oWelcome.language);
252
- oKeyboard = await this.keyboard();
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
- * return true if pv exist
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
- if (shx.exec(check, { silent: true }).stdout.trim() === '1') {
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
- const netmask2CIDR = (netmask) => countCharOccurences(getNetMaskParts(netmask)
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
- group = 'sudo';
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.Standard && !this.efi) {
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.Standard && this.efi) {
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) {