penguins-eggs 9.2.2 → 9.2.5
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/README.md +147 -132
- package/addons/eggs/theme/livecd/isolinux.theme.cfg +36 -41
- package/conf/eggs.yaml +41 -73
- package/conf/exclude.list +1 -0
- package/conf/krill.yaml +38 -0
- package/lib/classes/daddy.d.ts +2 -2
- package/lib/classes/distro.d.ts +2 -0
- package/lib/classes/distro.js +6 -0
- package/lib/classes/incubation/fisherman.js +1 -1
- package/lib/classes/pacman.js +3 -2
- package/lib/classes/pxe.d.ts +64 -0
- package/lib/classes/pxe.js +352 -0
- package/lib/classes/settings.d.ts +3 -3
- package/lib/classes/settings.js +2 -1
- package/lib/classes/tools.d.ts +2 -2
- package/lib/classes/utils.d.ts +1 -1
- package/lib/classes/utils.js +1 -1
- package/lib/commands/cuckoo.d.ts +24 -0
- package/lib/commands/cuckoo.js +70 -0
- package/lib/commands/install.d.ts +2 -2
- package/lib/commands/install.js +8 -14
- package/lib/commands/produce.js +3 -3
- package/lib/commands/{info.d.ts → status.d.ts} +1 -1
- package/lib/commands/{info.js → status.js} +5 -5
- package/lib/components/summary.d.ts +6 -1
- package/lib/components/summary.js +25 -8
- package/lib/components/users.js +3 -4
- package/lib/interfaces/i-config-tools.d.ts +1 -1
- package/lib/interfaces/i-distro.d.ts +2 -0
- package/lib/interfaces/{i-config.d.ts → i-eggs-config.d.ts} +2 -4
- package/lib/interfaces/{i-config.js → i-eggs-config.js} +0 -0
- package/lib/interfaces/i-krill-config.d.ts +26 -0
- package/lib/interfaces/i-krill-config.js +2 -0
- package/lib/interfaces/i-packages.d.ts +6 -9
- package/lib/interfaces/i-packages.js +3 -0
- package/lib/interfaces/index.d.ts +1 -1
- package/lib/krill/krill-prepare.d.ts +5 -3
- package/lib/krill/krill-prepare.js +159 -35
- package/lib/krill/krill-sequence.d.ts +5 -3
- package/lib/krill/krill-sequence.js +26 -12
- package/lib/krill/modules/fstab.d.ts +5 -0
- package/lib/krill/modules/fstab.js +5 -0
- package/lib/krill/modules/grubcfg.d.ts +5 -0
- package/lib/krill/modules/grubcfg.js +5 -0
- package/lib/krill/modules/hostname.d.ts +5 -0
- package/lib/krill/modules/hostname.js +5 -0
- package/lib/krill/modules/hosts.d.ts +5 -0
- package/lib/krill/modules/hosts.js +5 -0
- package/lib/krill/modules/initramfs-cfg.d.ts +5 -0
- package/lib/krill/modules/initramfs-cfg.js +5 -0
- package/lib/krill/modules/initramfs.d.ts +5 -0
- package/lib/krill/modules/initramfs.js +5 -0
- package/lib/krill/modules/locale-cfg.d.ts +5 -0
- package/lib/krill/modules/locale-cfg.js +5 -0
- package/lib/krill/modules/locale.d.ts +5 -0
- package/lib/krill/modules/locale.js +5 -0
- package/lib/krill/modules/machine-id.d.ts +5 -0
- package/lib/krill/modules/machine-id.js +5 -0
- package/lib/krill/modules/mkfs.d.ts +5 -0
- package/lib/krill/modules/mkfs.js +5 -0
- package/lib/krill/modules/mount-fs.d.ts +5 -0
- package/lib/krill/modules/mount-fs.js +5 -0
- package/lib/krill/modules/mount-vfs.d.ts +5 -0
- package/lib/krill/modules/mount-vfs.js +5 -0
- package/lib/krill/modules/network-cfg.d.ts +5 -0
- package/lib/krill/modules/network-cfg.js +5 -0
- package/lib/krill/modules/packages.d.ts +14 -0
- package/lib/krill/modules/packages.js +65 -0
- package/lib/krill/modules/{partitions.d.ts → partition.d.ts} +5 -0
- package/lib/krill/modules/{partitions.js → partition.js} +5 -0
- package/lib/krill/modules/remove-installer-link.d.ts +5 -0
- package/lib/krill/modules/remove-installer-link.js +5 -0
- package/lib/krill/modules/set-keyboard.d.ts +5 -0
- package/lib/krill/modules/set-keyboard.js +37 -18
- package/lib/krill/modules/set-timezone.d.ts +5 -0
- package/lib/krill/modules/set-timezone.js +5 -0
- package/lib/krill/modules/umount.d.ts +5 -0
- package/lib/krill/modules/umount.js +5 -0
- package/lib/krill/modules/unpackfs.d.ts +5 -0
- package/lib/krill/modules/unpackfs.js +5 -0
- package/manpages/doc/man/eggs.1.gz +0 -0
- package/manpages/doc/man/eggs.html +72 -83
- package/package.json +6 -2
- package/scripts/_eggs +19 -19
- package/scripts/eggs.bash +3 -3
- package/scripts/mom-cli.sh +11 -11
- package/scripts/netgrub.sh +39 -0
- package/manpages/doc/man/eggs.roll.gz +0 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* penguins-eggs: pxe.ts
|
|
4
|
+
* author: Piero Proietti
|
|
5
|
+
* mail: piero.proietti@gmail.com
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const tslib_1 = require("tslib");
|
|
9
|
+
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
10
|
+
const netmask_1 = require("netmask");
|
|
11
|
+
const node_static_1 = tslib_1.__importDefault(require("node-static"));
|
|
12
|
+
const http_1 = tslib_1.__importDefault(require("http"));
|
|
13
|
+
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
14
|
+
const utils_1 = tslib_1.__importDefault(require("../classes/utils"));
|
|
15
|
+
const settings_1 = tslib_1.__importDefault(require("../classes/settings"));
|
|
16
|
+
const utils_2 = require("../lib/utils");
|
|
17
|
+
/**
|
|
18
|
+
* Pxe:
|
|
19
|
+
*/
|
|
20
|
+
class Pxe {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.verbose = false;
|
|
23
|
+
this.echo = {};
|
|
24
|
+
this.settings = {};
|
|
25
|
+
this.bootLabel = '';
|
|
26
|
+
this.pxeRoot = '';
|
|
27
|
+
this.isoRoot = '';
|
|
28
|
+
this.vmlinuz = '';
|
|
29
|
+
this.initrd = '';
|
|
30
|
+
this.isos = [];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* fertilization()
|
|
34
|
+
*/
|
|
35
|
+
async fertilization() {
|
|
36
|
+
this.settings = new settings_1.default();
|
|
37
|
+
await this.settings.load();
|
|
38
|
+
if (utils_1.default.isLive()) {
|
|
39
|
+
this.isoRoot = this.settings.distro.liveMediumPath;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
this.isoRoot = node_path_1.default.dirname(this.settings.work_dir.path) + '/ovarium/iso/';
|
|
43
|
+
}
|
|
44
|
+
if (!utils_1.default.isLive() && !fs_1.default.existsSync(this.settings.work_dir.path)) {
|
|
45
|
+
console.log('no image available, build an image with: sudo eggs produce');
|
|
46
|
+
process.exit();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* se pxeRoot non esiste viene creato
|
|
50
|
+
*/
|
|
51
|
+
this.pxeRoot = node_path_1.default.dirname(this.settings.work_dir.path) + '/pxe/';
|
|
52
|
+
if (!fs_1.default.existsSync(this.pxeRoot)) {
|
|
53
|
+
await (0, utils_2.exec)(`mkdir ${this.pxeRoot} -p`);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Ricerca delle immagini ISO
|
|
57
|
+
*/
|
|
58
|
+
let isos = [];
|
|
59
|
+
if (!utils_1.default.isLive()) {
|
|
60
|
+
let isos = fs_1.default.readdirSync(node_path_1.default.dirname(this.settings.work_dir.path));
|
|
61
|
+
for (const iso of isos) {
|
|
62
|
+
if (node_path_1.default.extname(iso) === ".iso") {
|
|
63
|
+
this.isos.push(iso);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* installed: /home/eggs/ovarium/iso/live
|
|
69
|
+
* live: this.iso/live
|
|
70
|
+
*/
|
|
71
|
+
let pathFiles = this.isoRoot + '/live';
|
|
72
|
+
let files = fs_1.default.readdirSync(pathFiles);
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
if (node_path_1.default.basename(file).substring(0, 7) === 'vmlinuz') {
|
|
75
|
+
this.vmlinuz = node_path_1.default.basename(file);
|
|
76
|
+
}
|
|
77
|
+
if (node_path_1.default.basename(file).substring(0, 6) === 'initrd') {
|
|
78
|
+
this.initrd = node_path_1.default.basename(file);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* bootLabel
|
|
83
|
+
*/
|
|
84
|
+
const a = fs_1.default.readFileSync(this.isoRoot + '/.disk/mkisofs', "utf-8");
|
|
85
|
+
const b = a.substring(a.indexOf('-o ') + 3);
|
|
86
|
+
const c = b.substring(0, b.indexOf(' '));
|
|
87
|
+
this.bootLabel = c.substring(c.lastIndexOf('/') + 1);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* build
|
|
91
|
+
*/
|
|
92
|
+
async build() {
|
|
93
|
+
if (fs_1.default.existsSync(this.pxeRoot)) {
|
|
94
|
+
await this.tryCatch(`rm ${this.pxeRoot} -rf`);
|
|
95
|
+
}
|
|
96
|
+
let cmd = `mkdir -p ${this.pxeRoot}`;
|
|
97
|
+
await this.tryCatch(cmd);
|
|
98
|
+
await this.tryCatch(`mkdir ${this.pxeRoot} -p`);
|
|
99
|
+
await this.tryCatch(`ln -s ${this.isoRoot}live ${this.pxeRoot}/live`);
|
|
100
|
+
await this.tryCatch(`ln -s ${this.isoRoot}.disk ${this.pxeRoot}/.disk`);
|
|
101
|
+
await this.tryCatch(`ln -s ${this.isoRoot}live/${this.vmlinuz} ${this.pxeRoot}/vmlinuz`);
|
|
102
|
+
await this.tryCatch(`chmod 777 ${this.pxeRoot}/vmlinuz`);
|
|
103
|
+
await this.tryCatch(`ln -s ${this.isoRoot}live/${this.initrd} ${this.pxeRoot}/initrd`);
|
|
104
|
+
await this.tryCatch(`chmod 777 ${this.pxeRoot}/initrd`);
|
|
105
|
+
// link iso images in pxe
|
|
106
|
+
for (const iso of this.isos) {
|
|
107
|
+
await this.tryCatch(`ln /home/eggs/${iso} ${this.pxeRoot}/${iso}`);
|
|
108
|
+
}
|
|
109
|
+
await this.bios();
|
|
110
|
+
await this.uefi();
|
|
111
|
+
await this.html();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* configure PXE bios
|
|
115
|
+
*/
|
|
116
|
+
async bios() {
|
|
117
|
+
// isolinux.theme.cfg, splash.png MUST to be on root
|
|
118
|
+
await this.tryCatch(`ln -s ${this.isoRoot}isolinux/isolinux.theme.cfg ${this.pxeRoot}/isolinux.theme.cfg`);
|
|
119
|
+
await this.tryCatch(`ln -s ${this.isoRoot}isolinux/splash.png ${this.pxeRoot}/splash.png`);
|
|
120
|
+
// pxe
|
|
121
|
+
const distro = this.settings.distro;
|
|
122
|
+
await this.tryCatch(`ln ${distro.pxelinuxPath}pxelinux.0 ${this.pxeRoot}/pxelinux.0`);
|
|
123
|
+
await this.tryCatch(`ln ${distro.pxelinuxPath}lpxelinux.0 ${this.pxeRoot}/lpxelinux.0`);
|
|
124
|
+
// syslinux
|
|
125
|
+
await this.tryCatch(`ln ${distro.syslinuxPath}ldlinux.c32 ${this.pxeRoot}/ldlinux.c32`);
|
|
126
|
+
await this.tryCatch(`ln ${distro.syslinuxPath}vesamenu.c32 ${this.pxeRoot}/vesamenu.c32`);
|
|
127
|
+
await this.tryCatch(`ln ${distro.syslinuxPath}libcom32.c32 ${this.pxeRoot}/libcom32.c32`);
|
|
128
|
+
await this.tryCatch(`ln ${distro.syslinuxPath}libutil.c32 ${this.pxeRoot}/libutil.c32`);
|
|
129
|
+
await this.tryCatch(`ln /usr/lib/syslinux/memdisk ${this.pxeRoot}/memdisk`);
|
|
130
|
+
await this.tryCatch(`mkdir ${this.pxeRoot}/pxelinux.cfg`);
|
|
131
|
+
let content = ``;
|
|
132
|
+
content += `# eggs: pxelinux.cfg/default\n`;
|
|
133
|
+
content += `# search path for the c32 support libraries (libcom32, libutil etc.)\n`;
|
|
134
|
+
content += `path\n`;
|
|
135
|
+
content += `include isolinux.theme.cfg\n`;
|
|
136
|
+
content += `UI vesamenu.c32\n`;
|
|
137
|
+
content += `\n`;
|
|
138
|
+
content += `menu title Penguin's eggs - Perri's brewery edition - ${utils_1.default.address()}\n`;
|
|
139
|
+
content += `PROMPT 0\n`;
|
|
140
|
+
content += `TIMEOUT 0\n`;
|
|
141
|
+
content += `\n`;
|
|
142
|
+
content += `LABEL http\n`;
|
|
143
|
+
content += `MENU LABEL ${this.bootLabel}\n`;
|
|
144
|
+
content += `MENU DEFAULT\n`;
|
|
145
|
+
content += `KERNEL http://${utils_1.default.address()}/live/${this.vmlinuz}\n`;
|
|
146
|
+
content += `APPEND initrd=http://${utils_1.default.address()}/live/${this.initrd} boot=live config noswap noprompt fetch=http://${utils_1.default.address()}/live/filesystem.squashfs\n`;
|
|
147
|
+
content += `SYSAPPEND 3\n`;
|
|
148
|
+
content += `\n`;
|
|
149
|
+
if (this.isos.length > 0) {
|
|
150
|
+
content += `MENU SEPARATOR\n`;
|
|
151
|
+
for (const iso of this.isos) {
|
|
152
|
+
content += `\n`;
|
|
153
|
+
content += `LABEL isos\n`;
|
|
154
|
+
content += `MENU LABEL memdisk ${iso}\n`;
|
|
155
|
+
content += `KERNEL memdisk\n`;
|
|
156
|
+
content += `APPEND iso initrd=http://${utils_1.default.address()}/${iso}\n`;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
let file = `${this.pxeRoot}/pxelinux.cfg/default`;
|
|
160
|
+
fs_1.default.writeFileSync(file, content);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* configure PXE UEFI
|
|
164
|
+
*/
|
|
165
|
+
async uefi() {
|
|
166
|
+
await this.tryCatch(`mkdir ${this.pxeRoot}/grub`);
|
|
167
|
+
if (fs_1.default.existsSync('/usr/share/grub/unicode.pf2')) {
|
|
168
|
+
await this.tryCatch(`ln -s /usr/share/grub/unicode.pf2 ${this.pxeRoot}grub/font.pf2`);
|
|
169
|
+
}
|
|
170
|
+
// Copia spash.png, theme.cfg in /grub
|
|
171
|
+
await this.tryCatch(`ln -s ${this.isoRoot}boot/grub/splash.png ${this.pxeRoot}/grub/splash.png`);
|
|
172
|
+
await this.tryCatch(`ln -s ${this.isoRoot}boot/grub/theme.cfg ${this.pxeRoot}/grub/theme.cfg`);
|
|
173
|
+
// UEFI: /usr/lib/shim/shimx64.efi.signed
|
|
174
|
+
await this.tryCatch(`ln -s /usr/lib/shim/shimx64.efi.signed ${this.pxeRoot}/bootx64.efi`);
|
|
175
|
+
// UEFI: /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed
|
|
176
|
+
await this.tryCatch(`ln -s /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed ${this.pxeRoot}/grubx64.efi`);
|
|
177
|
+
/**
|
|
178
|
+
* creating /grub/grub.cfg
|
|
179
|
+
*/
|
|
180
|
+
let grubContent = '';
|
|
181
|
+
grubContent += `set default="0"\n`;
|
|
182
|
+
grubContent += `set timeout=-1\n`;
|
|
183
|
+
grubContent += `\n`;
|
|
184
|
+
grubContent += `if loadfont unicode ; then\n`;
|
|
185
|
+
grubContent += ` set gfxmode=auto\n`;
|
|
186
|
+
grubContent += ` set locale_dir=$prefix/locale\n`;
|
|
187
|
+
grubContent += ` set lang=en_US\n`;
|
|
188
|
+
grubContent += `fi\n`;
|
|
189
|
+
grubContent += `terminal_output gfxterm\n`;
|
|
190
|
+
grubContent += `\n`;
|
|
191
|
+
grubContent += `set menu_color_normal=white/black\n`;
|
|
192
|
+
grubContent += `set menu_color_highlight=black/light-gray\n`;
|
|
193
|
+
grubContent += `if background_color 44,0,30; then\n`;
|
|
194
|
+
grubContent += ` clear\n`;
|
|
195
|
+
grubContent += `fi\n`;
|
|
196
|
+
grubContent += `\n`;
|
|
197
|
+
grubContent += `function gfxmode {\n`;
|
|
198
|
+
grubContent += `\n`;
|
|
199
|
+
grubContent += ` set gfxpayload="${1}"\n`;
|
|
200
|
+
grubContent += ` if [ "${1}" = "keep" ]; then\n`;
|
|
201
|
+
grubContent += ` set vt_handoff=vt.handoff=7\n`;
|
|
202
|
+
grubContent += ` else\n`;
|
|
203
|
+
grubContent += ` set vt_handoff=\n`;
|
|
204
|
+
grubContent += ` fi\n`;
|
|
205
|
+
grubContent += `}\n`;
|
|
206
|
+
grubContent += `set linux_gfx_mode=keep\n`;
|
|
207
|
+
grubContent += `\n`;
|
|
208
|
+
grubContent += `export linux_gfx_mode\n`;
|
|
209
|
+
grubContent += `\n`;
|
|
210
|
+
grubContent += `if loadfont $prefix/font.pf2 ; then\n`;
|
|
211
|
+
grubContent += ` set gfxmode=640x480\n`;
|
|
212
|
+
grubContent += ` insmod efi_gop\n`;
|
|
213
|
+
grubContent += ` insmod efi_uga\n`;
|
|
214
|
+
grubContent += ` insmod video_bochs\n`;
|
|
215
|
+
grubContent += ` insmod video_cirrus\n`;
|
|
216
|
+
grubContent += ` insmod gfxterm\n`;
|
|
217
|
+
grubContent += ` insmod jpeg\n`;
|
|
218
|
+
grubContent += ` insmod png\n`;
|
|
219
|
+
grubContent += ` terminal_output gfxterm\n`;
|
|
220
|
+
grubContent += `fi\n`;
|
|
221
|
+
grubContent += `set theme=/grub/theme.cfg\n`;
|
|
222
|
+
grubContent += `menuentry '${this.bootLabel}' {\n`;
|
|
223
|
+
grubContent += ` gfxmode $linux_gfx_mode\n`;
|
|
224
|
+
grubContent += ` linuxefi vmlinuz boot=live config noswap noprompt fetch=http://${utils_1.default.address()}/live/filesystem.squashfs quiet splash sysappend 0x40000\n`;
|
|
225
|
+
grubContent += ` initrdefi initrd\n`;
|
|
226
|
+
grubContent += `}\n`;
|
|
227
|
+
let grubFile = `${this.pxeRoot}grub/grub.cfg`;
|
|
228
|
+
fs_1.default.writeFileSync(grubFile, grubContent);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* configure PXE html
|
|
232
|
+
*/
|
|
233
|
+
async html() {
|
|
234
|
+
let file = `${this.pxeRoot}/index.html`;
|
|
235
|
+
let content = ``;
|
|
236
|
+
content += `<html><title>Penguin's eggs PXE server</title>`;
|
|
237
|
+
content += `<div style="background-image:url('/splash.png');background-repeat:no-repeat;width: 640;height:480;padding:5px;border:1px solid black;">`;
|
|
238
|
+
content += `<h1>Penguin's eggs PXE server</h1>`;
|
|
239
|
+
content += `<body>address: <a href=http://${utils_1.default.address()}>${utils_1.default.address()}</a><br/>`;
|
|
240
|
+
if (!utils_1.default.isLive()) {
|
|
241
|
+
content += `download: <a href='http://${utils_1.default.address()}/${this.isos[0]}'>${this.isos[0]}</a><br/>`;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
content += `started from live iso image<br/>`;
|
|
245
|
+
}
|
|
246
|
+
content += `<br/>`;
|
|
247
|
+
content += `source: <a href='https://github.com/pieroproietti/penguins-eggs'>https://github.com/pieroproietti/penguins-eggs</a><br/>`;
|
|
248
|
+
content += `manual: <a href='https://penguins-eggs.net/book/italiano9.2.html'>italiano</a>, <a href='https://penguins--eggs-net.translate.goog/book/italiano9.2?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en'>translated</a><br/>`;
|
|
249
|
+
content += `discuss: <a href='https://t.me/penguins_eggs'>Telegram group<br/></body</html>`;
|
|
250
|
+
fs_1.default.writeFileSync(file, content);
|
|
251
|
+
}
|
|
252
|
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
253
|
+
//
|
|
254
|
+
// dncp: actually install and configure dnsmaq
|
|
255
|
+
//
|
|
256
|
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
257
|
+
/**
|
|
258
|
+
*
|
|
259
|
+
* @param real
|
|
260
|
+
*/
|
|
261
|
+
async dhcp(real = false, dnsmasq = true) {
|
|
262
|
+
if (dnsmasq) {
|
|
263
|
+
await this.dnsmasq(real);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
await this.nodeDhcp(real);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
*
|
|
271
|
+
*/
|
|
272
|
+
async nodeDhcp(real = false) {
|
|
273
|
+
console.log('to do!');
|
|
274
|
+
process.exit();
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
*
|
|
278
|
+
* @param real
|
|
279
|
+
*/
|
|
280
|
+
async dnsmasq(real = false) {
|
|
281
|
+
await (0, utils_2.exec)(`systemctl stop dnsmasq.service`);
|
|
282
|
+
let domain = `penguins-eggs.lan`;
|
|
283
|
+
let n = new netmask_1.Netmask(`${utils_1.default.address()}/${utils_1.default.netmask()}`);
|
|
284
|
+
let content = ``;
|
|
285
|
+
content += `# cuckoo.conf\n`;
|
|
286
|
+
content += `port=0\n`;
|
|
287
|
+
content += `interface=${await utils_1.default.iface()}\n`;
|
|
288
|
+
content += `bind-interfaces\n`;
|
|
289
|
+
content += `domain=${domain}\n`;
|
|
290
|
+
content += `dhcp-no-override\n`;
|
|
291
|
+
content += `dhcp-option=option:router,${n.first}\n`;
|
|
292
|
+
content += `dhcp-option=option:dns-server,${n.first}\n`;
|
|
293
|
+
content += `dhcp-option=option:dns-server,8.8.8.8\n`;
|
|
294
|
+
content += `dhcp-option=option:dns-server,8.8.4.4\n`;
|
|
295
|
+
content += `enable-tftp\n`;
|
|
296
|
+
content += `tftp-root=${this.pxeRoot}\n`;
|
|
297
|
+
content += `# boot config for BIOS\n`;
|
|
298
|
+
content += `dhcp-match=set:bios-x86,option:client-arch,0\n`;
|
|
299
|
+
content += `dhcp-boot=tag:bios-x86,lpxelinux.0\n`;
|
|
300
|
+
content += `# boot config for UEFI\n`;
|
|
301
|
+
content += `dhcp-match=set:efi-x86_64,option:client-arch,7\n`;
|
|
302
|
+
content += `dhcp-match=set:efi-x86_64,option:client-arch,9\n`;
|
|
303
|
+
content += `dhcp-boot=tag:efi-x86_64,/bootx64.efi\n`;
|
|
304
|
+
// Here we are OK Starting grub
|
|
305
|
+
/**
|
|
306
|
+
* https://thekelleys.org.uk/dnsmasq/CHANGELOG
|
|
307
|
+
*
|
|
308
|
+
* Don't do any PXE processing, even for clients with the
|
|
309
|
+
* correct vendorclass, unless at least one pxe-prompt or
|
|
310
|
+
* pxe-service option is given. This stops dnsmasq
|
|
311
|
+
* interfering with proxy PXE subsystems when it is just
|
|
312
|
+
* the DHCP server. Thanks to Spencer Clark for spotting this.
|
|
313
|
+
*/
|
|
314
|
+
content += `pxe-service=X86PC,"penguin's eggs cuckoo",pxelinux.0\n`;
|
|
315
|
+
if (real) {
|
|
316
|
+
content += `dhcp-range=${await utils_1.default.iface()},${n.first},${n.last},${n.mask},8h\n`;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
content += `dhcp-range=${await utils_1.default.iface()},${n.base},proxy,${n.mask},${n.broadcast} # dhcp proxy\n`;
|
|
320
|
+
}
|
|
321
|
+
let file = '/etc/dnsmasq.d/cuckoo.conf';
|
|
322
|
+
fs_1.default.writeFileSync(file, content);
|
|
323
|
+
// console.log(content)
|
|
324
|
+
await (0, utils_2.exec)(`systemctl start dnsmasq.service`);
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* start http server for images
|
|
328
|
+
*
|
|
329
|
+
*/
|
|
330
|
+
async httpStart() {
|
|
331
|
+
const port = 80;
|
|
332
|
+
const httpRoot = this.pxeRoot + "/";
|
|
333
|
+
var file = new (node_static_1.default.Server)(httpRoot);
|
|
334
|
+
http_1.default.createServer(function (req, res) {
|
|
335
|
+
file.serve(req, res);
|
|
336
|
+
}).listen(port);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
*
|
|
340
|
+
* @param cmd
|
|
341
|
+
*/
|
|
342
|
+
async tryCatch(cmd = '') {
|
|
343
|
+
try {
|
|
344
|
+
await (0, utils_2.exec)(cmd, this.echo);
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
console.log(`Error: ${error}`);
|
|
348
|
+
await utils_1.default.pressKeyToExit(cmd);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
exports.default = Pxe;
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { IRemix, IDistro, IApp, IWorkDir } from '../interfaces';
|
|
8
8
|
import Incubator from './incubation/incubator';
|
|
9
|
-
import {
|
|
9
|
+
import { IEggsConfig } from '../interfaces';
|
|
10
10
|
/**
|
|
11
11
|
* Setting
|
|
12
12
|
*/
|
|
13
13
|
export default class Settings {
|
|
14
14
|
app: IApp;
|
|
15
|
-
config:
|
|
15
|
+
config: IEggsConfig;
|
|
16
16
|
remix: IRemix;
|
|
17
17
|
work_dir: IWorkDir;
|
|
18
18
|
distro: IDistro;
|
|
@@ -31,7 +31,7 @@ export default class Settings {
|
|
|
31
31
|
*
|
|
32
32
|
* @param config
|
|
33
33
|
*/
|
|
34
|
-
save(config:
|
|
34
|
+
save(config: IEggsConfig): Promise<void>;
|
|
35
35
|
/**
|
|
36
36
|
* Load configuration from config_file
|
|
37
37
|
* @returns {boolean} Success
|
package/lib/classes/settings.js
CHANGED
|
@@ -79,7 +79,8 @@ class Settings {
|
|
|
79
79
|
this.work_dir.merged = this.work_dir.path + 'filesystem.squashfs';
|
|
80
80
|
this.efi_work = this.work_dir.path + 'efi-work/';
|
|
81
81
|
this.work_dir.pathIso = this.work_dir.path + 'iso/';
|
|
82
|
-
|
|
82
|
+
// remember: before was hostname, not empty
|
|
83
|
+
if (this.config.snapshot_basename === '') {
|
|
83
84
|
this.config.snapshot_basename = node_os_1.default.hostname();
|
|
84
85
|
}
|
|
85
86
|
if (this.config.make_efi && !pacman_1.default.isUefi()) {
|
package/lib/classes/tools.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* email: piero.proietti@gmail.com
|
|
5
5
|
* license: MIT
|
|
6
6
|
*/
|
|
7
|
-
interface
|
|
7
|
+
interface IEggsConfigTools {
|
|
8
8
|
remoteHost: string;
|
|
9
9
|
remoteUser: string;
|
|
10
10
|
remotePathDeb: string;
|
|
@@ -23,7 +23,7 @@ export default class Tools {
|
|
|
23
23
|
tools_yaml: string;
|
|
24
24
|
snapshot_dir: string;
|
|
25
25
|
snapshot_name: string;
|
|
26
|
-
config:
|
|
26
|
+
config: IEggsConfigTools;
|
|
27
27
|
loadSettings(): Promise<boolean>;
|
|
28
28
|
}
|
|
29
29
|
export {};
|
package/lib/classes/utils.d.ts
CHANGED
package/lib/classes/utils.js
CHANGED
|
@@ -541,7 +541,7 @@ class Utils {
|
|
|
541
541
|
/**
|
|
542
542
|
* return the name of network device
|
|
543
543
|
*/
|
|
544
|
-
static iface() {
|
|
544
|
+
static async iface() {
|
|
545
545
|
// return shx.exec(`ifconfig | awk 'FNR==1 { print $1 }' | tr --d :`, { silent: true }).stdout.trim()
|
|
546
546
|
const interfaces = Object.keys(os_1.default.networkInterfaces());
|
|
547
547
|
let netDeviceName = '';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* penguins-eggs-v7 based on Debian live
|
|
3
|
+
* author: Piero Proietti
|
|
4
|
+
* email: piero.proietti@gmail.com
|
|
5
|
+
* license: MIT
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from '@oclif/core';
|
|
8
|
+
import { IWorkDir } from '../interfaces/i-workdir';
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
export default class Cuckoo extends Command {
|
|
13
|
+
config_file: string;
|
|
14
|
+
snapshot_dir: string;
|
|
15
|
+
work_dir: IWorkDir;
|
|
16
|
+
static description: string;
|
|
17
|
+
static flags: {
|
|
18
|
+
real: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
|
|
20
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
};
|
|
22
|
+
static examples: string[];
|
|
23
|
+
run(): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
/**
|
|
5
|
+
* penguins-eggs-v7 based on Debian live
|
|
6
|
+
* author: Piero Proietti
|
|
7
|
+
* email: piero.proietti@gmail.com
|
|
8
|
+
* license: MIT
|
|
9
|
+
*/
|
|
10
|
+
const core_1 = require("@oclif/core");
|
|
11
|
+
const utils_1 = tslib_1.__importDefault(require("../classes/utils"));
|
|
12
|
+
const pacman_1 = tslib_1.__importDefault(require("../classes/pacman"));
|
|
13
|
+
const pxe_1 = tslib_1.__importDefault(require("../classes/pxe"));
|
|
14
|
+
const utils_2 = require("../lib/utils");
|
|
15
|
+
const distro_1 = tslib_1.__importDefault(require("../classes/distro"));
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
class Cuckoo extends core_1.Command {
|
|
20
|
+
constructor() {
|
|
21
|
+
super(...arguments);
|
|
22
|
+
this.config_file = '/etc/penguins-eggs.d/eggs.yaml';
|
|
23
|
+
this.snapshot_dir = '';
|
|
24
|
+
this.work_dir = {};
|
|
25
|
+
}
|
|
26
|
+
async run() {
|
|
27
|
+
utils_1.default.titles(this.id + ' ' + this.argv);
|
|
28
|
+
const { flags } = await this.parse(Cuckoo);
|
|
29
|
+
let verbose = flags.verbose;
|
|
30
|
+
const echo = utils_1.default.setEcho(verbose);
|
|
31
|
+
let real = flags.real;
|
|
32
|
+
const distro = new distro_1.default();
|
|
33
|
+
if (distro.familyId === 'debian') {
|
|
34
|
+
if (utils_1.default.isRoot()) {
|
|
35
|
+
if (!pacman_1.default.packageIsInstalled('dnsmasq') ||
|
|
36
|
+
(!pacman_1.default.packageIsInstalled("pxelinux"))) {
|
|
37
|
+
console.log('eggs cuckoo need to nstall dnsmasq and pxelinux.');
|
|
38
|
+
if (await utils_1.default.customConfirm()) {
|
|
39
|
+
console.log('Installing dnsmasq and pxelinux... wait a moment');
|
|
40
|
+
await (0, utils_2.exec)('sudo apt-get update -y', utils_1.default.setEcho(false));
|
|
41
|
+
await (0, utils_2.exec)('sudo apt-get install dnsmasq pxelinux -y', utils_1.default.setEcho(false));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
console.log('You need to install dnsmasq to start cuckoo PXE server');
|
|
45
|
+
process.exit();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const pxe = new pxe_1.default();
|
|
49
|
+
await pxe.fertilization();
|
|
50
|
+
await pxe.build();
|
|
51
|
+
let dnsmasq = true;
|
|
52
|
+
await pxe.dhcp(real, dnsmasq);
|
|
53
|
+
await pxe.httpStart();
|
|
54
|
+
console.log(`Serving PXE boot, read more at: http://${utils_1.default.address()}`);
|
|
55
|
+
console.log(`CTRL-c to quit`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
console.log(`Sorry: actually cuckoo is enabled just for debian family!`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.default = Cuckoo;
|
|
64
|
+
Cuckoo.description = 'cuckoo start a PXE boot server serving the live image';
|
|
65
|
+
Cuckoo.flags = {
|
|
66
|
+
real: core_1.Flags.boolean({ char: 'r', description: 'start a real dhcp server' }),
|
|
67
|
+
help: core_1.Flags.help({ char: 'h' }),
|
|
68
|
+
verbose: core_1.Flags.boolean({ char: 'v', description: 'verbose' })
|
|
69
|
+
};
|
|
70
|
+
Cuckoo.examples = ['$ sudo eggs cuckoo\nstart a PXE boot server'];
|
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { Command } from '@oclif/core';
|
|
8
8
|
/**
|
|
9
|
-
* Class
|
|
9
|
+
* Class Krill
|
|
10
10
|
*/
|
|
11
11
|
export default class Install extends Command {
|
|
12
12
|
static flags: {
|
|
13
|
+
unattended: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
14
|
crypted: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
15
|
pve: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
15
16
|
help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
|
|
16
17
|
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
17
18
|
};
|
|
18
|
-
static aliases: string[];
|
|
19
19
|
static description: string;
|
|
20
20
|
static examples: string[];
|
|
21
21
|
/**
|
package/lib/commands/install.js
CHANGED
|
@@ -11,7 +11,7 @@ const core_1 = require("@oclif/core");
|
|
|
11
11
|
const utils_1 = tslib_1.__importDefault(require("../classes/utils"));
|
|
12
12
|
const krill_prepare_1 = tslib_1.__importDefault(require("../krill/krill-prepare"));
|
|
13
13
|
/**
|
|
14
|
-
* Class
|
|
14
|
+
* Class Krill
|
|
15
15
|
*/
|
|
16
16
|
class Install extends core_1.Command {
|
|
17
17
|
/**
|
|
@@ -20,23 +20,17 @@ class Install extends core_1.Command {
|
|
|
20
20
|
async run() {
|
|
21
21
|
utils_1.default.titles(this.id + ' ' + this.argv);
|
|
22
22
|
const { flags } = await this.parse(Install);
|
|
23
|
-
let
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
let pve = false;
|
|
28
|
-
if (flags.pve) {
|
|
29
|
-
pve = true;
|
|
23
|
+
let unattended = flags.unattended;
|
|
24
|
+
let crypted = flags.crypted;
|
|
25
|
+
let pve = flags.pve;
|
|
26
|
+
if (pve) {
|
|
30
27
|
crypted = false;
|
|
31
28
|
}
|
|
32
|
-
let verbose =
|
|
33
|
-
if (flags.verbose) {
|
|
34
|
-
verbose = true;
|
|
35
|
-
}
|
|
29
|
+
let verbose = flags.verbose;
|
|
36
30
|
if (utils_1.default.isRoot()) {
|
|
37
31
|
if (utils_1.default.isLive()) {
|
|
38
32
|
const krill = new krill_prepare_1.default();
|
|
39
|
-
await krill.prepare(crypted, pve, verbose);
|
|
33
|
+
await krill.prepare(unattended, crypted, pve, verbose);
|
|
40
34
|
}
|
|
41
35
|
else {
|
|
42
36
|
utils_1.default.warning('You are in an installed system!');
|
|
@@ -49,11 +43,11 @@ class Install extends core_1.Command {
|
|
|
49
43
|
}
|
|
50
44
|
exports.default = Install;
|
|
51
45
|
Install.flags = {
|
|
46
|
+
unattended: core_1.Flags.boolean({ char: 'u', description: 'unattended CLI installation' }),
|
|
52
47
|
crypted: core_1.Flags.boolean({ char: 'k', description: 'crypted CLI installation' }),
|
|
53
48
|
pve: core_1.Flags.boolean({ char: 'p', description: 'Proxmox VE install' }),
|
|
54
49
|
help: core_1.Flags.help({ char: 'h' }),
|
|
55
50
|
verbose: core_1.Flags.boolean({ char: 'v', description: 'verbose' })
|
|
56
51
|
};
|
|
57
|
-
Install.aliases = [`krill`];
|
|
58
52
|
Install.description = 'command-line system installer - the egg became a penguin!';
|
|
59
53
|
Install.examples = ['$ eggs install\nInstall the system using krill installer\n'];
|
package/lib/commands/produce.js
CHANGED
|
@@ -66,9 +66,9 @@ class Produce extends core_1.Command {
|
|
|
66
66
|
compression = compressors.fast();
|
|
67
67
|
}
|
|
68
68
|
const release = flags.release;
|
|
69
|
-
if (release) {
|
|
70
|
-
|
|
71
|
-
}
|
|
69
|
+
// if (release) {
|
|
70
|
+
// compression = compressors.max()
|
|
71
|
+
// }
|
|
72
72
|
const backup = flags.backup;
|
|
73
73
|
const clone = flags.clone;
|
|
74
74
|
const verbose = flags.verbose;
|
|
@@ -5,7 +5,7 @@ import { Command } from '@oclif/core';
|
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
export default class
|
|
8
|
+
export default class Status extends Command {
|
|
9
9
|
static description: string;
|
|
10
10
|
static flags: {
|
|
11
11
|
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
@@ -9,12 +9,12 @@ const information_1 = tslib_1.__importDefault(require("../components/elements/in
|
|
|
9
9
|
/**
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
|
-
class
|
|
12
|
+
class Status extends core_1.Command {
|
|
13
13
|
/**
|
|
14
14
|
*
|
|
15
15
|
*/
|
|
16
16
|
async run() {
|
|
17
|
-
const { flags } = await this.parse(
|
|
17
|
+
const { flags } = await this.parse(Status);
|
|
18
18
|
let verbose = false;
|
|
19
19
|
if (flags.verbose) {
|
|
20
20
|
verbose = true;
|
|
@@ -22,9 +22,9 @@ class Info extends core_1.Command {
|
|
|
22
22
|
await (0, information_1.default)(verbose);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
exports.default =
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
exports.default = Status;
|
|
26
|
+
Status.description = 'informations about eggs status';
|
|
27
|
+
Status.flags = {
|
|
28
28
|
verbose: core_1.Flags.boolean({ char: 'v' }),
|
|
29
29
|
help: core_1.Flags.help({ char: 'h' })
|
|
30
30
|
};
|
|
@@ -6,6 +6,11 @@ declare type SummaryProps = {
|
|
|
6
6
|
keyboardModel: string;
|
|
7
7
|
keyboardLayout: string;
|
|
8
8
|
installationDevice: string;
|
|
9
|
+
name: string;
|
|
10
|
+
password: string;
|
|
11
|
+
rootPassword: string;
|
|
12
|
+
hostname: string;
|
|
13
|
+
message: string;
|
|
9
14
|
};
|
|
10
|
-
export default function Summary({ region, zone, language, keyboardModel, keyboardLayout, installationDevice }: SummaryProps): JSX.Element;
|
|
15
|
+
export default function Summary({ name, password, rootPassword, hostname, region, zone, language, keyboardModel, keyboardLayout, installationDevice, message }: SummaryProps): JSX.Element;
|
|
11
16
|
export {};
|