2014-04-15 11:47:41 +02:00
#! @shell@
2014-04-18 16:05:20 +02:00
if [ -x "@shell@" ] ; then export SHELL = "@shell@" ; fi ;
2014-04-15 11:47:41 +02:00
set -e
2007-02-06 14:09:25 +01:00
2007-02-06 14:12:10 +01:00
showSyntax( ) {
2013-10-11 14:05:53 +02:00
exec man nixos-rebuild
2007-02-06 14:09:25 +01:00
exit 1
2007-02-06 14:12:10 +01:00
}
2008-08-04 16:58:26 +02:00
# Parse the command line.
2014-04-15 11:47:41 +02:00
origArgs = ( " $@ " )
2012-11-22 12:04:00 +01:00
extraBuildFlags = ( )
2008-08-04 16:58:26 +02:00
action =
2009-08-03 14:36:15 +02:00
buildNix = 1
2017-02-11 14:52:23 +01:00
fast =
2009-08-19 17:04:19 +02:00
rollback =
2012-06-25 22:17:34 +02:00
upgrade =
2013-07-23 20:31:03 +02:00
repair =
2013-10-09 19:13:26 +02:00
profile = /nix/var/nix/profiles/system
2016-01-11 19:41:48 +01:00
buildHost =
targetHost =
2019-11-13 16:56:49 +01:00
maybeSudo = ( )
2008-08-04 16:58:26 +02:00
2013-01-16 13:21:59 +01:00
while [ " $# " -gt 0 ] ; do
2009-08-03 14:36:15 +02:00
i = " $1 " ; shift 1
2010-01-03 14:36:23 +01:00
case " $i " in
--help)
2008-08-04 16:58:26 +02:00
showSyntax
2012-06-25 22:17:34 +02:00
; ;
2019-02-25 00:59:35 +01:00
switch| boot| test| build| edit| dry-build| dry-run| dry-activate| build-vm| build-vm-with-bootloader)
2015-03-09 16:23:23 +01:00
if [ " $i " = dry-run ] ; then i = dry-build; fi
2008-08-04 16:58:26 +02:00
action = " $i "
2012-06-25 22:17:34 +02:00
; ;
2010-01-03 14:36:23 +01:00
--install-grub)
2016-08-16 13:51:58 +02:00
echo " $0 : --install-grub deprecated, use --install-bootloader instead " >& 2
export NIXOS_INSTALL_BOOTLOADER = 1
; ;
--install-bootloader)
export NIXOS_INSTALL_BOOTLOADER = 1
2012-06-25 22:17:34 +02:00
; ;
2010-01-03 14:36:23 +01:00
--no-build-nix)
2009-08-03 14:36:15 +02:00
buildNix =
2012-06-25 22:17:34 +02:00
; ;
2010-01-03 14:36:23 +01:00
--rollback)
2009-08-19 17:04:19 +02:00
rollback = 1
2012-06-25 22:17:34 +02:00
; ;
--upgrade)
upgrade = 1
; ;
2013-07-23 20:31:03 +02:00
--repair)
repair = 1
extraBuildFlags += ( " $i " )
; ;
2019-01-11 11:39:26 +01:00
--max-jobs| -j| --cores| -I| --builders)
2011-03-07 13:12:39 +01:00
j = " $1 " ; shift 1
2012-11-22 12:04:00 +01:00
extraBuildFlags += ( " $i " " $j " )
2012-06-25 22:17:34 +02:00
; ;
2019-01-11 11:39:26 +01:00
--show-trace| --keep-failed| -K| --keep-going| -k| --verbose| -v| -vv| -vvv| -vvvv| -vvvvv| --fallback| --repair| --no-build-output| -Q| -j*)
2017-02-11 13:18:17 +01:00
extraBuildFlags += ( " $i " )
; ;
2012-09-14 19:23:19 +02:00
--option)
j = " $1 " ; shift 1
k = " $1 " ; shift 1
2012-11-22 12:04:00 +01:00
extraBuildFlags += ( " $i " " $j " " $k " )
2012-09-14 19:23:19 +02:00
; ;
2010-01-03 14:36:23 +01:00
--fast)
2009-10-15 01:56:11 +02:00
buildNix =
2017-02-11 14:52:23 +01:00
fast = 1
2012-11-22 12:04:00 +01:00
extraBuildFlags += ( --show-trace)
2012-06-25 22:17:34 +02:00
; ;
2013-10-09 19:13:26 +02:00
--profile-name| -p)
if [ -z " $1 " ] ; then
echo " $0 : ‘ --profile-name’ requires an argument "
exit 1
fi
if [ " $1 " != system ] ; then
profile = " /nix/var/nix/profiles/system-profiles/ $1 "
mkdir -p -m 0755 " $( dirname " $profile " ) "
fi
shift 1
; ;
2016-01-11 19:41:48 +01:00
--build-host| h)
buildHost = " $1 "
shift 1
; ;
--target-host| t)
targetHost = " $1 "
shift 1
; ;
2019-10-23 20:22:39 +02:00
--use-remote-sudo)
# note the trailing space
2019-11-13 16:56:49 +01:00
maybeSudo = ( sudo --)
2019-10-23 20:22:39 +02:00
shift 1
; ;
2010-01-03 14:36:23 +01:00
*)
2008-08-04 16:58:26 +02:00
echo " $0 : unknown option \` $i ' "
exit 1
2012-06-25 22:17:34 +02:00
; ;
2010-01-03 14:36:23 +01:00
esac
2008-08-04 16:58:26 +02:00
done
2019-11-13 16:56:49 +01:00
if [ -n " $SUDO_USER " ] ; then
maybeSudo = ( sudo --)
fi
2016-01-11 19:41:48 +01:00
if [ -z " $buildHost " -a -n " $targetHost " ] ; then
buildHost = " $targetHost "
fi
if [ " $targetHost " = localhost ] ; then
targetHost =
fi
if [ " $buildHost " = localhost ] ; then
buildHost =
fi
buildHostCmd( ) {
if [ -z " $buildHost " ] ; then
" $@ "
elif [ -n " $remoteNix " ] ; then
2019-11-13 16:56:49 +01:00
ssh $SSHOPTS " $buildHost " env PATH = " $remoteNix : $PATH " " ${ maybeSudo [@] } " " $@ "
2016-01-11 19:41:48 +01:00
else
2019-11-13 16:56:49 +01:00
ssh $SSHOPTS " $buildHost " " ${ maybeSudo [@] } " " $@ "
2016-01-11 19:41:48 +01:00
fi
}
targetHostCmd( ) {
if [ -z " $targetHost " ] ; then
2019-11-13 16:56:49 +01:00
" ${ maybeSudo [@] } " " $@ "
2016-01-11 19:41:48 +01:00
else
2019-11-13 16:56:49 +01:00
ssh $SSHOPTS " $targetHost " " ${ maybeSudo [@] } " " $@ "
2016-01-11 19:41:48 +01:00
fi
}
copyToTarget( ) {
if ! [ " $targetHost " = " $buildHost " ] ; then
if [ -z " $targetHost " ] ; then
2016-12-18 22:39:27 +01:00
NIX_SSHOPTS = $SSHOPTS nix-copy-closure --from " $buildHost " " $1 "
2016-01-11 19:41:48 +01:00
elif [ -z " $buildHost " ] ; then
2016-12-18 22:39:27 +01:00
NIX_SSHOPTS = $SSHOPTS nix-copy-closure --to " $targetHost " " $1 "
2016-01-11 19:41:48 +01:00
else
buildHostCmd nix-copy-closure --to " $targetHost " " $1 "
fi
fi
}
nixBuild( ) {
if [ -z " $buildHost " ] ; then
nix-build " $@ "
else
local instArgs = ( )
local buildArgs = ( )
while [ " $# " -gt 0 ] ; do
local i = " $1 " ; shift 1
case " $i " in
-o)
local out = " $1 " ; shift 1
buildArgs += ( "--add-root" " $out " "--indirect" )
; ;
-A)
local j = " $1 " ; shift 1
instArgs += ( " $i " " $j " )
; ;
2016-02-01 10:54:58 +01:00
-I) # We don't want this in buildArgs
2016-01-11 19:41:48 +01:00
shift 1
; ;
2016-02-01 10:54:58 +01:00
--no-out-link) # We don't want this in buildArgs
; ;
2016-01-11 19:41:48 +01:00
"<" *) # nix paths
instArgs += ( " $i " )
; ;
*)
buildArgs += ( " $i " )
; ;
esac
done
local drv = " $( nix-instantiate " ${ instArgs [@] } " " ${ extraBuildFlags [@] } " ) "
if [ -a " $drv " ] ; then
2016-12-18 22:39:27 +01:00
NIX_SSHOPTS = $SSHOPTS nix-copy-closure --to " $buildHost " " $drv "
2016-01-11 19:41:48 +01:00
buildHostCmd nix-store -r " $drv " " ${ buildArgs [@] } "
else
echo "nix-instantiate failed"
exit 1
fi
fi
}
2013-01-16 13:21:59 +01:00
if [ -z " $action " ] ; then showSyntax; fi
2007-02-06 14:09:25 +01:00
2014-04-15 11:47:41 +02:00
# Only run shell scripts from the Nixpkgs tree if the action is
# "switch", "boot", or "test". With other actions (such as "build"),
# the user may reasonably expect that no code from the Nixpkgs tree is
# executed, so it's safe to run nixos-rebuild against a potentially
# untrusted tree.
canRun =
if [ " $action " = switch -o " $action " = boot -o " $action " = test ] ; then
canRun = 1
fi
2015-04-13 12:41:31 +02:00
# If ‘ --upgrade’ is given, run ‘ nix-channel --update nixos’ .
2014-04-15 11:47:41 +02:00
if [ -n " $upgrade " -a -z " $_NIXOS_REBUILD_REEXEC " ] ; then
2015-04-13 12:41:31 +02:00
nix-channel --update nixos
# If there are other channels that contain a file called
# ".update-on-nixos-rebuild", update them as well.
for channelpath in /nix/var/nix/profiles/per-user/root/channels/*; do
if [ -e " $channelpath /.update-on-nixos-rebuild " ] ; then
nix-channel --update " $( basename " $channelpath " ) "
fi
done
2014-04-15 11:47:41 +02:00
fi
2014-06-10 20:09:48 +02:00
# Make sure that we use the Nix package we depend on, not something
# else from the PATH for nix-{env,instantiate,build}. This is
# important, because NixOS defaults the architecture of the rebuilt
# system to the architecture of the nix-* binaries used. So if on an
# amd64 system the user has an i686 Nix package in her PATH, then we
# would silently downgrade the whole system to be i686 NixOS on the
# next reboot.
if [ -z " $_NIXOS_REBUILD_REEXEC " ] ; then
export PATH = @nix@/bin:$PATH
fi
2014-04-15 11:47:41 +02:00
# Re-execute nixos-rebuild from the Nixpkgs tree.
2017-02-11 14:52:23 +01:00
if [ -z " $_NIXOS_REBUILD_REEXEC " -a -n " $canRun " -a -z " $fast " ] ; then
2016-08-07 02:17:41 +02:00
if p = $( nix-build --no-out-link --expr 'with import <nixpkgs/nixos> {}; config.system.build.nixos-rebuild' " ${ extraBuildFlags [@] } " ) ; then
2014-04-15 11:47:41 +02:00
export _NIXOS_REBUILD_REEXEC = 1
2016-08-07 02:17:41 +02:00
exec $p /bin/nixos-rebuild " ${ origArgs [@] } "
2014-04-15 11:47:41 +02:00
exit 1
fi
2009-08-19 17:04:19 +02:00
fi
2019-02-25 00:59:35 +01:00
# Find configuration.nix and open editor instead of building.
if [ " $action " = edit ] ; then
NIXOS_CONFIG = ${ NIXOS_CONFIG :- $( nix-instantiate --find-file nixos-config) }
exec " ${ EDITOR :- nano } " " $NIXOS_CONFIG "
exit 1
fi
2007-02-06 14:09:25 +01:00
2009-08-03 14:44:45 +02:00
tmpDir = $( mktemp -t -d nixos-rebuild.XXXXXX)
2016-01-11 19:41:48 +01:00
SSHOPTS = " $NIX_SSHOPTS -o ControlMaster=auto -o ControlPath= $tmpDir /ssh-%n -o ControlPersist=60 "
cleanup( ) {
for ctrl in " $tmpDir " /ssh-*; do
ssh -o ControlPath = " $ctrl " -O exit dummyhost 2>/dev/null || true
done
rm -rf " $tmpDir "
}
trap cleanup EXIT
2009-08-03 14:44:45 +02:00
2008-06-04 11:01:54 +02:00
# If the Nix daemon is running, then use it. This allows us to use
# the latest Nix from Nixpkgs (below) for expression evaluation, while
# still using the old Nix (via the daemon) for actual store access.
# This matters if the new Nix in Nixpkgs has a schema change. It
# would upgrade the schema, which should only happen once we actually
# switch to the new configuration.
2013-07-23 20:31:03 +02:00
# If --repair is given, don't try to use the Nix daemon, because the
# flag can only be used directly.
if [ -z " $repair " ] && systemctl show nix-daemon.socket nix-daemon.service | grep -q ActiveState = active; then
2017-07-07 11:57:00 +02:00
export NIX_REMOTE = ${ NIX_REMOTE -daemon }
2008-06-04 11:01:54 +02:00
fi
2007-09-18 17:38:05 +02:00
# First build Nix, since NixOS may require a newer version than the
2014-04-15 12:03:30 +02:00
# current one.
2015-03-09 16:23:23 +01:00
if [ -n " $rollback " -o " $action " = dry-build ] ; then
2014-04-15 11:47:41 +02:00
buildNix =
fi
2019-02-21 02:02:20 +01:00
nixSystem( ) {
machine = " $( uname -m) "
if [ [ " $machine " = ~ i.86 ] ] ; then
machine = i686
fi
echo $machine -linux
}
2016-01-11 19:41:48 +01:00
prebuiltNix( ) {
machine = " $1 "
if [ " $machine " = x86_64 ] ; then
2016-09-06 16:07:24 +02:00
echo @nix_x86_64_linux@
2016-01-11 19:41:48 +01:00
elif [ [ " $machine " = ~ i.86 ] ] ; then
2016-09-06 16:07:24 +02:00
echo @nix_i686_linux@
2016-01-11 19:41:48 +01:00
else
echo " $0 : unsupported platform "
exit 1
fi
}
remotePATH =
2014-04-15 11:47:41 +02:00
if [ -n " $buildNix " ] ; then
2009-12-09 19:23:48 +01:00
echo "building Nix..." >& 2
2016-01-11 19:41:48 +01:00
nixDrv =
2016-04-24 13:06:04 +02:00
if ! nixDrv = " $( nix-instantiate '<nixpkgs/nixos>' --add-root $tmpDir /nix.drv --indirect -A config.nix.package.out " ${ extraBuildFlags [@] } " ) " ; then
2017-03-06 15:53:34 +01:00
if ! nixDrv = " $( nix-instantiate '<nixpkgs>' --add-root $tmpDir /nix.drv --indirect -A nix " ${ extraBuildFlags [@] } " ) " ; then
2019-02-21 02:02:20 +01:00
if ! nixStorePath = " $( nix-instantiate --eval '<nixpkgs/nixos/modules/installer/tools/nix-fallback-paths.nix>' -A $( nixSystem) | sed -e 's/^"//' -e 's/"$//' ) " ; then
nixStorePath = " $( prebuiltNix " $( uname -m) " ) "
fi
2017-03-06 15:53:34 +01:00
if ! nix-store -r $nixStorePath --add-root $tmpDir /nix --indirect \
--option extra-binary-caches https://cache.nixos.org/; then
echo "warning: don't know how to get latest Nix" >& 2
fi
# Older version of nix-store -r don't support --add-root.
[ -e $tmpDir /nix ] || ln -sf $nixStorePath $tmpDir /nix
if [ -n " $buildHost " ] ; then
remoteNixStorePath = " $( prebuiltNix " $( buildHostCmd uname -m) " ) "
remoteNix = " $remoteNixStorePath /bin "
if ! buildHostCmd nix-store -r $remoteNixStorePath \
--option extra-binary-caches https://cache.nixos.org/ >/dev/null; then
remoteNix =
2014-04-15 12:03:30 +02:00
echo "warning: don't know how to get latest Nix" >& 2
fi
fi
2010-03-04 15:38:53 +01:00
fi
2008-03-13 11:17:42 +01:00
fi
2016-01-11 19:41:48 +01:00
if [ -a " $nixDrv " ] ; then
2016-01-11 19:43:05 +01:00
nix-store -r " $nixDrv " '!' "out" --add-root $tmpDir /nix --indirect >/dev/null
2016-01-11 19:41:48 +01:00
if [ -n " $buildHost " ] ; then
nix-copy-closure --to " $buildHost " " $nixDrv "
# The nix build produces multiple outputs, we add them all to the remote path
for p in $( buildHostCmd nix-store -r " $( readlink " $nixDrv " ) " " ${ buildArgs [@] } " ) ; do
remoteNix = " $remoteNix ${ remoteNix : + : } $p /bin "
done
fi
fi
PATH = " $tmpDir /nix/bin: $PATH "
2008-01-02 16:30:31 +01:00
fi
2007-09-18 17:38:05 +02:00
2013-01-16 14:40:41 +01:00
# Update the version suffix if we're building from Git (so that
# nixos-version shows something useful).
2014-04-15 11:47:41 +02:00
if [ -n " $canRun " ] ; then
if nixpkgs = $( nix-instantiate --find-file nixpkgs " ${ extraBuildFlags [@] } " ) ; then
2016-08-09 14:11:29 +02:00
suffix = $( $SHELL $nixpkgs /nixos/modules/installer/tools/get-version-suffix " ${ extraBuildFlags [@] } " || true )
if [ -n " $suffix " ] ; then
echo -n " $suffix " > " $nixpkgs /.version-suffix " || true
2014-04-15 11:47:41 +02:00
fi
2013-01-16 14:40:41 +01:00
fi
fi
2015-03-09 16:23:23 +01:00
if [ " $action " = dry-build ] ; then
2013-01-16 16:11:51 +01:00
extraBuildFlags += ( --dry-run)
fi
2007-02-06 14:09:25 +01:00
# Either upgrade the configuration in the system profile (for "switch"
# or "boot"), or just build it and create a symlink "result" in the
# current directory (for "build" and "test").
2013-01-16 13:21:59 +01:00
if [ -z " $rollback " ] ; then
2009-12-09 19:23:48 +01:00
echo "building the system configuration..." >& 2
2013-01-16 13:21:59 +01:00
if [ " $action " = switch -o " $action " = boot ] ; then
2016-02-01 10:37:41 +01:00
pathToConfig = " $( nixBuild '<nixpkgs/nixos>' --no-out-link -A system " ${ extraBuildFlags [@] } " ) "
2016-01-11 19:41:48 +01:00
copyToTarget " $pathToConfig "
targetHostCmd nix-env -p " $profile " --set " $pathToConfig "
2015-03-09 16:23:23 +01:00
elif [ " $action " = test -o " $action " = build -o " $action " = dry-build -o " $action " = dry-activate ] ; then
2016-01-11 19:41:48 +01:00
pathToConfig = " $( nixBuild '<nixpkgs/nixos>' -A system -k " ${ extraBuildFlags [@] } " ) "
2010-09-13 14:34:58 +02:00
elif [ " $action " = build-vm ] ; then
2016-01-11 19:41:48 +01:00
pathToConfig = " $( nixBuild '<nixpkgs/nixos>' -A vm -k " ${ extraBuildFlags [@] } " ) "
2010-09-13 14:34:58 +02:00
elif [ " $action " = build-vm-with-bootloader ] ; then
2016-01-11 19:41:48 +01:00
pathToConfig = " $( nixBuild '<nixpkgs/nixos>' -A vmWithBootLoader -k " ${ extraBuildFlags [@] } " ) "
2009-08-19 17:04:19 +02:00
else
showSyntax
fi
2016-01-11 19:41:48 +01:00
# Copy build to target host if we haven't already done it
if ! [ " $action " = switch -o " $action " = boot ] ; then
copyToTarget " $pathToConfig "
fi
2013-01-16 13:21:59 +01:00
else # [ -n "$rollback" ]
if [ " $action " = switch -o " $action " = boot ] ; then
2016-01-11 19:41:48 +01:00
targetHostCmd nix-env --rollback -p " $profile "
2013-10-09 19:13:26 +02:00
pathToConfig = " $profile "
2013-01-16 13:21:59 +01:00
elif [ " $action " = test -o " $action " = build ] ; then
2009-08-19 17:04:19 +02:00
systemNumber = $(
2016-01-11 19:41:48 +01:00
targetHostCmd nix-env -p " $profile " --list-generations |
2009-08-19 17:04:19 +02:00
sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h'
)
2016-01-11 19:41:48 +01:00
pathToConfig = " $profile " -${ systemNumber } -link
if [ -z " $targetHost " ] ; then
ln -sT " $pathToConfig " ./result
fi
2009-08-19 17:04:19 +02:00
else
showSyntax
fi
2007-02-06 14:09:25 +01:00
fi
# If we're not just building, then make the new configuration the boot
# default and/or activate it now.
2015-03-09 16:23:23 +01:00
if [ " $action " = switch -o " $action " = boot -o " $action " = test -o " $action " = dry-activate ] ; then
2016-01-11 19:41:48 +01:00
if ! targetHostCmd $pathToConfig /bin/switch-to-configuration " $action " ; then
2015-10-25 02:26:49 +01:00
echo "warning: error(s) occurred while switching to the new configuration" >& 2
2014-08-15 01:57:36 +02:00
exit 1
fi
2007-02-06 14:09:25 +01:00
fi
2007-02-06 14:20:53 +01:00
2013-01-16 13:21:59 +01:00
if [ " $action " = build-vm ] ; then
2009-08-11 03:35:56 +02:00
cat >& 2 <<EOF
2018-03-09 09:36:57 +01:00
Done. The virtual machine can be started by running $( echo $pathToConfig /bin/run-*-vm)
2009-08-11 03:35:56 +02:00
EOF
fi