Compare commits
20 commits
9cd9d8fe3c
...
56b213c17d
Author | SHA1 | Date | |
---|---|---|---|
56b213c17d | |||
5b2bad6048 | |||
7f81b391c1 | |||
bc5c7553db | |||
4f10f70c70 | |||
f39c0b54d0 | |||
627b4e00b6 | |||
b0d5d260ff | |||
f9a234faea | |||
c07550cb44 | |||
eaa16464fa | |||
c62e6901a9 | |||
ecfe787bca | |||
5ced0ad3b2 | |||
966d88f2ba | |||
0b7be3144c | |||
19c4cb4c2f | |||
9e59fd06af | |||
672807280e | |||
ba94153c3b |
20 changed files with 2124 additions and 27 deletions
51
default.nix
Normal file
51
default.nix
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# if evaluating outside of the store, copy the current directory to the store and import it
|
||||||
|
# filtering out .gitignore files and .git directories
|
||||||
|
# if evaluating inside the store, import the outputs.nix file
|
||||||
|
|
||||||
|
let
|
||||||
|
contains = str: substr: let
|
||||||
|
str_length = builtins.stringLength str;
|
||||||
|
substr_length = builtins.stringLength substr;
|
||||||
|
listOfPossibleSubstrings = builtins.genList (i: builtins.substring i substr_length str) (str_length - substr_length + 1);
|
||||||
|
in if substr_length > str_length then false else builtins.any (x: x == substr) listOfPossibleSubstrings;
|
||||||
|
|
||||||
|
endsWith = str: substr: let
|
||||||
|
str_length = builtins.stringLength str;
|
||||||
|
substr_length = builtins.stringLength substr;
|
||||||
|
in if substr_length > str_length then false else builtins.substring (str_length - substr_length) str_length str == substr;
|
||||||
|
|
||||||
|
gitignore = builtins.filter (v:
|
||||||
|
# ignore comments and empty lines
|
||||||
|
if !(builtins.isString v) then false
|
||||||
|
else if !builtins.isNull(builtins.match "^#.*" v) then false
|
||||||
|
else if !builtins.isNull(builtins.match "^$" v) then false
|
||||||
|
else true
|
||||||
|
) (builtins.split "\n" (builtins.readFile ./.gitignore));
|
||||||
|
|
||||||
|
# checks if a given path matches a gitignore pattern
|
||||||
|
# string -> bool
|
||||||
|
matchesGitIgnore = path: builtins.any (pattern:
|
||||||
|
let
|
||||||
|
patternLength = builtins.stringLength pattern;
|
||||||
|
unsupportedPatternMessage = "matchesGitIgnore: Unsupported pattern: ${pattern}";
|
||||||
|
in
|
||||||
|
if pattern == "*" then true
|
||||||
|
else if pattern == ".*" then true
|
||||||
|
else if pattern == "*.*" then true
|
||||||
|
else if builtins.substring 0 2 pattern == "*." then endsWith path (builtins.substring 0 2 pattern)
|
||||||
|
else if contains pattern "*" then abort unsupportedPatternMessage
|
||||||
|
else if patternLength > 2 && builtins.substring 0 2 pattern == "./" then abort unsupportedPatternMessage
|
||||||
|
else if patternLength > 1 && builtins.substring 0 1 pattern == "/" then abort unsupportedPatternMessage
|
||||||
|
else contains path pattern
|
||||||
|
) gitignore;
|
||||||
|
|
||||||
|
currentFilePath = (builtins.unsafeGetAttrPos "any" { any = "any"; }).file;
|
||||||
|
storePathLength = builtins.stringLength (builtins.toString builtins.storeDir);
|
||||||
|
evaluatingInStore = (builtins.substring 0 storePathLength currentFilePath) == builtins.storeDir;
|
||||||
|
|
||||||
|
selfInStore = builtins.filterSource (path: type:
|
||||||
|
type != "unknown" && builtins.baseNameOf path != ".git" && !matchesGitIgnore path
|
||||||
|
) ./.;
|
||||||
|
in
|
||||||
|
if !(evaluatingInStore) then import selfInStore
|
||||||
|
else import ./outputs.nix
|
|
@ -1,4 +1,4 @@
|
||||||
{ pkgs, ... }:
|
{ inputs, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
../nix-os/services/nix-binary-cache.nix
|
../nix-os/services/nix-binary-cache.nix
|
||||||
../nix-os/udev.nix
|
../nix-os/udev.nix
|
||||||
|
|
||||||
(builtins.fetchTarball "https://github.com/nix-community/nixos-vscode-server/tarball/fc900c16efc6a5ed972fb6be87df018bcf3035bc")
|
"${inputs.nixos-vscode-server}"
|
||||||
];
|
];
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
@ -45,6 +45,8 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.printing.startWhenNeeded = false;
|
||||||
|
|
||||||
system.stateVersion = "23.05";
|
system.stateVersion = "23.05";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
19
inputs.nix
Normal file
19
inputs.nix
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
let self = {
|
||||||
|
lock ? import ./lock.nix
|
||||||
|
, lib ? import "${(self {}).nixpkgs}/lib"
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
inherit lock;
|
||||||
|
nixos-vscode-server = builtins.fetchTarball {
|
||||||
|
name = "nixos-vscode-server";
|
||||||
|
url = "https://github.com/nix-community/nixos-vscode-server/archive/${lock.nixos-vscode-server.revision}.tar.gz";
|
||||||
|
sha256 = "${lock.nixos-vscode-server.sha256}";
|
||||||
|
};
|
||||||
|
nixpkgs = builtins.fetchTarball {
|
||||||
|
name = "nixpkgs";
|
||||||
|
url = "https://github.com/NixOS/nixpkgs/archive/${lock.nixpkgs.revision}.tar.gz";
|
||||||
|
sha256 = "${lock.nixpkgs.sha256}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in self
|
8
lib/overlays/version-info-fixup.nix
Normal file
8
lib/overlays/version-info-fixup.nix
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{ inputs ? import ../../inputs.nix {} }:
|
||||||
|
|
||||||
|
selfLib: superLib: {
|
||||||
|
trivial = superLib.trivial // {
|
||||||
|
versionSuffix = ".git.${builtins.substring 0 12 inputs.lock.nixpkgs.revision}";
|
||||||
|
revisionWithDefault = default: inputs.lock.nixpkgs.revision or default;
|
||||||
|
};
|
||||||
|
}
|
10
lock.nix
Normal file
10
lock.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
nixos-vscode-server = {
|
||||||
|
revision = "fc900c16efc6a5ed972fb6be87df018bcf3035bc";
|
||||||
|
sha256 = "1rq8mrlmbzpcbv9ys0x88alw30ks70jlmvnfr2j8v830yy5wvw7h";
|
||||||
|
};
|
||||||
|
nixpkgs = {
|
||||||
|
revision = "10c832d0548e9e3a6df7eb51e68c2783212a303e";
|
||||||
|
sha256 = "1p206hgfxbz0rmkzaslfrknbdss4n4dnb09pi5466h8ksmm8216q";
|
||||||
|
};
|
||||||
|
}
|
|
@ -17,7 +17,7 @@
|
||||||
initialPassword = "nixos";
|
initialPassword = "nixos";
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
firefox
|
firefox
|
||||||
vivaldi
|
(vivaldi.override { proprietaryCodecs = true; })
|
||||||
discord-canary
|
discord-canary
|
||||||
unstablePkgs.vscode
|
unstablePkgs.vscode
|
||||||
gimp
|
gimp
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
config = {
|
config = {
|
||||||
services.printing.enable = true;
|
services.printing.enable = true;
|
||||||
|
|
||||||
sound.enable = true;
|
sound.enable = false;
|
||||||
hardware.pulseaudio.enable = false;
|
hardware.pulseaudio.enable = false;
|
||||||
security.rtkit.enable = true;
|
security.rtkit.enable = true;
|
||||||
services.pipewire = {
|
services.pipewire = {
|
||||||
|
@ -25,4 +25,4 @@
|
||||||
X11Forwarding yes
|
X11Forwarding yes
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# your system. Help is available in the configuration.nix(5) man page
|
# your system. Help is available in the configuration.nix(5) man page
|
||||||
# and in the NixOS manual (accessible by running 'nixos-help').
|
# and in the NixOS manual (accessible by running 'nixos-help').
|
||||||
|
|
||||||
{ config, pkgs, lib, ... }:
|
{ inputs, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
/*
|
/*
|
||||||
|
@ -47,7 +47,16 @@ in
|
||||||
|
|
||||||
# Allow unfree packages
|
# Allow unfree packages
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
nix.package = wrappedNix;
|
nix = {
|
||||||
|
package = wrappedNix;
|
||||||
|
channel.enable = false;
|
||||||
|
settings.nix-path = [
|
||||||
|
"nixpkgs=${pkgs.selfExpr { useConfig = false; }}"
|
||||||
|
"systemNixpkgs=${pkgs.selfExpr { useConfig = true; name = "systemNixpkgs-self"; }}"
|
||||||
|
# don't garbage collect the nixpkgs input
|
||||||
|
"inputsNixpkgs=${inputs.nixpkgs}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
# List packages installed in system profile. To search, run:
|
# List packages installed in system profile. To search, run:
|
||||||
# $ nix search wget
|
# $ nix search wget
|
||||||
|
|
56
outputs.nix
Normal file
56
outputs.nix
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
{ inputs ? import ./inputs.nix {} }:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
lib = (import "${inputs.nixpkgs}/lib").extend (import ./lib/overlays/version-info-fixup.nix { inherit inputs; });
|
||||||
|
|
||||||
|
self = {
|
||||||
|
inherit lib inputs;
|
||||||
|
modifiedNixpkgs = import ./pkgs/top-level/impure.nix;
|
||||||
|
modifiedNixpkgsPure = import ./pkgs/top-level/default.nix;
|
||||||
|
overlays = {
|
||||||
|
selfExpr = import ./pkgs/overlays/selfExpr.nix { nixpkgsPath = inputs.nixpkgs; };
|
||||||
|
unstable = import ./pkgs/overlays/unstable.nix;
|
||||||
|
versionInfoFixup = import ./pkgs/overlays/version-info-fixup.nix { inherit inputs; };
|
||||||
|
};
|
||||||
|
nixosConfigurations = let
|
||||||
|
# list nix file paths in ./hosts to attributes in nixosConfigurations
|
||||||
|
filePaths = lib.pipe ./hosts [
|
||||||
|
builtins.readDir
|
||||||
|
( lib.filterAttrs (name: type:
|
||||||
|
# filter out non-nix files
|
||||||
|
type == "regular"
|
||||||
|
# filter out files that don't end in .nix
|
||||||
|
&& lib.hasSuffix ".nix" name
|
||||||
|
# filter out files that start with .
|
||||||
|
&& !lib.hasPrefix "." name
|
||||||
|
))
|
||||||
|
(lib.mapAttrsToList (name: _: name))
|
||||||
|
];
|
||||||
|
nixosSystem = import "${inputs.nixpkgs}/nixos/lib/eval-config.nix";
|
||||||
|
in
|
||||||
|
# mapped list of nix file paths to attrSet with initialized NixOS configurations,
|
||||||
|
# whose names are derived from file names
|
||||||
|
lib.pipe filePaths [
|
||||||
|
(builtins.map (name: {
|
||||||
|
name = builtins.substring 0 (builtins.stringLength name - 4) name;
|
||||||
|
value = nixosSystem {
|
||||||
|
inherit lib;
|
||||||
|
modules = [
|
||||||
|
./hosts/${name}
|
||||||
|
{
|
||||||
|
config.nixpkgs.overlays = [
|
||||||
|
( import ./pkgs/overlays/selfExpr.nix { nixpkgsPath = "${builtins.toString ./.}/pkgs/top-level/impure.nix"; } )
|
||||||
|
( import "${inputs.nixpkgs}/pkgs/top-level/by-name-overlay.nix" "${builtins.toString ./.}/pkgs/by-name" )
|
||||||
|
self.overlays.versionInfoFixup
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
specialArgs = { inherit self inputs; };
|
||||||
|
};
|
||||||
|
}))
|
||||||
|
builtins.listToAttrs
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
in self
|
165
pkgs/by-name/ni/nixos-rebuild/_nixos-rebuild
Normal file
165
pkgs/by-name/ni/nixos-rebuild/_nixos-rebuild
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# We're faking a `nix build` command-line to re-use Nix's own completion
|
||||||
|
# for the few options passed through to Nix.
|
||||||
|
_nixos-rebuild_pretend-nix() {
|
||||||
|
COMP_LINE="nix build ${COMP_LINE}"
|
||||||
|
# number of prepended chars
|
||||||
|
(( COMP_POINT = COMP_POINT + 10))
|
||||||
|
|
||||||
|
COMP_WORDS=(
|
||||||
|
nix build
|
||||||
|
"${COMP_WORDS[@]}"
|
||||||
|
)
|
||||||
|
# Add the amount of prepended words
|
||||||
|
(( COMP_CWORD = COMP_CWORD + 2))
|
||||||
|
_complete_nix "nix"
|
||||||
|
}
|
||||||
|
|
||||||
|
_nixos-rebuild() {
|
||||||
|
local curr="$2"
|
||||||
|
local prev="$3"
|
||||||
|
local subcommandGiven=0
|
||||||
|
local word
|
||||||
|
local subcommand
|
||||||
|
|
||||||
|
__load_completion nix
|
||||||
|
|
||||||
|
# Arrays are re-ordered by the completion, so it's fine to sort them in logical chunks
|
||||||
|
local all_args=(
|
||||||
|
--verbose -v
|
||||||
|
|
||||||
|
# nixos-rebuild options
|
||||||
|
--fast
|
||||||
|
--no-build-nix
|
||||||
|
--profile-name -p # name
|
||||||
|
--rollback
|
||||||
|
--specialisation -c # name
|
||||||
|
--use-remote-sudo
|
||||||
|
--build-host # host
|
||||||
|
--target-host # host
|
||||||
|
# Used with list-generations
|
||||||
|
--json
|
||||||
|
|
||||||
|
# generation switching options
|
||||||
|
--install-bootloader
|
||||||
|
|
||||||
|
# nix-channel options
|
||||||
|
--upgrade
|
||||||
|
--upgrade-all
|
||||||
|
|
||||||
|
# flakes options
|
||||||
|
--commit-lock-file
|
||||||
|
--flake # flake-uri
|
||||||
|
--override-input # input-name flake-uri
|
||||||
|
--recreate-lock-file
|
||||||
|
--update-input
|
||||||
|
--no-flake
|
||||||
|
--no-registries
|
||||||
|
--no-update-lock-file
|
||||||
|
--no-write-lock-file
|
||||||
|
|
||||||
|
# Nix-copy options
|
||||||
|
--use-substitutes --substitute-on-destination -s
|
||||||
|
|
||||||
|
# Nix options
|
||||||
|
--option
|
||||||
|
--impure
|
||||||
|
--builders # builder-spec
|
||||||
|
--show-trace
|
||||||
|
--keep-failed -K
|
||||||
|
--keep-going -k
|
||||||
|
--max-jobs -j # number
|
||||||
|
--log-format # format
|
||||||
|
-I # NIX_PATH
|
||||||
|
)
|
||||||
|
|
||||||
|
local all_subcommands=(
|
||||||
|
boot
|
||||||
|
build
|
||||||
|
build-vm
|
||||||
|
build-vm-with-bootloader
|
||||||
|
dry-activate
|
||||||
|
dry-build
|
||||||
|
edit
|
||||||
|
list-generations
|
||||||
|
switch
|
||||||
|
test
|
||||||
|
)
|
||||||
|
|
||||||
|
# Suggest arguments that can be consumed under some conditions only
|
||||||
|
for word in "${COMP_WORDS[@]}"; do
|
||||||
|
for subcommand in "${all_subcommands[@]}"; do
|
||||||
|
if [[ "$word" == "$subcommand" ]]; then
|
||||||
|
subcommandGiven=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# Fake out a way to complete the second arg to some options
|
||||||
|
case "${COMP_WORDS[COMP_CWORD-2]}" in
|
||||||
|
"--override-input")
|
||||||
|
prev="--override-input_2"
|
||||||
|
;;
|
||||||
|
"--option")
|
||||||
|
prev="--option_2"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$prev" in
|
||||||
|
--max-jobs|-j)
|
||||||
|
COMPREPLY=( )
|
||||||
|
;;
|
||||||
|
|
||||||
|
--profile-name|-p)
|
||||||
|
if [[ "$curr" == "" ]]; then
|
||||||
|
COMPREPLY=( /nix/var/nix/profiles/* )
|
||||||
|
else
|
||||||
|
COMPREPLY=( "$curr"* )
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
--build-host|--target-host|-t|-h)
|
||||||
|
_known_hosts_real "$curr"
|
||||||
|
;;
|
||||||
|
|
||||||
|
--specialisation|-c)
|
||||||
|
COMPREPLY=()
|
||||||
|
;;
|
||||||
|
|
||||||
|
-I)
|
||||||
|
_nixos-rebuild_pretend-nix
|
||||||
|
;;
|
||||||
|
--builders)
|
||||||
|
_nixos-rebuild_pretend-nix
|
||||||
|
;;
|
||||||
|
--flake)
|
||||||
|
_nixos-rebuild_pretend-nix
|
||||||
|
;;
|
||||||
|
--override-input)
|
||||||
|
_nixos-rebuild_pretend-nix
|
||||||
|
;;
|
||||||
|
--override-input_2)
|
||||||
|
_nixos-rebuild_pretend-nix
|
||||||
|
;;
|
||||||
|
--log-format)
|
||||||
|
_nixos-rebuild_pretend-nix
|
||||||
|
;;
|
||||||
|
--option)
|
||||||
|
_nixos-rebuild_pretend-nix
|
||||||
|
;;
|
||||||
|
--option_2)
|
||||||
|
_nixos-rebuild_pretend-nix
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
if [[ "$curr" == -* ]] || (( subcommandGiven )); then
|
||||||
|
COMPREPLY=( $(compgen -W "${all_args[*]}" -- "$2") )
|
||||||
|
else
|
||||||
|
COMPREPLY=( $(compgen -W "${all_subcommands[*]}" -- "$2") )
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _nixos-rebuild nixos-rebuild
|
558
pkgs/by-name/ni/nixos-rebuild/nixos-rebuild.8
Normal file
558
pkgs/by-name/ni/nixos-rebuild/nixos-rebuild.8
Normal file
|
@ -0,0 +1,558 @@
|
||||||
|
.Dd January 1, 1980
|
||||||
|
.Dt nixos-rebuild 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm nixos-rebuild
|
||||||
|
.Nd reconfigure a NixOS machine
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Bro
|
||||||
|
.Cm switch | boot | test | build | dry-build | dry-activate | edit | repl | build-vm | build-vm-with-bootloader | list-generations Op Fl -json
|
||||||
|
.Brc
|
||||||
|
.br
|
||||||
|
.Op Fl -upgrade | -upgrade-all
|
||||||
|
.Op Fl -install-bootloader
|
||||||
|
.Op Fl -no-build-nix
|
||||||
|
.Op Fl -fast
|
||||||
|
.Op Fl -rollback
|
||||||
|
.br
|
||||||
|
.Op Fl -file | F Ar path
|
||||||
|
.Op Fl -attr | A Ar attrPath
|
||||||
|
.Op Fl -flake Ar flake-uri
|
||||||
|
.Op Fl -no-flake
|
||||||
|
.Op Fl -recreate-lock-file
|
||||||
|
.Op Fl -no-update-lock-file
|
||||||
|
.Op Fl -no-write-lock-file
|
||||||
|
.Op Fl -no-registries
|
||||||
|
.Op Fl -commit-lock-file
|
||||||
|
.Op Fl -update-input Ar input-path
|
||||||
|
.Op Fl -override-input Ar input-path flake-url
|
||||||
|
.br
|
||||||
|
.Op Fl -profile-name | p Ar name
|
||||||
|
.Op Fl -specialisation | c Ar name
|
||||||
|
.br
|
||||||
|
.Op Fl -build-host Va host
|
||||||
|
.Op Fl -target-host Va host
|
||||||
|
.Op Fl -use-remote-sudo
|
||||||
|
.br
|
||||||
|
.Op Fl -verbose | v
|
||||||
|
.Op Fl -quiet
|
||||||
|
.Op Fl -log-format Ar format
|
||||||
|
.Op Fl -no-build-output | Q
|
||||||
|
.Op Fl -max-jobs | j Va number
|
||||||
|
.Op Fl -cores Va number
|
||||||
|
.Op Fl -keep-going | k
|
||||||
|
.Op Fl -keep-failed | K
|
||||||
|
.Op Fl -fallback
|
||||||
|
.Op Fl I Va NIX_PATH
|
||||||
|
.Op Fl -option Ar name value
|
||||||
|
.Op Fl -repair
|
||||||
|
.Op Fl -builders Va builder-spec
|
||||||
|
.Op Fl -accept-flake-config
|
||||||
|
.Op Fl -print-build-logs | L
|
||||||
|
.Op Fl -show-trace
|
||||||
|
.Op Fl -refresh
|
||||||
|
.Op Fl -impure
|
||||||
|
.Op Fl -offline
|
||||||
|
.Op Fl -no-net
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
This command updates the system so that it corresponds to the
|
||||||
|
configuration specified in
|
||||||
|
.Pa /etc/nixos/configuration.nix Ns
|
||||||
|
,
|
||||||
|
.Pa /etc/nixos/flake.nix
|
||||||
|
or the file and attribute specified by the
|
||||||
|
.Fl -file
|
||||||
|
and/or
|
||||||
|
.Fl -attr
|
||||||
|
options. Thus, every time you modify the configuration or any other NixOS
|
||||||
|
module, you must run
|
||||||
|
.Nm
|
||||||
|
to make the changes take effect. It builds the new system in
|
||||||
|
.Pa /nix/store Ns
|
||||||
|
, runs its activation script, and stop and (re)starts any system services if
|
||||||
|
needed. Please note that user services need to be started manually as they
|
||||||
|
aren't detected by the activation script at the moment.
|
||||||
|
.
|
||||||
|
.Pp
|
||||||
|
This command has one required argument, which specifies the desired
|
||||||
|
operation. It must be one of the following:
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Cm switch
|
||||||
|
Build and activate the new configuration, and make it the boot default. That
|
||||||
|
is, the configuration is added to the GRUB boot menu as the default
|
||||||
|
menu entry, so that subsequent reboots will boot the system into the new
|
||||||
|
configuration. Previous configurations activated with
|
||||||
|
.Ic nixos-rebuild switch
|
||||||
|
or
|
||||||
|
.Ic nixos-rebuild boot
|
||||||
|
remain available in the GRUB menu.
|
||||||
|
.Pp
|
||||||
|
Note that if you are using specializations, running just
|
||||||
|
.Ic nixos-rebuild switch
|
||||||
|
will switch you back to the unspecialized, base system \(em in that case, you
|
||||||
|
might want to use this instead:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
$ nixos-rebuild switch --specialisation your-specialisation-name
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
This command will build all specialisations and make them bootable just
|
||||||
|
like regular
|
||||||
|
.Ic nixos-rebuild switch
|
||||||
|
does \(em the only thing different is that it will switch to given
|
||||||
|
specialisation instead of the base system; it can be also used to switch from
|
||||||
|
the base system into a specialised one, or to switch between specialisations.
|
||||||
|
.
|
||||||
|
.It Cm boot
|
||||||
|
Build the new configuration and make it the boot default (as with
|
||||||
|
.Ic nixos-rebuild switch Ns
|
||||||
|
), but do not activate it. That is, the system continues to run the previous
|
||||||
|
configuration until the next reboot.
|
||||||
|
.
|
||||||
|
.It Cm test
|
||||||
|
Build and activate the new configuration, but do not add it to the GRUB
|
||||||
|
boot menu. Thus, if you reboot the system (or if it crashes), you will
|
||||||
|
automatically revert to the default configuration (i.e. the
|
||||||
|
configuration resulting from the last call to
|
||||||
|
.Ic nixos-rebuild switch
|
||||||
|
or
|
||||||
|
.Ic nixos-rebuild boot Ns
|
||||||
|
).
|
||||||
|
.Pp
|
||||||
|
Note that if you are using specialisations, running just
|
||||||
|
.Ic nixos-rebuild test
|
||||||
|
will activate the unspecialised, base system \(em in that case, you might want
|
||||||
|
to use this instead:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
$ nixos-rebuild test --specialisation your-specialisation-name
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
This command can be also used to switch from the base system into a
|
||||||
|
specialised one, or to switch between specialisations.
|
||||||
|
.
|
||||||
|
.It Cm build
|
||||||
|
Build the new configuration, but neither activate it nor add it to the
|
||||||
|
GRUB boot menu. It leaves a symlink named
|
||||||
|
.Pa result
|
||||||
|
in the current directory, which points to the output of the top-level
|
||||||
|
.Dq system
|
||||||
|
derivation. This is essentially the same as doing
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
$ nix-build /path/to/nixpkgs/nixos -A system
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Note that you do not need to be root to run
|
||||||
|
.Ic nixos-rebuild build Ns
|
||||||
|
\&.
|
||||||
|
.
|
||||||
|
.It Cm dry-build
|
||||||
|
Show what store paths would be built or downloaded by any of the
|
||||||
|
operations above, but otherwise do nothing.
|
||||||
|
.
|
||||||
|
.It Cm dry-activate
|
||||||
|
Build the new configuration, but instead of activating it, show what
|
||||||
|
changes would be performed by the activation (i.e. by
|
||||||
|
.Ic nixos-rebuild test Ns
|
||||||
|
). For instance, this command will print which systemd units would be restarted.
|
||||||
|
The list of changes is not guaranteed to be complete.
|
||||||
|
.
|
||||||
|
.It Cm edit
|
||||||
|
Opens
|
||||||
|
.Pa configuration.nix
|
||||||
|
in the default editor.
|
||||||
|
.
|
||||||
|
.It Cm repl
|
||||||
|
Opens the configuration in
|
||||||
|
.Ic nix repl Ns .
|
||||||
|
.
|
||||||
|
.It Cm build-vm
|
||||||
|
Build a script that starts a NixOS virtual machine with the desired
|
||||||
|
configuration. It leaves a symlink
|
||||||
|
.Pa result
|
||||||
|
in the current directory that points (under
|
||||||
|
.Ql result/bin/run\- Ns Va hostname Ns \-vm Ns
|
||||||
|
)
|
||||||
|
at the script that starts the VM. Thus, to test a NixOS configuration in
|
||||||
|
a virtual machine, you should do the following:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
$ nixos-rebuild build-vm
|
||||||
|
$ ./result/bin/run-*-vm
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The VM is implemented using the
|
||||||
|
.Ql qemu
|
||||||
|
package. For best performance, you should load the
|
||||||
|
.Ql kvm-intel
|
||||||
|
or
|
||||||
|
.Ql kvm-amd
|
||||||
|
kernel modules to get hardware virtualisation.
|
||||||
|
.Pp
|
||||||
|
The VM mounts the Nix store of the host through the 9P file system. The
|
||||||
|
host Nix store is read-only, so Nix commands that modify the Nix store
|
||||||
|
will not work in the VM. This includes commands such as
|
||||||
|
.Nm Ns
|
||||||
|
; to change the VM’s configuration, you must halt the VM and re-run the commands
|
||||||
|
above.
|
||||||
|
.Pp
|
||||||
|
The VM has its own ext3 root file system, which is automatically created when
|
||||||
|
the VM is first started, and is persistent across reboots of the VM. It is
|
||||||
|
stored in
|
||||||
|
.Ql ./ Ns Va hostname Ns .qcow2 Ns
|
||||||
|
\&.
|
||||||
|
.\" The entire file system hierarchy of the host is available in
|
||||||
|
.\" the VM under
|
||||||
|
.\" .Pa /hostfs Ns
|
||||||
|
.\" .
|
||||||
|
.
|
||||||
|
.It Cm build-vm-with-bootloader
|
||||||
|
Like
|
||||||
|
.Cm build-vm Ns
|
||||||
|
, but boots using the regular boot loader of your configuration (e.g. GRUB 1 or
|
||||||
|
2), rather than booting directly into the kernel and initial ramdisk of the
|
||||||
|
system. This allows you to test whether the boot loader works correctly. \
|
||||||
|
However, it does not guarantee that your NixOS configuration will boot
|
||||||
|
successfully on the host hardware (i.e., after running
|
||||||
|
.Ic nixos-rebuild switch Ns
|
||||||
|
), because the hardware and boot loader configuration in the VM are different.
|
||||||
|
The boot loader is installed on an automatically generated virtual disk
|
||||||
|
containing a
|
||||||
|
.Pa /boot
|
||||||
|
partition.
|
||||||
|
.
|
||||||
|
.It Cm list-generations Op Fl -json
|
||||||
|
List the available generations in a similar manner to the boot loader
|
||||||
|
menu. It shows the generation number, build date and time, NixOS version,
|
||||||
|
kernel version and the configuration revision.
|
||||||
|
There is also a json version of output available.
|
||||||
|
.El
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.Sh OPTIONS
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Fl -upgrade , -upgrade-all
|
||||||
|
Update the root user's channel named
|
||||||
|
.Ql nixos
|
||||||
|
before rebuilding the system.
|
||||||
|
.Pp
|
||||||
|
In addition to the
|
||||||
|
.Ql nixos
|
||||||
|
channel, the root user's channels which have a file named
|
||||||
|
.Ql .update-on-nixos-rebuild
|
||||||
|
in their base directory will also be updated.
|
||||||
|
.Pp
|
||||||
|
Passing
|
||||||
|
.Fl -upgrade-all
|
||||||
|
updates all of the root user's channels.
|
||||||
|
.
|
||||||
|
.It Fl -install-bootloader
|
||||||
|
Causes the boot loader to be (re)installed on the device specified by the
|
||||||
|
relevant configuration options.
|
||||||
|
.
|
||||||
|
.It Fl -no-build-nix
|
||||||
|
Normally,
|
||||||
|
.Nm
|
||||||
|
first builds the
|
||||||
|
.Ql nixUnstable
|
||||||
|
attribute in Nixpkgs, and uses the resulting instance of the Nix package manager
|
||||||
|
to build the new system configuration. This is necessary if the NixOS modules
|
||||||
|
use features not provided by the currently installed version of Nix. This option
|
||||||
|
disables building a new Nix.
|
||||||
|
.
|
||||||
|
.It Fl -fast
|
||||||
|
Equivalent to
|
||||||
|
.Fl -no-build-nix Ns
|
||||||
|
\&. This option is useful if you call
|
||||||
|
.Nm
|
||||||
|
frequently (e.g. if you’re hacking on a NixOS module).
|
||||||
|
.
|
||||||
|
.It Fl -rollback
|
||||||
|
Instead of building a new configuration as specified by
|
||||||
|
.Pa /etc/nixos/configuration.nix Ns
|
||||||
|
, roll back to the previous configuration. (The previous configuration is
|
||||||
|
defined as the one before the “current” generation of the Nix profile
|
||||||
|
.Pa /nix/var/nix/profiles/system Ns
|
||||||
|
\&.)
|
||||||
|
.
|
||||||
|
.It Fl -builders Ar builder-spec
|
||||||
|
Allow ad-hoc remote builders for building the new system. This requires
|
||||||
|
the user executing
|
||||||
|
.Nm
|
||||||
|
(usually root) to be configured as a trusted user in the Nix daemon. This can be
|
||||||
|
achieved by using the
|
||||||
|
.Va nix.settings.trusted-users
|
||||||
|
NixOS option. Examples values for that option are described in the
|
||||||
|
.Dq Remote builds
|
||||||
|
chapter in the Nix manual, (i.e.
|
||||||
|
.Ql --builders \(dqssh://bigbrother x86_64-linux\(dq Ns
|
||||||
|
). By specifying an empty string existing builders specified in
|
||||||
|
.Pa /etc/nix/machines
|
||||||
|
can be ignored:
|
||||||
|
.Ql --builders \(dq\(dq
|
||||||
|
for example when they are not reachable due to network connectivity.
|
||||||
|
.
|
||||||
|
.It Fl -profile-name Ar name , Fl p Ar name
|
||||||
|
Instead of using the Nix profile
|
||||||
|
.Pa /nix/var/nix/profiles/system
|
||||||
|
to keep track of the current and previous system configurations, use
|
||||||
|
.Pa /nix/var/nix/profiles/system-profiles/ Ns Va name Ns
|
||||||
|
\&. When you use GRUB 2, for every system profile created with this flag, NixOS
|
||||||
|
will create a submenu named
|
||||||
|
.Dq NixOS - Profile Va name
|
||||||
|
in GRUB’s boot menu, containing the current and previous configurations of this profile.
|
||||||
|
.Pp
|
||||||
|
For instance, if you want to test a configuration file named
|
||||||
|
.Pa test.nix
|
||||||
|
without affecting the default system profile, you would do:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
$ nixos-rebuild switch -p test -I nixos-config=./test.nix
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The new configuration will appear in the GRUB 2 submenu
|
||||||
|
.Dq NixOS - Profile 'test' Ns
|
||||||
|
\&.
|
||||||
|
.
|
||||||
|
.It Fl -specialisation Ar name , Fl c Ar name
|
||||||
|
Activates given specialisation; when not specified, switching and testing
|
||||||
|
will activate the base, unspecialised system.
|
||||||
|
.
|
||||||
|
.It Fl -build-host Ar host
|
||||||
|
Instead of building the new configuration locally, use the specified host
|
||||||
|
to perform the build. The host needs to be accessible with
|
||||||
|
.Ic ssh Ns ,
|
||||||
|
and must be able to perform Nix builds. If the option
|
||||||
|
.Fl -target-host
|
||||||
|
is not set, the build will be copied back to the local machine when done.
|
||||||
|
.Pp
|
||||||
|
Note that, if
|
||||||
|
.Fl -no-build-nix
|
||||||
|
is not specified, Nix will be built both locally and remotely. This is because
|
||||||
|
the configuration will always be evaluated locally even though the building
|
||||||
|
might be performed remotely.
|
||||||
|
.Pp
|
||||||
|
You can include a remote user name in the host name
|
||||||
|
.Ns ( Va user@host Ns
|
||||||
|
). You can also set ssh options by defining the
|
||||||
|
.Ev NIX_SSHOPTS
|
||||||
|
environment variable.
|
||||||
|
.
|
||||||
|
.It Fl -target-host Ar host
|
||||||
|
Specifies the NixOS target host. By setting this to something other than an
|
||||||
|
empty string, the system activation will happen on the remote host instead of
|
||||||
|
the local machine. The remote host needs to be accessible over
|
||||||
|
.Ic ssh Ns ,
|
||||||
|
and for the commands
|
||||||
|
.Cm switch Ns
|
||||||
|
,
|
||||||
|
.Cm boot
|
||||||
|
and
|
||||||
|
.Cm test
|
||||||
|
you need root access.
|
||||||
|
.Pp
|
||||||
|
If
|
||||||
|
.Fl -build-host
|
||||||
|
is not explicitly specified or empty, building will take place locally.
|
||||||
|
.Pp
|
||||||
|
You can include a remote user name in the host name
|
||||||
|
.Ns ( Va user@host Ns
|
||||||
|
). You can also set ssh options by defining the
|
||||||
|
.Ev NIX_SSHOPTS
|
||||||
|
environment variable.
|
||||||
|
.Pp
|
||||||
|
Note that
|
||||||
|
.Nm
|
||||||
|
honors the
|
||||||
|
.Va nixpkgs.crossSystem
|
||||||
|
setting of the given configuration but disregards the true architecture of the
|
||||||
|
target host. Hence the
|
||||||
|
.Va nixpkgs.crossSystem
|
||||||
|
setting has to match the target platform or else activation will fail.
|
||||||
|
.
|
||||||
|
.It Fl -use-substitutes
|
||||||
|
When set, nixos-rebuild will add
|
||||||
|
.Fl -use-substitutes
|
||||||
|
to each invocation of nix-copy-closure. This will only affect the behavior of
|
||||||
|
nixos-rebuild if
|
||||||
|
.Fl -target-host
|
||||||
|
or
|
||||||
|
.Fl -build-host
|
||||||
|
is also set. This is useful when the target-host connection to cache.nixos.org
|
||||||
|
is faster than the connection between hosts.
|
||||||
|
.
|
||||||
|
.It Fl -use-remote-sudo
|
||||||
|
When set, nixos-rebuild prefixes activation commands that run on the
|
||||||
|
.Fl -target-host
|
||||||
|
system with
|
||||||
|
.Ic sudo Ns
|
||||||
|
\&. Setting this option allows deploying as a non-root user.
|
||||||
|
.
|
||||||
|
.It Fl -file Ar path , Fl F Ar path
|
||||||
|
Enable and build the NixOS system from the specified file. The file must
|
||||||
|
evaluate to an attribute set, and it must contain a valid NixOS configuration
|
||||||
|
at attribute
|
||||||
|
.Va attrPath Ns
|
||||||
|
\&. This is useful for building a NixOS system from a nix file that is not
|
||||||
|
a flake or a NixOS configuration module. Attribute set a with valid NixOS
|
||||||
|
configuration can be made using
|
||||||
|
.Va nixos
|
||||||
|
function in nixpkgs or importing and calling
|
||||||
|
.Pa nixos/lib/eval-config.nix
|
||||||
|
from nixpkgs. If specified without
|
||||||
|
.Fl -attr
|
||||||
|
option, builds the configuration from the top-level
|
||||||
|
attribute of the file.
|
||||||
|
.
|
||||||
|
.It Fl -attr Ar attrPath , Fl A Ar attrPath
|
||||||
|
Enable and build the NixOS system from nix file and use the specified attribute
|
||||||
|
path from file specified by the
|
||||||
|
.Fl -file
|
||||||
|
option. If specified without
|
||||||
|
.Fl -file
|
||||||
|
option, uses
|
||||||
|
.Pa default.nix
|
||||||
|
in current directory.
|
||||||
|
.
|
||||||
|
.It Fl -flake Va flake-uri Ns Op Va #name
|
||||||
|
Build the NixOS system from the specified flake. It defaults to the directory
|
||||||
|
containing the target of the symlink
|
||||||
|
.Pa /etc/nixos/flake.nix Ns
|
||||||
|
, if it exists. The flake must contain an output named
|
||||||
|
.Ql nixosConfigurations. Ns Va name Ns
|
||||||
|
\&. If
|
||||||
|
.Va name
|
||||||
|
is omitted, it default to the current host name.
|
||||||
|
.
|
||||||
|
.It Fl -no-flake
|
||||||
|
Do not imply
|
||||||
|
.Fl -flake
|
||||||
|
if
|
||||||
|
.Pa /etc/nixos/flake.nix
|
||||||
|
exists. With this option, it is possible to build non-flake NixOS configurations
|
||||||
|
even if the current NixOS systems uses flakes.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
In addition,
|
||||||
|
.Nm
|
||||||
|
accepts following options from nix commands that the tool calls:
|
||||||
|
.
|
||||||
|
.Pp
|
||||||
|
flake-related options:
|
||||||
|
.Bd -offset indent
|
||||||
|
.Fl -recreate-lock-file Ns ,
|
||||||
|
.Fl -no-update-lock-file Ns ,
|
||||||
|
.Fl -no-write-lock-file Ns ,
|
||||||
|
.Fl -no-registries Ns ,
|
||||||
|
.Fl -commit-lock-file Ns ,
|
||||||
|
.Fl -update-input Ar input-path Ns ,
|
||||||
|
.Fl -override-input Ar input-path flake-url Ns
|
||||||
|
.Ed
|
||||||
|
.
|
||||||
|
.Pp
|
||||||
|
Builder options:
|
||||||
|
.Bd -offset indent
|
||||||
|
.Fl -verbose Ns ,
|
||||||
|
.Fl v Ns ,
|
||||||
|
.Fl -quiet Ns ,
|
||||||
|
.Fl -log-format Ns ,
|
||||||
|
.Fl -no-build-output Ns ,
|
||||||
|
.Fl Q Ns ,
|
||||||
|
.Fl -max-jobs Ns ,
|
||||||
|
.Fl j Ns ,
|
||||||
|
.Fl -cores Ns ,
|
||||||
|
.Fl -keep-going Ns ,
|
||||||
|
.Fl k Ns ,
|
||||||
|
.Fl -keep-failed Ns ,
|
||||||
|
.Fl K Ns ,
|
||||||
|
.Fl -fallback Ns ,
|
||||||
|
.Fl I Ns ,
|
||||||
|
.Fl -option Ns
|
||||||
|
.Fl -repair Ns ,
|
||||||
|
.Fl -builders Ns ,
|
||||||
|
.Fl -accept-flake-config Ns ,
|
||||||
|
.Fl -print-build-logs Ns ,
|
||||||
|
.Fl L Ns ,
|
||||||
|
.Fl -show-trace Ns ,
|
||||||
|
.Fl -refresh Ns ,
|
||||||
|
.Fl -impure Ns ,
|
||||||
|
.Fl -offline Ns ,
|
||||||
|
.Fl -no-net Ns
|
||||||
|
.Ed
|
||||||
|
.
|
||||||
|
.Pp
|
||||||
|
See the Nix manual,
|
||||||
|
.Ic nix flake lock --help
|
||||||
|
or
|
||||||
|
.Ic nix-build --help
|
||||||
|
for details.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.Sh ENVIRONMENT
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Ev NIXOS_CONFIG
|
||||||
|
Path to the main NixOS configuration module. Defaults to
|
||||||
|
.Pa /etc/nixos/configuration.nix Ns
|
||||||
|
\&.
|
||||||
|
.
|
||||||
|
.It Ev NIX_PATH
|
||||||
|
A colon-separated list of directories used to look up Nix expressions enclosed
|
||||||
|
in angle brackets (e.g. <nixpkgs>). Example:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
nixpkgs=./my-nixpkgs
|
||||||
|
.Ed
|
||||||
|
.
|
||||||
|
.It Ev NIX_SSHOPTS
|
||||||
|
Additional options to be passed to
|
||||||
|
.Ic ssh
|
||||||
|
on the command line.
|
||||||
|
.Ed
|
||||||
|
.
|
||||||
|
.It Ev NIXOS_SWITCH_USE_DIRTY_ENV
|
||||||
|
Expose the the current environment variables to post activation scripts. Will
|
||||||
|
skip usage of
|
||||||
|
.Ic systemd-run
|
||||||
|
during system activation. Possibly dangerous, specially in remote environments
|
||||||
|
(e.g.: via SSH). Will be removed in the future.
|
||||||
|
.El
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Pa /etc/nixos/flake.nix
|
||||||
|
If this file exists, then
|
||||||
|
.Nm
|
||||||
|
will use it as if the
|
||||||
|
.Fl -flake
|
||||||
|
option was given. This file may be a symlink to a
|
||||||
|
.Pa flake.nix
|
||||||
|
in an actual flake; thus
|
||||||
|
.Pa /etc/nixos
|
||||||
|
need not be a flake.
|
||||||
|
.
|
||||||
|
.It Pa /run/current-system
|
||||||
|
A symlink to the currently active system configuration in the Nix store.
|
||||||
|
.
|
||||||
|
.It Pa /nix/var/nix/profiles/system
|
||||||
|
The Nix profile that contains the current and previous system
|
||||||
|
configurations. Used to generate the GRUB boot menu.
|
||||||
|
.El
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.Sh BUGS
|
||||||
|
This command should be renamed to something more descriptive.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
.An Eelco Dolstra
|
||||||
|
and
|
||||||
|
.An the Nixpkgs/NixOS contributors
|
874
pkgs/by-name/ni/nixos-rebuild/nixos-rebuild.sh
Executable file
874
pkgs/by-name/ni/nixos-rebuild/nixos-rebuild.sh
Executable file
|
@ -0,0 +1,874 @@
|
||||||
|
#! @runtimeShell@
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
if [ -x "@runtimeShell@" ]; then export SHELL="@runtimeShell@"; fi;
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -o pipefail
|
||||||
|
shopt -s inherit_errexit
|
||||||
|
|
||||||
|
export PATH=@path@:$PATH
|
||||||
|
|
||||||
|
showSyntax() {
|
||||||
|
exec man nixos-rebuild
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Parse the command line.
|
||||||
|
origArgs=("$@")
|
||||||
|
copyFlags=()
|
||||||
|
extraBuildFlags=()
|
||||||
|
lockFlags=()
|
||||||
|
flakeFlags=(--extra-experimental-features 'nix-command flakes')
|
||||||
|
action=
|
||||||
|
buildNix=1
|
||||||
|
fast=
|
||||||
|
rollback=
|
||||||
|
upgrade=
|
||||||
|
upgrade_all=
|
||||||
|
profile=/nix/var/nix/profiles/system
|
||||||
|
specialisation=
|
||||||
|
buildHost=
|
||||||
|
targetHost=
|
||||||
|
remoteSudo=
|
||||||
|
verboseScript=
|
||||||
|
noFlake=
|
||||||
|
attr=
|
||||||
|
buildFile=default.nix
|
||||||
|
buildingAttribute=1
|
||||||
|
installBootloader=
|
||||||
|
json=
|
||||||
|
|
||||||
|
# log the given argument to stderr
|
||||||
|
log() {
|
||||||
|
echo "$@" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
i="$1"; shift 1
|
||||||
|
case "$i" in
|
||||||
|
--help)
|
||||||
|
showSyntax
|
||||||
|
;;
|
||||||
|
switch|boot|test|build|edit|repl|dry-build|dry-run|dry-activate|build-vm|build-vm-with-bootloader|list-generations)
|
||||||
|
if [ "$i" = dry-run ]; then i=dry-build; fi
|
||||||
|
if [ "$i" = list-generations ]; then
|
||||||
|
buildNix=
|
||||||
|
fast=1
|
||||||
|
fi
|
||||||
|
# exactly one action mandatory, bail out if multiple are given
|
||||||
|
if [ -n "$action" ]; then showSyntax; fi
|
||||||
|
action="$i"
|
||||||
|
;;
|
||||||
|
--file|-f)
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
log "$0: ‘--file’ requires an argument"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
buildFile="$1"
|
||||||
|
buildingAttribute=
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--attr|-A)
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
log "$0: ‘--attr’ requires an argument"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
attr="$1"
|
||||||
|
buildingAttribute=
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--install-grub)
|
||||||
|
log "$0: --install-grub deprecated, use --install-bootloader instead"
|
||||||
|
installBootloader=1
|
||||||
|
;;
|
||||||
|
--install-bootloader)
|
||||||
|
installBootloader=1
|
||||||
|
;;
|
||||||
|
--no-build-nix)
|
||||||
|
buildNix=
|
||||||
|
;;
|
||||||
|
--rollback)
|
||||||
|
rollback=1
|
||||||
|
;;
|
||||||
|
--upgrade)
|
||||||
|
upgrade=1
|
||||||
|
;;
|
||||||
|
--upgrade-all)
|
||||||
|
upgrade=1
|
||||||
|
upgrade_all=1
|
||||||
|
;;
|
||||||
|
--use-substitutes|--substitute-on-destination|-s)
|
||||||
|
copyFlags+=("-s")
|
||||||
|
;;
|
||||||
|
-I|--max-jobs|-j|--cores|--builders|--log-format)
|
||||||
|
j="$1"; shift 1
|
||||||
|
extraBuildFlags+=("$i" "$j")
|
||||||
|
;;
|
||||||
|
--accept-flake-config|-j*|--quiet|--print-build-logs|-L|--no-build-output|-Q| --show-trace|--keep-going|-k|--keep-failed|-K|--fallback|--refresh|--repair|--impure|--offline|--no-net)
|
||||||
|
extraBuildFlags+=("$i")
|
||||||
|
;;
|
||||||
|
--verbose|-v|-vv|-vvv|-vvvv|-vvvvv)
|
||||||
|
verboseScript="true"
|
||||||
|
extraBuildFlags+=("$i")
|
||||||
|
;;
|
||||||
|
--option)
|
||||||
|
j="$1"; shift 1
|
||||||
|
k="$1"; shift 1
|
||||||
|
extraBuildFlags+=("$i" "$j" "$k")
|
||||||
|
;;
|
||||||
|
--fast)
|
||||||
|
buildNix=
|
||||||
|
fast=1
|
||||||
|
;;
|
||||||
|
--profile-name|-p)
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
log "$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
|
||||||
|
;;
|
||||||
|
--specialisation|-c)
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
log "$0: ‘--specialisation’ requires an argument"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
specialisation="$1"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--build-host)
|
||||||
|
buildHost="$1"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--target-host)
|
||||||
|
targetHost="$1"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--use-remote-sudo)
|
||||||
|
remoteSudo=1
|
||||||
|
;;
|
||||||
|
--flake)
|
||||||
|
flake="$1"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--no-flake)
|
||||||
|
noFlake=1
|
||||||
|
;;
|
||||||
|
--recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
|
||||||
|
lockFlags+=("$i")
|
||||||
|
;;
|
||||||
|
--update-input)
|
||||||
|
j="$1"; shift 1
|
||||||
|
lockFlags+=("$i" "$j")
|
||||||
|
;;
|
||||||
|
--override-input)
|
||||||
|
j="$1"; shift 1
|
||||||
|
k="$1"; shift 1
|
||||||
|
lockFlags+=("$i" "$j" "$k")
|
||||||
|
;;
|
||||||
|
--json)
|
||||||
|
json=1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log "$0: unknown option \`$i'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -n "$SUDO_USER" ]]; then
|
||||||
|
useSudo=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# log the given argument to stderr if verbose mode is on
|
||||||
|
logVerbose() {
|
||||||
|
if [ -n "$verboseScript" ]; then
|
||||||
|
echo "$@" >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run a command, logging it first if verbose mode is on
|
||||||
|
runCmd() {
|
||||||
|
logVerbose "$" "$@"
|
||||||
|
"$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildHostCmd() {
|
||||||
|
local c
|
||||||
|
if [[ "${useSudo:-x}" = 1 ]]; then
|
||||||
|
c=("sudo")
|
||||||
|
else
|
||||||
|
c=()
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$buildHost" ]; then
|
||||||
|
runCmd "$@"
|
||||||
|
elif [ -n "$remoteNix" ]; then
|
||||||
|
runCmd ssh $SSHOPTS "$buildHost" "${c[@]}" env PATH="$remoteNix":'$PATH' "$@"
|
||||||
|
else
|
||||||
|
runCmd ssh $SSHOPTS "$buildHost" "${c[@]}" "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
targetHostCmd() {
|
||||||
|
local c
|
||||||
|
if [[ "${useSudo:-x}" = 1 ]]; then
|
||||||
|
c=("sudo")
|
||||||
|
else
|
||||||
|
c=()
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$targetHost" ]; then
|
||||||
|
runCmd "${c[@]}" "$@"
|
||||||
|
else
|
||||||
|
runCmd ssh $SSHOPTS "$targetHost" "${c[@]}" "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
targetHostSudoCmd() {
|
||||||
|
if [ -n "$remoteSudo" ]; then
|
||||||
|
useSudo=1 SSHOPTS="$SSHOPTS -t" targetHostCmd "$@"
|
||||||
|
else
|
||||||
|
# While a tty might not be necessary, we apply it to be consistent with
|
||||||
|
# sudo usage, and an experience that is more consistent with local deployment.
|
||||||
|
SSHOPTS="$SSHOPTS -t" targetHostCmd "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToTarget() {
|
||||||
|
if ! [ "$targetHost" = "$buildHost" ]; then
|
||||||
|
if [ -z "$targetHost" ]; then
|
||||||
|
logVerbose "Running nix-copy-closure with these NIX_SSHOPTS: $SSHOPTS"
|
||||||
|
NIX_SSHOPTS=$SSHOPTS runCmd nix-copy-closure "${copyFlags[@]}" --from "$buildHost" "$1"
|
||||||
|
elif [ -z "$buildHost" ]; then
|
||||||
|
logVerbose "Running nix-copy-closure with these NIX_SSHOPTS: $SSHOPTS"
|
||||||
|
NIX_SSHOPTS=$SSHOPTS runCmd nix-copy-closure "${copyFlags[@]}" --to "$targetHost" "$1"
|
||||||
|
else
|
||||||
|
buildHostCmd nix-copy-closure "${copyFlags[@]}" --to "$targetHost" "$1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
nixBuild() {
|
||||||
|
logVerbose "Building in legacy (non-flake) mode."
|
||||||
|
if [ -z "$buildHost" ]; then
|
||||||
|
logVerbose "No --build-host given, running nix-build locally"
|
||||||
|
runCmd nix-build "$@"
|
||||||
|
else
|
||||||
|
logVerbose "buildHost set to \"$buildHost\", running nix-build remotely"
|
||||||
|
local instArgs=()
|
||||||
|
local buildArgs=()
|
||||||
|
local drv=
|
||||||
|
|
||||||
|
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")
|
||||||
|
;;
|
||||||
|
-I) # We don't want this in buildArgs
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
--no-out-link) # We don't want this in buildArgs
|
||||||
|
;;
|
||||||
|
"<"*) # nix paths
|
||||||
|
instArgs+=("$i")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
buildArgs+=("$i")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
drv="$(runCmd nix-instantiate "${instArgs[@]}" "${extraBuildFlags[@]}")"
|
||||||
|
if [ -a "$drv" ]; then
|
||||||
|
logVerbose "Running nix-copy-closure with these NIX_SSHOPTS: $SSHOPTS"
|
||||||
|
NIX_SSHOPTS=$SSHOPTS runCmd nix-copy-closure --to "$buildHost" "$drv"
|
||||||
|
buildHostCmd nix-store -r "$drv" "${buildArgs[@]}"
|
||||||
|
else
|
||||||
|
log "nix-instantiate failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
nixFlakeBuild() {
|
||||||
|
logVerbose "Building in flake mode."
|
||||||
|
if [[ -z "$buildHost" && -z "$targetHost" && "$action" != switch && "$action" != boot && "$action" != test && "$action" != dry-activate ]]
|
||||||
|
then
|
||||||
|
runCmd nix "${flakeFlags[@]}" build "$@"
|
||||||
|
readlink -f ./result
|
||||||
|
elif [ -z "$buildHost" ]; then
|
||||||
|
runCmd nix "${flakeFlags[@]}" build "$@" --out-link "${tmpDir}/result"
|
||||||
|
readlink -f "${tmpDir}/result"
|
||||||
|
else
|
||||||
|
local attr="$1"
|
||||||
|
shift 1
|
||||||
|
local evalArgs=()
|
||||||
|
local buildArgs=()
|
||||||
|
local drv=
|
||||||
|
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
local i="$1"; shift 1
|
||||||
|
case "$i" in
|
||||||
|
--recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
|
||||||
|
evalArgs+=("$i")
|
||||||
|
;;
|
||||||
|
--update-input)
|
||||||
|
local j="$1"; shift 1
|
||||||
|
evalArgs+=("$i" "$j")
|
||||||
|
;;
|
||||||
|
--override-input)
|
||||||
|
local j="$1"; shift 1
|
||||||
|
local k="$1"; shift 1
|
||||||
|
evalArgs+=("$i" "$j" "$k")
|
||||||
|
;;
|
||||||
|
--impure) # We don't want this in buildArgs, it's only needed at evaluation time, and unsupported during realisation
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
buildArgs+=("$i")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
drv="$(runCmd nix "${flakeFlags[@]}" eval --raw "${attr}.drvPath" "${evalArgs[@]}" "${extraBuildFlags[@]}")"
|
||||||
|
if [ -a "$drv" ]; then
|
||||||
|
logVerbose "Running nix with these NIX_SSHOPTS: $SSHOPTS"
|
||||||
|
NIX_SSHOPTS=$SSHOPTS runCmd nix "${flakeFlags[@]}" copy "${copyFlags[@]}" --derivation --to "ssh://$buildHost" "$drv"
|
||||||
|
buildHostCmd nix-store -r "$drv" "${buildArgs[@]}"
|
||||||
|
else
|
||||||
|
log "nix eval failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if [ -z "$action" ]; then showSyntax; fi
|
||||||
|
|
||||||
|
# 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 || "$action" = boot || "$action" = test ]]; then
|
||||||
|
canRun=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify that user is not trying to use attribute building and flake
|
||||||
|
# at the same time
|
||||||
|
if [[ -z $buildingAttribute && -n $flake ]]; then
|
||||||
|
log "error: '--flake' cannot be used with '--file' or '--attr'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If ‘--upgrade’ or `--upgrade-all` is given,
|
||||||
|
# run ‘nix-channel --update nixos’.
|
||||||
|
if [[ -n $upgrade && -z $_NIXOS_REBUILD_REEXEC && -z $flake ]]; then
|
||||||
|
# If --upgrade-all is passed, or there are other channels that
|
||||||
|
# contain a file called ".update-on-nixos-rebuild", update them as
|
||||||
|
# well. Also upgrade the nixos channel.
|
||||||
|
|
||||||
|
for channelpath in /nix/var/nix/profiles/per-user/root/channels/*; do
|
||||||
|
channel_name=$(basename "$channelpath")
|
||||||
|
|
||||||
|
if [[ "$channel_name" == "nixos" ]]; then
|
||||||
|
runCmd nix-channel --update "$channel_name"
|
||||||
|
elif [ -e "$channelpath/.update-on-nixos-rebuild" ]; then
|
||||||
|
runCmd nix-channel --update "$channel_name"
|
||||||
|
elif [[ -n $upgrade_all ]] ; then
|
||||||
|
runCmd nix-channel --update "$channel_name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Use /etc/nixos/flake.nix if it exists. It can be a symlink to the
|
||||||
|
# actual flake.
|
||||||
|
if [[ -z $flake && -e /etc/nixos/flake.nix && -z $noFlake ]]; then
|
||||||
|
flake="$(dirname "$(readlink -f /etc/nixos/flake.nix)")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For convenience, use the hostname as the default configuration to
|
||||||
|
# build from the flake.
|
||||||
|
if [[ -n $flake ]]; then
|
||||||
|
if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
|
||||||
|
flake="${BASH_REMATCH[1]}"
|
||||||
|
flakeAttr="${BASH_REMATCH[2]}"
|
||||||
|
fi
|
||||||
|
if [[ -z $flakeAttr ]]; then
|
||||||
|
hostname="$(targetHostCmd cat /proc/sys/kernel/hostname)"
|
||||||
|
if [[ -z $hostname ]]; then
|
||||||
|
hostname=default
|
||||||
|
fi
|
||||||
|
flakeAttr="nixosConfigurations.\"$hostname\""
|
||||||
|
else
|
||||||
|
flakeAttr="nixosConfigurations.\"$flakeAttr\""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -z "$specialisation" && ! "$action" = switch && ! "$action" = test ]]; then
|
||||||
|
log "error: ‘--specialisation’ can only be used with ‘switch’ and ‘test’"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmpDir=$(mktemp -t -d nixos-rebuild.XXXXXX)
|
||||||
|
|
||||||
|
if [[ ${#tmpDir} -ge 60 ]]; then
|
||||||
|
# Very long tmp dirs lead to "too long for Unix domain socket"
|
||||||
|
# SSH ControlPath errors. Especially macOS sets long TMPDIR paths.
|
||||||
|
rmdir "$tmpDir"
|
||||||
|
tmpDir=$(TMPDIR= mktemp -t -d nixos-rebuild.XXXXXX)
|
||||||
|
fi
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
# Re-execute nixos-rebuild from the Nixpkgs tree.
|
||||||
|
if [[ -z $_NIXOS_REBUILD_REEXEC && -n $canRun && -z $fast ]]; then
|
||||||
|
if [[ -z $buildingAttribute ]]; then
|
||||||
|
p=$(runCmd nix-build --no-out-link $buildFile -A "${attr:+$attr.}config.system.build.nixos-rebuild" "${extraBuildFlags[@]}")
|
||||||
|
SHOULD_REEXEC=1
|
||||||
|
elif [[ -z $flake ]]; then
|
||||||
|
if p=$(runCmd nix-build --no-out-link --expr 'with import <nixpkgs/nixos> {}; config.system.build.nixos-rebuild' "${extraBuildFlags[@]}"); then
|
||||||
|
SHOULD_REEXEC=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
runCmd nix "${flakeFlags[@]}" build --out-link "${tmpDir}/nixos-rebuild" "$flake#$flakeAttr.config.system.build.nixos-rebuild" "${extraBuildFlags[@]}" "${lockFlags[@]}"
|
||||||
|
if p=$(readlink -e "${tmpDir}/nixos-rebuild"); then
|
||||||
|
SHOULD_REEXEC=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $SHOULD_REEXEC ]]; then
|
||||||
|
export _NIXOS_REBUILD_REEXEC=1
|
||||||
|
# Manually call cleanup as the EXIT trap is not triggered when using exec
|
||||||
|
cleanup
|
||||||
|
runCmd exec "$p/bin/nixos-rebuild" "${origArgs[@]}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find configuration.nix and open editor instead of building.
|
||||||
|
if [ "$action" = edit ]; then
|
||||||
|
if [[ -n $attr || -n $buildFile ]]; then
|
||||||
|
log "error: '--file' and '--attr' are not supported with 'edit'"
|
||||||
|
exit 1
|
||||||
|
elif [[ -z $flake ]]; then
|
||||||
|
NIXOS_CONFIG=${NIXOS_CONFIG:-$(runCmd nix-instantiate --find-file nixos-config)}
|
||||||
|
if [[ -d $NIXOS_CONFIG ]]; then
|
||||||
|
NIXOS_CONFIG=$NIXOS_CONFIG/default.nix
|
||||||
|
fi
|
||||||
|
runCmd exec ${EDITOR:-nano} "$NIXOS_CONFIG"
|
||||||
|
else
|
||||||
|
runCmd exec nix "${flakeFlags[@]}" edit "${lockFlags[@]}" -- "$flake#$flakeAttr"
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SSHOPTS="$NIX_SSHOPTS -o ControlMaster=auto -o ControlPath=$tmpDir/ssh-%n -o ControlPersist=60"
|
||||||
|
|
||||||
|
# First build Nix, since NixOS may require a newer version than the
|
||||||
|
# current one.
|
||||||
|
if [[ -n "$rollback" || "$action" = dry-build ]]; then
|
||||||
|
buildNix=
|
||||||
|
fi
|
||||||
|
|
||||||
|
nixSystem() {
|
||||||
|
machine="$(uname -m)"
|
||||||
|
if [[ "$machine" =~ i.86 ]]; then
|
||||||
|
machine=i686
|
||||||
|
fi
|
||||||
|
echo $machine-linux
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuiltNix() {
|
||||||
|
machine="$1"
|
||||||
|
if [ "$machine" = x86_64 ]; then
|
||||||
|
echo @nix_x86_64_linux@
|
||||||
|
elif [[ "$machine" =~ i.86 ]]; then
|
||||||
|
echo @nix_i686_linux@
|
||||||
|
elif [[ "$machine" = aarch64 ]]; then
|
||||||
|
echo @nix_aarch64_linux@
|
||||||
|
else
|
||||||
|
log "$0: unsupported platform"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
getNixDrv() {
|
||||||
|
nixDrv=
|
||||||
|
|
||||||
|
if [[ -z $buildingAttribute ]]; then
|
||||||
|
if nixDrv="$(runCmd nix-instantiate $buildFile --add-root "$tmpDir/nix.drv" --indirect -A ${attr:+$attr.}config.nix.package.out "${extraBuildFlags[@]}")"; then return; fi
|
||||||
|
fi
|
||||||
|
if nixDrv="$(runCmd nix-instantiate '<nixpkgs/nixos>' --add-root "$tmpDir/nix.drv" --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then return; fi
|
||||||
|
if nixDrv="$(runCmd nix-instantiate '<nixpkgs>' --add-root "$tmpDir/nix.drv" --indirect -A nix "${extraBuildFlags[@]}")"; then return; fi
|
||||||
|
|
||||||
|
if ! nixStorePath="$(runCmd 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
|
||||||
|
if ! runCmd nix-store -r "$nixStorePath" --add-root "${tmpDir}/nix" --indirect \
|
||||||
|
--option extra-binary-caches https://cache.nixos.org/; then
|
||||||
|
log "warning: don't know how to get latest Nix"
|
||||||
|
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="$(runCmd 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=
|
||||||
|
log "warning: don't know how to get latest Nix"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -n $buildNix && -z $flake ]]; then
|
||||||
|
log "building Nix..."
|
||||||
|
getNixDrv
|
||||||
|
if [ -a "$nixDrv" ]; then
|
||||||
|
nix-store -r "$nixDrv"'!'"out" --add-root "$tmpDir/nix" --indirect >/dev/null
|
||||||
|
if [ -n "$buildHost" ]; then
|
||||||
|
nix-copy-closure "${copyFlags[@]}" --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"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Update the version suffix if we're building from Git (so that
|
||||||
|
# nixos-version shows something useful).
|
||||||
|
if [[ -n $canRun && -z $flake ]]; then
|
||||||
|
if nixpkgs=$(runCmd nix-instantiate --find-file nixpkgs "${extraBuildFlags[@]}"); then
|
||||||
|
suffix=$(runCmd $SHELL "$nixpkgs/nixos/modules/installer/tools/get-version-suffix" "${extraBuildFlags[@]}" || true)
|
||||||
|
if [ -n "$suffix" ]; then
|
||||||
|
echo -n "$suffix" > "$nixpkgs/.version-suffix" || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$action" = dry-build ]; then
|
||||||
|
extraBuildFlags+=(--dry-run)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$action" = repl ]; then
|
||||||
|
# This is a very end user command, implemented using sub-optimal means.
|
||||||
|
# You should feel free to improve its behavior, as well as resolve tech
|
||||||
|
# debt in "breaking" ways. Humans adapt quite well.
|
||||||
|
if [[ -z $buildingAttribute ]]; then
|
||||||
|
exec nix repl --file $buildFile $attr "${extraBuildFlags[@]}"
|
||||||
|
elif [[ -z $flake ]]; then
|
||||||
|
exec nix repl '<nixpkgs/nixos>' "${extraBuildFlags[@]}"
|
||||||
|
else
|
||||||
|
if [[ -n "${lockFlags[0]}" ]]; then
|
||||||
|
# nix repl itself does not support locking flags
|
||||||
|
log "nixos-rebuild repl does not support locking flags yet"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
d='$'
|
||||||
|
q='"'
|
||||||
|
bold="$(echo -e '\033[1m')"
|
||||||
|
blue="$(echo -e '\033[34;1m')"
|
||||||
|
attention="$(echo -e '\033[35;1m')"
|
||||||
|
reset="$(echo -e '\033[0m')"
|
||||||
|
if [[ -e $flake ]]; then
|
||||||
|
flakePath=$(realpath "$flake")
|
||||||
|
else
|
||||||
|
flakePath=$flake
|
||||||
|
fi
|
||||||
|
# This nix repl invocation is impure, because usually the flakeref is.
|
||||||
|
# For a solution that preserves the motd and custom scope, we need
|
||||||
|
# something like https://github.com/NixOS/nix/issues/8679.
|
||||||
|
exec nix repl --impure --expr "
|
||||||
|
let flake = builtins.getFlake ''$flakePath'';
|
||||||
|
configuration = flake.$flakeAttr;
|
||||||
|
motd = ''
|
||||||
|
$d{$q\n$q}
|
||||||
|
Hello and welcome to the NixOS configuration
|
||||||
|
$flakeAttr
|
||||||
|
in $flake
|
||||||
|
|
||||||
|
The following is loaded into nix repl's scope:
|
||||||
|
|
||||||
|
- ${blue}config${reset} All option values
|
||||||
|
- ${blue}options${reset} Option data and metadata
|
||||||
|
- ${blue}pkgs${reset} Nixpkgs package set
|
||||||
|
- ${blue}lib${reset} Nixpkgs library functions
|
||||||
|
- other module arguments
|
||||||
|
|
||||||
|
- ${blue}flake${reset} Flake outputs, inputs and source info of $flake
|
||||||
|
|
||||||
|
Use tab completion to browse around ${blue}config${reset}.
|
||||||
|
|
||||||
|
Use ${bold}:r${reset} to ${bold}reload${reset} everything after making a change in the flake.
|
||||||
|
(assuming $flake is a mutable flake ref)
|
||||||
|
|
||||||
|
See ${bold}:?${reset} for more repl commands.
|
||||||
|
|
||||||
|
${attention}warning:${reset} nixos-rebuild repl does not currently enforce pure evaluation.
|
||||||
|
'';
|
||||||
|
scope =
|
||||||
|
assert configuration._type or null == ''configuration'';
|
||||||
|
assert configuration.class or ''nixos'' == ''nixos'';
|
||||||
|
configuration._module.args //
|
||||||
|
configuration._module.specialArgs //
|
||||||
|
{
|
||||||
|
inherit (configuration) config options;
|
||||||
|
lib = configuration.lib or configuration.pkgs.lib;
|
||||||
|
inherit flake;
|
||||||
|
};
|
||||||
|
in builtins.seq scope builtins.trace motd scope
|
||||||
|
" "${extraBuildFlags[@]}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$action" = list-generations ]; then
|
||||||
|
if [ ! -L "$profile" ]; then
|
||||||
|
log "No profile \`$(basename "$profile")' found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
generation_from_dir() {
|
||||||
|
generation_dir="$1"
|
||||||
|
generation_base="$(basename "$generation_dir")" # Has the format "system-123-link" for generation 123
|
||||||
|
no_link_gen="${generation_base%-link}" # remove the "-link"
|
||||||
|
echo "${no_link_gen##*-}" # remove everything before the last dash
|
||||||
|
}
|
||||||
|
describe_generation(){
|
||||||
|
generation_dir="$1"
|
||||||
|
generation_number="$(generation_from_dir "$generation_dir")"
|
||||||
|
nixos_version="$(cat "$generation_dir/nixos-version" 2> /dev/null || echo "Unknown")"
|
||||||
|
|
||||||
|
kernel_dir="$(dirname "$(realpath "$generation_dir/kernel")")"
|
||||||
|
kernel_version="$(ls "$kernel_dir/lib/modules" || echo "Unknown")"
|
||||||
|
|
||||||
|
configurationRevision="$("$generation_dir/sw/bin/nixos-version" --configuration-revision 2> /dev/null || true)"
|
||||||
|
|
||||||
|
# Old nixos-version output ignored unknown flags and just printed the version
|
||||||
|
# therefore the following workaround is done not to show the default output
|
||||||
|
nixos_version_default="$("$generation_dir/sw/bin/nixos-version")"
|
||||||
|
if [ "$configurationRevision" == "$nixos_version_default" ]; then
|
||||||
|
configurationRevision=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# jq automatically quotes the output => don't try to quote it in output!
|
||||||
|
build_date="$(stat "$generation_dir" --format=%W | jq 'todate')"
|
||||||
|
|
||||||
|
pushd "$generation_dir/specialisation/" > /dev/null || :
|
||||||
|
specialisation_list=(*)
|
||||||
|
popd > /dev/null || :
|
||||||
|
|
||||||
|
specialisations="$(jq --compact-output --null-input '$ARGS.positional' --args -- "${specialisation_list[@]}")"
|
||||||
|
|
||||||
|
if [ "$(basename "$generation_dir")" = "$(readlink "$profile")" ]; then
|
||||||
|
current_generation_tag="true"
|
||||||
|
else
|
||||||
|
current_generation_tag="false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape userdefined strings
|
||||||
|
nixos_version="$(jq -aR <<< "$nixos_version")"
|
||||||
|
kernel_version="$(jq -aR <<< "$kernel_version")"
|
||||||
|
configurationRevision="$(jq -aR <<< "$configurationRevision")"
|
||||||
|
cat << EOF
|
||||||
|
{
|
||||||
|
"generation": $generation_number,
|
||||||
|
"date": $build_date,
|
||||||
|
"nixosVersion": $nixos_version,
|
||||||
|
"kernelVersion": $kernel_version,
|
||||||
|
"configurationRevision": $configurationRevision,
|
||||||
|
"specialisations": $specialisations,
|
||||||
|
"current": $current_generation_tag
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
find "$(dirname "$profile")" -regex "$profile-[0-9]+-link" |
|
||||||
|
sort -Vr |
|
||||||
|
while read -r generation_dir; do
|
||||||
|
describe_generation "$generation_dir"
|
||||||
|
done |
|
||||||
|
if [ -z "$json" ]; then
|
||||||
|
jq --slurp -r '.[] | [
|
||||||
|
([.generation, (if .current == true then "current" else "" end)] | join(" ")),
|
||||||
|
(.date | fromdate | strflocaltime("%Y-%m-%d %H:%M:%S")),
|
||||||
|
.nixosVersion, .kernelVersion, .configurationRevision,
|
||||||
|
(.specialisations | join(" "))
|
||||||
|
] | @tsv' |
|
||||||
|
column --separator $'\t' --table --table-columns "Generation,Build-date,NixOS version,Kernel,Configuration Revision,Specialisation" |
|
||||||
|
${PAGER:cat}
|
||||||
|
else
|
||||||
|
jq --slurp .
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# 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").
|
||||||
|
if [ -z "$rollback" ]; then
|
||||||
|
log "building the system configuration..."
|
||||||
|
if [[ "$action" = switch || "$action" = boot ]]; then
|
||||||
|
if [[ -z $buildingAttribute ]]; then
|
||||||
|
pathToConfig="$(nixBuild $buildFile -A "${attr:+$attr.}config.system.build.toplevel" "${extraBuildFlags[@]}")"
|
||||||
|
elif [[ -z $flake ]]; then
|
||||||
|
pathToConfig="$(nixBuild '<nixpkgs/nixos>' --no-out-link -A system "${extraBuildFlags[@]}")"
|
||||||
|
else
|
||||||
|
pathToConfig="$(nixFlakeBuild "$flake#$flakeAttr.config.system.build.toplevel" "${extraBuildFlags[@]}" "${lockFlags[@]}")"
|
||||||
|
fi
|
||||||
|
copyToTarget "$pathToConfig"
|
||||||
|
targetHostSudoCmd nix-env -p "$profile" --set "$pathToConfig"
|
||||||
|
elif [[ "$action" = test || "$action" = build || "$action" = dry-build || "$action" = dry-activate ]]; then
|
||||||
|
if [[ -z $buildingAttribute ]]; then
|
||||||
|
pathToConfig="$(nixBuild $buildFile -A "${attr:+$attr.}config.system.build.toplevel" "${extraBuildFlags[@]}")"
|
||||||
|
elif [[ -z $flake ]]; then
|
||||||
|
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A system -k "${extraBuildFlags[@]}")"
|
||||||
|
else
|
||||||
|
pathToConfig="$(nixFlakeBuild "$flake#$flakeAttr.config.system.build.toplevel" "${extraBuildFlags[@]}" "${lockFlags[@]}")"
|
||||||
|
fi
|
||||||
|
elif [ "$action" = build-vm ]; then
|
||||||
|
if [[ -z $buildingAttribute ]]; then
|
||||||
|
pathToConfig="$(nixBuild $buildFile -A "${attr:+$attr.}config.system.build.vm" "${extraBuildFlags[@]}")"
|
||||||
|
elif [[ -z $flake ]]; then
|
||||||
|
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vm -k "${extraBuildFlags[@]}")"
|
||||||
|
else
|
||||||
|
pathToConfig="$(nixFlakeBuild "$flake#$flakeAttr.config.system.build.vm" "${extraBuildFlags[@]}" "${lockFlags[@]}")"
|
||||||
|
fi
|
||||||
|
elif [ "$action" = build-vm-with-bootloader ]; then
|
||||||
|
if [[ -z $buildingAttribute ]]; then
|
||||||
|
pathToConfig="$(nixBuild $buildFile -A "${attr:+$attr.}config.system.build.vmWithBootLoader" "${extraBuildFlags[@]}")"
|
||||||
|
elif [[ -z $flake ]]; then
|
||||||
|
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vmWithBootLoader -k "${extraBuildFlags[@]}")"
|
||||||
|
else
|
||||||
|
pathToConfig="$(nixFlakeBuild "$flake#$flakeAttr.config.system.build.vmWithBootLoader" "${extraBuildFlags[@]}" "${lockFlags[@]}")"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
showSyntax
|
||||||
|
fi
|
||||||
|
# Copy build to target host if we haven't already done it
|
||||||
|
if ! [[ "$action" = switch || "$action" = boot ]]; then
|
||||||
|
copyToTarget "$pathToConfig"
|
||||||
|
fi
|
||||||
|
else # [ -n "$rollback" ]
|
||||||
|
if [[ "$action" = switch || "$action" = boot ]]; then
|
||||||
|
targetHostSudoCmd nix-env --rollback -p "$profile"
|
||||||
|
pathToConfig="$profile"
|
||||||
|
elif [[ "$action" = test || "$action" = build ]]; then
|
||||||
|
systemNumber=$(
|
||||||
|
targetHostCmd nix-env -p "$profile" --list-generations |
|
||||||
|
sed -n '/current/ {g; p;}; s/ *\([0-9]*\).*/\1/; h'
|
||||||
|
)
|
||||||
|
pathToConfig="$profile"-${systemNumber}-link
|
||||||
|
if [ -z "$targetHost" ]; then
|
||||||
|
ln -sT "$pathToConfig" ./result
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
showSyntax
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# If we're not just building, then make the new configuration the boot
|
||||||
|
# default and/or activate it now.
|
||||||
|
if [[ "$action" = switch || "$action" = boot || "$action" = test || "$action" = dry-activate ]]; then
|
||||||
|
# Using systemd-run here to protect against PTY failures/network
|
||||||
|
# disconnections during rebuild.
|
||||||
|
# See: https://github.com/NixOS/nixpkgs/issues/39118
|
||||||
|
cmd=(
|
||||||
|
"systemd-run"
|
||||||
|
"-E" "LOCALE_ARCHIVE" # Will be set to new value early in switch-to-configuration script, but interpreter starts out with old value
|
||||||
|
"-E" "NIXOS_INSTALL_BOOTLOADER=$installBootloader"
|
||||||
|
"--collect"
|
||||||
|
"--no-ask-password"
|
||||||
|
"--pipe"
|
||||||
|
"--quiet"
|
||||||
|
"--same-dir"
|
||||||
|
"--service-type=exec"
|
||||||
|
"--unit=nixos-rebuild-switch-to-configuration"
|
||||||
|
"--wait"
|
||||||
|
)
|
||||||
|
# Check if we have a working systemd-run. In chroot environments we may have
|
||||||
|
# a non-working systemd, so we fallback to not using systemd-run.
|
||||||
|
# You may also want to explicitly set NIXOS_SWITCH_USE_DIRTY_ENV environment
|
||||||
|
# variable, since systemd-run runs inside an isolated environment and
|
||||||
|
# this may break some post-switch scripts. However keep in mind that this
|
||||||
|
# may be dangerous in remote access (e.g. SSH).
|
||||||
|
if [[ -n "$NIXOS_SWITCH_USE_DIRTY_ENV" ]]; then
|
||||||
|
log "warning: skipping systemd-run since NIXOS_SWITCH_USE_DIRTY_ENV is set. This environment variable will be ignored in the future"
|
||||||
|
cmd=("env" "NIXOS_INSTALL_BOOTLOADER=$installBootloader")
|
||||||
|
elif ! targetHostSudoCmd "${cmd[@]}" true; then
|
||||||
|
logVerbose "Skipping systemd-run to switch configuration since it is not working in target host."
|
||||||
|
cmd=(
|
||||||
|
"env"
|
||||||
|
"-i"
|
||||||
|
"LOCALE_ARCHIVE=$LOCALE_ARCHIVE"
|
||||||
|
"NIXOS_INSTALL_BOOTLOADER=$installBootloader"
|
||||||
|
)
|
||||||
|
else
|
||||||
|
logVerbose "Using systemd-run to switch configuration."
|
||||||
|
fi
|
||||||
|
if [[ -z "$specialisation" ]]; then
|
||||||
|
cmd+=("$pathToConfig/bin/switch-to-configuration")
|
||||||
|
else
|
||||||
|
cmd+=("$pathToConfig/specialisation/$specialisation/bin/switch-to-configuration")
|
||||||
|
|
||||||
|
if [ -z "$targetHost" ]; then
|
||||||
|
specialisationExists=$(test -f "${cmd[-1]}")
|
||||||
|
else
|
||||||
|
specialisationExists=$(targetHostCmd test -f "${cmd[-1]}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! $specialisationExists; then
|
||||||
|
log "error: specialisation not found: $specialisation"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! targetHostSudoCmd "${cmd[@]}" "$action"; then
|
||||||
|
log "warning: error(s) occurred while switching to the new configuration"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [[ "$action" = build-vm || "$action" = build-vm-with-bootloader ]]; then
|
||||||
|
cat >&2 <<EOF
|
||||||
|
|
||||||
|
Done. The virtual machine can be started by running $(echo "${pathToConfig}/bin/"run-*-vm)
|
||||||
|
EOF
|
||||||
|
fi
|
59
pkgs/by-name/ni/nixos-rebuild/package.nix
Normal file
59
pkgs/by-name/ni/nixos-rebuild/package.nix
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
{ callPackage
|
||||||
|
, substitute
|
||||||
|
, runtimeShell
|
||||||
|
, coreutils
|
||||||
|
, gnused
|
||||||
|
, gnugrep
|
||||||
|
, jq
|
||||||
|
, util-linux
|
||||||
|
, nix
|
||||||
|
, lib
|
||||||
|
, nixosTests
|
||||||
|
, installShellFiles
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
fallback = import "${(import ../../../../inputs.nix {}).nixpkgs}/nixos/modules/installer/tools/nix-fallback-paths.nix";
|
||||||
|
in
|
||||||
|
substitute {
|
||||||
|
name = "nixos-rebuild";
|
||||||
|
src = ./nixos-rebuild.sh;
|
||||||
|
dir = "bin";
|
||||||
|
isExecutable = true;
|
||||||
|
|
||||||
|
substitutions = [
|
||||||
|
"--subst-var-by" "runtimeShell" runtimeShell
|
||||||
|
"--subst-var-by" "nix" nix
|
||||||
|
"--subst-var-by" "nix_x86_64_linux" fallback.x86_64-linux
|
||||||
|
"--subst-var-by" "nix_i686_linux" fallback.i686-linux
|
||||||
|
"--subst-var-by" "nix_aarch64_linux" fallback.aarch64-linux
|
||||||
|
"--subst-var-by" "path" (lib.makeBinPath [ coreutils gnused gnugrep jq util-linux ])
|
||||||
|
];
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
installShellFiles
|
||||||
|
];
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
installManPage ${./nixos-rebuild.8}
|
||||||
|
|
||||||
|
installShellCompletion \
|
||||||
|
--bash ${./_nixos-rebuild}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# run some a simple installer tests to make sure nixos-rebuild still works for them
|
||||||
|
passthru.tests = {
|
||||||
|
install-bootloader = nixosTests.nixos-rebuild-install-bootloader;
|
||||||
|
repl = callPackage ./test/repl.nix {};
|
||||||
|
simple-installer = nixosTests.installer.simple;
|
||||||
|
specialisations = nixosTests.nixos-rebuild-specialisations;
|
||||||
|
target-host = nixosTests.nixos-rebuild-target-host;
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Rebuild your NixOS configuration and switch to it, on local hosts and remote";
|
||||||
|
homepage = "https://github.com/NixOS/nixpkgs/tree/master/pkgs/os-specific/linux/nixos-rebuild";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
maintainers = [ lib.maintainers.Profpatsch ];
|
||||||
|
mainProgram = "nixos-rebuild";
|
||||||
|
};
|
||||||
|
}
|
159
pkgs/by-name/ni/nixos-rebuild/test/repl.nix
Normal file
159
pkgs/by-name/ni/nixos-rebuild/test/repl.nix
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
{ lib,
|
||||||
|
expect,
|
||||||
|
nix,
|
||||||
|
nixos-rebuild,
|
||||||
|
path,
|
||||||
|
runCommand,
|
||||||
|
stdenv,
|
||||||
|
writeText,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
# Arguably not true, but it holds up for now.
|
||||||
|
escapeExpect = lib.strings.escapeNixString;
|
||||||
|
|
||||||
|
expectSetup = ''
|
||||||
|
set timeout 180
|
||||||
|
proc expect_simple { pattern } {
|
||||||
|
puts "Expecting: $pattern"
|
||||||
|
expect {
|
||||||
|
timeout {
|
||||||
|
puts "\nTimeout waiting for: $pattern\n"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
$pattern
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# In case we want/need to evaluate packages or the assertions or whatever,
|
||||||
|
# we want to have a linux system.
|
||||||
|
# TODO: make the non-flake test use thise.
|
||||||
|
linuxSystem = lib.replaceStrings ["darwin"] ["linux"] stdenv.hostPlatform.system;
|
||||||
|
|
||||||
|
in
|
||||||
|
runCommand "test-nixos-rebuild-repl" {
|
||||||
|
nativeBuildInputs = [
|
||||||
|
expect
|
||||||
|
nix
|
||||||
|
nixos-rebuild
|
||||||
|
];
|
||||||
|
nixpkgs =
|
||||||
|
if builtins.pathExists (path + "/.git")
|
||||||
|
then lib.cleanSource path
|
||||||
|
else path;
|
||||||
|
} ''
|
||||||
|
export HOME=$(mktemp -d)
|
||||||
|
export TEST_ROOT=$PWD/test-tmp
|
||||||
|
|
||||||
|
# Prepare for running Nix in sandbox
|
||||||
|
export NIX_BUILD_HOOK=
|
||||||
|
export NIX_CONF_DIR=$TEST_ROOT/etc
|
||||||
|
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
||||||
|
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
||||||
|
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
||||||
|
export NIX_STORE_DIR=$TEST_ROOT/store
|
||||||
|
export PAGER=cat
|
||||||
|
mkdir -p $TEST_ROOT $NIX_CONF_DIR
|
||||||
|
|
||||||
|
echo General setup
|
||||||
|
##################
|
||||||
|
|
||||||
|
export NIX_PATH=nixpkgs=$nixpkgs:nixos-config=$HOME/configuration.nix
|
||||||
|
cat >> ~/configuration.nix <<EOF
|
||||||
|
{
|
||||||
|
boot.loader.grub.enable = false;
|
||||||
|
fileSystems."/".device = "x";
|
||||||
|
imports = [ ./hardware-configuration.nix ];
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo '{ }' > ~/hardware-configuration.nix
|
||||||
|
|
||||||
|
|
||||||
|
echo Test traditional NixOS configuration
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
expect ${writeText "test-nixos-rebuild-repl-expect" ''
|
||||||
|
${expectSetup}
|
||||||
|
spawn nixos-rebuild repl --fast
|
||||||
|
|
||||||
|
expect "nix-repl> "
|
||||||
|
|
||||||
|
send "config.networking.hostName\n"
|
||||||
|
expect "\"nixos\""
|
||||||
|
''}
|
||||||
|
|
||||||
|
|
||||||
|
echo Test flake based NixOS configuration
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
# Switch to flake flavored environment
|
||||||
|
unset NIX_PATH
|
||||||
|
cat > $NIX_CONF_DIR/nix.conf <<EOF
|
||||||
|
experimental-features = nix-command flakes
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Make the config pure
|
||||||
|
echo '{ nixpkgs.hostPlatform = "${linuxSystem}"; }' > ~/hardware-configuration.nix
|
||||||
|
|
||||||
|
cat >~/flake.nix <<EOF
|
||||||
|
{
|
||||||
|
inputs.nixpkgs.url = "path:$nixpkgs";
|
||||||
|
outputs = { nixpkgs, ... }: {
|
||||||
|
nixosConfigurations.testconf = nixpkgs.lib.nixosSystem {
|
||||||
|
modules = [
|
||||||
|
./configuration.nix
|
||||||
|
# Let's change it up a bit
|
||||||
|
{ networking.hostName = "itsme"; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# cat -n ~/flake.nix
|
||||||
|
|
||||||
|
expect ${writeText "test-nixos-rebuild-repl-absolute-path-expect" ''
|
||||||
|
${expectSetup}
|
||||||
|
spawn sh -c "nixos-rebuild repl --fast --flake path:\$HOME#testconf"
|
||||||
|
|
||||||
|
expect_simple "nix-repl>"
|
||||||
|
|
||||||
|
send "config.networking.hostName\n"
|
||||||
|
expect_simple "itsme"
|
||||||
|
|
||||||
|
expect_simple "nix-repl>"
|
||||||
|
send "lib.version\n"
|
||||||
|
expect_simple ${escapeExpect (
|
||||||
|
# The version string is a bit different in the flake lib, so we expect a prefix and ignore the rest
|
||||||
|
# Furthermore, including the revision (suffix) would cause unnecessary rebuilds.
|
||||||
|
# Note that a length of 4 only matches e.g. "24.
|
||||||
|
lib.strings.substring 0 4 (lib.strings.escapeNixString lib.version))}
|
||||||
|
|
||||||
|
# Make sure it's the right lib - should be the flake lib, not Nixpkgs lib.
|
||||||
|
expect_simple "nix-repl>"
|
||||||
|
send "lib?nixosSystem\n"
|
||||||
|
expect_simple "true"
|
||||||
|
expect_simple "nix-repl>"
|
||||||
|
send "lib?nixos\n"
|
||||||
|
expect_simple "true"
|
||||||
|
''}
|
||||||
|
|
||||||
|
pushd "$HOME"
|
||||||
|
expect ${writeText "test-nixos-rebuild-repl-relative-path-expect" ''
|
||||||
|
${expectSetup}
|
||||||
|
spawn sh -c "nixos-rebuild repl --fast --flake .#testconf"
|
||||||
|
|
||||||
|
expect_simple "nix-repl>"
|
||||||
|
|
||||||
|
send "config.networking.hostName\n"
|
||||||
|
expect_simple "itsme"
|
||||||
|
''}
|
||||||
|
popd
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
#########
|
||||||
|
echo Done
|
||||||
|
touch $out
|
||||||
|
''
|
|
@ -1,21 +1,43 @@
|
||||||
{ nixpkgsPath ? <nixpkgs> }:
|
{ nixpkgsPath ? <nixpkgs> }:
|
||||||
|
|
||||||
|
let
|
||||||
|
defaultNixpkgsPath = nixpkgsPath;
|
||||||
|
in
|
||||||
|
|
||||||
self: super: {
|
self: super: {
|
||||||
selfExpr = let
|
selfExpr = let
|
||||||
config = builtins.removeAttrs self.config [ "_undeclared" ];
|
config = builtins.removeAttrs self.config [ "_undeclared" ];
|
||||||
configJson = builtins.toJSON config;
|
configJson = builtins.toJSON config;
|
||||||
in
|
|
||||||
self.writeTextFile {
|
getSelfExpr = {
|
||||||
name = "nixpkgs-self";
|
useConfig ? true,
|
||||||
destination = "/default.nix";
|
nixpkgsPath ? defaultNixpkgsPath,
|
||||||
text = ''
|
...
|
||||||
|
}: let
|
||||||
|
configText = ''
|
||||||
|
config = (builtins.fromJSON '''
|
||||||
|
${configJson}
|
||||||
|
''') // args.config or {};
|
||||||
|
'';
|
||||||
|
|
||||||
|
removedAttrNames = self.lib.optional useConfig "config";
|
||||||
|
removedAttrNamesText = builtins.toJSON removedAttrNames;
|
||||||
|
in ''
|
||||||
{ ... } @ args:
|
{ ... } @ args:
|
||||||
|
|
||||||
import ${builtins.toString nixpkgsPath} {
|
import ${nixpkgsPath} {
|
||||||
config = (builtins.fromJSON '''
|
${self.lib.optionalString useConfig configText}
|
||||||
${configJson}
|
} // builtins.removeAttrs args (builtins.fromJSON '''
|
||||||
''') // args.config or {};
|
${removedAttrNamesText}
|
||||||
} // builtins.removeAttrs args [ "config" ]
|
''')
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
|
mkNixpkgsChannel = args: self.writeTextFile {
|
||||||
|
name = args.name or "nixpkgs-self";
|
||||||
|
destination = "/default.nix";
|
||||||
|
text = getSelfExpr args;
|
||||||
|
} // {
|
||||||
|
__functor = _: args: mkNixpkgsChannel args;
|
||||||
|
};
|
||||||
|
in mkNixpkgsChannel {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,21 @@ self: super:
|
||||||
|
|
||||||
let
|
let
|
||||||
nixos = self.config.nixos or true;
|
nixos = self.config.nixos or true;
|
||||||
|
unstableRevision = self.config.unstableRevision or null;
|
||||||
|
unstableRevisionHash = self.config.unstableRevisionHash or null;
|
||||||
useUnstable = self.config.useUnstable or true;
|
useUnstable = self.config.useUnstable or true;
|
||||||
|
|
||||||
unstablePkgsExprs = if nixos
|
unstablePkgsExprs = if !builtins.isNull unstableRevision
|
||||||
then builtins.fetchTarball "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
then if !builtins.isNull unstableRevisionHash
|
||||||
else builtins.fetchTarball "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
|
then builtins.fetchTarball {
|
||||||
|
url = "https://github.com/NixOS/nixpkgs/archive/${unstableRevision}.tar.gz";
|
||||||
|
sha256 = unstableRevisionHash;
|
||||||
|
}
|
||||||
|
else builtins.fetchTarball "https://github.com/NixOS/nixpkgs/archive/${unstableRevision}.tar.gz"
|
||||||
|
else if nixos
|
||||||
|
then builtins.fetchTarball "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
||||||
|
else builtins.fetchTarball "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
|
||||||
|
|
||||||
# Compiled nixpkgs expression eg expressions from a nix channel
|
# Compiled nixpkgs expression eg expressions from a nix channel
|
||||||
nixpkgsVersion = builtins.concatStringsSep "." [
|
nixpkgsVersion = builtins.concatStringsSep "." [
|
||||||
(builtins.readFile "${unstablePkgsExprs}/.version")
|
(builtins.readFile "${unstablePkgsExprs}/.version")
|
||||||
|
@ -16,10 +25,10 @@ let
|
||||||
|
|
||||||
nixpkgsRevision = (builtins.readFile "${unstablePkgsExprs}/.git-revision");
|
nixpkgsRevision = (builtins.readFile "${unstablePkgsExprs}/.git-revision");
|
||||||
unstablePkgsForNixpkgs = nixpkgs: import unstablePkgsExprs {
|
unstablePkgsForNixpkgs = nixpkgs: import unstablePkgsExprs {
|
||||||
# localSystem -> pkgs.stdenv.hostPlatform or pkgs.stdenv.hostPlatform ???
|
# localSystem -> pkgs.stdenv.buildPlatform
|
||||||
localSystem = nixpkgs.stdenv.hostPlatform;
|
localSystem = nixpkgs.stdenv.buildPlatform;
|
||||||
# crossSystem -> nixpkgs.stdenv.targetPlatform
|
# crossSystem -> pkgs.stdenv.hostPlatform or pkgs.stdenv.targetPlatform ??
|
||||||
crossSystem = nixpkgs.stdenv.targetPlatform;
|
crossSystem = nixpkgs.stdenv.hostPlatform;
|
||||||
# config -> pkgs.config
|
# config -> pkgs.config
|
||||||
config = nixpkgs.config;
|
config = nixpkgs.config;
|
||||||
# overlays -> partial of pkgs.overlays
|
# overlays -> partial of pkgs.overlays
|
||||||
|
|
5
pkgs/overlays/version-info-fixup.nix
Normal file
5
pkgs/overlays/version-info-fixup.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{ inputs ? import ../../inputs.nix {} }:
|
||||||
|
|
||||||
|
self: super: {
|
||||||
|
lib = super.lib.extend (import ../../lib/overlays/version-info-fixup.nix { inherit inputs; });
|
||||||
|
}
|
22
pkgs/top-level/default.nix
Normal file
22
pkgs/top-level/default.nix
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{ inputs ? import ../../inputs.nix {}
|
||||||
|
, uninitializedNixpkgs ? import "${inputs.nixpkgs}/pkgs/top-level/default.nix"
|
||||||
|
, ...
|
||||||
|
} @ args:
|
||||||
|
|
||||||
|
let
|
||||||
|
attrsToRemove = [
|
||||||
|
"inputs"
|
||||||
|
"overlays"
|
||||||
|
"uninitializedNixpkgs"
|
||||||
|
];
|
||||||
|
|
||||||
|
options = (builtins.removeAttrs args attrsToRemove) // {
|
||||||
|
overlays = (args.overlays or []) ++ [
|
||||||
|
( import ../overlays/selfExpr.nix { nixpkgsPath = ./impure.nix; } )
|
||||||
|
( import ../overlays/unstable.nix )
|
||||||
|
( import ../overlays/version-info-fixup.nix { inherit inputs; } )
|
||||||
|
( import "${inputs.nixpkgs}/pkgs/top-level/by-name-overlay.nix" ../by-name )
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
uninitializedNixpkgs options
|
70
pkgs/top-level/impure.nix
Normal file
70
pkgs/top-level/impure.nix
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
# Modified copy of github:NixOS/nixpkgs pkgs/top-level/impure.nix
|
||||||
|
# as of commit 242522b8fed8d63f262fd6e747ba1e4372b59a8e
|
||||||
|
|
||||||
|
# I wish I could just import from nixpkgs and set different path to entry point.
|
||||||
|
|
||||||
|
let
|
||||||
|
homeDir = builtins.getEnv "HOME";
|
||||||
|
|
||||||
|
# Return ‘x’ if it evaluates, or ‘def’ if it throws an exception.
|
||||||
|
try = x: def: let res = builtins.tryEval x; in if res.success then res.value else def;
|
||||||
|
in
|
||||||
|
|
||||||
|
{ localSystem ? { system = args.system or builtins.currentSystem; }
|
||||||
|
, system ? localSystem.system
|
||||||
|
, crossSystem ? localSystem
|
||||||
|
, config ? let
|
||||||
|
configFile = builtins.getEnv "NIXPKGS_CONFIG";
|
||||||
|
configFile2 = homeDir + "/.config/nixpkgs/config.nix";
|
||||||
|
configFile3 = homeDir + "/.nixpkgs/config.nix"; # obsolete
|
||||||
|
in
|
||||||
|
if configFile != "" && builtins.pathExists configFile then import configFile
|
||||||
|
else if homeDir != "" && builtins.pathExists configFile2 then import configFile2
|
||||||
|
else if homeDir != "" && builtins.pathExists configFile3 then import configFile3
|
||||||
|
else {}
|
||||||
|
, overlays ? let
|
||||||
|
isDir = path: builtins.pathExists (path + "/.");
|
||||||
|
pathOverlays = try (toString <nixpkgs-overlays>) "";
|
||||||
|
homeOverlaysFile = homeDir + "/.config/nixpkgs/overlays.nix";
|
||||||
|
homeOverlaysDir = homeDir + "/.config/nixpkgs/overlays";
|
||||||
|
overlays = path:
|
||||||
|
# check if the path is a directory or a file
|
||||||
|
if isDir path then
|
||||||
|
# it's a directory, so the set of overlays from the directory, ordered lexicographically
|
||||||
|
let content = builtins.readDir path; in
|
||||||
|
map (n: import (path + ("/" + n)))
|
||||||
|
(builtins.filter
|
||||||
|
(n:
|
||||||
|
(builtins.match ".*\\.nix" n != null &&
|
||||||
|
# ignore Emacs lock files (.#foo.nix)
|
||||||
|
builtins.match "\\.#.*" n == null) ||
|
||||||
|
builtins.pathExists (path + ("/" + n + "/default.nix")))
|
||||||
|
(builtins.attrNames content))
|
||||||
|
else
|
||||||
|
# it's a file, so the result is the contents of the file itself
|
||||||
|
import path;
|
||||||
|
in
|
||||||
|
if pathOverlays != "" && builtins.pathExists pathOverlays then overlays pathOverlays
|
||||||
|
else if builtins.pathExists homeOverlaysFile && builtins.pathExists homeOverlaysDir then
|
||||||
|
throw ''
|
||||||
|
Nixpkgs overlays can be specified with ${homeOverlaysFile} or ${homeOverlaysDir}, but not both.
|
||||||
|
Please remove one of them and try again.
|
||||||
|
''
|
||||||
|
else if builtins.pathExists homeOverlaysFile then
|
||||||
|
if isDir homeOverlaysFile then
|
||||||
|
throw (homeOverlaysFile + " should be a file")
|
||||||
|
else overlays homeOverlaysFile
|
||||||
|
else if builtins.pathExists homeOverlaysDir then
|
||||||
|
if !(isDir homeOverlaysDir) then
|
||||||
|
throw (homeOverlaysDir + " should be a directory")
|
||||||
|
else overlays homeOverlaysDir
|
||||||
|
else []
|
||||||
|
, crossOverlays ? []
|
||||||
|
, ...
|
||||||
|
} @ args:
|
||||||
|
|
||||||
|
# Assertion checked in called nixpkgs upstream, thus removed here
|
||||||
|
|
||||||
|
import ./. (builtins.removeAttrs args [ "system" ] // {
|
||||||
|
inherit config overlays localSystem;
|
||||||
|
})
|
1
vm.sh
1
vm.sh
|
@ -1 +0,0 @@
|
||||||
nix-build '<nixpkgs/nixos>' -A vm -I nixos-config=./hosts/vm.nix $@ && $(ls ./result/bin/run-*) -m 4096 && rm *.qcow2
|
|
Loading…
Reference in a new issue