penguins-eggs 10.0.21 → 10.0.22

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 (45) hide show
  1. package/.oclif.manifest.json +1 -1
  2. package/README.md +33 -29
  3. package/conf/derivatives.yaml +1 -0
  4. package/conf/distros/alpine/README.md +3 -0
  5. package/conf/distros/noble/calamares/modules/automirror.yml +6 -0
  6. package/conf/distros/noble/calamares/modules/before_bootloader_context.yml +18 -0
  7. package/conf/distros/noble/calamares/modules/before_bootloader_mkdirs_context.yml +10 -0
  8. package/conf/distros/noble/calamares/modules/bootloader.yml +33 -0
  9. package/conf/distros/noble/calamares/modules/displaymanager.yml +9 -0
  10. package/conf/distros/noble/calamares/modules/finished.yml +3 -0
  11. package/conf/distros/noble/calamares/modules/fstab.yml +2 -0
  12. package/conf/distros/noble/calamares/modules/grubcfg.yml +3 -0
  13. package/conf/distros/noble/calamares/modules/locale.yml +8 -0
  14. package/conf/distros/noble/calamares/modules/machineid.yml +8 -0
  15. package/conf/distros/noble/calamares/modules/mount.yml +38 -0
  16. package/conf/distros/noble/calamares/modules/oemid.yml +2 -0
  17. package/conf/distros/noble/calamares/modules/packages.yml +17 -0
  18. package/conf/distros/noble/calamares/modules/partition.yml +21 -0
  19. package/conf/distros/noble/calamares/modules/pkgselect_context.yml +19 -0
  20. package/conf/distros/noble/calamares/modules/pkgselect_snap_context.yml +9 -0
  21. package/conf/distros/noble/calamares/modules/shellprocess_add386arch.yml +5 -0
  22. package/conf/distros/noble/calamares/modules/shellprocess_bug-LP#1829805.yml +5 -0
  23. package/conf/distros/noble/calamares/modules/shellprocess_fixconkeys_part1.yml +5 -0
  24. package/conf/distros/noble/calamares/modules/shellprocess_fixconkeys_part2.yml +5 -0
  25. package/conf/distros/noble/calamares/modules/shellprocess_logs.yml +5 -0
  26. package/conf/distros/noble/calamares/modules/shellprocess_oemprep.yml +5 -0
  27. package/conf/distros/noble/calamares/modules/umount.yml +4 -0
  28. package/conf/distros/noble/calamares/modules/unpackfs.yml +5 -0
  29. package/conf/distros/noble/calamares/modules/users.conf.oem +30 -0
  30. package/conf/distros/noble/calamares/modules/users.yml +23 -0
  31. package/conf/distros/noble/calamares/modules/welcome.yml +28 -0
  32. package/conf/distros/noble/calamares/settings.yml +87 -0
  33. package/dist/classes/distro.js +4 -3
  34. package/dist/classes/incubation/incubator.js +9 -0
  35. package/dist/classes/ovary.js +19 -18
  36. package/dist/classes/pacman.js +11 -9
  37. package/dist/classes/utils.d.ts +1 -0
  38. package/dist/classes/utils.js +44 -7
  39. package/dist/classes/xdg.js +0 -3
  40. package/dist/components/information.js +5 -2
  41. package/dist/krill/modules/machine-id.js +9 -1
  42. package/dist/krill/sequence.js +21 -17
  43. package/manpages/doc/man/eggs.1.gz +0 -0
  44. package/manpages/doc/man/eggs.html +587 -3
  45. package/package.json +7 -7
@@ -0,0 +1,87 @@
1
+ # Ubuntu 24.04 noble
2
+ ---
3
+ modules-search: [ local ]
4
+
5
+ instances:
6
+ - id: before_bootloader_mkdirs
7
+ module: contextualprocess
8
+ config: before_bootloader_mkdirs_context.conf
9
+ - id: before_bootloader
10
+ module: contextualprocess
11
+ config: before_bootloader_context.conf
12
+ #- id: logs
13
+ # module: shellprocess
14
+ # config: shellprocess_logs.conf
15
+ - id: bug-LP#1829805
16
+ module: shellprocess
17
+ config: shellprocess_bug-LP#1829805.conf
18
+ - id: add386arch
19
+ module: shellprocess
20
+ config: shellprocess_add386arch.conf
21
+ #- id: pkgselect_action
22
+ # module: contextualprocess
23
+ # config: pkgselect_context.conf
24
+ #- id: pkgselect_snap_action
25
+ # module: contextualprocess
26
+ # config: pkgselect_snap_context.conf
27
+ - id: oemprep
28
+ module: shellprocess
29
+ config: shellprocess_oemprep.conf
30
+ - id: fixconkeys_part1
31
+ module: shellprocess
32
+ config: shellprocess_fixconkeys_part1.conf
33
+ - id: fixconkeys_part2
34
+ module: shellprocess
35
+ config: shellprocess_fixconkeys_part2.conf
36
+
37
+ sequence:
38
+ - show:
39
+ - welcome
40
+ - locale
41
+ - keyboard
42
+ # pkgselect
43
+ - partition
44
+ {{createUsers}}users
45
+ - summary
46
+ - exec:
47
+ - partition
48
+ - mount
49
+ - unpackfs
50
+ {{hasSystemd}}machineid
51
+ - fstab
52
+ - locale
53
+ - keyboard
54
+ - localecfg
55
+ - luksbootkeyfile
56
+ {{createUsers}}users
57
+ {{hasDisplaymanager}}displaymanager
58
+ - networkcfg
59
+ - hwclock
60
+ - contextualprocess@before_bootloader_mkdirs
61
+ - shellprocess@bug-LP#1829805
62
+ - initramfscfg
63
+ - initramfs
64
+ - grubcfg
65
+ - contextualprocess@before_bootloader
66
+ - bootloader
67
+ # automirror
68
+ - shellprocess@add386arch
69
+ - shellprocess@fixconkeys_part1
70
+ - shellprocess@fixconkeys_part2
71
+ - packages
72
+ - removeuser
73
+ # contextualprocess@pkgselect_action
74
+ # contextualprocess@pkgselect_snap_action
75
+ # shellprocess@logs
76
+ - cleanup
77
+ - sources-yolk-undo
78
+ - umount
79
+ - show:
80
+ - finished
81
+
82
+ branding: {{branding}}
83
+ prompt-install: true
84
+ dont-chroot: false
85
+ oem-setup: false
86
+ disable-cancel: false
87
+ disable-cancel-during-exec: false
@@ -108,8 +108,9 @@ class Distro {
108
108
  this.familyId = 'alpine';
109
109
  this.distroLike = 'Alpine';
110
110
  this.codenameId = 'rolling'; // questo viene rimosso dal nome
111
- this.codenameLikeId = 'alpine-rolling';
112
- this.liveMediumPath = '/.modloop/'; // ? è il mount della root su cd di installatione
111
+ this.codenameLikeId = 'alpine'; // prende alpine come codebaneLikeId
112
+ this.liveMediumPath = '/mnt/'; // Qua è deciso da noi
113
+ //this.liveMediumPath = '/run/live/medium/'
113
114
  this.squashfs = `live/filesystem.squashfs`;
114
115
  this.syslinuxPath = '/usr/share/syslinux/'; //correct
115
116
  this.pxelinuxPath = this.syslinuxPath;
@@ -117,7 +118,7 @@ class Distro {
117
118
  this.memdiskPath = this.syslinuxPath;
118
119
  this.isolinuxPath = this.syslinuxPath;
119
120
  // At the moment
120
- this.isCalamaresAvailable = false;
121
+ this.isCalamaresAvailable = true;
121
122
  }
122
123
  else if (this.distroId === 'Fedora') {
123
124
  this.familyId = 'fedora';
@@ -146,6 +146,15 @@ export default class Incubator {
146
146
  await rolling.create();
147
147
  break;
148
148
  }
149
+ /**
150
+ * Alpine
151
+ */
152
+ case 'alpine': {
153
+ // actually take Buster
154
+ const alpine = new Buster(this.installer, this.remix, this.distro, this.user_opt, release, this.theme, this.isClone, this.verbose);
155
+ await alpine.create();
156
+ break;
157
+ }
149
158
  }
150
159
  if (Pacman.calamaresExists()) {
151
160
  partitionCustomize();
@@ -198,14 +198,8 @@ export default class Ovary {
198
198
  ignore: false
199
199
  });
200
200
  const users = result.data.split('\n');
201
- let cmdUserDel = `userdel`;
202
- if (this.familyId === 'alpine') {
203
- // On Alpine we have just deluser
204
- cmdUserDel = "deluser";
205
- }
206
201
  for (let i = 0; i < users.length - 1; i++) {
207
- // cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} deluser ${users[i]}`, verbose))
208
- cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} ${cmdUserDel} ${users[i]}`, this.verbose));
202
+ cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} deluser ${users[i]}`, this.verbose));
209
203
  }
210
204
  }
211
205
  /**
@@ -220,14 +214,8 @@ export default class Ovary {
220
214
  const cmds = [];
221
215
  cmds.push(await rexec('chroot ' + this.settings.work_dir.merged + ' rm /home/' + this.settings.config.user_opt + ' -rf', this.verbose));
222
216
  cmds.push(await rexec('chroot ' + this.settings.work_dir.merged + ' mkdir /home/' + this.settings.config.user_opt, this.verbose));
223
- if (this.familyId === 'alpine') {
224
- // Create user using adduser
225
- cmds.push(await rexec('chroot ' + this.settings.work_dir.merged + ' adduser -D -h /home/' + this.settings.config.user_opt + ' -s /bin/bash ' + this.settings.config.user_opt, this.verbose));
226
- }
227
- else {
228
- // Create user using useradd
229
- cmds.push(await rexec('chroot ' + this.settings.work_dir.merged + ' useradd ' + this.settings.config.user_opt + ' --home-dir /home/' + this.settings.config.user_opt + ' --shell /bin/bash ', this.verbose));
230
- }
217
+ // Create user using useradd
218
+ cmds.push(await rexec('chroot ' + this.settings.work_dir.merged + ' useradd ' + this.settings.config.user_opt + ' --home-dir /home/' + this.settings.config.user_opt + ' --shell /bin/bash ', this.verbose));
231
219
  // live password
232
220
  cmds.push(await rexec('chroot ' + this.settings.work_dir.merged + ' echo ' + this.settings.config.user_opt + ':' + this.settings.config.user_opt_passwd + ' | chroot ' + this.settings.work_dir.merged + ' chpasswd', this.verbose));
233
221
  // root password
@@ -238,6 +226,14 @@ export default class Ovary {
238
226
  if (this.familyId === 'debian') {
239
227
  cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG sudo ${this.settings.config.user_opt}`, this.verbose));
240
228
  }
229
+ else if (this.familyId === 'alpine') {
230
+ cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG cdrom ${this.settings.config.user_opt}`, this.verbose));
231
+ cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG games ${this.settings.config.user_opt}`, this.verbose));
232
+ cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG input ${this.settings.config.user_opt}`, this.verbose));
233
+ cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG users ${this.settings.config.user_opt}`, this.verbose));
234
+ cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG video ${this.settings.config.user_opt}`, this.verbose));
235
+ cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} usermod -aG wheel ${this.settings.config.user_opt}`, this.verbose));
236
+ }
241
237
  else if (this.familyId === 'archlinux') {
242
238
  cmds.push(await rexec(`chroot ${this.settings.work_dir.merged} gpasswd -a ${this.settings.config.user_opt} wheel`, this.verbose));
243
239
  // check or create group: autologin
@@ -715,15 +711,20 @@ export default class Ovary {
715
711
  // mkinitfs
716
712
  const pathConf = path.resolve(__dirname, `../../mkinitfs/live.conf`);
717
713
  await exec(`mkinitfs -c ${pathConf} -o ${this.settings.iso_work}live/${initrdImg}`, Utils.setEcho(true));
718
- const sidecar = path.resolve(__dirname, `../../mkinitfs/sidecar.sh`);
719
- await exec(`cp ${sidecar} ${this.settings.iso_work}live/`);
714
+ const sidecars = path.resolve(__dirname, `../../mkinitfs/*.sh`);
715
+ await exec(`cp ${sidecars} ${this.settings.iso_work}live/`);
720
716
  }
721
717
  /**
722
718
  * initrdFedora()
723
719
  */
724
720
  async initrdFedora() {
725
721
  Utils.warning(`creating ${path.basename(this.settings.initrdImg)} Fedora on ISO/live`);
726
- await exec(`cp /boot/initramfs-*.img ${this.settings.iso_work}/live/`, this.echo);
722
+ // dracut
723
+ const kernelVersion = shx.exec('uname -r', { silent: true }).stdout.trim();
724
+ const initrdImg = `initramfs-${kernelVersion}`;
725
+ const pathConf = path.resolve(__dirname, `../../dracut/dracut.conf.d`);
726
+ await exec(`dracut --confdir ${pathConf} ${this.settings.iso_work}live/${initrdImg}`, Utils.setEcho(true));
727
+ //await exec(`cp /boot/initramfs-*.img ${this.settings.iso_work}/live/`, this.echo)
727
728
  }
728
729
  /**
729
730
  * initrdSuse()
@@ -406,8 +406,8 @@ export default class Pacman {
406
406
  }
407
407
  else if (this.distro().codenameLikeId === 'noble') {
408
408
  const dest = '/etc/penguins-eggs.d/distros/noble';
409
- const focal = `${rootPen}/conf/distros/focal/*`;
410
- await exec(`cp -r ${focal} ${dest}`, echo);
409
+ const noble = `${rootPen}/conf/distros/noble/*`;
410
+ await exec(`cp -r ${noble} ${dest}`, echo);
411
411
  await exec(`cp -r ${buster}/calamares/calamares-modules/cleanup ${dest}/calamares/calamares-modules/cleanup`, echo);
412
412
  await exec(`cp -r ${buster}/calamares/calamares-modules/sources-yolk ${dest}/calamares/calamares-modules/sources-yolk`, echo);
413
413
  await exec(`cp -r ${buster}/calamares/calamares-modules/sources-yolk-undo ${dest}/calamares/calamares-modules/sources-yolk-undo`, echo);
@@ -457,10 +457,10 @@ export default class Pacman {
457
457
  * Alpine
458
458
  **********************************************************************************/
459
459
  }
460
- else if (this.distro().codenameLikeId === 'alpine-rolling') {
461
- const dest = '/etc/penguins-eggs.d/distros/alpine-rolling/';
462
- const alpine = `${rootPen}/conf/distros/alpine-rolling/*`;
463
- await exec(`cp -r ${alpine} ${dest}`, echo);
460
+ else if (this.distro().codenameLikeId === 'alpine') {
461
+ // Prende tutto da buster
462
+ const dest = '/etc/penguins-eggs.d/distros/alpine/';
463
+ await exec(`cp -r ${buster}/calamares ${dest}/calamares`, echo);
464
464
  }
465
465
  }
466
466
  /**
@@ -528,8 +528,10 @@ export default class Pacman {
528
528
  installed = true;
529
529
  }
530
530
  }
531
- else if (this.distro().familyId === 'alpine' && Alpine.packageIsInstalled('xorg-x11-server')) {
532
- installed = true;
531
+ else if (this.distro().familyId === 'alpine') {
532
+ if (Alpine.packageIsInstalled('xorg-server')) {
533
+ installed = true;
534
+ }
533
535
  }
534
536
  return installed;
535
537
  }
@@ -688,7 +690,7 @@ export default class Pacman {
688
690
  }
689
691
  }
690
692
  else if (this.distro().familyId === 'alpine') {
691
- grubInstalled = 'grub2';
693
+ grubInstalled = 'grub';
692
694
  }
693
695
  return grubInstalled;
694
696
  }
@@ -44,6 +44,7 @@ export default class Utils {
44
44
  * @returns
45
45
  */
46
46
  static isSysvinit(): boolean;
47
+ static isOpenRc(): boolean;
47
48
  /**
48
49
  * ricava path per vmlinuz
49
50
  * Normalmente cerca BOOT_IMAGE
@@ -14,8 +14,6 @@ import inquirer from 'inquirer';
14
14
  import chalk from 'chalk';
15
15
  import { spawnSync } from 'child_process';
16
16
  import { Netmask } from 'netmask';
17
- // libraries
18
- import { exec } from '../lib/utils.js';
19
17
  import Distro from './distro.js';
20
18
  // pjson
21
19
  import { createRequire } from 'module';
@@ -99,6 +97,14 @@ export default class Utils {
99
97
  shx.exec(`rm ${checkFile}`);
100
98
  return isSysvinit;
101
99
  }
100
+ static isOpenRc() {
101
+ let isOpenRc = false;
102
+ let distro = new Distro();
103
+ if (distro.familyId === "alpine") {
104
+ isOpenRc = true;
105
+ }
106
+ return isOpenRc;
107
+ }
102
108
  /**
103
109
  * ricava path per vmlinuz
104
110
  * Normalmente cerca BOOT_IMAGE
@@ -229,13 +235,43 @@ export default class Utils {
229
235
  * Return the primary user's name
230
236
  */
231
237
  static async getPrimaryUser() {
232
- let primaryUser = (await exec('/usr/bin/logname 2>/dev/null || echo ${SUDO_USER:-${USER}}', { echo: false, ignore: false, capture: true })).data.trim();
233
- // if logname don't work seem we get '' so:
238
+ const { execSync } = require('child_process');
239
+ let primaryUser = '';
240
+ try {
241
+ // Attempt to get the user from logname
242
+ primaryUser = execSync('/usr/bin/logname 2>/dev/null', { encoding: 'utf-8' }).trim();
243
+ }
244
+ catch (error) {
245
+ // logname failed, so we continue with other methods
246
+ }
247
+ if (primaryUser === 'root') {
248
+ primaryUser = '';
249
+ }
250
+ if (primaryUser === '') {
251
+ try {
252
+ // Check if doas is installed and get the DOAS_USER
253
+ execSync('command -v doas', { stdio: 'ignore' });
254
+ primaryUser = execSync('echo $DOAS_USER', { encoding: 'utf-8' }).trim();
255
+ }
256
+ catch (error) {
257
+ // doas is not installed or DOAS_USER is not set, continue with the next method
258
+ }
259
+ }
260
+ if (primaryUser === '') {
261
+ try {
262
+ // Check for the SUDO_USER
263
+ primaryUser = execSync('echo $SUDO_USER', { encoding: 'utf-8' }).trim();
264
+ }
265
+ catch (error) {
266
+ // SUDO_USER is not set, continue with the next method
267
+ }
268
+ }
234
269
  if (primaryUser === '') {
235
- primaryUser = shx.exec('echo $SUDO_USER', { silent: true }).stdout.trim();
270
+ // Fallback to the USER environment variable
271
+ primaryUser = process.env.USER || '';
236
272
  }
237
273
  if (primaryUser === '') {
238
- console.log(`Cannot find your user name...`);
274
+ console.error('Cannot determine the primary user.');
239
275
  process.exit(1);
240
276
  }
241
277
  return primaryUser;
@@ -568,7 +604,8 @@ export default class Utils {
568
604
  '/lib/live/mount/rootfs/filesystem.squashfs', // ubuntu bionic
569
605
  '/live/aufs', // mx-linux
570
606
  '/run/miso/sfs/livefs', // ManjaroLinux
571
- '/run/archiso/airootfs' // Arch
607
+ '/run/archiso/airootfs', // Arch
608
+ '/media/root-rw' // AlpineLinux
572
609
  ];
573
610
  for (let i = 0; i < paths.length; i++) {
574
611
  if (Utils.isMountpoint(paths[i])) {
@@ -51,8 +51,6 @@ export default class Xdg {
51
51
  const regexDefaultUser = new RegExp(`default_user\\s*${olduser}`, 'g');
52
52
  content = content.replace(regexDefaultUser, `default_user ${newuser}`);
53
53
  fs.writeFileSync(`${chroot}/etc/${slimConf}`, content, 'utf8');
54
- // shx.sed('-i', 'auto_login no', 'auto_login yes', `${chroot}/etc/${slimConf}`)
55
- // shx.sed('-i', `default_user ${olduser}`, `default_user ${newuser}`, `${chroot}/etc/${slimConf}`)
56
54
  }
57
55
  /**
58
56
  * LIGHTDM
@@ -69,7 +67,6 @@ export default class Xdg {
69
67
  const regex = new RegExp(`autologin-user\\s*=\\s*${olduser}`, 'g'); // remove spaces
70
68
  content = content.replace(regex, `autologin-user=${newuser}`);
71
69
  fs.writeFileSync(curFile, content, 'utf8');
72
- // shx.sed('-i', `autologin-user=${olduser}`, `autologin-user=${newuser}`, curFile)
73
70
  }
74
71
  }
75
72
  }
@@ -94,8 +94,11 @@ export default async function information(verbose = false) {
94
94
  }
95
95
  initType = 'systemd';
96
96
  }
97
- const sysvinit = Utils.isSysvinit();
98
- const systemd = Utils.isSystemd();
97
+ if (initType === 'sysvinit') {
98
+ if (Utils.isOpenRc()) {
99
+ initType = 'openrc';
100
+ }
101
+ }
99
102
  const Checks = () => (React.createElement(Box, { borderStyle: "round", marginRight: 2, flexDirection: "row" },
100
103
  React.createElement(Box, { marginRight: 2 },
101
104
  React.createElement(Text, null,
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import fs from 'node:fs';
10
10
  import { exec } from '../../lib/utils.js';
11
+ import Distro from '../../classes/distro.js';
11
12
  /**
12
13
  * On Ubuntu
13
14
  * /etc/machine-id must exist to be re-created
@@ -18,5 +19,12 @@ export default async function machineId() {
18
19
  if (fs.existsSync(file)) {
19
20
  await exec(`rm ${file}`, this.echo);
20
21
  }
21
- await exec(`touch ${file}`);
22
+ const distro = new Distro();
23
+ if (distro.familyId === "alpine") {
24
+ await exec(`dbus-uuidgen > ${this.installTarget}/var/lib/dbus/machine-id`);
25
+ await exec(`cp ${this.installTarget}/var/lib/dbus/machine-id ${this.installTarget}/etc/machine-id`);
26
+ }
27
+ else {
28
+ await exec(`touch ${file}`);
29
+ }
22
30
  }
@@ -353,15 +353,17 @@ export default class Sequence {
353
353
  * - autologin
354
354
  */
355
355
  if (!this.is_clone) {
356
- // locale
357
- message = "Locale";
358
- percent = 0.70;
359
- try {
360
- redraw(React.createElement(Install, { message: message, percent: percent }));
361
- await this.locale();
362
- }
363
- catch (error) {
364
- await Utils.pressKeyToExit(JSON.stringify(error));
356
+ if (this.distro.familyId !== 'alpine') {
357
+ // locale
358
+ message = "Locale";
359
+ percent = 0.70;
360
+ try {
361
+ redraw(React.createElement(Install, { message: message, percent: percent }));
362
+ await this.locale();
363
+ }
364
+ catch (error) {
365
+ await Utils.pressKeyToExit(JSON.stringify(error));
366
+ }
365
367
  }
366
368
  // keyboard
367
369
  message = "settings keyboard";
@@ -373,14 +375,16 @@ export default class Sequence {
373
375
  await Utils.pressKeyToExit(JSON.stringify(error));
374
376
  }
375
377
  // localeCfg
376
- message = "Locale Configuration";
377
- percent = 0.72;
378
- try {
379
- await this.localeCfg();
380
- await exec("chroot " + this.installTarget + " locale-gen");
381
- }
382
- catch (error) {
383
- await Utils.pressKeyToExit(JSON.stringify(error));
378
+ if (this.distro.familyId !== 'alpine') {
379
+ message = "Locale Configuration";
380
+ percent = 0.72;
381
+ try {
382
+ await this.localeCfg();
383
+ await exec("chroot " + this.installTarget + " locale-gen");
384
+ }
385
+ catch (error) {
386
+ await Utils.pressKeyToExit(JSON.stringify(error));
387
+ }
384
388
  }
385
389
  // delLiveUser
386
390
  message = "Remove user LIVE";
Binary file