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 +1 -1
- package/bin/deploy.js +220 -150
- package/cli.md +1 -1
- package/docker-compose.yml +1 -1
- package/manifests/deployment/dd-template-development/deployment.yaml +2 -2
- package/manifests/maas/device-scan.sh +43 -0
- package/manifests/maas/maas-setup.sh +0 -19
- package/manifests/maas/nat-iptables.sh +21 -0
- package/package.json +1 -1
- package/src/cli/baremetal.js +1 -0
- package/src/index.js +1 -1
package/README.md
CHANGED
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
|
-
|
|
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
|
-
{
|
|
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://${
|
|
129
|
-
# metadata_url: http://${
|
|
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://${
|
|
142
|
+
metadata_url: http://${controlServerIp}:5240/MAAS/metadata/
|
|
141
143
|
${
|
|
142
|
-
|
|
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
|
-
|
|
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
|
-
- ${
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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/
|
|
374
|
+
logger.info('Build', `${nfsHostPath}/underpost/keys_current.sh`);
|
|
371
375
|
fs.writeFileSync(
|
|
372
|
-
`${nfsHostPath}/underpost/
|
|
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/
|
|
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 ({
|
|
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
|
-
|
|
538
|
-
|
|
588
|
+
auth: true,
|
|
589
|
+
controlServerIp,
|
|
539
590
|
architecture,
|
|
540
591
|
host,
|
|
541
592
|
nfsHostPath,
|
|
542
|
-
|
|
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
|
-
|
|
606
|
+
auth: false,
|
|
607
|
+
controlServerIp,
|
|
555
608
|
architecture,
|
|
556
609
|
host,
|
|
557
610
|
nfsHostPath,
|
|
558
|
-
|
|
611
|
+
commissioningDeviceIp,
|
|
559
612
|
update,
|
|
560
613
|
gatewayip,
|
|
561
614
|
},
|
|
562
615
|
{ consumer_key, consumer_secret, token_key, token_secret },
|
|
563
|
-
'/underpost/
|
|
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
|
-
|
|
1748
|
-
|
|
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
|
|
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
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
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
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
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) =>
|
|
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('
|
|
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
|
-
|
|
1844
|
-
|
|
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=${
|
|
2098
|
-
// `nfsroot=${
|
|
2099
|
-
`ip=${
|
|
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
|
-
|
|
2174
|
-
|
|
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,${
|
|
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
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
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(
|
|
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.
|
|
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 =
|
|
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
|
-
//
|
|
2343
|
-
|
|
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
|
|
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
|
|
2500
|
+
const commissioningDeviceIp = process.env.RPI4_IP;
|
|
2431
2501
|
const gatewayip = process.env.GATEWAY_IP;
|
|
2432
2502
|
await updateVirtualRoot({
|
|
2433
|
-
|
|
2503
|
+
controlServerIp,
|
|
2434
2504
|
architecture,
|
|
2435
2505
|
host,
|
|
2436
2506
|
nfsHostPath,
|
|
2437
|
-
|
|
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
|
|
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
|
|
2589
|
+
const commissioningDeviceIp = process.env.RPI4_IP;
|
|
2520
2590
|
|
|
2521
2591
|
await updateVirtualRoot({
|
|
2522
|
-
|
|
2592
|
+
controlServerIp,
|
|
2523
2593
|
architecture,
|
|
2524
2594
|
host,
|
|
2525
2595
|
nfsHostPath,
|
|
2526
|
-
|
|
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
|
|
2647
|
+
const commissioningDeviceIp = getLocalIPv4Address();
|
|
2578
2648
|
for (const port of ['5240']) {
|
|
2579
2649
|
const name = 'maas';
|
|
2580
|
-
cmd.push(`${name}:${port}-${port}:${
|
|
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
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.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.
|
|
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
package/src/cli/baremetal.js
CHANGED
|
@@ -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`);
|