@@ -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
- // # - ${JSON.stringify([...timeZoneSteps, ...chronySetUp(chronyConfPath)])}
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
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 } ,
117
+ { IP_ADDRESS , architecture, host, nfsHostPath, ipaddr, update, gatewayip, reset } ,
94
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 > /etc/cloud/cloud.cfg.d/90_maas.cfg
122
+ `cat <<EOF_MAAS_CFG > ${ path }
98
123
#cloud-config
99
124
100
125
hostname: ${ host }
@@ -114,7 +139,7 @@ datasource:
114
139
MAAS:
115
140
metadata_url: http://${ IP_ADDRESS } :5240/MAAS/metadata/
116
141
${
117
- process . argv . includes ( ' reset' )
142
+ reset
118
143
? ''
119
144
: `consumer_key: ${ consumer_key }
120
145
consumer_secret: ${ consumer_secret }
@@ -142,18 +167,15 @@ users:
142
167
143
168
# check timedatectl on host
144
169
# timezone: America/Santiago
145
- # timezone: ${ timezone }
170
+ timezone: ${ timezone }
146
171
147
172
ntp:
148
173
enabled: true
149
174
servers:
150
175
- ${ process . env . MAAS_NTP_SERVER }
151
176
ntp_client: chrony
152
- # config:
153
- # confpath: ${ chronyConfPath }
154
- # packages:
155
- # - chrony
156
- # service_name: chrony
177
+ config:
178
+ confpath: ${ chronyConfPath }
157
179
158
180
# ssh:
159
181
# allow-pw: false
@@ -167,9 +189,10 @@ packages:
167
189
- git
168
190
- htop
169
191
- snapd
192
+ - chrony
170
193
resize_rootfs: false
171
194
growpart:
172
- mode: off
195
+ mode: false
173
196
network:
174
197
version: 2
175
198
ethernets:
@@ -186,7 +209,7 @@ network:
186
209
# users:
187
210
# - {name: root, password: changeme, type: text}
188
211
189
- final_message: "The system is up, after $UPTIME seconds "
212
+ final_message: "====== Cloud init finished ====== "
190
213
191
214
# power_state:
192
215
# mode: reboot
@@ -197,6 +220,7 @@ bootcmd:
197
220
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
198
221
- echo "Init bootcmd"
199
222
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
223
+ ${ cloudConfigCmdRunFactory ( bootCmdSteps ) }
200
224
runcmd:
201
225
- echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
202
226
- echo "Init runcmd"
@@ -212,61 +236,37 @@ preserve_hostname: false
212
236
# The modules that run in the 'init' stage
213
237
cloud_init_modules:
214
238
- migrator
215
- - seed_random
216
239
- bootcmd
217
240
- write-files
218
241
- growpart
219
242
- resizefs
220
- - disk_setup
221
- - mounts
222
243
- set_hostname
223
- - update_hostname
224
244
- update_etc_hosts
225
- - ca-certs
226
245
- rsyslog
227
246
- users-groups
228
247
- ssh
229
248
230
- # The modules that run in the 'config' stage
231
249
cloud_config_modules:
232
- # Emit the cloud config ready event
233
- # this can be used by upstart jobs for 'start on cloud-config'.
234
- - emit_upstart
235
- - snap_config
236
- - ssh-import-id
250
+ - mounts
237
251
- locale
238
252
- set-passwords
239
- - grub-dpkg
240
- - apt-pipelining
241
- - apt-configure
242
- - ntp
253
+ - package-update-upgrade-install
243
254
- timezone
244
- - disable-ec2-metadata
245
255
- runcmd
246
- - byobu
256
+ - ssh-import-id
257
+ - ntp
247
258
248
- # The modules that run in the 'final' stage
249
259
cloud_final_modules:
250
- - snappy
251
- - package-update-upgrade-install
252
- # - fan
253
- # - landscape
254
- # - lxd
255
- # - puppet
256
- - chef
257
- - salt-minion
258
- - mcollective
259
260
- rightscale_userdata
260
- - scripts-vendor
261
261
- scripts-per-once
262
262
- scripts-per-boot
263
263
- scripts-per-instance
264
264
- scripts-user
265
265
- ssh-authkey-fingerprints
266
266
- keys-to-console
267
- # - phone-home
267
+ - phone-home
268
268
- final-message
269
- # - power-state-change
269
+
270
270
EOF_MAAS_CFG` ,
271
271
] ;
272
272
@@ -285,7 +285,9 @@ EOF_OUTER`;
285
285
shellExec ( cmd ) ;
286
286
} ;
287
287
288
- const chronySetUp = ( path ) => {
288
+ const chronySetUp = ( path , alias = 'chrony' ) => {
289
+ // use alias = 'chronyd' for RHEL
290
+ // use alias = 'chrony' for Ubuntu
289
291
return [
290
292
`echo '
291
293
# Use public servers from the pool.ntp.org project.
@@ -328,25 +330,25 @@ logdir /var/log/chrony
328
330
# Select which information is logged.
329
331
#log measurements statistics tracking
330
332
' > ${ path } ` ,
331
- `sudo systemctl stop chronyd` ,
333
+ `systemctl stop ${ alias } ` ,
334
+
335
+ `${ alias } d -q 'server ntp.ubuntu.com iburst'` ,
332
336
333
337
// `chronyd -q 'server 0.europe.pool.ntp.org iburst'`,
334
- `chronyd -q 'server ntp.ubuntu.com iburst'` ,
335
338
336
- `sudo systemctl enable --now chronyd ` ,
337
- `sudo systemctl restart chronyd ` ,
338
- `sudo systemctl status chronyd ` ,
339
+ `sudo systemctl enable --now ${ alias } ` ,
340
+ `sudo systemctl restart ${ alias } ` ,
341
+ `sudo systemctl status ${ alias } ` ,
339
342
340
343
`chronyc sources` ,
341
344
`chronyc tracking` ,
342
- // sudo firewall-cmd --add-service=ntp --permanent
343
- // sudo firewall-cmd --reload
344
345
345
346
`chronyc sourcestats -v` ,
347
+ `timedatectl status` ,
346
348
] ;
347
349
} ;
348
350
349
- const installUbuntuUnderpostTools = ( nfsHostPath ) => {
351
+ const installUbuntuUnderpostTools = ( { nfsHostPath, host } ) => {
350
352
fs . mkdirSync ( `${ nfsHostPath } /underpost` , { recursive : true } ) ;
351
353
352
354
logger . info ( 'Build' , `${ nfsHostPath } /underpost/date.sh` ) ;
@@ -358,6 +360,20 @@ ${chronySetUp(chronyConfPath).join('\n')}
358
360
'utf8' ,
359
361
) ;
360
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
+
361
377
logger . info ( 'Build' , `${ nfsHostPath } /underpost/keyboard.sh` ) ;
362
378
fs . writeFileSync (
363
379
`${ nfsHostPath } /underpost/keyboard.sh` ,
@@ -376,6 +392,24 @@ ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf`,
376
392
'utf8' ,
377
393
) ;
378
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
+
379
413
logger . info ( 'Build' , `${ nfsHostPath } /underpost/help.sh` ) ;
380
414
fs . writeFileSync (
381
415
`${ nfsHostPath } /underpost/help.sh` ,
@@ -417,7 +451,12 @@ cut -d: -f1 /etc/passwd
417
451
`chmod +x /underpost/dns.sh` ,
418
452
`chmod +x /underpost/help.sh` ,
419
453
`chmod +x /underpost/config-path.sh` ,
454
+ `chmod +x /underpost/host.sh` ,
455
+ `chmod +x /underpost/keys.sh` ,
420
456
`chmod +x /underpost/test.sh` ,
457
+ `chmod +x /underpost/start.sh` ,
458
+ `chmod +x /underpost/reset.sh` ,
459
+ chronySetUp ( chronyConfPath ) [ 0 ] ,
421
460
`sudo chmod 700 ~/.ssh/` ,
422
461
`sudo chmod 600 ~/.ssh/authorized_keys` ,
423
462
`sudo chmod 644 ~/.ssh/known_hosts` ,
@@ -461,8 +500,7 @@ const updateVirtualRoot = async ({ IP_ADDRESS, architecture, host, nfsHostPath,
461
500
// --reboot
462
501
if ( process . argv . includes ( 'reset' ) )
463
502
shellExec ( `sudo chroot ${ nfsHostPath } /usr/bin/qemu-aarch64-static /bin/bash <<'EOF'
464
- sudo cloud-init clean --logs --seed --configs all --machine-id
465
- sudo rm -rf /var/lib/cloud/*
503
+ ${ cloudInitReset }
466
504
EOF` ) ;
467
505
468
506
if ( fs . existsSync ( `${ nfsHostPath } /var/log/` ) ) {
@@ -495,11 +533,38 @@ EOF`);
495
533
runSteps (
496
534
nfsHostPath ,
497
535
cloudConfigFactory (
498
- { IP_ADDRESS , architecture, host, nfsHostPath, ipaddr, update, gatewayip } ,
536
+ {
537
+ reset : process . argv . includes ( 'reset' ) ? true : false ,
538
+ IP_ADDRESS ,
539
+ architecture,
540
+ host,
541
+ nfsHostPath,
542
+ ipaddr,
543
+ update,
544
+ gatewayip,
545
+ } ,
546
+ { consumer_key, consumer_secret, token_key, token_secret } ,
547
+ ) ,
548
+ ) ;
549
+
550
+ runSteps (
551
+ nfsHostPath ,
552
+ cloudConfigFactory (
553
+ {
554
+ IP_ADDRESS ,
555
+ architecture,
556
+ host,
557
+ nfsHostPath,
558
+ ipaddr,
559
+ update,
560
+ gatewayip,
561
+ } ,
499
562
{ consumer_key, consumer_secret, token_key, token_secret } ,
563
+ '/underpost/90_maas.cfg' ,
500
564
) ,
501
565
) ;
502
- installUbuntuUnderpostTools ( nfsHostPath ) ;
566
+
567
+ installUbuntuUnderpostTools ( { nfsHostPath, host } ) ;
503
568
} ;
504
569
505
570
try {
@@ -2022,6 +2087,7 @@ EOF`);
2022
2087
] ;
2023
2088
const cmd = [
2024
2089
`console=serial0,115200` ,
2090
+ // `console=ttyAMA0,115200`,
2025
2091
`console=tty1` ,
2026
2092
// `initrd=-1`,
2027
2093
// `net.ifnames=0`,
@@ -2045,6 +2111,12 @@ EOF`);
2045
2111
// 'ip=dfcp',
2046
2112
// 'autoinstall',
2047
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` ,
2048
2120
] ;
2049
2121
2050
2122
// TODO: use autoinstall cloud-config-url=http://<MAAS_IP>:5240/MAAS/metadata/latest
@@ -2392,7 +2464,6 @@ udp-port = 32766
2392
2464
shellExec ( `sudo mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc` ) ;
2393
2465
2394
2466
if ( process . argv . includes ( 'build' ) ) {
2395
- // shellExec(`depmod -a`);
2396
2467
shellExec ( `mkdir -p ${ nfsHostPath } ` ) ;
2397
2468
let cmd ;
2398
2469
switch ( host ) {
0 commit comments