35
35
sshConnection=
36
36
postKexecSshPort=22
37
37
buildOnRemote=n
38
+ buildOn=auto
38
39
envPassword=n
39
40
40
41
# Facts set by get-facts.sh
@@ -126,8 +127,11 @@ Options:
126
127
* --disko-mode disko|mount|format
127
128
set the disko mode to format, mount or destroy. Default is disko.
128
129
disko: first unmount and destroy all filesystems on the disks we want to format, then run the create and mount mode
129
- mount: mount the partition at the specified root-mountpoint
130
- format: create partition tables, zpools, lvms, raids and filesystems (Experimental: Can be run increntally, but use with caution and good backups)
130
+ * --build-on auto|remote|local
131
+ sets the build on settings to auto, remote or local. Default is auto.
132
+ auto: tries to figure out, if the build is possible on the local host, if not falls back gracefully to remote build
133
+ local: will build on the local host
134
+ remote: will build on the remote host
131
135
USAGE
132
136
}
133
137
@@ -143,6 +147,7 @@ step() {
143
147
parseArgs () {
144
148
local substituteOnDestination=y
145
149
local printBuildLogs=n
150
+ local buildOnRemote=n
146
151
while [[ $# -gt 0 ]]; do
147
152
case " $1 " in
148
153
-f | --flake)
@@ -227,6 +232,18 @@ parseArgs() {
227
232
;;
228
233
esac
229
234
235
+ shift
236
+ ;;
237
+ --build-on)
238
+ case " $2 " in
239
+ auto | local | remote)
240
+ buildOn=$2
241
+ ;;
242
+ * )
243
+ abort " Supported values for --build-on are auto, local and remote. Unknown mode : $2 "
244
+ ;;
245
+ esac
246
+
230
247
shift
231
248
;;
232
249
--extra-files)
@@ -281,7 +298,9 @@ parseArgs() {
281
298
substituteOnDestination=n
282
299
;;
283
300
--build-on-remote)
301
+ echo " WARNING: --build-on-remote is deprecated, use --build-on remote instead" 2>&1
284
302
buildOnRemote=y
303
+ buildOn=" remote"
285
304
;;
286
305
--env-password)
287
306
envPassword=y
@@ -313,6 +332,10 @@ parseArgs() {
313
332
abort " ssh-host must be set"
314
333
fi
315
334
335
+ if [[ $buildOn == " local" ]] && [[ $buildOnRemote == " y" ]]; then
336
+ abort " Conflicting flags: --build-on local and --build-on-remote used."
337
+ fi
338
+
316
339
if [[ -n ${flake} ]]; then
317
340
if [[ $flake =~ ^(.* )\# ([^\#\" ]* )$ ]]; then
318
341
flake=" ${BASH_REMATCH[1]} "
@@ -364,7 +387,7 @@ runVmTest() {
364
387
exit 1
365
388
fi
366
389
367
- if [[ ${buildOnRemote } == " y " ]]; then
390
+ if [[ ${buildOn } == " remote " ]]; then
368
391
echo " --vm-test is not supported with --build-on-remote" >&2
369
392
exit 1
370
393
fi
@@ -450,6 +473,46 @@ importFacts() {
450
473
done
451
474
}
452
475
476
+ canBuildLocally () {
477
+ local system extraPlatforms machineSystem
478
+ system=" $( nix --extra-experimental-features ' nix-command flakes' config show system) "
479
+ extraPlatforms=" $( nix --extra-experimental-features ' nix-command flakes' config show extra-platforms) "
480
+
481
+ if [[ $# -gt 0 ]]; then
482
+ machineSystem=$1
483
+ elif [[ -n ${nixosSystem} ]]; then
484
+ machineSystem=" $( cat " ${nixosSystem} " /system) "
485
+ else
486
+ machineSystem=" $( nix --extra-experimental-features ' nix-command flakes' eval --raw " ${flake} " # "${flakeAttr}".pkgs.system 2>/dev/null || echo "unknown")"
487
+ if [[ ${machineSystem} == " unknown" ]]; then
488
+ return
489
+ fi
490
+ fi
491
+
492
+ if [[ ${system} == " ${machineSystem} " ]]; then
493
+ return
494
+ fi
495
+
496
+ if [[ ${extraPlatforms} == " *${machineSystem} *" ]]; then
497
+ return
498
+ fi
499
+
500
+ local entropy nonSubstitutableDrv
501
+ entropy=" $( date +' %Y%m%d%H%M%S' ) "
502
+ nonSubstitutableDrv=$( nix eval \
503
+ --impure \
504
+ --raw \
505
+ -L \
506
+ " ${nixOptions[@]} " \
507
+ --expr \
508
+ " ((builtins.getFlake \" $flake \" ).inputs.nixpkgs.legacyPackages.$system .runCommandNoCC \" nixos-anywhere-can-build-$entropy \" { } \" echo > \$ out\" ).drvPath" )
509
+
510
+ if ! nix build " ${nixOptions[@]} " " ${nonSubstitutableDrv} ^*" ; then
511
+ # The local build failed
512
+ export buildOn=remote
513
+ fi
514
+ }
515
+
453
516
generateHardwareConfig () {
454
517
local maybeSudo=" $maybeSudo "
455
518
mkdir -p " $( dirname " $hardwareConfigPath " ) "
@@ -557,7 +620,7 @@ runDisko() {
557
620
done
558
621
if [[ -n ${diskoScript} ]]; then
559
622
nixCopy --to " ssh://$sshConnection " " $diskoScript "
560
- elif [[ ${buildOnRemote } == " y " ]]; then
623
+ elif [[ ${buildOn } == " remote " ]]; then
561
624
step Building disko script
562
625
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
563
626
# Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
@@ -579,7 +642,7 @@ nixosInstall() {
579
642
if [[ -n ${nixosSystem} ]]; then
580
643
step Uploading the system closure
581
644
nixCopy --to " ssh://$sshConnection ?remote-store=local?root=/mnt" " $nixosSystem "
582
- elif [[ ${buildOnRemote } == " y " ]]; then
645
+ elif [[ ${buildOn } == " remote " ]]; then
583
646
step Building the system closure
584
647
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
585
648
# Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
@@ -644,9 +707,13 @@ main() {
644
707
exit 0
645
708
fi
646
709
710
+ if [[ ${buildOn} == " auto" ]]; then
711
+ canBuildLocally
712
+ fi
713
+
647
714
# parse flake nixos-install style syntax, get the system attr
648
715
if [[ -n ${flake} ]]; then
649
- if [[ ${buildOnRemote } == " n " ]] && [[ ${hardwareConfigBackend} == " none" ]]; then
716
+ if [[ ${buildOn } == " local " ]] && [[ ${hardwareConfigBackend} == " none" ]]; then
650
717
if [[ ${phases[disko]} == 1 ]]; then
651
718
diskoScript=$( nixBuild " ${flake} #${flakeAttr} .system.build.${diskoMode} Script" )
652
719
fi
@@ -708,7 +775,14 @@ main() {
708
775
generateHardwareConfig
709
776
fi
710
777
711
- if [[ ${buildOnRemote} == " n" ]] && [[ -n ${flake} ]] && [[ ${hardwareConfigBackend} != " none" ]]; then
778
+ # Before we do not have a valid hardware configuration we don't know the machine system
779
+ if [[ ${buildOn} == " auto" ]]; then
780
+ local remoteSystem
781
+ remoteSystem=$( runSsh -o ConnectTimeout=10 nix --extra-experimental-features ' nix-command flakes' config show system)
782
+ canBuildLocally " ${remoteSystem} "
783
+ fi
784
+
785
+ if [[ ${buildOn} != " remote" ]] && [[ -n ${flake} ]] && [[ ${hardwareConfigBackend} != " none" ]]; then
712
786
if [[ ${phases[disko]} == 1 ]]; then
713
787
diskoScript=$( nixBuild " ${flake} #${flakeAttr} .system.build.${diskoMode} Script" )
714
788
fi
0 commit comments