underpost 2.8.798 → 2.8.811
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/.github/workflows/ghpkg.yml +23 -21
- package/.github/workflows/npmpkg.yml +16 -11
- package/.github/workflows/pwa-microservices-template.page.yml +12 -3
- package/.github/workflows/pwa-microservices-template.test.yml +20 -17
- package/.vscode/extensions.json +1 -2
- package/.vscode/settings.json +3 -0
- package/Dockerfile +14 -33
- package/README.md +25 -24
- package/bin/deploy.js +379 -101
- package/bin/vs.js +10 -3
- package/cli.md +331 -217
- package/docker-compose.yml +1 -1
- package/manifests/deployment/dd-template-development/deployment.yaml +18 -18
- package/manifests/lxd/underpost-setup.sh +1 -1
- package/manifests/maas/lxd-preseed.yaml +32 -0
- package/manifests/maas/maas-setup.sh +64 -0
- package/manifests/mariadb/statefulset.yaml +2 -1
- package/manifests/mariadb/storage-class.yaml +10 -0
- package/package.json +1 -1
- package/src/cli/baremetal.js +99 -0
- package/src/cli/cluster.js +15 -1
- package/src/cli/deploy.js +1 -1
- package/src/cli/env.js +2 -2
- package/src/cli/image.js +4 -3
- package/src/cli/index.js +244 -238
- package/src/cli/lxd.js +1 -4
- package/src/index.js +9 -1
- package/src/runtime/lampp/Dockerfile +68 -38
- package/src/server/conf.js +58 -0
- package/supervisord-openssh-server.conf +0 -5
package/bin/deploy.js
CHANGED
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
setUpProxyMaintenanceServer,
|
|
28
28
|
writeEnv,
|
|
29
29
|
getUnderpostRootPath,
|
|
30
|
+
buildCliDoc,
|
|
30
31
|
} from '../src/server/conf.js';
|
|
31
32
|
import { buildClient } from '../src/server/client-build.js';
|
|
32
33
|
import { range, s4, setPad, timer, uniqueArray } from '../src/client/components/core/CommonJs.js';
|
|
@@ -37,10 +38,10 @@ import { JSONweb } from '../src/server/client-formatted.js';
|
|
|
37
38
|
|
|
38
39
|
import { Xampp } from '../src/runtime/xampp/Xampp.js';
|
|
39
40
|
import { ejs } from '../src/server/json-schema.js';
|
|
40
|
-
import { buildCliDoc } from '../src/cli/index.js';
|
|
41
41
|
import { getLocalIPv4Address, ip } from '../src/server/dns.js';
|
|
42
42
|
import { Downloader } from '../src/server/downloader.js';
|
|
43
43
|
import colors from 'colors';
|
|
44
|
+
import { program } from '../src/cli/index.js';
|
|
44
45
|
|
|
45
46
|
colors.enable();
|
|
46
47
|
|
|
@@ -50,53 +51,137 @@ logger.info('argv', process.argv);
|
|
|
50
51
|
|
|
51
52
|
const [exe, dir, operator] = process.argv;
|
|
52
53
|
|
|
53
|
-
const updateVirtualRoot = async ({
|
|
54
|
-
|
|
54
|
+
const updateVirtualRoot = async ({ IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update }) => {
|
|
55
|
+
// <consumer_key>:<consumer_token>:<secret>
|
|
56
|
+
const MAAS_API_TOKEN = shellExec(`maas apikey --username ${process.env.MAAS_ADMIN_USERNAME}`, {
|
|
57
|
+
stdout: true,
|
|
58
|
+
}).trim();
|
|
59
|
+
const [consumer_key, consumer_token, secret] = MAAS_API_TOKEN.split(`\n`)[1].split(':');
|
|
60
|
+
const chronyConfPath = `/etc/chrony/chrony.conf`;
|
|
61
|
+
const timezone = 'America/New_York';
|
|
62
|
+
const timeZoneSteps = [
|
|
63
|
+
`apt-get update`,
|
|
64
|
+
|
|
65
|
+
`export DEBIAN_FRONTEND=noninteractive`,
|
|
66
|
+
|
|
67
|
+
`ln -fs /usr/share/zoneinfo/${timezone} /etc/localtime`,
|
|
68
|
+
|
|
69
|
+
`DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata`,
|
|
70
|
+
`dpkg-reconfigure --frontend noninteractive tzdata`,
|
|
71
|
+
];
|
|
72
|
+
const keyboardSteps = [
|
|
73
|
+
`sudo locale-gen en_US.UTF-8`,
|
|
74
|
+
`sudo update-locale LANG=en_US.UTF-8`,
|
|
75
|
+
`sudo sed -i 's/XKBLAYOUT="us"/XKBLAYOUT="es"/' /etc/default/keyboard`,
|
|
76
|
+
`sudo dpkg-reconfigure --frontend noninteractive keyboard-configuration`,
|
|
77
|
+
`sudo systemctl restart keyboard-setup.service`,
|
|
78
|
+
];
|
|
79
|
+
const installSteps = [
|
|
55
80
|
`apt update`,
|
|
81
|
+
`apt install -y cloud-init systemd-sysv openssh-server sudo locales udev util-linux systemd-sysv iproute2 netplan.io ca-certificates curl wget chrony keyboard-configuration`,
|
|
56
82
|
`ln -sf /lib/systemd/systemd /sbin/init`,
|
|
57
|
-
|
|
58
|
-
`
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
`
|
|
68
|
-
`
|
|
83
|
+
|
|
84
|
+
`echo 'deb http://ports.ubuntu.com/ubuntu-ports noble main restricted universe multiverse
|
|
85
|
+
deb http://ports.ubuntu.com/ubuntu-ports noble-updates main restricted universe multiverse
|
|
86
|
+
deb http://ports.ubuntu.com/ubuntu-ports noble-security main restricted universe multiverse
|
|
87
|
+
|
|
88
|
+
# Uncomment the following lines if you also need source packages (for building from source)
|
|
89
|
+
# deb-src http://ports.ubuntu.com/ubuntu-ports noble main restricted universe multiverse
|
|
90
|
+
# deb-src http://ports.ubuntu.com/ubuntu-ports noble-updates main restricted universe multiverse
|
|
91
|
+
# deb-src http://ports.ubuntu.com/ubuntu-ports noble-security main restricted universe multiverse
|
|
92
|
+
' > /etc/apt/sources.list`,
|
|
93
|
+
`apt update`,
|
|
94
|
+
`apt -y full-upgrade`,
|
|
95
|
+
// `apt install -y cloud-init=25.1.2-0ubuntu0~24.04.1`,
|
|
96
|
+
|
|
97
|
+
`systemctl enable ssh`,
|
|
98
|
+
|
|
99
|
+
`apt update -qq`,
|
|
100
|
+
`apt install -y xinput x11-xkb-utils usbutils`,
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
let steps = [
|
|
104
|
+
// `date -s "${shellExec(`date '+%Y-%m-%d %H:%M:%S'`, { stdout: true }).trim()}"`,
|
|
105
|
+
// `date`,
|
|
106
|
+
|
|
107
|
+
...timeZoneSteps,
|
|
108
|
+
...chronySetUp(chronyConfPath),
|
|
109
|
+
|
|
110
|
+
// Create root user
|
|
111
|
+
`useradd -m -s /bin/bash -G sudo root`,
|
|
112
|
+
`echo 'root:root' | chpasswd`,
|
|
69
113
|
`mkdir -p /home/root/.ssh`,
|
|
70
114
|
`echo '${fs.readFileSync(
|
|
71
115
|
`/home/dd/engine/engine-private/deploy/id_rsa.pub`,
|
|
72
116
|
'utf8',
|
|
73
|
-
)}'
|
|
117
|
+
)}' > /home/root/.ssh/authorized_keys`,
|
|
118
|
+
`chown -R root /home/root/.ssh`,
|
|
74
119
|
`chmod 700 /home/root/.ssh`,
|
|
75
120
|
`chmod 600 /home/root/.ssh/authorized_keys`,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
`apt install -y linux-generic-hwe-24.04`,
|
|
79
|
-
`modprobe ip_tables`,
|
|
121
|
+
|
|
122
|
+
// Configure cloud-init for MAAS
|
|
80
123
|
`cat <<EOF_MAAS_CFG > /etc/cloud/cloud.cfg.d/90_maas.cfg
|
|
124
|
+
#cloud-config
|
|
125
|
+
|
|
126
|
+
hostname: ${host}
|
|
127
|
+
# fqdn: server01.midominio.cl
|
|
128
|
+
# prefer_fqdn_over_hostname: true
|
|
129
|
+
# metadata_url: http://${IP_ADDRESS}:5240/MAAS/metadata
|
|
130
|
+
# metadata_url: http://${IP_ADDRESS}:5248/MAAS/metadata
|
|
131
|
+
|
|
132
|
+
# Check:
|
|
133
|
+
# /MAAS/metadata/latest/enlist-preseed/?op=get_enlist_preseed
|
|
134
|
+
|
|
135
|
+
# Debug:
|
|
136
|
+
# https://maas.io/docs/how-to-use-logging
|
|
137
|
+
|
|
81
138
|
datasource_list: [ MAAS ]
|
|
82
139
|
datasource:
|
|
83
140
|
MAAS:
|
|
84
|
-
metadata_url: http://${IP_ADDRESS}:
|
|
141
|
+
metadata_url: http://${IP_ADDRESS}:5240/MAAS/metadata
|
|
142
|
+
consumer_key: ${consumer_key}
|
|
143
|
+
token_key: ${consumer_token}
|
|
144
|
+
token_secret: ${secret}
|
|
85
145
|
users:
|
|
86
|
-
- name:
|
|
146
|
+
- name: rpiadmin
|
|
147
|
+
sudo: ['ALL=(ALL) NOPASSWD:ALL']
|
|
148
|
+
shell: /bin/bash
|
|
149
|
+
lock_passwd: true
|
|
87
150
|
ssh_authorized_keys:
|
|
88
151
|
- ${fs.readFileSync(`/home/dd/engine/engine-private/deploy/id_rsa.pub`, 'utf8')}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
# keyboard:
|
|
155
|
+
# layout: es
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
# check timedatectl on host
|
|
159
|
+
# timezone: America/Santiago
|
|
160
|
+
timezone: ${timezone}
|
|
161
|
+
|
|
162
|
+
ntp:
|
|
163
|
+
enabled: true
|
|
164
|
+
servers:
|
|
165
|
+
- ${IP_ADDRESS}
|
|
166
|
+
ntp_client: chrony
|
|
167
|
+
config:
|
|
168
|
+
confpath: ${chronyConfPath}
|
|
169
|
+
packages:
|
|
170
|
+
- chrony
|
|
171
|
+
service_name: chrony
|
|
172
|
+
|
|
173
|
+
# ssh:
|
|
174
|
+
# allow-pw: false
|
|
175
|
+
# install-server: true
|
|
176
|
+
|
|
177
|
+
# ssh_pwauth: false
|
|
178
|
+
|
|
179
|
+
package_update: true
|
|
180
|
+
package_upgrade: true
|
|
92
181
|
packages:
|
|
93
182
|
- git
|
|
94
183
|
- htop
|
|
95
|
-
-
|
|
96
|
-
# package_update: true
|
|
97
|
-
runcmd:
|
|
98
|
-
- ufw enable
|
|
99
|
-
- ufw allow ssh
|
|
184
|
+
- snapd
|
|
100
185
|
resize_rootfs: false
|
|
101
186
|
growpart:
|
|
102
187
|
mode: off
|
|
@@ -107,9 +192,36 @@ network:
|
|
|
107
192
|
dhcp4: true
|
|
108
193
|
addresses:
|
|
109
194
|
- ${ipaddr}/24
|
|
195
|
+
|
|
196
|
+
# chpasswd:
|
|
197
|
+
# expire: false
|
|
198
|
+
# users:
|
|
199
|
+
# - {name: rpiadmin, password: changeme, type: text}
|
|
200
|
+
|
|
201
|
+
final_message: "The system is up, after $UPTIME seconds"
|
|
202
|
+
|
|
203
|
+
# power_state:
|
|
204
|
+
# mode: reboot
|
|
205
|
+
# message: Rebooting after initial setup
|
|
206
|
+
# timeout: 30
|
|
207
|
+
# condition: True
|
|
208
|
+
bootcmd:
|
|
209
|
+
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
|
|
210
|
+
- echo "Init bootcmd"
|
|
211
|
+
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
|
|
212
|
+
# - ${JSON.stringify([...timeZoneSteps, ...chronySetUp(chronyConfPath)])}
|
|
213
|
+
runcmd:
|
|
214
|
+
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
|
|
215
|
+
- echo "Init runcmd"
|
|
216
|
+
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
|
|
110
217
|
EOF_MAAS_CFG`,
|
|
218
|
+
...keyboardSteps,
|
|
111
219
|
];
|
|
112
220
|
|
|
221
|
+
if (!update) {
|
|
222
|
+
steps = installSteps.concat(steps);
|
|
223
|
+
}
|
|
224
|
+
|
|
113
225
|
shellExec(`sudo chroot ${nfsHostPath} /usr/bin/qemu-aarch64-static /bin/bash <<'EOF'
|
|
114
226
|
${steps
|
|
115
227
|
.map(
|
|
@@ -124,6 +236,82 @@ EOF`);
|
|
|
124
236
|
echo "nameserver ${process.env.MAAS_DNS}" | tee /etc/resolv.conf > /dev/null
|
|
125
237
|
apt update
|
|
126
238
|
EOF`);
|
|
239
|
+
|
|
240
|
+
if (update) {
|
|
241
|
+
shellExec(`sudo chroot ${nfsHostPath} /usr/bin/qemu-aarch64-static /bin/bash <<'EOF'
|
|
242
|
+
sudo cloud-init clean --logs --reboot
|
|
243
|
+
EOF`);
|
|
244
|
+
fs.writeFileSync(`${nfsHostPath}/var/log/cloud-init.log`, '', 'utf8');
|
|
245
|
+
|
|
246
|
+
fs.writeFileSync(
|
|
247
|
+
`${nfsHostPath}/dns.sh`,
|
|
248
|
+
`rm /etc/resolv.conf
|
|
249
|
+
echo 'nameserver 8.8.8.8' > /run/systemd/resolve/stub-resolv.conf
|
|
250
|
+
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf`,
|
|
251
|
+
'utf8',
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const chronySetUp = (path) => {
|
|
257
|
+
return [
|
|
258
|
+
`echo '
|
|
259
|
+
# Use public servers from the pool.ntp.org project.
|
|
260
|
+
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
|
|
261
|
+
# pool 2.pool.ntp.org iburst
|
|
262
|
+
server ntp.ubuntu.com iburst
|
|
263
|
+
|
|
264
|
+
# Record the rate at which the system clock gains/losses time.
|
|
265
|
+
driftfile /var/lib/chrony/drift
|
|
266
|
+
|
|
267
|
+
# Allow the system clock to be stepped in the first three updates
|
|
268
|
+
# if its offset is larger than 1 second.
|
|
269
|
+
makestep 1.0 3
|
|
270
|
+
|
|
271
|
+
# Enable kernel synchronization of the real-time clock (RTC).
|
|
272
|
+
rtcsync
|
|
273
|
+
|
|
274
|
+
# Enable hardware timestamping on all interfaces that support it.
|
|
275
|
+
#hwtimestamp *
|
|
276
|
+
|
|
277
|
+
# Increase the minimum number of selectable sources required to adjust
|
|
278
|
+
# the system clock.
|
|
279
|
+
#minsources 2
|
|
280
|
+
|
|
281
|
+
# Allow NTP client access from local network.
|
|
282
|
+
#allow 192.168.0.0/16
|
|
283
|
+
|
|
284
|
+
# Serve time even if not synchronized to a time source.
|
|
285
|
+
#local stratum 10
|
|
286
|
+
|
|
287
|
+
# Specify file containing keys for NTP authentication.
|
|
288
|
+
keyfile /etc/chrony.keys
|
|
289
|
+
|
|
290
|
+
# Get TAI-UTC offset and leap seconds from the system tz database.
|
|
291
|
+
leapsectz right/UTC
|
|
292
|
+
|
|
293
|
+
# Specify directory for log files.
|
|
294
|
+
logdir /var/log/chrony
|
|
295
|
+
|
|
296
|
+
# Select which information is logged.
|
|
297
|
+
#log measurements statistics tracking
|
|
298
|
+
' > ${path} `,
|
|
299
|
+
`sudo systemctl stop chronyd`,
|
|
300
|
+
|
|
301
|
+
// `chronyd -q 'server 0.europe.pool.ntp.org iburst'`,
|
|
302
|
+
`chronyd -q 'server ntp.ubuntu.com iburst'`,
|
|
303
|
+
|
|
304
|
+
`sudo systemctl enable --now chronyd`,
|
|
305
|
+
`sudo systemctl restart chronyd`,
|
|
306
|
+
`sudo systemctl status chronyd`,
|
|
307
|
+
|
|
308
|
+
`chronyc sources`,
|
|
309
|
+
`chronyc tracking`,
|
|
310
|
+
// sudo firewall-cmd --add-service=ntp --permanent
|
|
311
|
+
// sudo firewall-cmd --reload
|
|
312
|
+
|
|
313
|
+
`chronyc sourcestats -v`,
|
|
314
|
+
];
|
|
127
315
|
};
|
|
128
316
|
|
|
129
317
|
try {
|
|
@@ -1158,7 +1346,7 @@ EOF`);
|
|
|
1158
1346
|
}
|
|
1159
1347
|
|
|
1160
1348
|
case 'cli-docs': {
|
|
1161
|
-
buildCliDoc();
|
|
1349
|
+
buildCliDoc(program);
|
|
1162
1350
|
break;
|
|
1163
1351
|
}
|
|
1164
1352
|
|
|
@@ -1210,12 +1398,63 @@ EOF`);
|
|
|
1210
1398
|
break;
|
|
1211
1399
|
}
|
|
1212
1400
|
|
|
1401
|
+
case 'postgresql-17': {
|
|
1402
|
+
if (process.argv.includes('install')) {
|
|
1403
|
+
shellExec(`sudo dnf module reset postgresql -y`);
|
|
1404
|
+
shellExec(`sudo dnf -qy module disable postgresql`);
|
|
1405
|
+
shellExec(
|
|
1406
|
+
`sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm`,
|
|
1407
|
+
);
|
|
1408
|
+
shellExec(`sudo dnf -qy module disable postgresql`);
|
|
1409
|
+
shellExec(`sudo dnf install -y postgresql17 postgresql17-server postgresql17-contrib`);
|
|
1410
|
+
|
|
1411
|
+
shellExec(`sudo /usr/pgsql-17/bin/postgresql-17-setup initdb`);
|
|
1412
|
+
}
|
|
1413
|
+
if (process.argv.includes('uninstall')) {
|
|
1414
|
+
shellExec(`sudo systemctl stop postgresql-17`);
|
|
1415
|
+
shellExec(`sudo systemctl disable postgresql-17`);
|
|
1416
|
+
|
|
1417
|
+
// Remove PostgreSQL 17 packages and repo
|
|
1418
|
+
shellExec(`sudo dnf remove -y postgresql17 postgresql17-server postgresql17-contrib`);
|
|
1419
|
+
shellExec(`sudo rpm -e pgdg-redhat-repo-$(rpm -q pgdg-redhat-repo --qf '%{VERSION}-%{RELEASE}') || true`);
|
|
1420
|
+
shellExec(`sudo rm -f /etc/yum.repos.d/pgdg-redhat-*.repo`);
|
|
1421
|
+
|
|
1422
|
+
// Clean up data, logs, config, and the postgres user
|
|
1423
|
+
shellExec(`sudo rm -rf /var/lib/pgsql/17 /var/log/pgsql`);
|
|
1424
|
+
shellExec(`sudo rm -rf /etc/postgresql`);
|
|
1425
|
+
} else {
|
|
1426
|
+
shellExec(`sudo systemctl enable postgresql-17`);
|
|
1427
|
+
shellExec(`sudo systemctl start postgresql-17`);
|
|
1428
|
+
}
|
|
1429
|
+
break;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1213
1432
|
case 'postgresql-14': {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1433
|
+
if (process.argv.includes('install')) {
|
|
1434
|
+
shellExec(`sudo dnf module reset postgresql -y`);
|
|
1435
|
+
shellExec(`sudo dnf -qy module disable postgresql`);
|
|
1436
|
+
|
|
1437
|
+
shellExec(`sudo systemctl stop postgresql-14`);
|
|
1438
|
+
shellExec(`sudo systemctl disable postgresql-14`);
|
|
1439
|
+
|
|
1440
|
+
shellExec(`sudo dnf remove -y postgresql14 postgresql14-server postgresql14-contrib`);
|
|
1441
|
+
shellExec(`sudo rm -rf /var/lib/pgsql`);
|
|
1442
|
+
|
|
1443
|
+
shellExec(`sudo dnf install postgresql14 postgresql14-server postgresql14-contrib -y`);
|
|
1444
|
+
}
|
|
1445
|
+
if (process.argv.includes('uninstall')) {
|
|
1446
|
+
shellExec(`sudo systemctl stop postgresql-14`);
|
|
1447
|
+
shellExec(`sudo systemctl disable postgresql-14`);
|
|
1448
|
+
shellExec(`sudo dnf remove -y postgresql14 postgresql14-server postgresql14-contrib`);
|
|
1449
|
+
shellExec(`sudo rm -rf /var/lib/pgsql /var/log/pgsql /etc/postgresql`);
|
|
1450
|
+
} else {
|
|
1451
|
+
shellExec(`sudo /usr/pgsql-14/bin/postgresql-14-setup initdb`);
|
|
1452
|
+
shellExec(`sudo systemctl start postgresql-14`);
|
|
1453
|
+
shellExec(`sudo systemctl enable postgresql-14`);
|
|
1454
|
+
shellExec(`sudo systemctl status postgresql-14`);
|
|
1455
|
+
// sudo dnf install postgresql14-contrib
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1219
1458
|
break;
|
|
1220
1459
|
}
|
|
1221
1460
|
|
|
@@ -1252,6 +1491,9 @@ EOF`);
|
|
|
1252
1491
|
}
|
|
1253
1492
|
|
|
1254
1493
|
case 'maas': {
|
|
1494
|
+
shellExec(
|
|
1495
|
+
`underpost secret underpost --create-from-file /home/dd/engine/engine-private/conf/dd-cron/.env.production`,
|
|
1496
|
+
);
|
|
1255
1497
|
dotenv.config({ path: `${getUnderpostRootPath()}/.env`, override: true });
|
|
1256
1498
|
const IP_ADDRESS = getLocalIPv4Address();
|
|
1257
1499
|
const serverip = IP_ADDRESS;
|
|
@@ -1260,6 +1502,13 @@ EOF`);
|
|
|
1260
1502
|
const netmask = process.env.NETMASK;
|
|
1261
1503
|
const gatewayip = process.env.GATEWAY_IP;
|
|
1262
1504
|
|
|
1505
|
+
const machineFactory = (m) => ({
|
|
1506
|
+
system_id: m.interface_set[0].system_id,
|
|
1507
|
+
mac_address: m.interface_set[0].mac_address,
|
|
1508
|
+
hostname: m.hostname,
|
|
1509
|
+
status_name: m.status_name,
|
|
1510
|
+
});
|
|
1511
|
+
|
|
1263
1512
|
let resources;
|
|
1264
1513
|
try {
|
|
1265
1514
|
resources = JSON.parse(
|
|
@@ -1276,13 +1525,6 @@ EOF`);
|
|
|
1276
1525
|
logger.error(error);
|
|
1277
1526
|
}
|
|
1278
1527
|
|
|
1279
|
-
const machineFactory = (m) => ({
|
|
1280
|
-
system_id: m.interface_set[0].system_id,
|
|
1281
|
-
mac_address: m.interface_set[0].mac_address,
|
|
1282
|
-
hostname: m.hostname,
|
|
1283
|
-
status_name: m.status_name,
|
|
1284
|
-
});
|
|
1285
|
-
|
|
1286
1528
|
let machines;
|
|
1287
1529
|
try {
|
|
1288
1530
|
machines = JSON.parse(
|
|
@@ -1295,6 +1537,25 @@ EOF`);
|
|
|
1295
1537
|
logger.error(error);
|
|
1296
1538
|
}
|
|
1297
1539
|
|
|
1540
|
+
if (process.argv.includes('ls')) {
|
|
1541
|
+
shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-sources read`);
|
|
1542
|
+
shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} commissioning-scripts read`);
|
|
1543
|
+
// shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-source-selections read 60`);
|
|
1544
|
+
logger.info('Resources');
|
|
1545
|
+
console.table(resources);
|
|
1546
|
+
logger.info('Machines');
|
|
1547
|
+
console.table(machines);
|
|
1548
|
+
process.exit(0);
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
if (process.argv.includes('config')) {
|
|
1552
|
+
shellExec(`sudo sed -i 's/^#Storage=auto/Storage=volatile/' /etc/systemd/journald.conf`);
|
|
1553
|
+
shellExec(`sudo systemctl daemon-reload`);
|
|
1554
|
+
shellExec(`sudo systemctl restart systemd-journald`);
|
|
1555
|
+
shellExec(`journalctl --disk-usage`);
|
|
1556
|
+
process.exit(0);
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1298
1559
|
if (process.argv.includes('db')) {
|
|
1299
1560
|
// DROP, ALTER, CREATE, WITH ENCRYPTED
|
|
1300
1561
|
// sudo -u <user> -h <host> psql <db-name>
|
|
@@ -1315,20 +1576,13 @@ EOF`);
|
|
|
1315
1576
|
shellExec(`sudo -i -u postgres createdb -O "$DB_PG_MAAS_USER" "$DB_PG_MAAS_NAME"`);
|
|
1316
1577
|
|
|
1317
1578
|
shellExec(`sudo -i -u postgres psql -c "\\l"`);
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
if (process.argv.includes('ls')) {
|
|
1321
|
-
shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-sources read`);
|
|
1322
|
-
shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} commissioning-scripts read`);
|
|
1323
|
-
// shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-source-selections read 60`);
|
|
1324
|
-
console.table(resources);
|
|
1325
|
-
console.table(machines);
|
|
1326
1579
|
process.exit(0);
|
|
1327
1580
|
}
|
|
1328
1581
|
|
|
1329
1582
|
// TODO: - Disable maas proxy (egress forwarding to public dns)
|
|
1583
|
+
// - Configure maas dhcp control server
|
|
1330
1584
|
// - Configure maas dns forwarding ${process.env.MAAS_DNS}
|
|
1331
|
-
// -
|
|
1585
|
+
// - Disable DNSSEC validation to No (Disable DNSSEC; useful when upstream DNS is misconfigured)
|
|
1332
1586
|
|
|
1333
1587
|
if (process.argv.includes('clear')) {
|
|
1334
1588
|
for (const machine of machines) {
|
|
@@ -1370,35 +1624,23 @@ EOF`);
|
|
|
1370
1624
|
pbcopy(cmd);
|
|
1371
1625
|
process.exit(0);
|
|
1372
1626
|
}
|
|
1373
|
-
if (process.argv.includes('dhcp')) {
|
|
1374
|
-
const snippets = JSON.parse(
|
|
1375
|
-
shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} dhcpsnippets read`, {
|
|
1376
|
-
stdout: true,
|
|
1377
|
-
silent: true,
|
|
1378
|
-
disableLog: true,
|
|
1379
|
-
}),
|
|
1380
|
-
);
|
|
1381
|
-
for (const snippet of snippets) {
|
|
1382
|
-
switch (snippet.name) {
|
|
1383
|
-
case 'arm64':
|
|
1384
|
-
snippet.value = snippet.value.split(`\n`);
|
|
1385
|
-
snippet.value[1] = ` filename "http://${IP_ADDRESS}:5248/images/bootloaders/uefi/arm64/grubaa64.efi";`;
|
|
1386
|
-
snippet.value[5] = ` filename "http://${IP_ADDRESS}:5248/images/bootloaders/uefi/arm64/grubaa64.efi";`;
|
|
1387
|
-
snippet.value = snippet.value.join(`\n`);
|
|
1388
|
-
shellExec(
|
|
1389
|
-
`maas ${process.env.MAAS_ADMIN_USERNAME} dhcpsnippet update ${snippet.name} value='${snippet.value}'`,
|
|
1390
|
-
);
|
|
1391
|
-
break;
|
|
1392
1627
|
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1628
|
+
if (process.argv.includes('restart')) {
|
|
1629
|
+
shellExec(`sudo snap restart maas.pebble`);
|
|
1630
|
+
let secs = 0;
|
|
1631
|
+
while (
|
|
1632
|
+
!(
|
|
1633
|
+
shellExec(`maas status`, { silent: true, disableLog: true, stdout: true })
|
|
1634
|
+
.split(' ')
|
|
1635
|
+
.filter((l) => l.match('inactive')).length === 1
|
|
1636
|
+
)
|
|
1637
|
+
) {
|
|
1638
|
+
await timer(1000);
|
|
1639
|
+
console.log(`Waiting... (${++secs}s)`);
|
|
1396
1640
|
}
|
|
1397
|
-
|
|
1398
|
-
console.log(snippets);
|
|
1399
|
-
|
|
1400
1641
|
process.exit(0);
|
|
1401
1642
|
}
|
|
1643
|
+
|
|
1402
1644
|
// shellExec(`MAAS_ADMIN_USERNAME=${process.env.MAAS_ADMIN_USERNAME}`);
|
|
1403
1645
|
// shellExec(`MAAS_ADMIN_EMAIL=${process.env.MAAS_ADMIN_EMAIL}`);
|
|
1404
1646
|
// shellExec(`maas createadmin --username $MAAS_ADMIN_USERNAME --email $MAAS_ADMIN_EMAIL`);
|
|
@@ -1509,7 +1751,7 @@ EOF`);
|
|
|
1509
1751
|
|
|
1510
1752
|
switch (process.argv[3]) {
|
|
1511
1753
|
case 'rpi4mb':
|
|
1512
|
-
const resourceId = process.argv[4] ?? '
|
|
1754
|
+
const resourceId = process.argv[4] ?? '12';
|
|
1513
1755
|
tftpSubDir = '/rpi4mb';
|
|
1514
1756
|
zipFirmwareFileName = `RPi4_UEFI_Firmware_v1.41.zip`;
|
|
1515
1757
|
zipFirmwareName = zipFirmwareFileName.split('.zip')[0];
|
|
@@ -1594,13 +1836,48 @@ EOF`);
|
|
|
1594
1836
|
// 'boot=casper',
|
|
1595
1837
|
// 'ro',
|
|
1596
1838
|
'netboot=nfs',
|
|
1597
|
-
`
|
|
1839
|
+
`init=/sbin/init`,
|
|
1840
|
+
// `cloud-config-url=/dev/null`,
|
|
1598
1841
|
// 'ip=dhcp',
|
|
1599
1842
|
// 'ip=dfcp',
|
|
1600
1843
|
// 'autoinstall',
|
|
1601
1844
|
// 'rd.break',
|
|
1602
1845
|
];
|
|
1603
1846
|
|
|
1847
|
+
// TODO: use autoinstall cloud-config-url=http://<MAAS_IP>:5240/MAAS/metadata/latest
|
|
1848
|
+
// #cloud-config
|
|
1849
|
+
// autoinstall:
|
|
1850
|
+
// version: 1
|
|
1851
|
+
|
|
1852
|
+
// keyboard:
|
|
1853
|
+
// layout: es
|
|
1854
|
+
// variant: latinamerican
|
|
1855
|
+
|
|
1856
|
+
// identity:
|
|
1857
|
+
// hostname: rpi4
|
|
1858
|
+
// username: rpiadmin
|
|
1859
|
+
// password: "{{PASSWORD}}"
|
|
1860
|
+
|
|
1861
|
+
// ssh:
|
|
1862
|
+
// install-server: true
|
|
1863
|
+
// allow-pw: true
|
|
1864
|
+
// authorized-keys:
|
|
1865
|
+
// - "{{SSH_KEY}}"
|
|
1866
|
+
|
|
1867
|
+
// locale: es_ES.UTF-8
|
|
1868
|
+
// timezone: America/Santiago
|
|
1869
|
+
|
|
1870
|
+
// packages:
|
|
1871
|
+
// - cloud-init
|
|
1872
|
+
// - systemd-sysv
|
|
1873
|
+
// - openssh-server
|
|
1874
|
+
// - sudo
|
|
1875
|
+
// - udev
|
|
1876
|
+
// - netplan.io
|
|
1877
|
+
|
|
1878
|
+
// late-commands:
|
|
1879
|
+
// - curtin in-target --target=/target ln -sf /lib/systemd/systemd /sbin/init
|
|
1880
|
+
|
|
1604
1881
|
nfsConnectStr = cmd.join(' ');
|
|
1605
1882
|
bootConf = `[all]
|
|
1606
1883
|
MAC_ADDRESS=00:00:00:00:00:00
|
|
@@ -1618,7 +1895,8 @@ DHCP_TIMEOUT=45000
|
|
|
1618
1895
|
DHCP_REQ_TIMEOUT=4000
|
|
1619
1896
|
TFTP_FILE_TIMEOUT=30000
|
|
1620
1897
|
BOOT_ORDER=0x21`;
|
|
1621
|
-
|
|
1898
|
+
// CLIENT_IP=${ipaddr}
|
|
1899
|
+
// SUBNET=255.255.255.0
|
|
1622
1900
|
break;
|
|
1623
1901
|
|
|
1624
1902
|
default:
|
|
@@ -1635,21 +1913,6 @@ BOOT_ORDER=0x21`;
|
|
|
1635
1913
|
|
|
1636
1914
|
shellExec(`node bin/deploy nfs`);
|
|
1637
1915
|
|
|
1638
|
-
if (process.argv.includes('restart')) {
|
|
1639
|
-
shellExec(`sudo snap restart maas.pebble`);
|
|
1640
|
-
let secs = 0;
|
|
1641
|
-
while (
|
|
1642
|
-
!(
|
|
1643
|
-
shellExec(`maas status`, { silent: true, disableLog: true, stdout: true })
|
|
1644
|
-
.split(' ')
|
|
1645
|
-
.filter((l) => l.match('inactive')).length === 1
|
|
1646
|
-
)
|
|
1647
|
-
) {
|
|
1648
|
-
await timer(1000);
|
|
1649
|
-
console.log(`Waiting... (${++secs}s)`);
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
|
|
1653
1916
|
switch (process.argv[3]) {
|
|
1654
1917
|
case 'rpi4mb':
|
|
1655
1918
|
{
|
|
@@ -1815,9 +2078,12 @@ BOOT_ORDER=0x21`;
|
|
|
1815
2078
|
newMachine = machineFactory(JSON.parse(newMachine));
|
|
1816
2079
|
machines.push(newMachine);
|
|
1817
2080
|
console.log(newMachine);
|
|
1818
|
-
shellExec(
|
|
1819
|
-
|
|
1820
|
-
|
|
2081
|
+
shellExec(
|
|
2082
|
+
`maas ${process.env.MAAS_ADMIN_USERNAME} machine commission ${newMachine.system_id} enable_ssh=1 commissioning_scripts=90-verify-user.sh skip_bmc_config=1 skip_networking=1 skip_storage=1`,
|
|
2083
|
+
{
|
|
2084
|
+
silent: true,
|
|
2085
|
+
},
|
|
2086
|
+
);
|
|
1821
2087
|
} catch (error) {
|
|
1822
2088
|
logger.error(error, error.stack);
|
|
1823
2089
|
}
|
|
@@ -1925,6 +2191,7 @@ udp-port = 32766
|
|
|
1925
2191
|
host,
|
|
1926
2192
|
nfsHostPath,
|
|
1927
2193
|
ipaddr,
|
|
2194
|
+
update: true,
|
|
1928
2195
|
});
|
|
1929
2196
|
break;
|
|
1930
2197
|
}
|
|
@@ -1963,7 +2230,7 @@ udp-port = 32766
|
|
|
1963
2230
|
`--arch=arm64`,
|
|
1964
2231
|
`--variant=minbase`,
|
|
1965
2232
|
`--foreign`, // arm64 on amd64
|
|
1966
|
-
`noble`,
|
|
2233
|
+
[`noble`, `jammy`][0],
|
|
1967
2234
|
nfsHostPath,
|
|
1968
2235
|
`http://ports.ubuntu.com/ubuntu-ports/`,
|
|
1969
2236
|
];
|
|
@@ -1995,8 +2262,10 @@ EOF`);
|
|
|
1995
2262
|
}
|
|
1996
2263
|
if (process.argv.includes('mount')) {
|
|
1997
2264
|
shellExec(`sudo mount --bind /proc ${nfsHostPath}/proc`);
|
|
1998
|
-
shellExec(`sudo mount --bind /sys
|
|
1999
|
-
shellExec(`sudo mount --rbind /dev
|
|
2265
|
+
shellExec(`sudo mount --bind /sys ${nfsHostPath}/sys`);
|
|
2266
|
+
shellExec(`sudo mount --rbind /dev ${nfsHostPath}/dev`);
|
|
2267
|
+
shellExec(`sudo mount --rbind /dev/pts ${nfsHostPath}/dev/pts`);
|
|
2268
|
+
shellExec(`sudo mount --bind /run ${nfsHostPath}/run`);
|
|
2000
2269
|
}
|
|
2001
2270
|
|
|
2002
2271
|
if (process.argv.includes('build')) {
|
|
@@ -2031,6 +2300,7 @@ EOF`);
|
|
|
2031
2300
|
const nfsHostPath = `${process.env.NFS_EXPORT_PATH}/${host}`;
|
|
2032
2301
|
shellExec(`sudo umount ${nfsHostPath}/proc`);
|
|
2033
2302
|
shellExec(`sudo umount ${nfsHostPath}/sys`);
|
|
2303
|
+
shellExec(`sudo umount ${nfsHostPath}/dev/pts`);
|
|
2034
2304
|
shellExec(`sudo umount ${nfsHostPath}/dev`);
|
|
2035
2305
|
// shellExec(`sudo umount ${nfsHostPath}/lib/modules`);
|
|
2036
2306
|
break;
|
|
@@ -2425,6 +2695,14 @@ nvidia/gpu-operator \
|
|
|
2425
2695
|
// sudo yum install sbt
|
|
2426
2696
|
break;
|
|
2427
2697
|
}
|
|
2698
|
+
|
|
2699
|
+
case 'chrony': {
|
|
2700
|
+
shellExec(`sudo dnf install chrony -y`);
|
|
2701
|
+
// debian chroot: sudo apt install chrony
|
|
2702
|
+
for (const cmd of chronySetUp(`/etc/chrony.conf`)) shellExec(cmd);
|
|
2703
|
+
|
|
2704
|
+
break;
|
|
2705
|
+
}
|
|
2428
2706
|
}
|
|
2429
2707
|
} catch (error) {
|
|
2430
2708
|
logger.error(error, error.stack);
|