underpost 2.8.815 → 2.8.817
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 +1 -1
- package/bin/deploy.js +280 -145
- package/cli.md +1 -1
- package/docker-compose.yml +1 -1
- package/manifests/deployment/dd-template-development/deployment.yaml +2 -2
- package/manifests/maas/maas-setup.sh +1 -0
- package/package.json +1 -1
- package/src/index.js +1 -1
package/README.md
CHANGED
package/bin/deploy.js
CHANGED
|
@@ -69,7 +69,9 @@ const keyboardSteps = [
|
|
|
69
69
|
`sudo dpkg-reconfigure --frontend noninteractive keyboard-configuration`,
|
|
70
70
|
`sudo systemctl restart keyboard-setup.service`,
|
|
71
71
|
];
|
|
72
|
-
|
|
72
|
+
|
|
73
|
+
const kernelLibVersion = `6.8.0-41-generic`;
|
|
74
|
+
|
|
73
75
|
const installSteps = [
|
|
74
76
|
`cat <<EOF | tee /etc/apt/sources.list
|
|
75
77
|
deb http://ports.ubuntu.com/ubuntu-ports noble main restricted universe multiverse
|
|
@@ -79,7 +81,11 @@ EOF`,
|
|
|
79
81
|
|
|
80
82
|
`apt update -qq`,
|
|
81
83
|
`apt -y full-upgrade`,
|
|
82
|
-
`apt install -y xinput x11-xkb-utils usbutils`,
|
|
84
|
+
`apt install -y build-essential xinput x11-xkb-utils usbutils`,
|
|
85
|
+
'apt install -y linux-image-generic',
|
|
86
|
+
`apt install -y linux-modules-${kernelLibVersion} linux-modules-extra-${kernelLibVersion}`,
|
|
87
|
+
|
|
88
|
+
`depmod -a ${kernelLibVersion}`,
|
|
83
89
|
// `apt install -y cloud-init=25.1.2-0ubuntu0~24.04.1`,
|
|
84
90
|
`apt install -y cloud-init systemd-sysv openssh-server sudo locales udev util-linux systemd-sysv iproute2 netplan.io ca-certificates curl wget chrony`,
|
|
85
91
|
`ln -sf /lib/systemd/systemd /sbin/init`,
|
|
@@ -89,12 +95,31 @@ EOF`,
|
|
|
89
95
|
`DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata kmod keyboard-configuration console-setup iputils-ping`,
|
|
90
96
|
];
|
|
91
97
|
|
|
98
|
+
const bootCmdSteps = [
|
|
99
|
+
`/underpost/dns.sh`,
|
|
100
|
+
`/underpost/host.sh`,
|
|
101
|
+
// `/underpost/date.sh`,
|
|
102
|
+
`cp -a /underpost/90_maas.cfg /etc/cloud/cloud.cfg.d/90_maas.cfg`,
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
const cloudInitReset = `sudo cloud-init clean --logs --seed --configs all --machine-id
|
|
106
|
+
sudo rm -rf /var/lib/cloud/*`;
|
|
107
|
+
|
|
108
|
+
const cloudConfigCmdRunFactory = (steps = []) =>
|
|
109
|
+
steps
|
|
110
|
+
.map(
|
|
111
|
+
(step, i, a) =>
|
|
112
|
+
' - echo "\\$(date) | ' + (i + 1) + '/' + a.length + ' - ' + step.split('\n')[0] + '"' + `\n` + ` - ${step}`,
|
|
113
|
+
)
|
|
114
|
+
.join('\n');
|
|
115
|
+
|
|
92
116
|
const cloudConfigFactory = (
|
|
93
|
-
{ IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip },
|
|
94
|
-
{ consumer_key,
|
|
117
|
+
{ IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip, reset },
|
|
118
|
+
{ consumer_key, consumer_secret, token_key, token_secret },
|
|
119
|
+
path = '/etc/cloud/cloud.cfg.d/90_maas.cfg',
|
|
95
120
|
) => [
|
|
96
121
|
// Configure cloud-init for MAAS
|
|
97
|
-
`cat <<EOF_MAAS_CFG >
|
|
122
|
+
`cat <<EOF_MAAS_CFG > ${path}
|
|
98
123
|
#cloud-config
|
|
99
124
|
|
|
100
125
|
hostname: ${host}
|
|
@@ -112,16 +137,24 @@ hostname: ${host}
|
|
|
112
137
|
datasource_list: [ MAAS ]
|
|
113
138
|
datasource:
|
|
114
139
|
MAAS:
|
|
115
|
-
metadata_url: http://${IP_ADDRESS}:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
140
|
+
metadata_url: http://${IP_ADDRESS}:5240/MAAS/metadata/
|
|
141
|
+
${
|
|
142
|
+
reset
|
|
143
|
+
? ''
|
|
144
|
+
: `consumer_key: ${consumer_key}
|
|
145
|
+
consumer_secret: ${consumer_secret}
|
|
146
|
+
token_key: ${token_key}
|
|
147
|
+
token_secret: ${token_secret}`
|
|
148
|
+
}
|
|
149
|
+
|
|
119
150
|
|
|
120
151
|
users:
|
|
121
|
-
- name:
|
|
152
|
+
- name: ${process.env.MAAS_ADMIN_USERNAME}
|
|
122
153
|
sudo: ['ALL=(ALL) NOPASSWD:ALL']
|
|
123
154
|
shell: /bin/bash
|
|
124
|
-
lock_passwd:
|
|
155
|
+
lock_passwd: false
|
|
156
|
+
groups: sudo,users,admin,wheel,lxd
|
|
157
|
+
plain_text_passwd: '${process.env.MAAS_ADMIN_USERNAME}'
|
|
125
158
|
ssh_authorized_keys:
|
|
126
159
|
- ${fs.readFileSync(`/home/dd/engine/engine-private/deploy/id_rsa.pub`, 'utf8')}
|
|
127
160
|
|
|
@@ -134,18 +167,15 @@ users:
|
|
|
134
167
|
|
|
135
168
|
# check timedatectl on host
|
|
136
169
|
# timezone: America/Santiago
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
# packages:
|
|
147
|
-
# - chrony
|
|
148
|
-
# service_name: chrony
|
|
170
|
+
timezone: ${timezone}
|
|
171
|
+
|
|
172
|
+
ntp:
|
|
173
|
+
enabled: true
|
|
174
|
+
servers:
|
|
175
|
+
- ${process.env.MAAS_NTP_SERVER}
|
|
176
|
+
ntp_client: chrony
|
|
177
|
+
config:
|
|
178
|
+
confpath: ${chronyConfPath}
|
|
149
179
|
|
|
150
180
|
# ssh:
|
|
151
181
|
# allow-pw: false
|
|
@@ -159,16 +189,17 @@ packages:
|
|
|
159
189
|
- git
|
|
160
190
|
- htop
|
|
161
191
|
- snapd
|
|
192
|
+
- chrony
|
|
162
193
|
resize_rootfs: false
|
|
163
194
|
growpart:
|
|
164
|
-
mode:
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
195
|
+
mode: false
|
|
196
|
+
network:
|
|
197
|
+
version: 2
|
|
198
|
+
ethernets:
|
|
199
|
+
${process.env.RPI4_INTERFACE_NAME}:
|
|
200
|
+
dhcp4: true
|
|
201
|
+
addresses:
|
|
202
|
+
- ${ipaddr}/24
|
|
172
203
|
# routes:
|
|
173
204
|
# - to: default
|
|
174
205
|
# via: ${gatewayip}
|
|
@@ -178,7 +209,7 @@ growpart:
|
|
|
178
209
|
# users:
|
|
179
210
|
# - {name: root, password: changeme, type: text}
|
|
180
211
|
|
|
181
|
-
final_message: "
|
|
212
|
+
final_message: "====== Cloud init finished ======"
|
|
182
213
|
|
|
183
214
|
# power_state:
|
|
184
215
|
# mode: reboot
|
|
@@ -189,10 +220,53 @@ bootcmd:
|
|
|
189
220
|
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
|
|
190
221
|
- echo "Init bootcmd"
|
|
191
222
|
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
|
|
223
|
+
${cloudConfigCmdRunFactory(bootCmdSteps)}
|
|
192
224
|
runcmd:
|
|
193
225
|
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
|
|
194
226
|
- echo "Init runcmd"
|
|
195
227
|
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
|
|
228
|
+
|
|
229
|
+
# If this is set, 'root' will not be able to ssh in and they
|
|
230
|
+
# will get a message to login instead as the default $user
|
|
231
|
+
disable_root: true
|
|
232
|
+
|
|
233
|
+
# This will cause the set+update hostname module to not operate (if true)
|
|
234
|
+
preserve_hostname: false
|
|
235
|
+
|
|
236
|
+
# The modules that run in the 'init' stage
|
|
237
|
+
cloud_init_modules:
|
|
238
|
+
- migrator
|
|
239
|
+
- bootcmd
|
|
240
|
+
- write-files
|
|
241
|
+
- growpart
|
|
242
|
+
- resizefs
|
|
243
|
+
- set_hostname
|
|
244
|
+
- update_etc_hosts
|
|
245
|
+
- rsyslog
|
|
246
|
+
- users-groups
|
|
247
|
+
- ssh
|
|
248
|
+
|
|
249
|
+
cloud_config_modules:
|
|
250
|
+
- mounts
|
|
251
|
+
- locale
|
|
252
|
+
- set-passwords
|
|
253
|
+
- package-update-upgrade-install
|
|
254
|
+
- timezone
|
|
255
|
+
- runcmd
|
|
256
|
+
- ssh-import-id
|
|
257
|
+
- ntp
|
|
258
|
+
|
|
259
|
+
cloud_final_modules:
|
|
260
|
+
- rightscale_userdata
|
|
261
|
+
- scripts-per-once
|
|
262
|
+
- scripts-per-boot
|
|
263
|
+
- scripts-per-instance
|
|
264
|
+
- scripts-user
|
|
265
|
+
- ssh-authkey-fingerprints
|
|
266
|
+
- keys-to-console
|
|
267
|
+
- phone-home
|
|
268
|
+
- final-message
|
|
269
|
+
|
|
196
270
|
EOF_MAAS_CFG`,
|
|
197
271
|
];
|
|
198
272
|
|
|
@@ -211,7 +285,9 @@ EOF_OUTER`;
|
|
|
211
285
|
shellExec(cmd);
|
|
212
286
|
};
|
|
213
287
|
|
|
214
|
-
const chronySetUp = (path) => {
|
|
288
|
+
const chronySetUp = (path, alias = 'chrony') => {
|
|
289
|
+
// use alias = 'chronyd' for RHEL
|
|
290
|
+
// use alias = 'chrony' for Ubuntu
|
|
215
291
|
return [
|
|
216
292
|
`echo '
|
|
217
293
|
# Use public servers from the pool.ntp.org project.
|
|
@@ -254,25 +330,25 @@ logdir /var/log/chrony
|
|
|
254
330
|
# Select which information is logged.
|
|
255
331
|
#log measurements statistics tracking
|
|
256
332
|
' > ${path} `,
|
|
257
|
-
`
|
|
333
|
+
`systemctl stop ${alias}`,
|
|
334
|
+
|
|
335
|
+
`${alias}d -q 'server ntp.ubuntu.com iburst'`,
|
|
258
336
|
|
|
259
337
|
// `chronyd -q 'server 0.europe.pool.ntp.org iburst'`,
|
|
260
|
-
`chronyd -q 'server ntp.ubuntu.com iburst'`,
|
|
261
338
|
|
|
262
|
-
`sudo systemctl enable --now
|
|
263
|
-
`sudo systemctl restart
|
|
264
|
-
`sudo systemctl status
|
|
339
|
+
`sudo systemctl enable --now ${alias}`,
|
|
340
|
+
`sudo systemctl restart ${alias}`,
|
|
341
|
+
`sudo systemctl status ${alias}`,
|
|
265
342
|
|
|
266
343
|
`chronyc sources`,
|
|
267
344
|
`chronyc tracking`,
|
|
268
|
-
// sudo firewall-cmd --add-service=ntp --permanent
|
|
269
|
-
// sudo firewall-cmd --reload
|
|
270
345
|
|
|
271
346
|
`chronyc sourcestats -v`,
|
|
347
|
+
`timedatectl status`,
|
|
272
348
|
];
|
|
273
349
|
};
|
|
274
350
|
|
|
275
|
-
const installUbuntuUnderpostTools = (nfsHostPath) => {
|
|
351
|
+
const installUbuntuUnderpostTools = ({ nfsHostPath, host }) => {
|
|
276
352
|
fs.mkdirSync(`${nfsHostPath}/underpost`, { recursive: true });
|
|
277
353
|
|
|
278
354
|
logger.info('Build', `${nfsHostPath}/underpost/date.sh`);
|
|
@@ -284,6 +360,20 @@ ${chronySetUp(chronyConfPath).join('\n')}
|
|
|
284
360
|
'utf8',
|
|
285
361
|
);
|
|
286
362
|
|
|
363
|
+
logger.info('Build', `${nfsHostPath}/underpost/host.sh`);
|
|
364
|
+
fs.writeFileSync(
|
|
365
|
+
`${nfsHostPath}/underpost/host.sh`,
|
|
366
|
+
`echo -e "127.0.0.1 localhost\n127.0.1.1 ${host}" | tee -a /etc/hosts`,
|
|
367
|
+
'utf8',
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
logger.info('Build', `${nfsHostPath}/underpost/keys.sh`);
|
|
371
|
+
fs.writeFileSync(
|
|
372
|
+
`${nfsHostPath}/underpost/keys.sh`,
|
|
373
|
+
`cat /etc/cloud/cloud.cfg.d/90_maas.cfg | grep -C 5 'metadata'`,
|
|
374
|
+
'utf8',
|
|
375
|
+
);
|
|
376
|
+
|
|
287
377
|
logger.info('Build', `${nfsHostPath}/underpost/keyboard.sh`);
|
|
288
378
|
fs.writeFileSync(
|
|
289
379
|
`${nfsHostPath}/underpost/keyboard.sh`,
|
|
@@ -302,11 +392,30 @@ ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf`,
|
|
|
302
392
|
'utf8',
|
|
303
393
|
);
|
|
304
394
|
|
|
395
|
+
logger.info('Build', `${nfsHostPath}/underpost/start.sh`);
|
|
396
|
+
fs.writeFileSync(
|
|
397
|
+
`${nfsHostPath}/underpost/start.sh`,
|
|
398
|
+
`#!/bin/bash
|
|
399
|
+
set -x
|
|
400
|
+
sudo cloud-init --all-stages
|
|
401
|
+
`,
|
|
402
|
+
'utf8',
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
logger.info('Build', `${nfsHostPath}/underpost/reset.sh`);
|
|
406
|
+
fs.writeFileSync(
|
|
407
|
+
`${nfsHostPath}/underpost/reset.sh`,
|
|
408
|
+
`${cloudInitReset}
|
|
409
|
+
${bootCmdSteps.join('\n')}`,
|
|
410
|
+
'utf8',
|
|
411
|
+
);
|
|
412
|
+
|
|
305
413
|
logger.info('Build', `${nfsHostPath}/underpost/help.sh`);
|
|
306
414
|
fs.writeFileSync(
|
|
307
415
|
`${nfsHostPath}/underpost/help.sh`,
|
|
308
416
|
`echo "=== Cloud init utils ==="
|
|
309
417
|
echo "sudo cloud-init --all-stages"
|
|
418
|
+
echo "sudo cloud-init clean --logs --seed --configs all --machine-id --reboot"
|
|
310
419
|
echo "sudo cloud-init init --local"
|
|
311
420
|
echo "sudo cloud-init init"
|
|
312
421
|
echo "sudo cloud-init modules --mode=config"
|
|
@@ -342,7 +451,12 @@ cut -d: -f1 /etc/passwd
|
|
|
342
451
|
`chmod +x /underpost/dns.sh`,
|
|
343
452
|
`chmod +x /underpost/help.sh`,
|
|
344
453
|
`chmod +x /underpost/config-path.sh`,
|
|
454
|
+
`chmod +x /underpost/host.sh`,
|
|
455
|
+
`chmod +x /underpost/keys.sh`,
|
|
345
456
|
`chmod +x /underpost/test.sh`,
|
|
457
|
+
`chmod +x /underpost/start.sh`,
|
|
458
|
+
`chmod +x /underpost/reset.sh`,
|
|
459
|
+
chronySetUp(chronyConfPath)[0],
|
|
346
460
|
`sudo chmod 700 ~/.ssh/`,
|
|
347
461
|
`sudo chmod 600 ~/.ssh/authorized_keys`,
|
|
348
462
|
`sudo chmod 644 ~/.ssh/known_hosts`,
|
|
@@ -355,29 +469,38 @@ cut -d: -f1 /etc/passwd
|
|
|
355
469
|
|
|
356
470
|
const updateVirtualRoot = async ({ IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip }) => {
|
|
357
471
|
// <consumer_key>:<consumer_token>:<secret>
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
:
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
472
|
+
// <consumer_key>:<consumer_secret>:<token_key>:<token_secret>
|
|
473
|
+
// maas apikey --with-names --username ${process.env.MAAS_ADMIN_USERNAME}
|
|
474
|
+
// maas ${process.env.MAAS_ADMIN_USERNAME} account create-authorisation-token
|
|
475
|
+
// maas apikey --generate --username ${process.env.MAAS_ADMIN_USERNAME}
|
|
476
|
+
// https://github.com/CanonicalLtd/maas-docs/issues/647
|
|
477
|
+
|
|
478
|
+
const parts = shellExec(`maas apikey --with-names --username ${process.env.MAAS_ADMIN_USERNAME}`, {
|
|
479
|
+
stdout: true,
|
|
480
|
+
})
|
|
481
|
+
.trim()
|
|
482
|
+
.split(`\n`)[0]
|
|
483
|
+
.split(':');
|
|
484
|
+
|
|
485
|
+
let consumer_key, consumer_secret, token_key, token_secret;
|
|
486
|
+
|
|
487
|
+
if (parts.length === 4) {
|
|
488
|
+
[consumer_key, consumer_secret, token_key, token_secret] = parts;
|
|
489
|
+
} else if (parts.length === 3) {
|
|
490
|
+
[consumer_key, token_key, token_secret] = parts;
|
|
491
|
+
consumer_secret = '""';
|
|
492
|
+
token_secret = token_secret.split(' MAAS consumer')[0].trim();
|
|
493
|
+
} else {
|
|
494
|
+
throw new Error('Invalid token format');
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
logger.info('Maas api token generated', { consumer_key, consumer_secret, token_key, token_secret });
|
|
374
498
|
|
|
375
499
|
if (update) {
|
|
376
500
|
// --reboot
|
|
377
501
|
if (process.argv.includes('reset'))
|
|
378
502
|
shellExec(`sudo chroot ${nfsHostPath} /usr/bin/qemu-aarch64-static /bin/bash <<'EOF'
|
|
379
|
-
|
|
380
|
-
sudo rm -rf /var/lib/cloud/*
|
|
503
|
+
${cloudInitReset}
|
|
381
504
|
EOF`);
|
|
382
505
|
|
|
383
506
|
if (fs.existsSync(`${nfsHostPath}/var/log/`)) {
|
|
@@ -410,15 +533,38 @@ EOF`);
|
|
|
410
533
|
runSteps(
|
|
411
534
|
nfsHostPath,
|
|
412
535
|
cloudConfigFactory(
|
|
413
|
-
{ IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip },
|
|
414
536
|
{
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
537
|
+
reset: process.argv.includes('reset') ? true : false,
|
|
538
|
+
IP_ADDRESS,
|
|
539
|
+
architecture,
|
|
540
|
+
host,
|
|
541
|
+
nfsHostPath,
|
|
542
|
+
ipaddr,
|
|
543
|
+
update,
|
|
544
|
+
gatewayip,
|
|
418
545
|
},
|
|
546
|
+
{ consumer_key, consumer_secret, token_key, token_secret },
|
|
419
547
|
),
|
|
420
548
|
);
|
|
421
|
-
|
|
549
|
+
|
|
550
|
+
runSteps(
|
|
551
|
+
nfsHostPath,
|
|
552
|
+
cloudConfigFactory(
|
|
553
|
+
{
|
|
554
|
+
IP_ADDRESS,
|
|
555
|
+
architecture,
|
|
556
|
+
host,
|
|
557
|
+
nfsHostPath,
|
|
558
|
+
ipaddr,
|
|
559
|
+
update,
|
|
560
|
+
gatewayip,
|
|
561
|
+
},
|
|
562
|
+
{ consumer_key, consumer_secret, token_key, token_secret },
|
|
563
|
+
'/underpost/90_maas.cfg',
|
|
564
|
+
),
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
installUbuntuUnderpostTools({ nfsHostPath, host });
|
|
422
568
|
};
|
|
423
569
|
|
|
424
570
|
try {
|
|
@@ -1604,7 +1750,9 @@ EOF`);
|
|
|
1604
1750
|
dotenv.config({ path: `${getUnderpostRootPath()}/.env`, override: true });
|
|
1605
1751
|
const IP_ADDRESS = getLocalIPv4Address();
|
|
1606
1752
|
const serverip = IP_ADDRESS;
|
|
1607
|
-
const tftpRoot = process.
|
|
1753
|
+
const tftpRoot = process.argv.includes('v3.0')
|
|
1754
|
+
? `/var/snap/maas/common/maas/boot-resources/snapshot-20250720-162718`
|
|
1755
|
+
: process.env.TFTP_ROOT;
|
|
1608
1756
|
const ipaddr = process.env.RPI4_IP;
|
|
1609
1757
|
const netmask = process.env.NETMASK;
|
|
1610
1758
|
const gatewayip = process.env.GATEWAY_IP;
|
|
@@ -1854,7 +2002,9 @@ EOF`);
|
|
|
1854
2002
|
zipFirmwareName,
|
|
1855
2003
|
zipFirmwareUrl,
|
|
1856
2004
|
interfaceName,
|
|
1857
|
-
nfsHost
|
|
2005
|
+
nfsHost,
|
|
2006
|
+
bootResourcesPath,
|
|
2007
|
+
bootKernelPath;
|
|
1858
2008
|
|
|
1859
2009
|
switch (process.argv[3]) {
|
|
1860
2010
|
case 'rpi4mb':
|
|
@@ -1872,7 +2022,7 @@ EOF`);
|
|
|
1872
2022
|
resource = resources.find((o) => o.architecture === 'arm64/ga-24.04' && o.name === 'ubuntu/noble');
|
|
1873
2023
|
name = resource.name;
|
|
1874
2024
|
architecture = resource.architecture;
|
|
1875
|
-
resource = resources.find((o) => o.name === name && o.architecture === architecture);
|
|
2025
|
+
// resource = resources.find((o) => o.name === name && o.architecture === architecture);
|
|
1876
2026
|
nfsServerRootPath = `${process.env.NFS_EXPORT_PATH}/rpi4mb`;
|
|
1877
2027
|
// ,anonuid=1001,anongid=100
|
|
1878
2028
|
// etcExports = `${nfsServerRootPath} *(rw,all_squash,sync,no_root_squash,insecure)`;
|
|
@@ -1884,21 +2034,33 @@ EOF`);
|
|
|
1884
2034
|
'no_subtree_check',
|
|
1885
2035
|
'insecure',
|
|
1886
2036
|
]})`;
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
2037
|
+
if (process.argv.includes('v3.0')) {
|
|
2038
|
+
bootResourcesPath = `/var/snap/maas/common/maas/boot-resources/snapshot-20250720-162718`;
|
|
2039
|
+
bootKernelPath = `/var/snap/maas/common/maas/boot-resources/snapshot-20250720-162718/ubuntu/arm64/hwe-24.04/noble/stable`;
|
|
2040
|
+
kernelFilesPaths = {
|
|
2041
|
+
'vmlinuz-efi': `${bootKernelPath}/boot-kernel`,
|
|
2042
|
+
'initrd.img': `${bootKernelPath}/boot-initrd`,
|
|
2043
|
+
squashfs: `${bootKernelPath}/squashfs`,
|
|
2044
|
+
};
|
|
2045
|
+
} else {
|
|
2046
|
+
const resourceData = JSON.parse(
|
|
2047
|
+
shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-resource read ${resource.id}`, {
|
|
2048
|
+
stdout: true,
|
|
2049
|
+
silent: true,
|
|
2050
|
+
disableLog: true,
|
|
2051
|
+
}),
|
|
2052
|
+
);
|
|
2053
|
+
const bootFiles = resourceData.sets[Object.keys(resourceData.sets)[0]].files;
|
|
2054
|
+
const suffix = architecture.match('xgene') ? '.xgene' : '';
|
|
2055
|
+
bootResourcesPath = `/var/snap/maas/common/maas/image-storage/bootloaders/uefi/arm64`;
|
|
2056
|
+
bootKernelPath = `/var/snap/maas/common/maas/image-storage`;
|
|
2057
|
+
kernelFilesPaths = {
|
|
2058
|
+
'vmlinuz-efi': `${bootKernelPath}/${bootFiles['boot-kernel' + suffix].filename_on_disk}`,
|
|
2059
|
+
'initrd.img': `${bootKernelPath}/${bootFiles['boot-initrd' + suffix].filename_on_disk}`,
|
|
2060
|
+
squashfs: `${bootKernelPath}/${bootFiles['squashfs'].filename_on_disk}`,
|
|
2061
|
+
};
|
|
2062
|
+
}
|
|
1896
2063
|
|
|
1897
|
-
kernelFilesPaths = {
|
|
1898
|
-
'vmlinuz-efi': bootFiles['boot-kernel' + suffix].filename_on_disk,
|
|
1899
|
-
'initrd.img': bootFiles['boot-initrd' + suffix].filename_on_disk,
|
|
1900
|
-
squashfs: bootFiles['squashfs'].filename_on_disk,
|
|
1901
|
-
};
|
|
1902
2064
|
const protocol = 'tcp'; // v3 -> tcp, v4 -> udp
|
|
1903
2065
|
|
|
1904
2066
|
const mountOptions = [
|
|
@@ -1925,6 +2087,7 @@ EOF`);
|
|
|
1925
2087
|
];
|
|
1926
2088
|
const cmd = [
|
|
1927
2089
|
`console=serial0,115200`,
|
|
2090
|
+
// `console=ttyAMA0,115200`,
|
|
1928
2091
|
`console=tty1`,
|
|
1929
2092
|
// `initrd=-1`,
|
|
1930
2093
|
// `net.ifnames=0`,
|
|
@@ -1948,6 +2111,12 @@ EOF`);
|
|
|
1948
2111
|
// 'ip=dfcp',
|
|
1949
2112
|
// 'autoinstall',
|
|
1950
2113
|
// 'rd.break',
|
|
2114
|
+
|
|
2115
|
+
// Disable services that not apply over nfs
|
|
2116
|
+
`systemd.mask=systemd-network-generator.service`,
|
|
2117
|
+
`systemd.mask=systemd-networkd.service`,
|
|
2118
|
+
`systemd.mask=systemd-fsck-root.service`,
|
|
2119
|
+
`systemd.mask=systemd-udev-trigger.service`,
|
|
1951
2120
|
];
|
|
1952
2121
|
|
|
1953
2122
|
// TODO: use autoinstall cloud-config-url=http://<MAAS_IP>:5240/MAAS/metadata/latest
|
|
@@ -2022,52 +2191,18 @@ BOOT_ORDER=0x21`;
|
|
|
2022
2191
|
switch (process.argv[3]) {
|
|
2023
2192
|
case 'rpi4mb':
|
|
2024
2193
|
{
|
|
2025
|
-
// subnet DHCP snippets
|
|
2026
|
-
// # UEFI ARM64
|
|
2027
|
-
// if option arch = 00:0B {
|
|
2028
|
-
// filename "rpi4mb/pxe/grubaa64.efi";
|
|
2029
|
-
// }
|
|
2030
|
-
// elsif option arch = 00:13 {
|
|
2031
|
-
// filename "http://<IP_ADDRESS>:5248/images/bootloaders/uefi/arm64/grubaa64.efi";
|
|
2032
|
-
// option vendor-class-identifier "HTTPClient";
|
|
2033
|
-
// }
|
|
2034
2194
|
for (const file of ['bootaa64.efi', 'grubaa64.efi']) {
|
|
2035
|
-
shellExec(
|
|
2036
|
-
`sudo cp -a /var/snap/maas/common/maas/image-storage/bootloaders/uefi/arm64/${file} ${tftpRoot}${tftpSubDir}/pxe/${file}`,
|
|
2037
|
-
);
|
|
2195
|
+
shellExec(`sudo cp -a ${bootResourcesPath}/${file} ${tftpRoot}${tftpSubDir}/pxe/${file}`);
|
|
2038
2196
|
}
|
|
2039
|
-
// const file = 'bcm2711-rpi-4-b.dtb';
|
|
2040
|
-
// shellExec(
|
|
2041
|
-
// `sudo cp -a ${firmwarePath}/${file} /var/snap/maas/common/maas/image-storage/bootloaders/uefi/arm64/${file}`,
|
|
2042
|
-
// );
|
|
2043
|
-
|
|
2044
|
-
// const ipxeSrc = fs
|
|
2045
|
-
// .readFileSync(`${tftpRoot}/ipxe.cfg`, 'utf8')
|
|
2046
|
-
// .replaceAll('amd64', 'arm64')
|
|
2047
|
-
// .replaceAll('${next-server}', IP_ADDRESS);
|
|
2048
|
-
// fs.writeFileSync(`${tftpRoot}/ipxe.cfg`, ipxeSrc, 'utf8');
|
|
2049
2197
|
|
|
2050
2198
|
{
|
|
2051
2199
|
for (const file of Object.keys(kernelFilesPaths)) {
|
|
2052
|
-
shellExec(
|
|
2053
|
-
`sudo cp -a /var/snap/maas/common/maas/image-storage/${kernelFilesPaths[file]} ${tftpRoot}${tftpSubDir}/pxe/${file}`,
|
|
2054
|
-
);
|
|
2200
|
+
shellExec(`sudo cp -a ${kernelFilesPaths[file]} ${tftpRoot}${tftpSubDir}/pxe/${file}`);
|
|
2055
2201
|
}
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
// .replace(`kernel=kernel8.img`, `kernel=vmlinuz`)
|
|
2061
|
-
// .replace(`# max_framebuffers=2`, `max_framebuffers=2`)
|
|
2062
|
-
// .replace(`initramfs initramfs8 followkernel`, `initramfs initrd.img followkernel`),
|
|
2063
|
-
// 'utf8',
|
|
2064
|
-
// );
|
|
2065
|
-
|
|
2066
|
-
// grub:
|
|
2067
|
-
// set root=(pxe)
|
|
2068
|
-
|
|
2069
|
-
// UNDERPOST.NET UEFI/GRUB/MAAS RPi4 commissioning (ARM64)
|
|
2070
|
-
const menuentryStr = 'underpost.net rpi4mb maas commissioning (ARM64)';
|
|
2202
|
+
|
|
2203
|
+
fs.mkdirSync(`${tftpRoot}/grub`, { recursive: true });
|
|
2204
|
+
|
|
2205
|
+
const menuentryStr = 'UNDERPOST.NET UEFI/GRUB/MAAS RPi4 commissioning (ARM64)';
|
|
2071
2206
|
const grubCfgPath = `${tftpRoot}/grub/grub.cfg`;
|
|
2072
2207
|
fs.writeFileSync(
|
|
2073
2208
|
grubCfgPath,
|
|
@@ -2171,29 +2306,30 @@ BOOT_ORDER=0x21`;
|
|
|
2171
2306
|
};
|
|
2172
2307
|
machine.hostname = machine.hostname.replaceAll(' ', '').replaceAll('.', '');
|
|
2173
2308
|
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
.
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2309
|
+
if (machine.hostname.match('generic-host'))
|
|
2310
|
+
try {
|
|
2311
|
+
let newMachine = shellExec(
|
|
2312
|
+
`maas ${process.env.MAAS_ADMIN_USERNAME} machines create ${Object.keys(machine)
|
|
2313
|
+
.map((k) => `${k}="${machine[k]}"`)
|
|
2314
|
+
.join(' ')}`,
|
|
2315
|
+
{
|
|
2316
|
+
silent: true,
|
|
2317
|
+
stdout: true,
|
|
2318
|
+
},
|
|
2319
|
+
);
|
|
2320
|
+
newMachine = machineFactory(JSON.parse(newMachine));
|
|
2321
|
+
machines.push(newMachine);
|
|
2322
|
+
console.log(newMachine);
|
|
2323
|
+
// commissioning_scripts=90-verify-user.sh
|
|
2324
|
+
shellExec(
|
|
2325
|
+
`maas ${process.env.MAAS_ADMIN_USERNAME} machine commission ${newMachine.system_id} enable_ssh=1 skip_bmc_config=1 skip_networking=1 skip_storage=1`,
|
|
2326
|
+
{
|
|
2327
|
+
silent: true,
|
|
2328
|
+
},
|
|
2329
|
+
);
|
|
2330
|
+
} catch (error) {
|
|
2331
|
+
logger.error(error, error.stack);
|
|
2332
|
+
}
|
|
2197
2333
|
}
|
|
2198
2334
|
// if (discoveries.length > 0) {
|
|
2199
2335
|
// shellExec(
|
|
@@ -2328,7 +2464,6 @@ udp-port = 32766
|
|
|
2328
2464
|
shellExec(`sudo mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc`);
|
|
2329
2465
|
|
|
2330
2466
|
if (process.argv.includes('build')) {
|
|
2331
|
-
// shellExec(`depmod -a`);
|
|
2332
2467
|
shellExec(`mkdir -p ${nfsHostPath}`);
|
|
2333
2468
|
let cmd;
|
|
2334
2469
|
switch (host) {
|
package/cli.md
CHANGED
package/docker-compose.yml
CHANGED
|
@@ -17,7 +17,7 @@ spec:
|
|
|
17
17
|
spec:
|
|
18
18
|
containers:
|
|
19
19
|
- name: dd-template-development-blue
|
|
20
|
-
image: localhost/rockylinux9-underpost:v2.8.
|
|
20
|
+
image: localhost/rockylinux9-underpost:v2.8.817
|
|
21
21
|
# resources:
|
|
22
22
|
# requests:
|
|
23
23
|
# memory: "124Ki"
|
|
@@ -100,7 +100,7 @@ spec:
|
|
|
100
100
|
spec:
|
|
101
101
|
containers:
|
|
102
102
|
- name: dd-template-development-green
|
|
103
|
-
image: localhost/rockylinux9-underpost:v2.8.
|
|
103
|
+
image: localhost/rockylinux9-underpost:v2.8.817
|
|
104
104
|
# resources:
|
|
105
105
|
# requests:
|
|
106
106
|
# memory: "124Ki"
|
package/package.json
CHANGED