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 CHANGED
@@ -68,7 +68,7 @@ Run dev client server
68
68
  npm run dev
69
69
  ```
70
70
  <!-- -->
71
- ## underpost ci/cd cli v2.8.815
71
+ ## underpost ci/cd cli v2.8.817
72
72
 
73
73
  ### Usage: `underpost [options] [command]`
74
74
  ```
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
- // # - ${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,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, consumer_token, secret },
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 > /etc/cloud/cloud.cfg.d/90_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}:5248/MAAS/metadata
116
- consumer_key: ${consumer_key}
117
- token_key: ${consumer_token}
118
- token_secret: ${secret}
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: root
152
+ - name: ${process.env.MAAS_ADMIN_USERNAME}
122
153
  sudo: ['ALL=(ALL) NOPASSWD:ALL']
123
154
  shell: /bin/bash
124
- lock_passwd: true
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
- # timezone: ${timezone}
138
-
139
- # ntp:
140
- # enabled: true
141
- # servers:
142
- # - ${IP_ADDRESS}
143
- # ntp_client: chrony
144
- # config:
145
- # confpath: ${chronyConfPath}
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: off
165
- # network:
166
- # version: 2
167
- # ethernets:
168
- # ${process.env.RPI4_INTERFACE_NAME}:
169
- # dhcp4: true
170
- # addresses:
171
- # - ${ipaddr}/24
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: "The system is up, after $UPTIME seconds"
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
- `sudo systemctl stop chronyd`,
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 chronyd`,
263
- `sudo systemctl restart chronyd`,
264
- `sudo systemctl status chronyd`,
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
- let [consumer_key, consumer_token, secret] = process.argv.includes('reset')
359
- ? shellExec(`maas apikey --username ${process.env.MAAS_ADMIN_USERNAME}`, {
360
- stdout: true,
361
- })
362
- .trim()
363
- .split(`\n`)[0]
364
- .split(':')
365
- : shellExec(`maas apikey --generate --username ${process.env.MAAS_ADMIN_USERNAME}`, {
366
- stdout: true,
367
- })
368
- .trim()
369
- .split(':');
370
-
371
- if (process.argv.includes('reset')) secret = '&' + secret;
372
-
373
- logger.info('Maas api token generated', { consumer_key, consumer_token, secret });
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
- sudo cloud-init clean --logs --seed --configs all --machine-id
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
- consumer_key,
416
- consumer_token,
417
- secret,
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
- installUbuntuUnderpostTools(nfsHostPath);
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.env.TFTP_ROOT;
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
- const resourceData = JSON.parse(
1888
- shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-resource read ${resource.id}`, {
1889
- stdout: true,
1890
- silent: true,
1891
- disableLog: true,
1892
- }),
1893
- );
1894
- const bootFiles = resourceData.sets[Object.keys(resourceData.sets)[0]].files;
1895
- const suffix = architecture.match('xgene') ? '.xgene' : '';
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
- // const configTxtSrc = fs.readFileSync(`${firmwarePath}/config.txt`, 'utf8');
2057
- // fs.writeFileSync(
2058
- // `${tftpRoot}${tftpSubDir}/config.txt`,
2059
- // configTxtSrc
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
- try {
2175
- let newMachine = shellExec(
2176
- `maas ${process.env.MAAS_ADMIN_USERNAME} machines create ${Object.keys(machine)
2177
- .map((k) => `${k}="${machine[k]}"`)
2178
- .join(' ')}`,
2179
- {
2180
- silent: true,
2181
- stdout: true,
2182
- },
2183
- );
2184
- newMachine = machineFactory(JSON.parse(newMachine));
2185
- machines.push(newMachine);
2186
- console.log(newMachine);
2187
- // commissioning_scripts=90-verify-user.sh
2188
- shellExec(
2189
- `maas ${process.env.MAAS_ADMIN_USERNAME} machine commission ${newMachine.system_id} enable_ssh=1 skip_bmc_config=1 skip_networking=1 skip_storage=1`,
2190
- {
2191
- silent: true,
2192
- },
2193
- );
2194
- } catch (error) {
2195
- logger.error(error, error.stack);
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
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.8.815
1
+ ## underpost ci/cd cli v2.8.817
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -58,7 +58,7 @@ services:
58
58
  cpus: '0.25'
59
59
  memory: 20M
60
60
  labels: # labels in Compose file instead of Dockerfile
61
- engine.version: '2.8.815'
61
+ engine.version: '2.8.817'
62
62
  networks:
63
63
  - load-balancer
64
64
 
@@ -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.815
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.815
103
+ image: localhost/rockylinux9-underpost:v2.8.817
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -2,6 +2,7 @@
2
2
  set -euo pipefail
3
3
 
4
4
  sudo snap install jq
5
+ # sudo snap install --channel=3.0/stable maas
5
6
  sudo snap install maas
6
7
 
7
8
  # Get default interface and IP address
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "underpost",
5
- "version": "2.8.815",
5
+ "version": "2.8.817",
6
6
  "description": "pwa api rest template",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
package/src/index.js CHANGED
@@ -32,7 +32,7 @@ class Underpost {
32
32
  * @type {String}
33
33
  * @memberof Underpost
34
34
  */
35
- static version = 'v2.8.815';
35
+ static version = 'v2.8.817';
36
36
  /**
37
37
  * Repository cli API
38
38
  * @static