@underpostnet/underpost 2.98.3 → 2.99.1
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/.env.development +1 -0
- package/.env.production +1 -0
- package/.env.test +1 -0
- package/README.md +2 -3
- package/bin/deploy.js +1 -1
- package/cli.md +113 -110
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/dd-test-development/deployment.yaml +4 -4
- package/package.json +1 -2
- package/src/api/user/user.router.js +7 -40
- package/src/cli/baremetal.js +67 -71
- package/src/cli/cloud-init.js +11 -12
- package/src/cli/cluster.js +22 -24
- package/src/cli/db.js +43 -50
- package/src/cli/deploy.js +163 -61
- package/src/cli/env.js +20 -5
- package/src/cli/fs.js +19 -21
- package/src/cli/index.js +38 -32
- package/src/cli/lxd.js +5 -5
- package/src/cli/monitor.js +83 -88
- package/src/cli/repository.js +7 -6
- package/src/cli/run.js +498 -288
- package/src/cli/secrets.js +3 -3
- package/src/cli/ssh.js +80 -32
- package/src/cli/static.js +1 -1
- package/src/cli/test.js +6 -7
- package/src/index.js +49 -32
- package/src/runtime/express/Express.js +7 -6
- package/src/server/auth.js +6 -1
- package/src/server/backup.js +11 -1
- package/src/server/conf.js +4 -4
- package/src/{cli → server}/cron.js +56 -29
- package/src/server/dns.js +39 -31
- package/src/server/peer.js +2 -2
- package/src/server/process.js +2 -2
- package/src/server/proxy.js +8 -7
- package/src/server/runtime.js +4 -7
- package/src/server/start.js +28 -15
- package/src/ws/IoServer.js +2 -3
- package/scripts/ssh-cluster-info.sh +0 -15
- package/src/cli/script.js +0 -85
- package/src/monitor.js +0 -34
package/src/cli/baremetal.js
CHANGED
|
@@ -9,12 +9,9 @@ import { getNpmRootPath, getUnderpostRootPath } from '../server/conf.js';
|
|
|
9
9
|
import { openTerminal, pbcopy, shellExec } from '../server/process.js';
|
|
10
10
|
import dotenv from 'dotenv';
|
|
11
11
|
import { loggerFactory } from '../server/logger.js';
|
|
12
|
-
import { getLocalIPv4Address } from '../server/dns.js';
|
|
13
12
|
import fs from 'fs-extra';
|
|
14
13
|
import path from 'path';
|
|
15
14
|
import Downloader from '../server/downloader.js';
|
|
16
|
-
import UnderpostCloudInit from './cloud-init.js';
|
|
17
|
-
import UnderpostRepository from './repository.js';
|
|
18
15
|
import { newInstance, range, s4, timer } from '../client/components/core/CommonJs.js';
|
|
19
16
|
import { spawnSync } from 'child_process';
|
|
20
17
|
import Underpost from '../index.js';
|
|
@@ -153,7 +150,7 @@ class UnderpostBaremetal {
|
|
|
153
150
|
workflowId = workflowId ? workflowId : 'rpi4mbarm64-iso-ram';
|
|
154
151
|
hostname = hostname ? hostname : workflowId;
|
|
155
152
|
ipAddress = ipAddress ? ipAddress : '192.168.1.191';
|
|
156
|
-
ipFileServer = ipFileServer ? ipFileServer : getLocalIPv4Address();
|
|
153
|
+
ipFileServer = ipFileServer ? ipFileServer : Underpost.dns.getLocalIPv4Address();
|
|
157
154
|
netmask = netmask ? netmask : '255.255.255.0';
|
|
158
155
|
dnsServer = dnsServer ? dnsServer : '8.8.8.8';
|
|
159
156
|
|
|
@@ -166,8 +163,8 @@ class UnderpostBaremetal {
|
|
|
166
163
|
ipConfig = ipConfig ? ipConfig : 'none';
|
|
167
164
|
|
|
168
165
|
// Set default MAC address
|
|
169
|
-
let macAddress =
|
|
170
|
-
const workflowsConfig =
|
|
166
|
+
let macAddress = Underpost.baremetal.macAddressFactory(options).mac;
|
|
167
|
+
const workflowsConfig = Underpost.baremetal.loadWorkflowsConfig();
|
|
171
168
|
|
|
172
169
|
if (!workflowsConfig[workflowId]) {
|
|
173
170
|
throw new Error(`Workflow configuration not found for ID: ${workflowId}`);
|
|
@@ -207,7 +204,7 @@ class UnderpostBaremetal {
|
|
|
207
204
|
const callbackMetaData = {
|
|
208
205
|
args: { workflowId, ipAddress, hostname, ipFileServer, ipConfig, netmask, dnsServer },
|
|
209
206
|
options,
|
|
210
|
-
runnerHost: { architecture:
|
|
207
|
+
runnerHost: { architecture: Underpost.baremetal.getHostArch().alias, ip: Underpost.dns.getLocalIPv4Address() },
|
|
211
208
|
nfsHostPath,
|
|
212
209
|
tftpRootPath,
|
|
213
210
|
bootstrapHttpServerPath,
|
|
@@ -244,7 +241,7 @@ class UnderpostBaremetal {
|
|
|
244
241
|
});
|
|
245
242
|
|
|
246
243
|
// Create new machine with correct MAC
|
|
247
|
-
machine =
|
|
244
|
+
machine = Underpost.baremetal.machineFactory({
|
|
248
245
|
hostname,
|
|
249
246
|
ipAddress,
|
|
250
247
|
macAddress,
|
|
@@ -263,7 +260,7 @@ class UnderpostBaremetal {
|
|
|
263
260
|
logger.info(`Hardware MAC mode - machine will be created after discovery`);
|
|
264
261
|
machine = null;
|
|
265
262
|
} else {
|
|
266
|
-
machine =
|
|
263
|
+
machine = Underpost.baremetal.machineFactory({
|
|
267
264
|
hostname,
|
|
268
265
|
ipAddress,
|
|
269
266
|
macAddress,
|
|
@@ -274,7 +271,7 @@ class UnderpostBaremetal {
|
|
|
274
271
|
}
|
|
275
272
|
|
|
276
273
|
if (options.installPacker) {
|
|
277
|
-
await
|
|
274
|
+
await Underpost.baremetal.installPacker(underpostRoot);
|
|
278
275
|
return;
|
|
279
276
|
}
|
|
280
277
|
|
|
@@ -292,8 +289,8 @@ class UnderpostBaremetal {
|
|
|
292
289
|
logger.info(`Target directory: ${targetDir}`);
|
|
293
290
|
|
|
294
291
|
try {
|
|
295
|
-
// Use
|
|
296
|
-
const result = await
|
|
292
|
+
// Use Underpost.repo to copy files from GitHub
|
|
293
|
+
const result = await Underpost.repo.copyGitUrlDirectoryRecursive({
|
|
297
294
|
gitUrl: 'https://github.com/canonical/packer-maas',
|
|
298
295
|
directoryPath: templatePath,
|
|
299
296
|
targetPath: targetDir,
|
|
@@ -316,9 +313,9 @@ class UnderpostBaremetal {
|
|
|
316
313
|
},
|
|
317
314
|
};
|
|
318
315
|
|
|
319
|
-
const workflows =
|
|
316
|
+
const workflows = Underpost.baremetal.loadPackerMaasImageBuildWorkflows();
|
|
320
317
|
workflows[workflowId] = workflowConfig;
|
|
321
|
-
|
|
318
|
+
Underpost.baremetal.writePackerMaasImageBuildWorkflows(workflows);
|
|
322
319
|
|
|
323
320
|
logger.info('Template extracted successfully!');
|
|
324
321
|
logger.info(`Added configuration for ${workflowId} to engine/baremetal/packer-workflows.json`);
|
|
@@ -343,7 +340,7 @@ class UnderpostBaremetal {
|
|
|
343
340
|
|
|
344
341
|
workflowId = options.packerWorkflowId;
|
|
345
342
|
|
|
346
|
-
const workflow =
|
|
343
|
+
const workflow = Underpost.baremetal.loadPackerMaasImageBuildWorkflows()[workflowId];
|
|
347
344
|
if (!workflow) {
|
|
348
345
|
throw new Error(`Packer MAAS image build workflow not found: ${workflowId}`);
|
|
349
346
|
}
|
|
@@ -357,7 +354,7 @@ class UnderpostBaremetal {
|
|
|
357
354
|
}
|
|
358
355
|
|
|
359
356
|
// Check for QEMU support if building for a different architecture (validator bots case)
|
|
360
|
-
|
|
357
|
+
Underpost.baremetal.checkQemuCrossArchSupport(workflow);
|
|
361
358
|
|
|
362
359
|
logger.info(`Building Packer image for ${workflowId} in ${packerDir}...`);
|
|
363
360
|
|
|
@@ -562,7 +559,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
562
559
|
|
|
563
560
|
// Handle NFS mount operation.
|
|
564
561
|
if (options.nfsMount === true) {
|
|
565
|
-
await
|
|
562
|
+
await Underpost.baremetal.nfsMountCallback({
|
|
566
563
|
hostname,
|
|
567
564
|
nfsHostPath,
|
|
568
565
|
workflowId,
|
|
@@ -573,7 +570,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
573
570
|
|
|
574
571
|
// Handle NFS unmount operation.
|
|
575
572
|
if (options.nfsUnmount === true) {
|
|
576
|
-
await
|
|
573
|
+
await Underpost.baremetal.nfsMountCallback({
|
|
577
574
|
hostname,
|
|
578
575
|
nfsHostPath,
|
|
579
576
|
workflowId,
|
|
@@ -584,7 +581,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
584
581
|
|
|
585
582
|
// Handle NFS root filesystem build operation.
|
|
586
583
|
if (options.nfsBuild === true) {
|
|
587
|
-
await
|
|
584
|
+
await Underpost.baremetal.nfsMountCallback({
|
|
588
585
|
hostname,
|
|
589
586
|
nfsHostPath,
|
|
590
587
|
workflowId,
|
|
@@ -623,7 +620,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
623
620
|
|
|
624
621
|
// If cross-architecture, copy the QEMU static binary into the chroot.
|
|
625
622
|
if (bootstrapArch !== callbackMetaData.runnerHost.architecture)
|
|
626
|
-
|
|
623
|
+
Underpost.baremetal.crossArchBinFactory({
|
|
627
624
|
nfsHostPath,
|
|
628
625
|
bootstrapArch,
|
|
629
626
|
});
|
|
@@ -634,7 +631,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
634
631
|
shellExec(`file ${nfsHostPath}/bin/bash`); // Verify the bash executable in the chroot.
|
|
635
632
|
|
|
636
633
|
// Mount necessary filesystems and register binfmt for the second stage.
|
|
637
|
-
await
|
|
634
|
+
await Underpost.baremetal.nfsMountCallback({
|
|
638
635
|
hostname,
|
|
639
636
|
nfsHostPath,
|
|
640
637
|
workflowId,
|
|
@@ -643,7 +640,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
643
640
|
|
|
644
641
|
// Perform the second stage of debootstrap within the chroot environment.
|
|
645
642
|
if (workflowsConfig[workflowId].type === 'chroot-debootstrap') {
|
|
646
|
-
|
|
643
|
+
Underpost.baremetal.crossArchRunner({
|
|
647
644
|
nfsHostPath,
|
|
648
645
|
bootstrapArch,
|
|
649
646
|
callbackMetaData,
|
|
@@ -675,7 +672,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
675
672
|
];
|
|
676
673
|
const allPackages = packages && packages.length > 0 ? [...basePackages, ...packages] : basePackages;
|
|
677
674
|
|
|
678
|
-
|
|
675
|
+
Underpost.baremetal.crossArchRunner({
|
|
679
676
|
nfsHostPath,
|
|
680
677
|
bootstrapArch,
|
|
681
678
|
callbackMetaData,
|
|
@@ -764,18 +761,18 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
764
761
|
console.table(machines);
|
|
765
762
|
}
|
|
766
763
|
|
|
767
|
-
if (options.clearDiscovered)
|
|
764
|
+
if (options.clearDiscovered) Underpost.baremetal.removeDiscoveredMachines();
|
|
768
765
|
|
|
769
766
|
// Handle remove existing machines from MAAS.
|
|
770
767
|
if (options.removeMachines)
|
|
771
|
-
machines =
|
|
768
|
+
machines = Underpost.baremetal.removeMachines({
|
|
772
769
|
machines: options.removeMachines === 'all' ? machines : options.removeMachines.split(','),
|
|
773
770
|
ignore: machine ? [machine.system_id] : [],
|
|
774
771
|
});
|
|
775
772
|
|
|
776
773
|
if (workflowsConfig[workflowId].type === 'chroot-debootstrap') {
|
|
777
774
|
if (options.ubuntuToolsBuild) {
|
|
778
|
-
|
|
775
|
+
Underpost.cloudInit.buildTools({
|
|
779
776
|
workflowId,
|
|
780
777
|
nfsHostPath,
|
|
781
778
|
hostname,
|
|
@@ -787,24 +784,24 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
787
784
|
const { timezone, chronyConfPath } = chronyc;
|
|
788
785
|
const systemProvisioning = 'ubuntu';
|
|
789
786
|
|
|
790
|
-
|
|
787
|
+
Underpost.baremetal.crossArchRunner({
|
|
791
788
|
nfsHostPath,
|
|
792
789
|
bootstrapArch,
|
|
793
790
|
callbackMetaData,
|
|
794
791
|
steps: [
|
|
795
|
-
...
|
|
796
|
-
...
|
|
797
|
-
...
|
|
792
|
+
...Underpost.baremetal.systemProvisioningFactory[systemProvisioning].base(),
|
|
793
|
+
...Underpost.baremetal.systemProvisioningFactory[systemProvisioning].user(),
|
|
794
|
+
...Underpost.baremetal.systemProvisioningFactory[systemProvisioning].timezone({
|
|
798
795
|
timezone,
|
|
799
796
|
chronyConfPath,
|
|
800
797
|
}),
|
|
801
|
-
...
|
|
798
|
+
...Underpost.baremetal.systemProvisioningFactory[systemProvisioning].keyboard(keyboard.layout),
|
|
802
799
|
],
|
|
803
800
|
});
|
|
804
801
|
}
|
|
805
802
|
|
|
806
803
|
if (options.ubuntuToolsTest)
|
|
807
|
-
|
|
804
|
+
Underpost.baremetal.crossArchRunner({
|
|
808
805
|
nfsHostPath,
|
|
809
806
|
bootstrapArch,
|
|
810
807
|
callbackMetaData,
|
|
@@ -841,24 +838,24 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
841
838
|
const { timezone } = chronyc;
|
|
842
839
|
const systemProvisioning = 'rocky';
|
|
843
840
|
|
|
844
|
-
|
|
841
|
+
Underpost.baremetal.crossArchRunner({
|
|
845
842
|
nfsHostPath,
|
|
846
843
|
bootstrapArch,
|
|
847
844
|
callbackMetaData,
|
|
848
845
|
steps: [
|
|
849
|
-
...
|
|
850
|
-
...
|
|
851
|
-
...
|
|
846
|
+
...Underpost.baremetal.systemProvisioningFactory[systemProvisioning].base(),
|
|
847
|
+
...Underpost.baremetal.systemProvisioningFactory[systemProvisioning].user(),
|
|
848
|
+
...Underpost.baremetal.systemProvisioningFactory[systemProvisioning].timezone({
|
|
852
849
|
timezone,
|
|
853
850
|
chronyConfPath: chronyc.chronyConfPath,
|
|
854
851
|
}),
|
|
855
|
-
...
|
|
852
|
+
...Underpost.baremetal.systemProvisioningFactory[systemProvisioning].keyboard(keyboard.layout),
|
|
856
853
|
],
|
|
857
854
|
});
|
|
858
855
|
}
|
|
859
856
|
|
|
860
857
|
if (options.rockyToolsTest)
|
|
861
|
-
|
|
858
|
+
Underpost.baremetal.crossArchRunner({
|
|
862
859
|
nfsHostPath,
|
|
863
860
|
bootstrapArch,
|
|
864
861
|
callbackMetaData,
|
|
@@ -879,8 +876,8 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
879
876
|
if (options.cloudInit || options.cloudInitUpdate) {
|
|
880
877
|
const { chronyc, networkInterfaceName } = workflowsConfig[workflowId];
|
|
881
878
|
const { timezone, chronyConfPath } = chronyc;
|
|
882
|
-
const authCredentials =
|
|
883
|
-
const { cloudConfigSrc } =
|
|
879
|
+
const authCredentials = Underpost.cloudInit.authCredentialsFactory();
|
|
880
|
+
const { cloudConfigSrc } = Underpost.cloudInit.configFactory(
|
|
884
881
|
{
|
|
885
882
|
controlServerIp: callbackMetaData.runnerHost.ip,
|
|
886
883
|
hostname,
|
|
@@ -897,7 +894,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
897
894
|
authCredentials,
|
|
898
895
|
);
|
|
899
896
|
|
|
900
|
-
|
|
897
|
+
Underpost.baremetal.httpBootstrapServerStaticFactory({
|
|
901
898
|
bootstrapHttpServerPath,
|
|
902
899
|
hostname,
|
|
903
900
|
cloudConfigSrc,
|
|
@@ -912,7 +909,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
912
909
|
workflowsConfig[workflowId].type === 'chroot-container')
|
|
913
910
|
) {
|
|
914
911
|
shellExec(`${underpostRoot}/scripts/nat-iptables.sh`, { silent: true });
|
|
915
|
-
|
|
912
|
+
Underpost.baremetal.rebuildNfsServer({
|
|
916
913
|
nfsHostPath,
|
|
917
914
|
});
|
|
918
915
|
}
|
|
@@ -958,7 +955,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
958
955
|
shellExec(`sudo cp -a ${path}/* ${tftpRootPath}`); // Copy firmware files to TFTP root.
|
|
959
956
|
|
|
960
957
|
if (gateway && subnet) {
|
|
961
|
-
const bootConfSrc =
|
|
958
|
+
const bootConfSrc = Underpost.baremetal.bootConfFactory({
|
|
962
959
|
workflowId,
|
|
963
960
|
tftpIp: callbackMetaData.runnerHost.ip,
|
|
964
961
|
tftpPrefixStr: tftpPrefix,
|
|
@@ -985,7 +982,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
985
982
|
'initrd.img': `${nfsHostPath}/boot/initrd.img`,
|
|
986
983
|
};
|
|
987
984
|
} else {
|
|
988
|
-
const kf =
|
|
985
|
+
const kf = Underpost.baremetal.kernelFactory({
|
|
989
986
|
resource,
|
|
990
987
|
type,
|
|
991
988
|
nfsHostPath,
|
|
@@ -996,7 +993,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
996
993
|
resourcesPath = kf.resourcesPath;
|
|
997
994
|
}
|
|
998
995
|
|
|
999
|
-
const { cmd } =
|
|
996
|
+
const { cmd } = Underpost.baremetal.kernelCmdBootParamsFactory({
|
|
1000
997
|
ipClient: ipAddress,
|
|
1001
998
|
ipDhcpServer: callbackMetaData.runnerHost.ip,
|
|
1002
999
|
ipConfig,
|
|
@@ -1020,7 +1017,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1020
1017
|
let useIpxe = options.ipxe;
|
|
1021
1018
|
if (options.ipxe) {
|
|
1022
1019
|
const arch = commissioningImage.architecture.split('/')[0];
|
|
1023
|
-
const ipxeScript =
|
|
1020
|
+
const ipxeScript = Underpost.baremetal.ipxeScriptFactory({
|
|
1024
1021
|
maasIp: callbackMetaData.runnerHost.ip,
|
|
1025
1022
|
macAddress,
|
|
1026
1023
|
architecture: arch,
|
|
@@ -1030,7 +1027,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1030
1027
|
fs.writeFileSync(`${tftpRootPath}/stable-id.ipxe`, ipxeScript, 'utf8');
|
|
1031
1028
|
|
|
1032
1029
|
// Create embedded boot script that does DHCP and chains to the main script
|
|
1033
|
-
const embeddedScript =
|
|
1030
|
+
const embeddedScript = Underpost.baremetal.ipxeEmbeddedScriptFactory({
|
|
1034
1031
|
tftpServer: callbackMetaData.runnerHost.ip,
|
|
1035
1032
|
scriptPath: `/${tftpPrefix}/stable-id.ipxe`,
|
|
1036
1033
|
macAddress: macAddress,
|
|
@@ -1043,7 +1040,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1043
1040
|
embeddedPath: `${tftpRootPath}/boot.ipxe`,
|
|
1044
1041
|
});
|
|
1045
1042
|
|
|
1046
|
-
|
|
1043
|
+
Underpost.baremetal.ipxeEfiFactory({
|
|
1047
1044
|
tftpRootPath,
|
|
1048
1045
|
ipxeCacheDir,
|
|
1049
1046
|
arch,
|
|
@@ -1053,7 +1050,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1053
1050
|
});
|
|
1054
1051
|
}
|
|
1055
1052
|
|
|
1056
|
-
const { grubCfgSrc } =
|
|
1053
|
+
const { grubCfgSrc } = Underpost.baremetal.grubFactory({
|
|
1057
1054
|
menuentryStr,
|
|
1058
1055
|
kernelPath: `/${tftpPrefix}/pxe/vmlinuz-efi`,
|
|
1059
1056
|
initrdPath: `/${tftpPrefix}/pxe/initrd.img`,
|
|
@@ -1062,13 +1059,13 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1062
1059
|
ipxe: useIpxe,
|
|
1063
1060
|
ipxePath: `/${tftpPrefix}/ipxe.efi`,
|
|
1064
1061
|
});
|
|
1065
|
-
|
|
1062
|
+
Underpost.baremetal.writeGrubConfigToFile({
|
|
1066
1063
|
grubCfgSrc: machine ? grubCfgSrc.replaceAll('system-id', machine.system_id) : grubCfgSrc,
|
|
1067
1064
|
});
|
|
1068
1065
|
if (machine) {
|
|
1069
1066
|
logger.info('✓ GRUB config written with system_id', { system_id: machine.system_id });
|
|
1070
1067
|
}
|
|
1071
|
-
|
|
1068
|
+
Underpost.baremetal.updateKernelFiles({
|
|
1072
1069
|
commissioningImage,
|
|
1073
1070
|
resourcesPath,
|
|
1074
1071
|
tftpRootPath,
|
|
@@ -1078,13 +1075,13 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1078
1075
|
|
|
1079
1076
|
// Pass architecture from commissioning or deployment config
|
|
1080
1077
|
const grubArch = commissioningImage.architecture;
|
|
1081
|
-
|
|
1078
|
+
Underpost.baremetal.efiGrubModulesFactory({ image: { architecture: grubArch } });
|
|
1082
1079
|
|
|
1083
1080
|
// Set ownership and permissions for TFTP root.
|
|
1084
1081
|
shellExec(`sudo chown -R $(whoami):$(whoami) ${process.env.TFTP_ROOT}`);
|
|
1085
1082
|
shellExec(`sudo sudo chmod 755 ${process.env.TFTP_ROOT}`);
|
|
1086
1083
|
|
|
1087
|
-
|
|
1084
|
+
Underpost.baremetal.httpBootstrapServerRunnerFactory({
|
|
1088
1085
|
hostname,
|
|
1089
1086
|
bootstrapHttpServerPath,
|
|
1090
1087
|
bootstrapHttpServerPort:
|
|
@@ -1092,7 +1089,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1092
1089
|
});
|
|
1093
1090
|
|
|
1094
1091
|
if (type === 'chroot-debootstrap' || type === 'chroot-container')
|
|
1095
|
-
await
|
|
1092
|
+
await Underpost.baremetal.nfsMountCallback({
|
|
1096
1093
|
hostname,
|
|
1097
1094
|
nfsHostPath,
|
|
1098
1095
|
workflowId,
|
|
@@ -1115,7 +1112,7 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1115
1112
|
machine: machine ? machine.system_id : null,
|
|
1116
1113
|
});
|
|
1117
1114
|
|
|
1118
|
-
const { discovery } = await
|
|
1115
|
+
const { discovery } = await Underpost.baremetal.commissionMonitor(commissionMonitorPayload);
|
|
1119
1116
|
|
|
1120
1117
|
if ((type === 'chroot-debootstrap' || type === 'chroot-container') && options.cloudInit === true) {
|
|
1121
1118
|
openTerminal(`node ${underpostRoot}/bin baremetal ${workflowId} ${ipAddress} ${hostname} --logs cloud-init`);
|
|
@@ -1314,8 +1311,8 @@ rm -rf ${artifacts.join(' ')}`);
|
|
|
1314
1311
|
if (type === 'iso-ram' || type === 'iso-nfs') {
|
|
1315
1312
|
logger.info('Using live ISO for boot (disk-based commissioning)');
|
|
1316
1313
|
const arch = resource.architecture.split('/')[0];
|
|
1317
|
-
const workflowsConfig =
|
|
1318
|
-
const kernelFilesPaths =
|
|
1314
|
+
const workflowsConfig = Underpost.baremetal.loadWorkflowsConfig();
|
|
1315
|
+
const kernelFilesPaths = Underpost.baremetal.downloadISO({
|
|
1319
1316
|
resource,
|
|
1320
1317
|
architecture: arch,
|
|
1321
1318
|
nfsHostPath,
|
|
@@ -2213,7 +2210,7 @@ shell
|
|
|
2213
2210
|
);
|
|
2214
2211
|
|
|
2215
2212
|
for (const discovery of discoveries) {
|
|
2216
|
-
const
|
|
2213
|
+
const discoverHostname = discovery.hostname
|
|
2217
2214
|
? discovery.hostname
|
|
2218
2215
|
: discovery.mac_organization
|
|
2219
2216
|
? discovery.mac_organization
|
|
@@ -2221,7 +2218,7 @@ shell
|
|
|
2221
2218
|
? discovery.domain
|
|
2222
2219
|
: `generic-host-${s4()}${s4()}`;
|
|
2223
2220
|
|
|
2224
|
-
console.log(
|
|
2221
|
+
console.log(discoverHostname.bgBlue.bold.white);
|
|
2225
2222
|
console.log('ip target:'.green + ipAddress, 'ip discovered:'.green + discovery.ip);
|
|
2226
2223
|
console.log('mac target:'.green + macAddress, 'mac discovered:'.green + discovery.mac_address);
|
|
2227
2224
|
|
|
@@ -2233,18 +2230,17 @@ shell
|
|
|
2233
2230
|
ipAddress,
|
|
2234
2231
|
hostname,
|
|
2235
2232
|
});
|
|
2236
|
-
machine =
|
|
2233
|
+
machine = Underpost.baremetal.machineFactory({
|
|
2237
2234
|
ipAddress,
|
|
2238
2235
|
macAddress: discovery.mac_address,
|
|
2239
2236
|
hostname,
|
|
2240
2237
|
architecture,
|
|
2241
2238
|
}).machine;
|
|
2242
2239
|
console.log('New machine system id:', machine.system_id.bgYellow.bold.black);
|
|
2243
|
-
|
|
2244
|
-
grubCfgSrc:
|
|
2245
|
-
|
|
2246
|
-
machine.system_id,
|
|
2247
|
-
),
|
|
2240
|
+
Underpost.baremetal.writeGrubConfigToFile({
|
|
2241
|
+
grubCfgSrc: Underpost.baremetal
|
|
2242
|
+
.getGrubConfigFromFile()
|
|
2243
|
+
.grubCfgSrc.replaceAll('system-id', machine.system_id),
|
|
2248
2244
|
});
|
|
2249
2245
|
} else {
|
|
2250
2246
|
const systemId = machine.system_id;
|
|
@@ -2292,7 +2288,7 @@ shell
|
|
|
2292
2288
|
}
|
|
2293
2289
|
}
|
|
2294
2290
|
await timer(1000);
|
|
2295
|
-
return await
|
|
2291
|
+
return await Underpost.baremetal.commissionMonitor({
|
|
2296
2292
|
macAddress,
|
|
2297
2293
|
ipAddress,
|
|
2298
2294
|
hostname,
|
|
@@ -2373,7 +2369,7 @@ shell
|
|
|
2373
2369
|
return;
|
|
2374
2370
|
}
|
|
2375
2371
|
await timer(1000);
|
|
2376
|
-
await
|
|
2372
|
+
await Underpost.baremetal.macMonitor({ nfsHostPath });
|
|
2377
2373
|
},
|
|
2378
2374
|
|
|
2379
2375
|
/**
|
|
@@ -2420,7 +2416,7 @@ shell
|
|
|
2420
2416
|
*/
|
|
2421
2417
|
crossArchRunner({ nfsHostPath, bootstrapArch, callbackMetaData, steps }) {
|
|
2422
2418
|
// Render the steps with logging for better visibility during execution.
|
|
2423
|
-
steps =
|
|
2419
|
+
steps = Underpost.baremetal.stepsRender(steps, false);
|
|
2424
2420
|
|
|
2425
2421
|
let qemuCrossArchBash = '';
|
|
2426
2422
|
// Determine if QEMU is needed for cross-architecture execution.
|
|
@@ -2491,10 +2487,10 @@ EOF`);
|
|
|
2491
2487
|
*/
|
|
2492
2488
|
async nfsMountCallback({ hostname, nfsHostPath, workflowId, mount, unmount }, currentRecall = 0, maxRecalls = 5) {
|
|
2493
2489
|
// Mount binfmt_misc filesystem.
|
|
2494
|
-
if (mount)
|
|
2490
|
+
if (mount) Underpost.baremetal.mountBinfmtMisc();
|
|
2495
2491
|
const unMountCmds = [];
|
|
2496
2492
|
const mountCmds = [];
|
|
2497
|
-
const workflowsConfig =
|
|
2493
|
+
const workflowsConfig = Underpost.baremetal.loadWorkflowsConfig();
|
|
2498
2494
|
let recall = false;
|
|
2499
2495
|
if (!workflowsConfig[workflowId]) {
|
|
2500
2496
|
throw new Error(`Workflow configuration not found for ID: ${workflowId}`);
|
|
@@ -2542,7 +2538,7 @@ EOF`);
|
|
|
2542
2538
|
}
|
|
2543
2539
|
logger.info(`nfsMountCallback recall attempt ${currentRecall + 1}/${maxRecalls} for hostname: ${hostname}`);
|
|
2544
2540
|
await timer(1000);
|
|
2545
|
-
return await
|
|
2541
|
+
return await Underpost.baremetal.nfsMountCallback(
|
|
2546
2542
|
{ hostname, nfsHostPath, workflowId, mount, unmount },
|
|
2547
2543
|
currentRecall + 1,
|
|
2548
2544
|
maxRecalls,
|
package/src/cli/cloud-init.js
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
import dotenv from 'dotenv';
|
|
9
9
|
import { shellExec } from '../server/process.js';
|
|
10
10
|
import fs from 'fs-extra';
|
|
11
|
-
import UnderpostBaremetal from './baremetal.js';
|
|
12
11
|
import { loggerFactory } from '../server/logger.js';
|
|
13
12
|
import { getNpmRootPath } from '../server/conf.js';
|
|
13
|
+
import Underpost from '../index.js';
|
|
14
14
|
|
|
15
15
|
dotenv.config();
|
|
16
16
|
|
|
@@ -43,7 +43,7 @@ class UnderpostCloudInit {
|
|
|
43
43
|
buildTools({ workflowId, nfsHostPath, hostname, callbackMetaData, dev }) {
|
|
44
44
|
// Destructure workflow configuration for easier access.
|
|
45
45
|
const { chronyc, networkInterfaceName, debootstrap, keyboard } =
|
|
46
|
-
|
|
46
|
+
Underpost.baremetal.loadWorkflowsConfig()[workflowId];
|
|
47
47
|
const { timezone, chronyConfPath } = chronyc;
|
|
48
48
|
// Define the specific directory for underpost tools within the NFS host path.
|
|
49
49
|
const nfsHostToolsPath = `${nfsHostPath}/underpost`;
|
|
@@ -63,8 +63,8 @@ class UnderpostCloudInit {
|
|
|
63
63
|
logger.info('Build', `${nfsHostToolsPath}/date.sh`);
|
|
64
64
|
fs.writeFileSync(
|
|
65
65
|
`${nfsHostToolsPath}/date.sh`,
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
Underpost.baremetal.stepsRender(
|
|
67
|
+
Underpost.baremetal.systemProvisioningFactory[systemProvisioning].timezone({
|
|
68
68
|
timezone,
|
|
69
69
|
chronyConfPath,
|
|
70
70
|
}),
|
|
@@ -77,8 +77,8 @@ class UnderpostCloudInit {
|
|
|
77
77
|
logger.info('Build', `${nfsHostToolsPath}/keyboard.sh`);
|
|
78
78
|
fs.writeFileSync(
|
|
79
79
|
`${nfsHostToolsPath}/keyboard.sh`,
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
Underpost.baremetal.stepsRender(
|
|
81
|
+
Underpost.baremetal.systemProvisioningFactory[systemProvisioning].keyboard(keyboard.layout),
|
|
82
82
|
false,
|
|
83
83
|
),
|
|
84
84
|
'utf8',
|
|
@@ -109,7 +109,7 @@ ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf`,
|
|
|
109
109
|
`#!/bin/bash
|
|
110
110
|
set -x
|
|
111
111
|
# sudo cloud-init --all-stages
|
|
112
|
-
${
|
|
112
|
+
${Underpost.baremetal.stepsRender(
|
|
113
113
|
[
|
|
114
114
|
`/underpost/date.sh`,
|
|
115
115
|
`sleep 3`,
|
|
@@ -292,10 +292,9 @@ curl -X POST \\
|
|
|
292
292
|
if (ubuntuToolsBuild) {
|
|
293
293
|
bootcmd = [
|
|
294
294
|
...bootcmd,
|
|
295
|
-
...
|
|
296
|
-
[`/underpost/dns.sh`, `/underpost/host.sh`, `/underpost/mac.sh`, `cat /underpost/mac`],
|
|
297
|
-
|
|
298
|
-
).split('\n'),
|
|
295
|
+
...Underpost.baremetal
|
|
296
|
+
.stepsRender([`/underpost/dns.sh`, `/underpost/host.sh`, `/underpost/mac.sh`, `cat /underpost/mac`], false)
|
|
297
|
+
.split('\n'),
|
|
299
298
|
];
|
|
300
299
|
}
|
|
301
300
|
|
|
@@ -313,7 +312,7 @@ curl -X POST \\
|
|
|
313
312
|
runcmd = [...runcmd, ...runcmdParam.split(',')];
|
|
314
313
|
}
|
|
315
314
|
|
|
316
|
-
const cloudConfigSrc =
|
|
315
|
+
const cloudConfigSrc = Underpost.cloudInit.generateCloudConfig({
|
|
317
316
|
hostname,
|
|
318
317
|
fqdn: `${hostname}.maas`,
|
|
319
318
|
datasource_list: ['MAAS'],
|