underpost 2.8.817 → 2.8.818

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.817
71
+ ## underpost ci/cd cli v2.8.818
72
72
 
73
73
  ### Usage: `underpost [options] [command]`
74
74
  ```
package/bin/deploy.js CHANGED
@@ -99,7 +99,9 @@ const bootCmdSteps = [
99
99
  `/underpost/dns.sh`,
100
100
  `/underpost/host.sh`,
101
101
  // `/underpost/date.sh`,
102
- `cp -a /underpost/90_maas.cfg /etc/cloud/cloud.cfg.d/90_maas.cfg`,
102
+ `/underpost/keys_import.sh`,
103
+ `/underpost/mac.sh`,
104
+ `cat /underpost/mac`,
103
105
  ];
104
106
 
105
107
  const cloudInitReset = `sudo cloud-init clean --logs --seed --configs all --machine-id
@@ -114,7 +116,7 @@ const cloudConfigCmdRunFactory = (steps = []) =>
114
116
  .join('\n');
115
117
 
116
118
  const cloudConfigFactory = (
117
- { IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip, reset },
119
+ { controlServerIp, architecture, host, nfsHostPath, commissioningDeviceIp, update, gatewayip, auth },
118
120
  { consumer_key, consumer_secret, token_key, token_secret },
119
121
  path = '/etc/cloud/cloud.cfg.d/90_maas.cfg',
120
122
  ) => [
@@ -125,8 +127,8 @@ const cloudConfigFactory = (
125
127
  hostname: ${host}
126
128
  # fqdn: server01.midominio.cl
127
129
  # prefer_fqdn_over_hostname: true
128
- # metadata_url: http://${IP_ADDRESS}:5240/MAAS/metadata
129
- # metadata_url: http://${IP_ADDRESS}:5248/MAAS/metadata
130
+ # metadata_url: http://${controlServerIp}:5240/MAAS/metadata
131
+ # metadata_url: http://${controlServerIp}:5248/MAAS/metadata
130
132
 
131
133
  # Check:
132
134
  # /MAAS/metadata/latest/enlist-preseed/?op=get_enlist_preseed
@@ -137,9 +139,9 @@ hostname: ${host}
137
139
  datasource_list: [ MAAS ]
138
140
  datasource:
139
141
  MAAS:
140
- metadata_url: http://${IP_ADDRESS}:5240/MAAS/metadata/
142
+ metadata_url: http://${controlServerIp}:5240/MAAS/metadata/
141
143
  ${
142
- reset
144
+ !auth
143
145
  ? ''
144
146
  : `consumer_key: ${consumer_key}
145
147
  consumer_secret: ${consumer_secret}
@@ -197,17 +199,18 @@ network:
197
199
  version: 2
198
200
  ethernets:
199
201
  ${process.env.RPI4_INTERFACE_NAME}:
200
- dhcp4: true
202
+ match:
203
+ macaddress: "${process.env.RPI4_MAC_ADDRESS}"
204
+ mtu: 1500
205
+ set-name: ${process.env.RPI4_INTERFACE_NAME}
206
+ dhcp4: false
201
207
  addresses:
202
- - ${ipaddr}/24
203
- # routes:
204
- # - to: default
205
- # via: ${gatewayip}
208
+ - ${commissioningDeviceIp}/24
209
+ gateway4: ${gatewayip}
210
+ nameservers:
211
+ addresses:
212
+ - ${process.env.MAAS_DNS}
206
213
 
207
- # chpasswd:
208
- # expire: false
209
- # users:
210
- # - {name: root, password: changeme, type: text}
211
214
 
212
215
  final_message: "====== Cloud init finished ======"
213
216
 
@@ -216,6 +219,7 @@ final_message: "====== Cloud init finished ======"
216
219
  # message: Rebooting after initial setup
217
220
  # timeout: 30
218
221
  # condition: True
222
+
219
223
  bootcmd:
220
224
  - echo "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
221
225
  - echo "Init bootcmd"
@@ -367,13 +371,29 @@ ${chronySetUp(chronyConfPath).join('\n')}
367
371
  'utf8',
368
372
  );
369
373
 
370
- logger.info('Build', `${nfsHostPath}/underpost/keys.sh`);
374
+ logger.info('Build', `${nfsHostPath}/underpost/keys_current.sh`);
371
375
  fs.writeFileSync(
372
- `${nfsHostPath}/underpost/keys.sh`,
376
+ `${nfsHostPath}/underpost/keys_current.sh`,
373
377
  `cat /etc/cloud/cloud.cfg.d/90_maas.cfg | grep -C 5 'metadata'`,
374
378
  'utf8',
375
379
  );
376
380
 
381
+ logger.info('Build', `${nfsHostPath}/underpost/keys_remove.sh`);
382
+ fs.writeFileSync(
383
+ `${nfsHostPath}/underpost/keys_remove.sh`,
384
+ `cp -a /underpost/90_maas_no_keys.cfg /etc/cloud/cloud.cfg.d/90_maas.cfg
385
+ /underpost/keys_current.sh`,
386
+ 'utf8',
387
+ );
388
+
389
+ logger.info('Build', `${nfsHostPath}/underpost/keys_import.sh`);
390
+ fs.writeFileSync(
391
+ `${nfsHostPath}/underpost/keys_import.sh`,
392
+ `cp -a /underpost/90_maas_keys.cfg /etc/cloud/cloud.cfg.d/90_maas.cfg
393
+ /underpost/keys_current.sh`,
394
+ 'utf8',
395
+ );
396
+
377
397
  logger.info('Build', `${nfsHostPath}/underpost/keyboard.sh`);
378
398
  fs.writeFileSync(
379
399
  `${nfsHostPath}/underpost/keyboard.sh`,
@@ -436,6 +456,24 @@ cut -d: -f1 /etc/passwd
436
456
  'utf8',
437
457
  );
438
458
 
459
+ logger.info('Build', `${nfsHostPath}/underpost/shutdown.sh`);
460
+ fs.writeFileSync(
461
+ `${nfsHostPath}/underpost/shutdown.sh`,
462
+ `cp -a /underpost/90_maas_no_keys.cfg /etc/cloud/cloud.cfg.d/90_maas.cfg
463
+ sudo shutdown -h now`,
464
+ 'utf8',
465
+ );
466
+
467
+ logger.info('Build', `${nfsHostPath}/underpost/mac.sh`);
468
+ fs.writeFileSync(
469
+ `${nfsHostPath}/underpost/mac.sh`,
470
+ `echo "$(cat /sys/class/net/${process.env.RPI4_INTERFACE_NAME}/address)" > /underpost/mac`,
471
+ 'utf8',
472
+ );
473
+
474
+ logger.info('Build', `${nfsHostPath}/underpost/device_scan.sh`);
475
+ fs.copySync(`./manifests/maas/device-scan.sh`, `${nfsHostPath}/underpost/device_scan.sh`);
476
+
439
477
  logger.info('Build', `${nfsHostPath}/underpost/config-path.sh`);
440
478
  fs.writeFileSync(`${nfsHostPath}/underpost/config-path.sh`, `echo "/etc/cloud/cloud.cfg.d/90_maas.cfg"`, 'utf8');
441
479
 
@@ -452,10 +490,15 @@ cut -d: -f1 /etc/passwd
452
490
  `chmod +x /underpost/help.sh`,
453
491
  `chmod +x /underpost/config-path.sh`,
454
492
  `chmod +x /underpost/host.sh`,
455
- `chmod +x /underpost/keys.sh`,
493
+ `chmod +x /underpost/keys_current.sh`,
494
+ `chmod +x /underpost/keys_import.sh`,
495
+ `chmod +x /underpost/keys_remove.sh`,
456
496
  `chmod +x /underpost/test.sh`,
457
497
  `chmod +x /underpost/start.sh`,
458
498
  `chmod +x /underpost/reset.sh`,
499
+ `chmod +x /underpost/shutdown.sh`,
500
+ `chmod +x /underpost/device_scan.sh`,
501
+ `chmod +x /underpost/mac.sh`,
459
502
  chronySetUp(chronyConfPath)[0],
460
503
  `sudo chmod 700 ~/.ssh/`,
461
504
  `sudo chmod 600 ~/.ssh/authorized_keys`,
@@ -467,7 +510,15 @@ cut -d: -f1 /etc/passwd
467
510
  ]);
468
511
  };
469
512
 
470
- const updateVirtualRoot = async ({ IP_ADDRESS, architecture, host, nfsHostPath, ipaddr, update, gatewayip }) => {
513
+ const updateVirtualRoot = async ({
514
+ controlServerIp,
515
+ architecture,
516
+ host,
517
+ nfsHostPath,
518
+ commissioningDeviceIp,
519
+ update,
520
+ gatewayip,
521
+ }) => {
471
522
  // <consumer_key>:<consumer_token>:<secret>
472
523
  // <consumer_key>:<consumer_secret>:<token_key>:<token_secret>
473
524
  // maas apikey --with-names --username ${process.env.MAAS_ADMIN_USERNAME}
@@ -534,16 +585,17 @@ EOF`);
534
585
  nfsHostPath,
535
586
  cloudConfigFactory(
536
587
  {
537
- reset: process.argv.includes('reset') ? true : false,
538
- IP_ADDRESS,
588
+ auth: true,
589
+ controlServerIp,
539
590
  architecture,
540
591
  host,
541
592
  nfsHostPath,
542
- ipaddr,
593
+ commissioningDeviceIp,
543
594
  update,
544
595
  gatewayip,
545
596
  },
546
597
  { consumer_key, consumer_secret, token_key, token_secret },
598
+ '/underpost/90_maas_keys.cfg',
547
599
  ),
548
600
  );
549
601
 
@@ -551,20 +603,31 @@ EOF`);
551
603
  nfsHostPath,
552
604
  cloudConfigFactory(
553
605
  {
554
- IP_ADDRESS,
606
+ auth: false,
607
+ controlServerIp,
555
608
  architecture,
556
609
  host,
557
610
  nfsHostPath,
558
- ipaddr,
611
+ commissioningDeviceIp,
559
612
  update,
560
613
  gatewayip,
561
614
  },
562
615
  { consumer_key, consumer_secret, token_key, token_secret },
563
- '/underpost/90_maas.cfg',
616
+ '/underpost/90_maas_no_keys.cfg',
564
617
  ),
565
618
  );
566
619
 
620
+ if (process.argv.includes('auth')) {
621
+ shellExec(`cp ${nfsHostPath}/underpost/90_maas_keys.cfg ${nfsHostPath}/etc/cloud/cloud.cfg.d/90_maas.cfg`);
622
+ } else {
623
+ shellExec(`cp ${nfsHostPath}/underpost/90_maas_no_keys.cfg ${nfsHostPath}/etc/cloud/cloud.cfg.d/90_maas.cfg`);
624
+ }
625
+
567
626
  installUbuntuUnderpostTools({ nfsHostPath, host });
627
+
628
+ shellExec(`./manifests/maas/nat-iptables.sh`, { silent: true });
629
+
630
+ shellExec(`cat ${nfsHostPath}/etc/cloud/cloud.cfg.d/90_maas.cfg`);
568
631
  };
569
632
 
570
633
  try {
@@ -1744,41 +1807,60 @@ EOF`);
1744
1807
  }
1745
1808
 
1746
1809
  case 'maas': {
1747
- shellExec(
1748
- `underpost secret underpost --create-from-file /home/dd/engine/engine-private/conf/dd-cron/.env.production`,
1749
- );
1750
- dotenv.config({ path: `${getUnderpostRootPath()}/.env`, override: true });
1751
- const IP_ADDRESS = getLocalIPv4Address();
1752
- const serverip = IP_ADDRESS;
1810
+ dotenv.config({ path: `/home/dd/engine/engine-private/conf/dd-cron/.env.production`, override: true });
1811
+ const controlServerIp = getLocalIPv4Address();
1753
1812
  const tftpRoot = process.argv.includes('v3.0')
1754
1813
  ? `/var/snap/maas/common/maas/boot-resources/snapshot-20250720-162718`
1755
1814
  : process.env.TFTP_ROOT;
1756
- const ipaddr = process.env.RPI4_IP;
1815
+ const commissioningDeviceIp = process.env.RPI4_IP;
1757
1816
  const netmask = process.env.NETMASK;
1758
1817
  const gatewayip = process.env.GATEWAY_IP;
1818
+ let commissioningMac = '00:00:00:00:00:00';
1759
1819
 
1760
- const machineFactory = (m) => ({
1761
- system_id: m.interface_set[0].system_id,
1762
- mac_address: m.interface_set[0].mac_address,
1763
- hostname: m.hostname,
1764
- status_name: m.status_name,
1765
- });
1820
+ const removeMachines = () => {
1821
+ for (const machine of machines) {
1822
+ shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} machine delete ${machine.system_id}`);
1823
+ }
1824
+ machines = [];
1825
+ };
1826
+
1827
+ const clearDiscoveries = () => {
1828
+ shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} discoveries clear all=true`);
1829
+ if (process.argv.includes('force')) {
1830
+ shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} discoveries scan force=true`);
1831
+ }
1832
+ };
1833
+
1834
+ const macMonitor = async (nfsServerRootPath) => {
1835
+ if (fs.existsSync(`${nfsServerRootPath}/underpost/mac`)) {
1836
+ commissioningMac = fs.readFileSync(`${nfsServerRootPath}/underpost/mac`, 'utf8').trim();
1837
+ logger.info('Commissioning MAC', commissioningMac);
1838
+ return;
1839
+ }
1840
+ await timer(1000);
1841
+ await macMonitor(nfsServerRootPath);
1842
+ };
1766
1843
 
1767
1844
  let resources;
1768
- try {
1769
- resources = JSON.parse(
1770
- shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-resources read`, {
1771
- silent: true,
1772
- stdout: true,
1773
- }),
1774
- ).map((o) => ({
1775
- id: o.id,
1776
- name: o.name,
1777
- architecture: o.architecture,
1778
- }));
1779
- } catch (error) {
1780
- logger.error(error);
1781
- }
1845
+ if (!process.argv.includes('machines'))
1846
+ try {
1847
+ resources = JSON.parse(
1848
+ shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-resources read`, {
1849
+ silent: true,
1850
+ stdout: true,
1851
+ }),
1852
+ ).map((o) => ({
1853
+ id: o.id,
1854
+ name: o.name,
1855
+ architecture: o.architecture,
1856
+ }));
1857
+ if (process.argv.includes('images')) {
1858
+ console.table(resources);
1859
+ process.exit(0);
1860
+ }
1861
+ } catch (error) {
1862
+ logger.error(error);
1863
+ }
1782
1864
 
1783
1865
  let machines;
1784
1866
  try {
@@ -1787,23 +1869,21 @@ EOF`);
1787
1869
  stdout: true,
1788
1870
  silent: true,
1789
1871
  }),
1790
- ).map((m) => machineFactory(m));
1872
+ ).map((m) => ({
1873
+ system_id: m.interface_set[0].system_id,
1874
+ mac_address: m.interface_set[0].mac_address,
1875
+ hostname: m.hostname,
1876
+ status_name: m.status_name,
1877
+ }));
1878
+ if (process.argv.includes('machines')) {
1879
+ console.table(machines);
1880
+ process.exit(0);
1881
+ }
1791
1882
  } catch (error) {
1792
1883
  logger.error(error);
1793
1884
  }
1794
1885
 
1795
- if (process.argv.includes('ls')) {
1796
- shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-sources read`);
1797
- shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} commissioning-scripts read`);
1798
- // shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-source-selections read 60`);
1799
- logger.info('Resources');
1800
- console.table(resources);
1801
- logger.info('Machines');
1802
- console.table(machines);
1803
- process.exit(0);
1804
- }
1805
-
1806
- if (process.argv.includes('config')) {
1886
+ if (process.argv.includes('journald')) {
1807
1887
  shellExec(`sudo sed -i 's/^#Storage=auto/Storage=volatile/' /etc/systemd/journald.conf`);
1808
1888
  shellExec(`sudo systemctl daemon-reload`);
1809
1889
  shellExec(`sudo systemctl restart systemd-journald`);
@@ -1840,14 +1920,8 @@ EOF`);
1840
1920
  // - Disable DNSSEC validation to No (Disable DNSSEC; useful when upstream DNS is misconfigured)
1841
1921
 
1842
1922
  if (process.argv.includes('clear')) {
1843
- for (const machine of machines) {
1844
- shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} machine delete ${machine.system_id}`);
1845
- }
1846
- // machines = [];
1847
- shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} discoveries clear all=true`);
1848
- if (process.argv.includes('force')) {
1849
- shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} discoveries scan force=true`);
1850
- }
1923
+ removeMachines();
1924
+ clearDiscoveries();
1851
1925
  process.exit(0);
1852
1926
  }
1853
1927
  if (process.argv.includes('grub-arm64')) {
@@ -1868,37 +1942,13 @@ EOF`);
1868
1942
  pbcopy(cmd);
1869
1943
  process.exit(0);
1870
1944
  }
1871
- if (process.argv.includes('reset')) {
1872
- // shellExec(
1873
- // `maas init region+rack --database-uri "postgres://$DB_PG_MAAS_USER:$DB_PG_MAAS_PASS@$DB_PG_MAAS_HOST/$DB_PG_MAAS_NAME"` +
1874
- // ` --maas-url http://${IP_ADDRESS}:5240/MAAS`,
1875
- // );
1876
- const cmd =
1877
- `maas init region+rack --database-uri "postgres://${process.env.DB_PG_MAAS_USER}:${process.env.DB_PG_MAAS_PASS}@${process.env.DB_PG_MAAS_HOST}/${process.env.DB_PG_MAAS_NAME}"` +
1878
- ` --maas-url http://${IP_ADDRESS}:5240/MAAS`;
1879
- pbcopy(cmd);
1880
- process.exit(0);
1881
- }
1882
-
1883
- if (process.argv.includes('restart')) {
1884
- shellExec(`sudo snap restart maas.pebble`);
1885
- let secs = 0;
1886
- while (
1887
- !(
1888
- shellExec(`maas status`, { silent: true, disableLog: true, stdout: true })
1889
- .split(' ')
1890
- .filter((l) => l.match('inactive')).length === 1
1891
- )
1892
- ) {
1893
- await timer(1000);
1894
- console.log(`Waiting... (${++secs}s)`);
1895
- }
1896
- process.exit(0);
1897
- }
1898
1945
 
1899
1946
  // shellExec(`MAAS_ADMIN_USERNAME=${process.env.MAAS_ADMIN_USERNAME}`);
1900
1947
  // shellExec(`MAAS_ADMIN_EMAIL=${process.env.MAAS_ADMIN_EMAIL}`);
1901
1948
  // shellExec(`maas createadmin --username $MAAS_ADMIN_USERNAME --email $MAAS_ADMIN_EMAIL`);
1949
+ // shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-sources read`);
1950
+ // shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} commissioning-scripts read`);
1951
+ // shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} boot-source-selections read 60`);
1902
1952
 
1903
1953
  // MaaS admin CLI:
1904
1954
  // maas login <maas-admin-username> http://localhost:5240/MAAS
@@ -2094,9 +2144,9 @@ EOF`);
2094
2144
  // `dwc_otg.lpm_enable=0`,
2095
2145
  // `elevator=deadline`,
2096
2146
  `root=/dev/nfs`,
2097
- `nfsroot=${serverip}:${process.env.NFS_EXPORT_PATH}/rpi4mb,${mountOptions}`,
2098
- // `nfsroot=${serverip}:${process.env.NFS_EXPORT_PATH}/rpi4mb`,
2099
- `ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${nfsHost}:${interfaceName}:static`,
2147
+ `nfsroot=${controlServerIp}:${process.env.NFS_EXPORT_PATH}/rpi4mb,${mountOptions}`,
2148
+ // `nfsroot=${controlServerIp}:${process.env.NFS_EXPORT_PATH}/rpi4mb`,
2149
+ `ip=${commissioningDeviceIp}:${controlServerIp}:${gatewayip}:${netmask}:${nfsHost}:${interfaceName}:static`,
2100
2150
  `rootfstype=nfs`,
2101
2151
  `rw`,
2102
2152
  `rootwait`,
@@ -2155,30 +2205,58 @@ EOF`);
2155
2205
 
2156
2206
  nfsConnectStr = cmd.join(' ');
2157
2207
  bootConf = `[all]
2158
- MAC_ADDRESS=00:00:00:00:00:00
2159
- MAC_ADDRESS_OTP=0,1
2160
2208
  BOOT_UART=0
2161
2209
  WAKE_ON_GPIO=1
2162
2210
  POWER_OFF_ON_HALT=0
2163
2211
  ENABLE_SELF_UPDATE=1
2164
2212
  DISABLE_HDMI=0
2165
- TFTP_IP=${serverip}
2166
- TFTP_PREFIX=1
2167
- TFTP_PREFIX_STR=${tftpSubDir.slice(1)}/
2168
2213
  NET_INSTALL_ENABLED=1
2169
2214
  DHCP_TIMEOUT=45000
2170
2215
  DHCP_REQ_TIMEOUT=4000
2171
2216
  TFTP_FILE_TIMEOUT=30000
2172
- BOOT_ORDER=0x21`;
2173
- // CLIENT_IP=${ipaddr}
2174
- // SUBNET=255.255.255.0
2217
+ BOOT_ORDER=0x21
2218
+
2219
+ # ─────────────────────────────────────────────────────────────
2220
+ # TFTP configuration
2221
+ # ─────────────────────────────────────────────────────────────
2222
+
2223
+ # Custom TFTP prefix string (e.g., based on MAC address, no colons)
2224
+ #TFTP_PREFIX_STR=AA-BB-CC-DD-EE-FF/
2225
+
2226
+ # Optional PXE Option43 override (leave commented if unused)
2227
+ #PXE_OPTION43="Raspberry Pi Boot"
2228
+
2229
+ # DHCP client GUID (Option 97); 0x34695052 is the FourCC for Raspberry Pi 4
2230
+ #DHCP_OPTION97=0x34695052
2231
+
2232
+ TFTP_IP=${controlServerIp}
2233
+ TFTP_PREFIX=1
2234
+ TFTP_PREFIX_STR=${tftpSubDir.slice(1)}/
2235
+
2236
+ # ─────────────────────────────────────────────────────────────
2237
+ # Manually override Ethernet MAC address
2238
+ # ─────────────────────────────────────────────────────────────
2239
+
2240
+ MAC_ADDRESS=${process.env.RPI4_MAC_ADDRESS}
2241
+
2242
+ # OTP MAC address override
2243
+ #MAC_ADDRESS_OTP=0,1
2244
+
2245
+ # ─────────────────────────────────────────────────────────────
2246
+ # Static IP configuration (bypasses DHCP completely)
2247
+ # ─────────────────────────────────────────────────────────────
2248
+ CLIENT_IP=${commissioningDeviceIp}
2249
+ SUBNET=255.255.255.0
2250
+ GATEWAY=192.168.1.1
2251
+
2252
+ `;
2175
2253
  break;
2176
2254
 
2177
2255
  default:
2178
2256
  break;
2179
2257
  }
2180
- shellExec(`sudo chmod 755 ${process.env.NFS_EXPORT_PATH}/${nfsHost}`);
2181
2258
 
2259
+ shellExec(`sudo chmod 755 ${process.env.NFS_EXPORT_PATH}/${nfsHost}`);
2182
2260
  shellExec(`sudo rm -rf ${tftpRoot}${tftpSubDir}`);
2183
2261
  shellExec(`sudo cp -a ${firmwarePath} ${tftpRoot}${tftpSubDir}`);
2184
2262
  shellExec(`mkdir -p ${tftpRoot}${tftpSubDir}/pxe`);
@@ -2214,7 +2292,7 @@ BOOT_ORDER=0x21`;
2214
2292
  set default=0
2215
2293
 
2216
2294
  menuentry '${menuentryStr}' {
2217
- set root=(tftp,${serverip})
2295
+ set root=(tftp,${controlServerIp})
2218
2296
  linux ${tftpSubDir}/pxe/vmlinuz-efi ${nfsConnectStr}
2219
2297
  initrd ${tftpSubDir}/pxe/initrd.img
2220
2298
  boot
@@ -2245,19 +2323,12 @@ BOOT_ORDER=0x21`;
2245
2323
  nfsServerRootPath,
2246
2324
  nfsConnectStr,
2247
2325
  });
2248
- if (process.argv.includes('restart')) {
2249
- if (fs.existsSync(`node engine-private/r.js`)) shellExec(`node engine-private/r`);
2250
- shellExec(`node bin/deploy maas dhcp`);
2251
- shellExec(`sudo chown -R root:root ${tftpRoot}`);
2252
- shellExec(`sudo sudo chmod 755 ${tftpRoot}`);
2253
- }
2254
- // for (const machine of machines) {
2255
- // // shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} machine delete ${machine.system_id}`);
2256
- // shellExec(`maas ${process.env.MAAS_ADMIN_USERNAME} machine commission ${machine.system_id}`, {
2257
- // silent: true,
2258
- // });
2259
- // }
2260
- // machines = [];
2326
+ shellExec(`sudo chown -R root:root ${tftpRoot}`);
2327
+ shellExec(`sudo sudo chmod 755 ${tftpRoot}`);
2328
+
2329
+ logger.info('Waiting for MAC assignment...');
2330
+ fs.removeSync(`${nfsServerRootPath}/underpost/mac`);
2331
+ await macMonitor(nfsServerRootPath);
2261
2332
 
2262
2333
  const monitor = async () => {
2263
2334
  // discoveries Query observed discoveries.
@@ -2268,8 +2339,6 @@ BOOT_ORDER=0x21`;
2268
2339
  silent: true,
2269
2340
  stdout: true,
2270
2341
  }),
2271
- ).filter(
2272
- (o) => o.ip !== IP_ADDRESS && o.ip !== gatewayip && !machines.find((_o) => _o.mac_address === o.mac_address),
2273
2342
  );
2274
2343
 
2275
2344
  // {
@@ -2290,12 +2359,14 @@ BOOT_ORDER=0x21`;
2290
2359
  // "resource_uri": "/MAAS/api/2.0/discovery/MTkyLjE2OC4xLjE4OSwwMDowMDowMDowMDowMDowMA==/"
2291
2360
  // },
2292
2361
 
2362
+ console.log(discoveries.map((d) => d.ip).join(' | '));
2363
+
2293
2364
  for (const discovery of discoveries) {
2294
2365
  const machine = {
2295
2366
  architecture: architecture.match('amd') ? 'amd64/generic' : 'arm64/generic',
2296
2367
  mac_address: discovery.mac_address,
2297
2368
  hostname: discovery.hostname ?? discovery.mac_organization ?? discovery.domain ?? `generic-host-${s4()}`,
2298
- // discovery.ip.match(ipaddr)
2369
+ // discovery.ip.match(commissioningDeviceIp)
2299
2370
  // ? nfsHost
2300
2371
  // : `unknown-${s4()}`,
2301
2372
  // description: '',
@@ -2303,11 +2374,14 @@ BOOT_ORDER=0x21`;
2303
2374
  power_type: 'manual', // manual
2304
2375
  // power_parameters_power_address: discovery.ip,
2305
2376
  mac_addresses: discovery.mac_address,
2377
+ ip: discovery.ip,
2306
2378
  };
2307
2379
  machine.hostname = machine.hostname.replaceAll(' ', '').replaceAll('.', '');
2308
2380
 
2309
- if (machine.hostname.match('generic-host'))
2381
+ if (machine.mac_addresses === commissioningMac)
2310
2382
  try {
2383
+ machine.hostname = nfsHost;
2384
+ machine.mac_address = commissioningMac;
2311
2385
  let newMachine = shellExec(
2312
2386
  `maas ${process.env.MAAS_ADMIN_USERNAME} machines create ${Object.keys(machine)
2313
2387
  .map((k) => `${k}="${machine[k]}"`)
@@ -2317,31 +2391,27 @@ BOOT_ORDER=0x21`;
2317
2391
  stdout: true,
2318
2392
  },
2319
2393
  );
2320
- newMachine = machineFactory(JSON.parse(newMachine));
2394
+ newMachine = { discovery, machine: JSON.parse(newMachine) };
2321
2395
  machines.push(newMachine);
2322
2396
  console.log(newMachine);
2323
2397
  // commissioning_scripts=90-verify-user.sh
2324
2398
  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`,
2399
+ `maas ${process.env.MAAS_ADMIN_USERNAME} machine commission ${newMachine.machine.boot_interface.system_id} enable_ssh=1 skip_bmc_config=1 skip_networking=1 skip_storage=1`,
2326
2400
  {
2327
2401
  silent: true,
2328
2402
  },
2329
2403
  );
2330
2404
  } catch (error) {
2331
2405
  logger.error(error, error.stack);
2406
+ } finally {
2407
+ process.exit(0);
2332
2408
  }
2333
2409
  }
2334
- // if (discoveries.length > 0) {
2335
- // shellExec(
2336
- // `maas ${process.env.MAAS_ADMIN_USERNAME} machines read | jq '.[] | {system_id: .interface_set[0].system_id, hostname, status_name, mac_address: .interface_set[0].mac_address}'`,
2337
- // );
2338
- // }
2339
2410
  await timer(1000);
2340
2411
  monitor();
2341
2412
  };
2342
- // shellExec(`node bin/deploy open-virtual-root ${architecture.match('amd') ? 'amd64' : 'arm64'} ${nfsHost}`);
2343
- machines = [];
2344
- shellExec(`node bin/deploy maas clear`);
2413
+ // clearDiscoveries();
2414
+ removeMachines();
2345
2415
  monitor();
2346
2416
  break;
2347
2417
  }
@@ -2423,18 +2493,18 @@ udp-port = 32766
2423
2493
  }
2424
2494
  case 'update-virtual-root': {
2425
2495
  dotenv.config({ path: `${getUnderpostRootPath()}/.env`, override: true });
2426
- const IP_ADDRESS = getLocalIPv4Address();
2496
+ const controlServerIp = getLocalIPv4Address();
2427
2497
  const architecture = process.argv[3];
2428
2498
  const host = process.argv[4];
2429
2499
  const nfsHostPath = `${process.env.NFS_EXPORT_PATH}/${host}`;
2430
- const ipaddr = process.env.RPI4_IP;
2500
+ const commissioningDeviceIp = process.env.RPI4_IP;
2431
2501
  const gatewayip = process.env.GATEWAY_IP;
2432
2502
  await updateVirtualRoot({
2433
- IP_ADDRESS,
2503
+ controlServerIp,
2434
2504
  architecture,
2435
2505
  host,
2436
2506
  nfsHostPath,
2437
- ipaddr,
2507
+ commissioningDeviceIp,
2438
2508
  update: true,
2439
2509
  gatewayip,
2440
2510
  });
@@ -2442,7 +2512,7 @@ udp-port = 32766
2442
2512
  }
2443
2513
  case 'open-virtual-root': {
2444
2514
  dotenv.config({ path: `${getUnderpostRootPath()}/.env`, override: true });
2445
- const IP_ADDRESS = getLocalIPv4Address();
2515
+ const controlServerIp = getLocalIPv4Address();
2446
2516
  const architecture = process.argv[3];
2447
2517
  const host = process.argv[4];
2448
2518
  const nfsHostPath = `${process.env.NFS_EXPORT_PATH}/${host}`;
@@ -2516,14 +2586,14 @@ EOF`);
2516
2586
  if (process.argv.includes('build')) {
2517
2587
  switch (host) {
2518
2588
  case 'rpi4mb':
2519
- const ipaddr = process.env.RPI4_IP;
2589
+ const commissioningDeviceIp = process.env.RPI4_IP;
2520
2590
 
2521
2591
  await updateVirtualRoot({
2522
- IP_ADDRESS,
2592
+ controlServerIp,
2523
2593
  architecture,
2524
2594
  host,
2525
2595
  nfsHostPath,
2526
- ipaddr,
2596
+ commissioningDeviceIp,
2527
2597
  gatewayip,
2528
2598
  });
2529
2599
 
@@ -2574,10 +2644,10 @@ EOF`);
2574
2644
 
2575
2645
  case 'create-ports': {
2576
2646
  const cmd = [];
2577
- const ipaddr = getLocalIPv4Address();
2647
+ const commissioningDeviceIp = getLocalIPv4Address();
2578
2648
  for (const port of ['5240']) {
2579
2649
  const name = 'maas';
2580
- cmd.push(`${name}:${port}-${port}:${ipaddr}`);
2650
+ cmd.push(`${name}:${port}-${port}:${commissioningDeviceIp}`);
2581
2651
  }
2582
2652
  pbcopy(`node engine-private/r create-port ${cmd}`);
2583
2653
  break;
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.8.817
1
+ ## underpost ci/cd cli v2.8.818
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.817'
61
+ engine.version: '2.8.818'
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.817
20
+ image: localhost/rockylinux9-underpost:v2.8.818
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.817
103
+ image: localhost/rockylinux9-underpost:v2.8.818
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env bash
2
+
3
+ for iface_path in /sys/class/net/*; do
4
+ name=$(basename "$iface_path")
5
+ mac=$(< "$iface_path/address")
6
+ ip=$(ip -4 addr show dev "$name" \
7
+ | grep -oP '(?<=inet\s)\d+(\.\d+){3}' || echo "—")
8
+ operstate=$(< "$iface_path/operstate")
9
+ mtu=$(< "$iface_path/mtu")
10
+
11
+ # Driver: módulo kernel que maneja esta interfaz
12
+ if [ -L "$iface_path/device/driver" ]; then
13
+ driver=$(basename "$(readlink -f "$iface_path/device/driver")")
14
+ else
15
+ driver="—"
16
+ fi
17
+
18
+ # Vendor:Device ID PCI
19
+ pci_dev="$iface_path/device"
20
+ if [ -f "$pci_dev/vendor" ] && [ -f "$pci_dev/device" ]; then
21
+ vendor_id=$(< "$pci_dev/vendor")
22
+ device_id=$(< "$pci_dev/device")
23
+ # pasamos de 0x8086 a 8086, etc.
24
+ vendor_id=${vendor_id#0x}
25
+ device_id=${device_id#0x}
26
+ pci="${vendor_id}:${device_id}"
27
+ else
28
+ pci="—"
29
+ fi
30
+
31
+ # Link Speed: lectura directa de /sys/class/net/<iface>/speed
32
+ speed=$(cat "$iface_path/speed" 2>/dev/null || echo "—")
33
+
34
+ echo "Interface: $name"
35
+ echo " MAC: $mac"
36
+ echo " IPv4: $ip"
37
+ echo " Estado: $operstate"
38
+ echo " MTU: $mtu"
39
+ echo " Driver: $driver"
40
+ echo " PCI Vendor:Device ID: $pci"
41
+ echo " Link Speed: ${speed}Mb/s"
42
+ echo
43
+ done
@@ -9,25 +9,6 @@ sudo snap install maas
9
9
  INTERFACE=$(ip route | grep default | awk '{print $5}')
10
10
  IP_ADDRESS=$(ip -4 addr show dev "$INTERFACE" | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
11
11
 
12
- # Disable firewalld
13
- sudo systemctl disable --now iptables
14
- sudo systemctl disable --now ufw
15
- sudo systemctl disable --now firewalld
16
-
17
- # Enable IP forwarding and configure NAT
18
- echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
19
- echo "net.ipv6.conf.all.forwarding = 1" | sudo tee -a /etc/sysctl.conf
20
- sudo sysctl -p
21
-
22
- # Accept all traffic
23
- sudo iptables -P INPUT ACCEPT
24
- sudo iptables -P FORWARD ACCEPT
25
- sudo iptables -P OUTPUT ACCEPT
26
-
27
- # List iptables rules
28
- sudo iptables -L -n
29
- sysctl net.ipv4.ip_forward
30
-
31
12
  cd /home/dd/engine
32
13
 
33
14
  # Load secrets
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ # Disable firewalld
5
+ sudo systemctl disable --now iptables
6
+ sudo systemctl disable --now ufw
7
+ sudo systemctl disable --now firewalld
8
+
9
+ # Enable IP forwarding and configure NAT
10
+ echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
11
+ echo "net.ipv6.conf.all.forwarding = 1" | sudo tee -a /etc/sysctl.conf
12
+ sudo sysctl -p
13
+
14
+ # Accept all traffic
15
+ sudo iptables -P INPUT ACCEPT
16
+ sudo iptables -P FORWARD ACCEPT
17
+ sudo iptables -P OUTPUT ACCEPT
18
+
19
+ # List iptables rules
20
+ sudo iptables -L -n
21
+ sysctl net.ipv4.ip_forward
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.817",
5
+ "version": "2.8.818",
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",
@@ -66,6 +66,7 @@ maas login "$MAAS_ADMIN_USERNAME" "http://localhost:5240/MAAS/" "$APIKEY"`);
66
66
  if (options.controlServerInstall === true) {
67
67
  shellExec(`chmod +x ${underpostRoot}/manifests/maas/maas-setup.sh`);
68
68
  shellExec(`${underpostRoot}/manifests/maas/maas-setup.sh`);
69
+ shellExec(`${underpostRoot}/manifests/maas/nat-iptables.sh`);
69
70
  }
70
71
  if (options.controlServerInit === true) {
71
72
  shellExec(`node ${underpostRoot}/bin/deploy maas reset`);
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.817';
35
+ static version = 'v2.8.818';
36
36
  /**
37
37
  * Repository cli API
38
38
  * @static