36
36
sshConnection=
37
37
postKexecSshPort=22
38
38
buildOnRemote=n
39
+ buildOn=auto
39
40
envPassword=n
40
41
41
42
# Facts set by get-facts.sh
@@ -129,8 +130,11 @@ Options:
129
130
* --disko-mode disko|mount|format
130
131
set the disko mode to format, mount or destroy. Default is disko.
131
132
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
132
- mount: mount the partition at the specified root-mountpoint
133
- format: create partition tables, zpools, lvms, raids and filesystems (Experimental: Can be run increntally, but use with caution and good backups)
133
+ * --build-on auto|remote|local
134
+ sets the build on settings to auto, remote or local. Default is auto.
135
+ auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build
136
+ local: will build on the local host
137
+ remote: will build on the remote host
134
138
USAGE
135
139
}
136
140
@@ -146,6 +150,7 @@ step() {
146
150
parseArgs () {
147
151
local substituteOnDestination=y
148
152
local printBuildLogs=n
153
+ local buildOnRemote=n
149
154
while [[ $# -gt 0 ]]; do
150
155
case " $1 " in
151
156
-f | --flake)
@@ -233,6 +238,18 @@ parseArgs() {
233
238
;;
234
239
esac
235
240
241
+ shift
242
+ ;;
243
+ --build-on)
244
+ case " $2 " in
245
+ auto | local | remote)
246
+ buildOn=$2
247
+ ;;
248
+ * )
249
+ abort " Supported values for --build-on are auto, local and remote. Unknown mode : $2 "
250
+ ;;
251
+ esac
252
+
236
253
shift
237
254
;;
238
255
--extra-files)
@@ -287,7 +304,9 @@ parseArgs() {
287
304
substituteOnDestination=n
288
305
;;
289
306
--build-on-remote)
307
+ echo " WARNING: --build-on-remote is deprecated, use --build-on remote instead" 2>&1
290
308
buildOnRemote=y
309
+ buildOn=" remote"
291
310
;;
292
311
--env-password)
293
312
envPassword=y
@@ -319,6 +338,10 @@ parseArgs() {
319
338
abort " ssh-host must be set"
320
339
fi
321
340
341
+ if [[ $buildOn == " local" ]] && [[ $buildOnRemote == " y" ]]; then
342
+ abort " Conflicting flags: --build-on local and --build-on-remote used."
343
+ fi
344
+
322
345
if [[ -n ${flake} ]]; then
323
346
if [[ $flake =~ ^(.* )\# ([^\#\" ]* )$ ]]; then
324
347
flake=" ${BASH_REMATCH[1]} "
@@ -371,7 +394,7 @@ runVmTest() {
371
394
exit 1
372
395
fi
373
396
374
- if [[ ${buildOnRemote } == " y " ]]; then
397
+ if [[ ${buildOn } == " remote " ]]; then
375
398
echo " --vm-test is not supported with --build-on-remote" >&2
376
399
exit 1
377
400
fi
@@ -458,6 +481,47 @@ importFacts() {
458
481
done
459
482
}
460
483
484
+ checkBuildLocally () {
485
+ local system extraPlatforms machineSystem
486
+ system=" $( nix --extra-experimental-features ' nix-command flakes' config show system) "
487
+ extraPlatforms=" $( nix --extra-experimental-features ' nix-command flakes' config show extra-platforms) "
488
+
489
+ if [[ $# -gt 0 ]]; then
490
+ machineSystem=$1
491
+ elif [[ -n ${nixosSystem} ]]; then
492
+ machineSystem=" $( cat " ${nixosSystem} " /system) "
493
+ else
494
+ machineSystem=" $( nix --extra-experimental-features ' nix-command flakes' eval --raw " ${flake} " # "${flakeAttr}".pkgs.system 2>/dev/null || echo "unknown")"
495
+ if [[ ${machineSystem} == " unknown" ]]; then
496
+ buildOn=auto
497
+ return
498
+ fi
499
+ fi
500
+
501
+ if [[ ${system} == " ${machineSystem} " ]]; then
502
+ buildOn=local
503
+ return
504
+ fi
505
+
506
+ if [[ ${extraPlatforms} == " *${machineSystem} *" ]]; then
507
+ buildOn=local
508
+ return
509
+ fi
510
+
511
+ local entropy
512
+ entropy=" $( date +' %Y%m%d%H%M%S' ) "
513
+ if nix build \
514
+ -L \
515
+ " ${nixOptions[@]} " \
516
+ --expr \
517
+ " derivation { system = \" $system \" ; name = \" env-$entropy \" ; builder = \" /bin/sh\" ; args = [ \" -c\" \" echo > \$ out\" ]; }" ; then
518
+ # The local build failed
519
+ buildOn=local
520
+ fi
521
+
522
+ buildOn=remote
523
+ }
524
+
461
525
generateHardwareConfig () {
462
526
local maybeSudo=" $maybeSudo "
463
527
mkdir -p " $( dirname " $hardwareConfigPath " ) "
@@ -565,7 +629,7 @@ runDisko() {
565
629
done
566
630
if [[ -n ${diskoScript} ]]; then
567
631
nixCopy --to " ssh://$sshConnection " " $diskoScript "
568
- elif [[ ${buildOnRemote } == " y " ]]; then
632
+ elif [[ ${buildOn } == " remote " ]]; then
569
633
step Building disko script
570
634
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
571
635
# Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
@@ -587,7 +651,7 @@ nixosInstall() {
587
651
if [[ -n ${nixosSystem} ]]; then
588
652
step Uploading the system closure
589
653
nixCopy --to " ssh://$sshConnection ?remote-store=local?root=/mnt" " $nixosSystem "
590
- elif [[ ${buildOnRemote } == " y " ]]; then
654
+ elif [[ ${buildOn } == " remote " ]]; then
591
655
step Building the system closure
592
656
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
593
657
# Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
@@ -652,9 +716,13 @@ main() {
652
716
exit 0
653
717
fi
654
718
719
+ if [[ ${buildOn} == " auto" ]]; then
720
+ checkBuildLocally
721
+ fi
722
+
655
723
# parse flake nixos-install style syntax, get the system attr
656
724
if [[ -n ${flake} ]]; then
657
- if [[ ${buildOnRemote } == " n " ]] && [[ ${hardwareConfigBackend} == " none" ]]; then
725
+ if [[ ${buildOn } == " local " ]] && [[ ${hardwareConfigBackend} == " none" ]]; then
658
726
if [[ ${phases[disko]} == 1 ]]; then
659
727
diskoScript=$( nixBuild " ${flake} #${flakeAttr} .system.build.${diskoMode} Script" )
660
728
fi
@@ -716,7 +784,18 @@ main() {
716
784
generateHardwareConfig
717
785
fi
718
786
719
- if [[ ${buildOnRemote} == " n" ]] && [[ -n ${flake} ]] && [[ ${hardwareConfigBackend} != " none" ]]; then
787
+ # Before we do not have a valid hardware configuration we don't know the machine system
788
+ if [[ ${buildOn} == " auto" ]]; then
789
+ local remoteSystem
790
+ remoteSystem=$( runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features nix-command config show system)
791
+ checkBuildLocally " ${remoteSystem} "
792
+ # if we cannot figure it out at this point, we will build on the remote host
793
+ if [[ ${buildOn} == " auto" ]]; then
794
+ buildOn=remote
795
+ fi
796
+ fi
797
+
798
+ if [[ ${buildOn} != " remote" ]] && [[ -n ${flake} ]] && [[ -z ${diskoScript} ]]; then
720
799
if [[ ${phases[disko]} == 1 ]]; then
721
800
diskoScript=$( nixBuild " ${flake} #${flakeAttr} .system.build.${diskoMode} Script" )
722
801
fi
0 commit comments