Merge branch 'main' into cosmic

This commit is contained in:
Wroclaw 2024-07-06 06:17:43 +02:00
commit 3009a03edc
26 changed files with 2260 additions and 51 deletions

51
default.nix Normal file
View 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

View file

@ -1,4 +1,4 @@
{ pkgs, ... }:
{ inputs, pkgs, ... }:
{
imports = [
@ -20,7 +20,7 @@
../nix-os/services/nix-binary-cache.nix
../nix-os/udev.nix
(builtins.fetchTarball "https://github.com/nix-community/nixos-vscode-server/tarball/fc900c16efc6a5ed972fb6be87df018bcf3035bc")
"${inputs.nixos-vscode-server}"
];
config = {
@ -45,6 +45,8 @@
];
};
services.printing.startWhenNeeded = false;
system.stateVersion = "23.05";
};
}

View file

@ -21,7 +21,6 @@
networking.hostName = "wroclaw-hp";
networking.networkmanager.enable = true;
networking.firewall.enable = true;
services.xserver.displayManager.gdm.wayland = lib.mkForce true;
hardware.sensor.iio.enable = true;
networking.firewall.allowedTCPPortRanges = [

19
inputs.nix Normal file
View 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

View 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
View file

@ -0,0 +1,10 @@
{
nixos-vscode-server = {
revision = "fc900c16efc6a5ed972fb6be87df018bcf3035bc";
sha256 = "1rq8mrlmbzpcbv9ys0x88alw30ks70jlmvnfr2j8v830yy5wvw7h";
};
nixpkgs = {
revision = "10c832d0548e9e3a6df7eb51e68c2783212a303e";
sha256 = "1p206hgfxbz0rmkzaslfrknbdss4n4dnb09pi5466h8ksmm8216q";
};
}

View file

@ -17,7 +17,10 @@
initialPassword = "nixos";
packages = with pkgs; [
firefox
vivaldi
(vivaldi.override {
proprietaryCodecs = true;
commandLineArgs = [ "--ozone-platform=wayland" ];
})
discord-canary
unstablePkgs.vscode
gimp

View file

@ -4,7 +4,7 @@
config = {
services.printing.enable = true;
sound.enable = true;
sound.enable = false;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
@ -24,5 +24,12 @@
services.openssh.extraConfig = ''
X11Forwarding yes
'';
# Fonts
fonts.packages = with pkgs; [
corefonts
nerdfonts
roboto
];
};
}

View file

@ -2,27 +2,41 @@
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running 'nixos-help').
{ config, pkgs, lib, ... }:
{ inputs, lib, pkgs, ... }:
let
/*
* pkgs: package - nixpkgs package
* pkg: package - nixpkgs package
* exe: string - executable (under bin) in pkgs
* wrapperArgs: string[] - arguments to pass to the wrapper
*/
mkWrappedExecutable = {pkg, exe ? pkg.meta.mainProgram, wrapperArgs}: let inherit (pkgs) lib makeWrapper; in pkgs.stdenv.mkDerivation {
name = "${pkg.name}-wrap-${exe}";
nativeBuildInputs = [ makeWrapper ];
phases = ["installPhase"];
installPhase = ''
mkdir -p $out/bin
makeWrapper ${pkg}/bin/${exe} $out/bin/${exe} ${lib.concatStringsSep " " wrapperArgs}
'';
};
wrapedNixPrograms = builtins.map lib.hiPrio [
(mkWrappedExecutable {pkg = pkgs.nix; exe = "nix-build"; wrapperArgs = ["--add-flags" "\"--log-format\"" "--add-flags" "bar-with-logs"];})
mkWrappedExecutable = {pkg, exe ? pkg.meta.mainProgram, wrapperArgs}: let inherit (pkgs) lib makeWrapper; in lib.hiPrio (
pkgs.stdenv.mkDerivation {
inherit wrapperArgs;
name = "${pkg.name}-wrap-${exe}";
nativeBuildInputs = [ makeWrapper ];
phases = ["installPhase"];
installPhase = ''
mkdir -p $out/bin
makeWrapper ${pkg}/bin/${exe} $out/bin/${exe} $wrapperArgs
'';
}
);
# bool -> nixpkgs[]
wrappedNixExecutables = inEnvironment: assert builtins.isBool inEnvironment; [
(mkWrappedExecutable {pkg = pkgs.nix; exe = "nix-build"; wrapperArgs = ["--add-flags" "\"--log-format\"" "--add-flags" "bar${lib.optionalString inEnvironment "-with-logs"}"];})
(mkWrappedExecutable {pkg = pkgs.nix; exe = "nix-shell"; wrapperArgs = ["--add-flags" "\"--log-format\"" "--add-flags" "bar"];})
];
wrappedNixosExecutables = [
(mkWrappedExecutable {pkg = pkgs.nixos-rebuild; wrapperArgs = ["--add-flags" "\"--log-format\"" "--add-flags" "bar"];})
];
wrappedNix = (pkgs.buildEnv {
name = "wrappedNix-${pkgs.nix.version}";
paths = [ pkgs.nix ] ++ wrappedNixExecutables false;
}).overrideAttrs {
version = pkgs.nix.version;
};
in
{
# kernel
@ -33,6 +47,16 @@ in
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
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:
# $ nix search wget
@ -45,7 +69,8 @@ in
fastfetch
smartmontools
ddrescue
] ++ wrapedNixPrograms;
] ++ wrappedNixExecutables true
++ wrappedNixosExecutables;
programs.git.enable = true;
programs.git.config = {

View file

@ -1,6 +1,21 @@
{pkgs, ... }:
{config, lib, pkgs, ... }:
let
maxThumbnails = config.programs.gnome.extensions.workspaceIndicator.maxThumbnails;
workspaceIndicator = pkgs.gnomeExtensions.workspace-indicator.overrideAttrs {
postPatch = ''
sed -i 's/const MAX_THUMBNAILS = 6;/const MAX_THUMBNAILS = '${builtins.toString maxThumbnails}'/' extension.js
'';
};
in
{
options = {
programs.gnome.extensions.workspaceIndicator.maxThumbnails = lib.mkOption {
type = lib.types.int;
default = 11;
description = "The maximum number of thumbnails to show in the workspace indicator";
};
};
imports = [
../unstable-packages.nix
../dconf-common.nix
@ -56,6 +71,7 @@
];
environment.systemPackages = with pkgs; [
workspaceIndicator
gnomeExtensions.pop-shell
gnomeExtensions.vitals
gnomeExtensions.tray-icons-reloaded

View file

@ -7,7 +7,6 @@
config = {
services.xserver.displayManager.gdm = {
enable = true;
wayland = false;
autoSuspend = false;
};

View file

@ -12,6 +12,12 @@
powerManagement.enable = true;
open = false;
nvidiaSettings = true;
package = config.boot.kernelPackages.nvidiaPackages.stable;
package = config.boot.kernelPackages.nvidiaPackages.mkDriver {
version = "555.42.02";
sha256_64bit = "sha256-k7cI3ZDlKp4mT46jMkLaIrc2YUx1lh1wj/J4SVSHWyk=";
settingsSha256 = "sha256-rtDxQjClJ+gyrCLvdZlT56YyHQ4sbaL+d5tL4L4VfkA=";
persistencedSha256 = "";
};
};
nixpkgs.config.nvidia.acceptLicense = true;
}

View file

@ -47,6 +47,7 @@ in
'';
environment.etc."xdg/kitty/kitty.conf".text = ''
font_family MesloLGS Nerd Font
font_size 10.0
scrollback_lines 10000
window_border_width 0.5
@ -91,17 +92,38 @@ in
set shiftwidth=4
set expandtab
set autoindent
set updatetime=500
syntax on
set encoding=utf-8
set wildmode=longest,list,full
set listchars=space:·,tab:»
set indentkeys-=0#
" rainbow-delimeters-nvim
let g:rainbow_delimiters = {
\ 'strategy': {
\ ${"''"}: rainbow_delimiters#strategy.global,
\ },
\ }
" vim-gitguter
set signcolumn=yes
highlight SignColumn ctermbg=NONE
highlight GitGutterAdd ctermfg=2
highlight GitGutterChange ctermfg=4
highlight GitGutterDelete ctermfg=1
lua require('guess-indent').setup {}
'';
packages.myVimPackage = with pkgs.vimPlugins; {
start = [
guess-indent-nvim
vim-visual-multi
autoclose-nvim
rainbow-delimiters-nvim
vimagit
vim-gitgutter
];
};
};

View file

@ -1,37 +1,20 @@
{config, pkgs, lib, ...}:
let
nixos-unstable-exprs = builtins.fetchTarball https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz;
nixos-unstable = import nixos-unstable-exprs {
inherit (config.nixpkgs) config localSystem crossSystem;
overlays = if config.unstable.usePkgsOverlays then config.pkgs.overlays else [];
};
nixos-unstable-version = builtins.concatStringsSep "." [
(builtins.readFile "${builtins.toString nixos-unstable-exprs}/.version")
(builtins.readFile "${builtins.toString nixos-unstable-exprs}/.version-suffix")
];
cfg = config.unstable;
unstableOverlay = import ../pkgs/overlays/unstable.nix;
in
{
options.unstable = {
enable = lib.mkEnableOption (lib.mkDoc ''
use of unstable packages in configuration. You can use `unstablePkgs` in configuration modules
'') // { default = true; };
usePkgsOverlays = lib.mkEnableOption (lib.mkDoc ''
use overlays from `nixpkgs.overlays`
'');
pkgs = lib.mkOption {
default = if config.unstable.enable then nixos-unstable else pkgs;
description = lib.mkDoc ''
acts like pkgs, but it has unstable packages if `unstable.enable` is enabled.
You can also use `unstablePkgs` in module arguments.
'';
visible = true;
readOnly = true;
type = lib.types.pkgs;
};
};
config._module.args.unstablePkgs = config.unstable.pkgs;
config.system.extraSystemBuilderCmds = lib.mkIf config.unstable.enable ''
echo ${nixos-unstable-version} > $out/nixos-unstable-version
'';
config = {
_module.args.unstablePkgs = if config.unstable.enable then pkgs.unstable else pkgs;
nixpkgs.overlays = lib.mkIf cfg.enable [ unstableOverlay ];
system.extraSystemBuilderCmds = lib.mkIf config.unstable.enable ''
echo ${pkgs.unstableVersion} > $out/nixos-unstable-version
'';
};
}

56
outputs.nix Normal file
View 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

View 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

View 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 VMs 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 youre 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 GRUBs 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

View 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

View 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";
};
}

View 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
''

View file

@ -0,0 +1,43 @@
{ nixpkgsPath ? <nixpkgs> }:
let
defaultNixpkgsPath = nixpkgsPath;
in
self: super: {
selfExpr = let
config = builtins.removeAttrs self.config [ "_undeclared" ];
configJson = builtins.toJSON config;
getSelfExpr = {
useConfig ? true,
nixpkgsPath ? defaultNixpkgsPath,
...
}: let
configText = ''
config = (builtins.fromJSON '''
${configJson}
''') // args.config or {};
'';
removedAttrNames = self.lib.optional useConfig "config";
removedAttrNamesText = builtins.toJSON removedAttrNames;
in ''
{ ... } @ args:
import ${nixpkgsPath} {
${self.lib.optionalString useConfig configText}
} // builtins.removeAttrs args (builtins.fromJSON '''
${removedAttrNamesText}
''')
'';
mkNixpkgsChannel = args: self.writeTextFile {
name = args.name or "nixpkgs-self";
destination = "/default.nix";
text = getSelfExpr args;
} // {
__functor = _: args: mkNixpkgsChannel args;
};
in mkNixpkgsChannel {};
}

View file

@ -0,0 +1,49 @@
self: super:
let
nixos = self.config.nixos or true;
unstableRevision = self.config.unstableRevision or null;
unstableRevisionHash = self.config.unstableRevisionHash or null;
useUnstable = self.config.useUnstable or true;
unstablePkgsExprs = if !builtins.isNull unstableRevision
then if !builtins.isNull unstableRevisionHash
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
nixpkgsVersion = builtins.concatStringsSep "." [
(builtins.readFile "${unstablePkgsExprs}/.version")
(builtins.readFile "${unstablePkgsExprs}/.version-suffix")
];
nixpkgsRevision = (builtins.readFile "${unstablePkgsExprs}/.git-revision");
unstablePkgsForNixpkgs = nixpkgs: import unstablePkgsExprs {
# localSystem -> pkgs.stdenv.buildPlatform
localSystem = nixpkgs.stdenv.buildPlatform;
# crossSystem -> pkgs.stdenv.hostPlatform or pkgs.stdenv.targetPlatform ??
# passing below
# config -> pkgs.config
config = nixpkgs.config;
# overlays -> partial of pkgs.overlays
overlays = nixpkgs.overlays;
# crossOverlays -> partial of pkgs.overlays
# crossOverlays are merged to overlays, not sure what issues that might raise.
# ignoring.
} // (if nixpkgs.stdenv.buildPlatform == nixpkgs.stdenv.hostPlatform then {} else {
# workaround for some odd structured packages that changes behaviour
# when crossSystem is passed.
crossSystem = nixpkgs.stdenv.hostPlatform;
});
in
{
unstable = if useUnstable then unstablePkgsForNixpkgs self else self;
unstableVersion = self.lib.optionalString useUnstable nixpkgsVersion;
unstableRevision = self.lib.optionalString useUnstable nixpkgsRevision;
}

View file

@ -0,0 +1,5 @@
{ inputs ? import ../../inputs.nix {} }:
self: super: {
lib = super.lib.extend (import ../../lib/overlays/version-info-fixup.nix { inherit inputs; });
}

View 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
View 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
View file

@ -1 +0,0 @@
nix-build '<nixpkgs/nixos>' -A vm -I nixos-config=./hosts/vm.nix $@ && $(ls ./result/bin/run-*) -m 4096 && rm *.qcow2