underpost 2.8.815 → 2.8.816

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.816
72
72
 
73
73
  ### Usage: `underpost [options] [command]`
74
74
  ```
package/bin/deploy.js CHANGED
@@ -91,7 +91,7 @@ EOF`,
91
91
 
92
92
  const cloudConfigFactory = (
93
93
  { IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip },
94
- { consumer_key, consumer_token, secret },
94
+ { consumer_key, consumer_secret, token_key, token_secret },
95
95
  ) => [
96
96
  // Configure cloud-init for MAAS
97
97
  `cat <<EOF_MAAS_CFG > /etc/cloud/cloud.cfg.d/90_maas.cfg
@@ -112,16 +112,24 @@ hostname: ${host}
112
112
  datasource_list: [ MAAS ]
113
113
  datasource:
114
114
  MAAS:
115
- metadata_url: http://${IP_ADDRESS}:5248/MAAS/metadata
116
- consumer_key: ${consumer_key}
117
- token_key: ${consumer_token}
118
- token_secret: ${secret}
115
+ metadata_url: http://${IP_ADDRESS}:5240/MAAS/metadata/
116
+ ${
117
+ process.argv.includes('reset')
118
+ ? ''
119
+ : `consumer_key: ${consumer_key}
120
+ consumer_secret: ${consumer_secret}
121
+ token_key: ${token_key}
122
+ token_secret: ${token_secret}`
123
+ }
124
+
119
125
 
120
126
  users:
121
- - name: root
127
+ - name: ${process.env.MAAS_ADMIN_USERNAME}
122
128
  sudo: ['ALL=(ALL) NOPASSWD:ALL']
123
129
  shell: /bin/bash
124
- lock_passwd: true
130
+ lock_passwd: false
131
+ groups: sudo,users,admin,wheel,lxd
132
+ plain_text_passwd: '${process.env.MAAS_ADMIN_USERNAME}'
125
133
  ssh_authorized_keys:
126
134
  - ${fs.readFileSync(`/home/dd/engine/engine-private/deploy/id_rsa.pub`, 'utf8')}
127
135
 
@@ -136,11 +144,11 @@ users:
136
144
  # timezone: America/Santiago
137
145
  # timezone: ${timezone}
138
146
 
139
- # ntp:
140
- # enabled: true
141
- # servers:
142
- # - ${IP_ADDRESS}
143
- # ntp_client: chrony
147
+ ntp:
148
+ enabled: true
149
+ servers:
150
+ - ${process.env.MAAS_NTP_SERVER}
151
+ ntp_client: chrony
144
152
  # config:
145
153
  # confpath: ${chronyConfPath}
146
154
  # packages:
@@ -162,13 +170,13 @@ packages:
162
170
  resize_rootfs: false
163
171
  growpart:
164
172
  mode: off
165
- # network:
166
- # version: 2
167
- # ethernets:
168
- # ${process.env.RPI4_INTERFACE_NAME}:
169
- # dhcp4: true
170
- # addresses:
171
- # - ${ipaddr}/24
173
+ network:
174
+ version: 2
175
+ ethernets:
176
+ ${process.env.RPI4_INTERFACE_NAME}:
177
+ dhcp4: true
178
+ addresses:
179
+ - ${ipaddr}/24
172
180
  # routes:
173
181
  # - to: default
174
182
  # via: ${gatewayip}
@@ -193,6 +201,72 @@ runcmd:
193
201
  - echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
194
202
  - echo "Init runcmd"
195
203
  - echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
204
+
205
+ # If this is set, 'root' will not be able to ssh in and they
206
+ # will get a message to login instead as the default $user
207
+ disable_root: true
208
+
209
+ # This will cause the set+update hostname module to not operate (if true)
210
+ preserve_hostname: false
211
+
212
+ # The modules that run in the 'init' stage
213
+ cloud_init_modules:
214
+ - migrator
215
+ - seed_random
216
+ - bootcmd
217
+ - write-files
218
+ - growpart
219
+ - resizefs
220
+ - disk_setup
221
+ - mounts
222
+ - set_hostname
223
+ - update_hostname
224
+ - update_etc_hosts
225
+ - ca-certs
226
+ - rsyslog
227
+ - users-groups
228
+ - ssh
229
+
230
+ # The modules that run in the 'config' stage
231
+ 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
237
+ - locale
238
+ - set-passwords
239
+ - grub-dpkg
240
+ - apt-pipelining
241
+ - apt-configure
242
+ - ntp
243
+ - timezone
244
+ - disable-ec2-metadata
245
+ - runcmd
246
+ - byobu
247
+
248
+ # The modules that run in the 'final' stage
249
+ 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
+ - rightscale_userdata
260
+ - scripts-vendor
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
+ # - power-state-change
196
270
  EOF_MAAS_CFG`,
197
271
  ];
198
272
 
@@ -307,6 +381,7 @@ ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf`,
307
381
  `${nfsHostPath}/underpost/help.sh`,
308
382
  `echo "=== Cloud init utils ==="
309
383
  echo "sudo cloud-init --all-stages"
384
+ echo "sudo cloud-init clean --logs --seed --configs all --machine-id --reboot"
310
385
  echo "sudo cloud-init init --local"
311
386
  echo "sudo cloud-init init"
312
387
  echo "sudo cloud-init modules --mode=config"
@@ -355,22 +430,32 @@ cut -d: -f1 /etc/passwd
355
430
 
356
431
  const updateVirtualRoot = async ({ IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip }) => {
357
432
  // <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 });
433
+ // <consumer_key>:<consumer_secret>:<token_key>:<token_secret>
434
+ // maas apikey --with-names --username ${process.env.MAAS_ADMIN_USERNAME}
435
+ // maas ${process.env.MAAS_ADMIN_USERNAME} account create-authorisation-token
436
+ // maas apikey --generate --username ${process.env.MAAS_ADMIN_USERNAME}
437
+ // https://github.com/CanonicalLtd/maas-docs/issues/647
438
+
439
+ const parts = shellExec(`maas apikey --with-names --username ${process.env.MAAS_ADMIN_USERNAME}`, {
440
+ stdout: true,
441
+ })
442
+ .trim()
443
+ .split(`\n`)[0]
444
+ .split(':');
445
+
446
+ let consumer_key, consumer_secret, token_key, token_secret;
447
+
448
+ if (parts.length === 4) {
449
+ [consumer_key, consumer_secret, token_key, token_secret] = parts;
450
+ } else if (parts.length === 3) {
451
+ [consumer_key, token_key, token_secret] = parts;
452
+ consumer_secret = '""';
453
+ token_secret = token_secret.split(' MAAS consumer')[0].trim();
454
+ } else {
455
+ throw new Error('Invalid token format');
456
+ }
457
+
458
+ logger.info('Maas api token generated', { consumer_key, consumer_secret, token_key, token_secret });
374
459
 
375
460
  if (update) {
376
461
  // --reboot
@@ -411,11 +496,7 @@ EOF`);
411
496
  nfsHostPath,
412
497
  cloudConfigFactory(
413
498
  { IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip },
414
- {
415
- consumer_key,
416
- consumer_token,
417
- secret,
418
- },
499
+ { consumer_key, consumer_secret, token_key, token_secret },
419
500
  ),
420
501
  );
421
502
  installUbuntuUnderpostTools(nfsHostPath);
@@ -1604,7 +1685,9 @@ EOF`);
1604
1685
  dotenv.config({ path: `${getUnderpostRootPath()}/.env`, override: true });
1605
1686
  const IP_ADDRESS = getLocalIPv4Address();
1606
1687
  const serverip = IP_ADDRESS;
1607
- const tftpRoot = process.env.TFTP_ROOT;
1688
+ const tftpRoot = process.argv.includes('v3.0')
1689
+ ? `/var/snap/maas/common/maas/boot-resources/snapshot-20250720-162718`
1690
+ : process.env.TFTP_ROOT;
1608
1691
  const ipaddr = process.env.RPI4_IP;
1609
1692
  const netmask = process.env.NETMASK;
1610
1693
  const gatewayip = process.env.GATEWAY_IP;
@@ -1854,7 +1937,9 @@ EOF`);
1854
1937
  zipFirmwareName,
1855
1938
  zipFirmwareUrl,
1856
1939
  interfaceName,
1857
- nfsHost;
1940
+ nfsHost,
1941
+ bootResourcesPath,
1942
+ bootKernelPath;
1858
1943
 
1859
1944
  switch (process.argv[3]) {
1860
1945
  case 'rpi4mb':
@@ -1872,7 +1957,7 @@ EOF`);
1872
1957
  resource = resources.find((o) => o.architecture === 'arm64/ga-24.04' && o.name === 'ubuntu/noble');
1873
1958
  name = resource.name;
1874
1959
  architecture = resource.architecture;
1875
- resource = resources.find((o) => o.name === name && o.architecture === architecture);
1960
+ // resource = resources.find((o) => o.name === name && o.architecture === architecture);
1876
1961
  nfsServerRootPath = `${process.env.NFS_EXPORT_PATH}/rpi4mb`;
1877
1962
  // ,anonuid=1001,anongid=100
1878
1963
  // etcExports = `${nfsServerRootPath} *(rw,all_squash,sync,no_root_squash,insecure)`;
@@ -1884,21 +1969,33 @@ EOF`);
1884
1969
  'no_subtree_check',
1885
1970
  'insecure',
1886
1971
  ]})`;
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' : '';
1972
+ if (process.argv.includes('v3.0')) {
1973
+ bootResourcesPath = `/var/snap/maas/common/maas/boot-resources/snapshot-20250720-162718`;
1974
+ bootKernelPath = `/var/snap/maas/common/maas/boot-resources/snapshot-20250720-162718/ubuntu/arm64/hwe-24.04/noble/stable`;
1975
+ kernelFilesPaths = {
1976
+ 'vmlinuz-efi': `${bootKernelPath}/boot-kernel`,
1977
+ 'initrd.img': `${bootKernelPath}/boot-initrd`,
1978
+ squashfs: `${bootKernelPath}/squashfs`,
1979
+ };
1980
+ } else {
1981
+ const resourceData = JSON.parse(
1982
+ shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-resource read ${resource.id}`, {
1983
+ stdout: true,
1984
+ silent: true,
1985
+ disableLog: true,
1986
+ }),
1987
+ );
1988
+ const bootFiles = resourceData.sets[Object.keys(resourceData.sets)[0]].files;
1989
+ const suffix = architecture.match('xgene') ? '.xgene' : '';
1990
+ bootResourcesPath = `/var/snap/maas/common/maas/image-storage/bootloaders/uefi/arm64`;
1991
+ bootKernelPath = `/var/snap/maas/common/maas/image-storage`;
1992
+ kernelFilesPaths = {
1993
+ 'vmlinuz-efi': `${bootKernelPath}/${bootFiles['boot-kernel' + suffix].filename_on_disk}`,
1994
+ 'initrd.img': `${bootKernelPath}/${bootFiles['boot-initrd' + suffix].filename_on_disk}`,
1995
+ squashfs: `${bootKernelPath}/${bootFiles['squashfs'].filename_on_disk}`,
1996
+ };
1997
+ }
1896
1998
 
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
1999
  const protocol = 'tcp'; // v3 -> tcp, v4 -> udp
1903
2000
 
1904
2001
  const mountOptions = [
@@ -2022,52 +2119,18 @@ BOOT_ORDER=0x21`;
2022
2119
  switch (process.argv[3]) {
2023
2120
  case 'rpi4mb':
2024
2121
  {
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
2122
  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
- );
2123
+ shellExec(`sudo cp -a ${bootResourcesPath}/${file} ${tftpRoot}${tftpSubDir}/pxe/${file}`);
2038
2124
  }
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
2125
 
2050
2126
  {
2051
2127
  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
- );
2128
+ shellExec(`sudo cp -a ${kernelFilesPaths[file]} ${tftpRoot}${tftpSubDir}/pxe/${file}`);
2055
2129
  }
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)';
2130
+
2131
+ fs.mkdirSync(`${tftpRoot}/grub`, { recursive: true });
2132
+
2133
+ const menuentryStr = 'UNDERPOST.NET UEFI/GRUB/MAAS RPi4 commissioning (ARM64)';
2071
2134
  const grubCfgPath = `${tftpRoot}/grub/grub.cfg`;
2072
2135
  fs.writeFileSync(
2073
2136
  grubCfgPath,
@@ -2171,29 +2234,30 @@ BOOT_ORDER=0x21`;
2171
2234
  };
2172
2235
  machine.hostname = machine.hostname.replaceAll(' ', '').replaceAll('.', '');
2173
2236
 
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
- }
2237
+ if (machine.hostname.match('generic-host'))
2238
+ try {
2239
+ let newMachine = shellExec(
2240
+ `maas ${process.env.MAAS_ADMIN_USERNAME} machines create ${Object.keys(machine)
2241
+ .map((k) => `${k}="${machine[k]}"`)
2242
+ .join(' ')}`,
2243
+ {
2244
+ silent: true,
2245
+ stdout: true,
2246
+ },
2247
+ );
2248
+ newMachine = machineFactory(JSON.parse(newMachine));
2249
+ machines.push(newMachine);
2250
+ console.log(newMachine);
2251
+ // commissioning_scripts=90-verify-user.sh
2252
+ shellExec(
2253
+ `maas ${process.env.MAAS_ADMIN_USERNAME} machine commission ${newMachine.system_id} enable_ssh=1 skip_bmc_config=1 skip_networking=1 skip_storage=1`,
2254
+ {
2255
+ silent: true,
2256
+ },
2257
+ );
2258
+ } catch (error) {
2259
+ logger.error(error, error.stack);
2260
+ }
2197
2261
  }
2198
2262
  // if (discoveries.length > 0) {
2199
2263
  // shellExec(
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.8.815
1
+ ## underpost ci/cd cli v2.8.816
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.816'
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.816
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.816
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.816",
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.816';
36
36
  /**
37
37
  * Repository cli API
38
38
  * @static