Compare commits

..

No commits in common. "main" and "flakelike" have entirely different histories.

86 changed files with 2099 additions and 1287 deletions

View file

@ -3,134 +3,49 @@
# if evaluating inside the store, import the outputs.nix file
let
# Ideally this file should be selfcontained, but I like the utilities in nixpkgs lib
lib = (import "${(import ./inputs.nix {}).nixpkgs}/lib");
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;
# function that takes gitignore file pattern and returns filter function
# true - include file
# false - exclude file
# null - no match
# string -> string -> [(string -> string -> (bool | null))]
toGitignoreMatcher = gitignorePath: pattern: lib.pipe pattern [
(v: { pattern = v; invalid = false; })
# trim whitespaces not preceded by backslash
(v: v // { pattern = let
stringLength = builtins.stringLength v.pattern;
leftPaddingLength = builtins.stringLength (lib.trimWith { start = true; end = false; } v.pattern) - stringLength;
rightPaddingLength = builtins.stringLength (lib.trimWith { start = false; end = true; } v.pattern) - stringLength;
isLastCharBackslash = if stringLength == 0 then false
else builtins.substring (stringLength - rightPaddingLength - 1) 1 v.pattern == "\\";
trimmedString = builtins.substring leftPaddingLength (stringLength - leftPaddingLength - rightPaddingLength) v.pattern;
in if isLastCharBackslash && rightPaddingLength > 0 then trimmedString + " " else trimmedString; })
# ignore empty lines
(v: if v.pattern != "" then v else v // { invalid = true; })
# ignore comments
(v: if !v.invalid && builtins.substring 0 1 v.pattern != "#" then v else v // { invalid = true; })
# mark negated patterns
(v:
if !v.invalid && builtins.substring 0 1 v.pattern == "!"
then v // {
negated = true;
pattern = builtins.substring 1 (builtins.stringLength v) v;
}
else v // { negated = false; }
)
# ignore escapes
(v: if v.invalid then v else v // { pattern = builtins.replaceStrings ["\\"] [""] v.pattern; })
# convert parsed pattern to matchers
({ pattern, negated, invalid }: {
__functor = _: path: type: let
relative = builtins.match "^/.+[^/]$" pattern == [];
directory = builtins.match "/$" pattern == [];
regexPattern = lib.pipe pattern [
(v: if relative then "${gitignorePath}/${v}" else v)
(builtins.split "/")
(builtins.filter (v: v != []))
(builtins.map (builtins.split "(\\*\\*|\\*)"))
(builtins.concatMap (v:
# v: (string | [string])[]
if v == [ "" ] then []
# TODO: check and add support for .. <directory-up> if git supports
else if v == [ "." ] then []
else [( builtins.foldl' (acc: vp:
# vp: string | [string]
if builtins.isString vp then acc + lib.escapeRegex vp
else if vp == [ "**" ] then acc + ".*"
else if vp == [ "*" ] then acc + "[^/]*"
else throw "unreachable"
) "" v )]
))
(builtins.concatStringsSep "/" )
(v: if relative then v else ".*/${v}")
];
matches = (!directory || type == "directory")
&& (builtins.match regexPattern path == []);
in if invalid then null
else if matches then negated
else null;
# for debug purposes
inherit pattern negated;
# for filtering purposes
inherit invalid;
})
];
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;
# TODO: optimize this so if match is found in a given gitignore,
# no further checks in gitignores in parent directories are performed
parseGitignore = gitRepositoryPath: filePath: lib.pipe filePath [
(builtins.dirOf)
(builtins.split "/" )
(builtins.filter (v: v != [] && v != ""))
# ["a" "b" "c"] -> ["/" "/a/" "/a/b/" "/a/b/c/"]
(
builtins.foldl' (acc: v: acc ++ [(
(builtins.elemAt acc (builtins.length acc - 1)) + "${v}/"
)] ) ["/"]
)
(builtins.map (v: "${v}.gitignore"))
# Filter out paths that are not part of git repository and don't exist
(builtins.filter (v: lib.hasPrefix gitRepositoryPath v && builtins.pathExists v))
(builtins.map (v: {
path = v;
# Split gitignore files into lines
contents = lib.pipe v [
builtins.readFile
(builtins.split "\n")
# builtins.split uses lists for matches
(builtins.filter (v: v != []))
];
}))
# Convert gitignore patterns to matchers
(builtins.map (v:
builtins.map (toGitignoreMatcher v.path) v.contents)
)
lib.flatten
(lib.filter (v: !v.invalid))
];
runGitignoreFilter = filters: path: type: lib.pipe filters [
(builtins.map (v: v path type))
(builtins.filter (v: v != null))
# If any filter didn't match anything, include the file
(v: if v == [] then [ true ] else v)
(v: builtins.elemAt v (builtins.length v - 1))
];
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:
let
selfPath = builtins.dirOf currentFilePath;
gitIgnoreFilters = parseGitignore selfPath path;
result = type != "unknown"
&& type != "symlink"
&& builtins.baseNameOf path != ".git"
&& runGitignoreFilter gitIgnoreFilters path type;
in result
type != "unknown" && builtins.baseNameOf path != ".git" && !matchesGitIgnore path
) ./.;
in
if !(evaluatingInStore) then { ... }@args: import selfInStore ({ selfPath = selfInStore; } // args )
else { ... }@args: import ./outputs.nix ({ selfPath = selfInStore; } // args)
if !(evaluatingInStore) then import selfInStore
else import ./outputs.nix

52
hosts/main.nix Normal file
View file

@ -0,0 +1,52 @@
{ inputs, pkgs, ... }:
{
imports = [
../nix-os/core.nix
../nix-os/core-desktop.nix
../nix-os/nvidia.nix
../nix-os/docker.nix
../nix-os/razer.nix
../nix-os/desktopManagers/gnome.nix
../nix-os/displayManagers/gdm.nix
#../nix-os/desktop/kde-plasma.nix
../nix-os/shell.nix
../nix-os/virtualization.nix
../nix-os/polkit/disable-shutdown.nix
../nix-os/locale.nix
../nix-os/adb.nix
../nix-os/account.nix
../nix-os/xdg-default-apps.nix
../nix-os/services/nix-binary-cache.nix
../nix-os/udev.nix
"${inputs.nixos-vscode-server}"
];
config = {
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "wroclaw-main";
services.xrdp.enable = true;
users.groups."tsusers".members = [ "wroclaw" ];
services.printing.drivers = with pkgs; [
hplip
];
# nixos-vscode-server module needs this
programs.nix-ld.enable = true;
services.vscode-server = {
enable = true;
extraRuntimeDependencies = with pkgs; [
docker
];
};
services.printing.startWhenNeeded = false;
system.stateVersion = "23.05";
};
}

View file

@ -1,88 +0,0 @@
{
inputs,
config,
pkgs,
self,
...
}:
{
imports = [
../../nix-os/core.nix
../../nix-os/core-desktop.nix
../../nix-os/nvidia.nix
../../nix-os/docker.nix
../../nix-os/razer.nix
../../nix-os/desktopManagers/cosmic.nix
../../nix-os/displayManagers/cosmic-greeter.nix
../../nix-os/shell.nix
../../nix-os/virtualization.nix
../../nix-os/polkit/disable-shutdown.nix
../../nix-os/locale.nix
../../nix-os/adb.nix
../../nix-os/account.nix
../../nix-os/services/nix-binary-cache.nix
../../nix-os/udev.nix
../../nix-os/gnupg.nix
"${inputs.nixos-vscode-server}"
];
config = {
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = "wroclaw-main";
services.printing.drivers = with pkgs; [
hplip
];
nixpkgs.overlays = [
self.overlays.cosmicPackages
];
nixpkgs.config = {
cudaSupport = true;
};
# nixos-vscode-server module needs this
programs.nix-ld.enable = true;
services.vscode-server = {
enable = true;
extraRuntimeDependencies = with pkgs; [
docker
];
};
services.pipewire.wireplumber.configPackages = [(
pkgs.stdenvNoCC.mkDerivation {
name = "wireplumber-config";
src = ./wireplumber;
phases = [ "installPhase" ];
installPhase = ''
mkdir -p $out/share/wireplumber/wireplumber.conf.d
cp -r $src/* $out/share/wireplumber/wireplumber.conf.d
'';
}
)];
services.printing.startWhenNeeded = false;
# rgb control for razer, graphics card and motherboard
hardware.i2c.enable = true;
services.hardware.openrgb.enable = true;
services.ollama = {
enable = true;
port = 1434;
acceleration = "cuda";
package = pkgs.unstable.ollama;
host = "0.0.0.0";
};
environment.sessionVariables = {
OLLAMA_HOST = "127.0.0.1:${builtins.toString config.services.ollama.port}";
};
system.stateVersion = "23.05";
};
}

View file

@ -1,10 +0,0 @@
monitor.alsa.rules = [{
matches = [{
node.name = "alsa_output.pci-0000_00_1f.3.iec958-stereo"
}]
actions = {
update-props = {
node.description = "Digital Output"
}
}
}]

View file

@ -1,10 +0,0 @@
monitor.alsa.rules = [{
matches = [{
node.name = "alsa_output.pci-0000_01_00.1.hdmi-stereo"
}]
actions = {
update-props = {
node.description = "Monitor speakers"
}
}
}]

View file

@ -1,11 +0,0 @@
monitor.alsa.rules = [{
matches = [{
device.name = "alsa_card.usb-Razer_Razer_USB_Audio_Controller_000000000000000000000000-00"
}]
actions = {
update-props = {
device.description = "Headphones"
device.profile = "Pro Audio"
}
}
}]

View file

@ -1,10 +0,0 @@
monitor.alsa.rules = [{
matches = [{
node.name = "alsa_input.usb-Razer_Razer_USB_Audio_Controller_000000000000000000000000-00.pro-input-0"
}]
actions = {
update-props = {
node.description = "Headphones"
}
}
}]

View file

@ -1,22 +0,0 @@
monitor.alsa.rules = [
{
matches = [{
node.name = "alsa_output.usb-Razer_Razer_USB_Audio_Controller_000000000000000000000000-00.pro-output-0"
}]
actions = {
update-props = {
node.description = "Headphones (Chat)"
}
}
}
{
matches = [{
node.name = "alsa_output.usb-Razer_Razer_USB_Audio_Controller_000000000000000000000000-00.pro-output-1"
}]
actions = {
update-props = {
node.description = "Headphones (Game)"
}
}
}
]

View file

@ -1,7 +1,4 @@
{
self,
...
}:
{ config, lib, pkgs, ... }:
{
imports = [
@ -11,11 +8,9 @@
../nix-os/adb.nix
../nix-os/locale.nix
../nix-os/shell.nix
../nix-os/gnupg.nix
../nix-os/polkit/network.nix
../nix-os/desktopManagers/cosmic.nix
../nix-os/displayManagers/cosmic-greeter.nix
../nix-os/desktopManagers/gnome.nix
../nix-os/displayManagers/gdm.nix
../nix-os/udev.nix
];
@ -28,10 +23,6 @@
networking.firewall.enable = true;
hardware.sensor.iio.enable = true;
nixpkgs.overlays = [
self.overlays.cosmicPackages
];
networking.firewall.allowedTCPPortRanges = [
# KDE Connect
rec { from = 1714; to = from + 50; }

View file

@ -1,24 +0,0 @@
{ lib, modulesPath, ... }:
{
imports = [
"${modulesPath}/virtualisation/qemu-vm.nix"
../nix-os/account.nix
../nix-os/core.nix
../nix-os/core-desktop.nix
../nix-os/locale.nix
../nix-os/polkit/disable-shutdown.nix
../nix-os/shell.nix
../nix-os/udev.nix
];
config = {
services.syncthing.enable = lib.mkForce false;
virtualisation = {
memorySize = 4096;
};
virtualisation.forwardPorts = [
{ from = "host"; host.port = 2222; guest.port = 22; }
];
};
}

View file

@ -1,17 +0,0 @@
{ inputs, ... }:
{
imports = [
./vm-base.nix
../nix-os/desktopManagers/cosmic.nix
../nix-os/displayManagers/cosmic-greeter.nix
];
config = {
nixpkgs.overlays = [(import ../pkgs/overlays/cosmic-packages.nix { inherit inputs; })];
nix.settings = {
substituters = [ "https://cosmic.cachix.org/" ];
trusted-public-keys = [ "cosmic.cachix.org-1:Dya9IyXD4xdBehWjrkPv6rtxpmMdRel02smYzA85dPE=" ];
};
};
}

View file

@ -1,9 +0,0 @@
{ lib, ... }:
{
imports = [
./vm-base.nix
../nix-os/desktopManagers/gnome.nix
../nix-os/displayManagers/gdm.nix
];
}

19
hosts/vm.nix Normal file
View file

@ -0,0 +1,19 @@
{ ... }:
{
imports = [
../nix-os/core.nix
../nix-os/docker.nix
../nix-os/desktopManagers/gnome.nix
../nix-os/displayManagers/gdm.nix
#../nix-os/desktop/kde-plasma.nix
../nix-os/shell.nix
../nix-os/virtualization.nix
../nix-os/polkit/disable-shutdown.nix
../nix-os/locale.nix
../nix-os/adb.nix
../nix-os/account.nix
../nix-os/xdg-default-apps.nix
../nix-os/udev.nix
];
}

View file

@ -15,15 +15,5 @@ let self = {
url = "https://github.com/NixOS/nixpkgs/archive/${lock.nixpkgs.revision}.tar.gz";
sha256 = "${lock.nixpkgs.sha256}";
};
nixpkgs-unstable = builtins.fetchTarball {
name = "nixpkgs-unstable";
url = "https://github.com/NixOS/nixpkgs/archive/${lock.nixpkgs-unstable.revision}.tar.gz";
sha256 = "${lock.nixpkgs-unstable.sha256}";
};
cosmic-modules = builtins.fetchTarball {
name = "cosmic-modules";
url = "https://github.com/lilyinstarlight/nixos-cosmic/archive/${lock.cosmic-modules.revision}.tar.gz";
sha256 = "${lock.cosmic-modules.sha256}";
};
};
in self

View file

@ -1,8 +1,8 @@
{ revision }:
{ inputs ? import ../../inputs.nix {} }:
selfLib: superLib: {
trivial = superLib.trivial // {
versionSuffix = ".git.${builtins.substring 0 12 revision}";
revisionWithDefault = default: revision;
versionSuffix = ".git.${builtins.substring 0 12 inputs.lock.nixpkgs.revision}";
revisionWithDefault = default: inputs.lock.nixpkgs.revision or default;
};
}

View file

@ -4,15 +4,7 @@
sha256 = "1rq8mrlmbzpcbv9ys0x88alw30ks70jlmvnfr2j8v830yy5wvw7h";
};
nixpkgs = {
revision = "6a3ae7a5a12fb8cac2d59d7df7cbd95f9b2f0566";
sha256 = "0srx4jvdqw14xmi0gsghynpki9fpadshnvsjzz4zv55fyf9hm3dk";
};
nixpkgs-unstable = {
revision = "5df43628fdf08d642be8ba5b3625a6c70731c19c";
sha256 = "05xhbk4yjbv0f760ld6q9z2v0nphakgk78kgd0wnnmzdjqqkbfad";
};
cosmic-modules = {
revision = "6ec08f11bbf0e936ad82f1bb532f3757f8b5e3c2";
sha256 = "055dwpmbp2q6xnrk1gdrql4w5w4cxb82d8ar7ma5z2kz0sfjf1yi";
revision = "10c832d0548e9e3a6df7eb51e68c2783212a303e";
sha256 = "1p206hgfxbz0rmkzaslfrknbdss4n4dnb09pi5466h8ksmm8216q";
};
}

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, unstablePkgs, ... }:
{ config, pkgs, unstablePkgs, ... }:
{
imports = [
@ -11,22 +11,18 @@
extraGroups = [
"users"
"wheel"
] ++ lib.optional config.programs.adb.enable "adbusers";
(if config.programs.adb.enable then "adbusers" else null)
];
linger = true;
initialPassword = "nixos";
packages = with pkgs; [
firefox
(vivaldi.override {
proprietaryCodecs = true;
commandLineArgs = [ "--ozone-platform=wayland" ];
})
vesktop
(vivaldi.override { proprietaryCodecs = true; })
discord-canary
unstablePkgs.vscode
gimp
inkscape
jitsi-meet-electron
krita
telegram-desktop
unstablePkgs.zettlr
];
};

View file

@ -1,13 +1,10 @@
{config, lib, pkgs, ... }:
{
imports = [
./generic/mpv.nix
./xdg-default-apps.nix
];
config = {
services.printing.enable = true;
sound.enable = false;
hardware.pulseaudio.enable = false;
security.rtkit.enable = true;
services.pipewire = {
@ -18,159 +15,14 @@
# Enable audio interfaces renaming
wireplumber.enable = true;
wireplumber.extraConfig = {
"dont-switch-device-profiles"."wireplumber.settings"."bluetooth.autoswitch-to-headset-profile" = false;
};
};
environment.systemPackages = with pkgs; [
kdePackages.kdeconnect-kde
pcmanfm
pwvucontrol
qimgv
mpv
];
programs.mpv = let
fetchMpvScript = {url, hash, scriptName}: pkgs.fetchurl {
inherit url hash;
name = "mpv-script-${scriptName}";
recursiveHash = true;
downloadToTemp = true;
postFetch = ''
mkdir -p $out/share/mpv/scripts
mv $downloadedFile $out/share/mpv/scripts/${scriptName}
'';
passthru.scriptName = scriptName;
};
in {
enable = true;
scripts = [
pkgs.mpvScripts.sponsorblock
pkgs.mpvScripts.mpris
] ++ lib.map (script: fetchMpvScript {
url = "https://raw.githubusercontent.com/occivink/mpv-scripts/d0390c8e802c2e888ff4a2e1d5e4fb040f855b89/scripts/${script.name}";
hash = script.hash;
scriptName = script.name;
}) [
{ name = "crop.lua"; hash = "sha256-/uaTCtV8Aanvnxrt8afBbO4uu2xp8Ec6DxApMb+fg2s="; }
{ name = "encode.lua"; hash = "sha256-yK/DV0cpGhl4Uobl7xA1myZiECJpsShrHnsJftBqzAY="; }
];
settings = {
mpv = {
keep-open = "yes";
volume = "40";
osd-fractions = "yes";
background = "none";
border = "no";
};
input = lib.mkMerge [
# mpv core
''
Alt+1 set window-scale 0.125
Alt+2 set window-scale 0.25
Alt+3 set window-scale 0.5
Alt+4 set window-scale 1
Alt+5 set window-scale 2
''
# crop.lua
''
c script-message-to crop start-crop hard
alt+c script-message-to crop start-crop soft
ctrl+shift+c script-message-to crop start-crop delogo
C script-message-to crop toggle-crop hard
''
# encode.lua
''
b script-message-to encode encode_default
alt+b script-message-to encode set-timestamp encode_default
''
];
script-opts = {
"encode_default.conf" = {
only_active_tracks = "no";
preserve_filters = "yes";
append_filder = "";
codec = "";
output_format = "$f_$n.$x";
output_dir = "/tmp";
detached = "no";
ffmpeg_command = lib.getExe pkgs.ffmpeg;
};
};
};
};
# Fonts
fonts.packages = with pkgs; [
corefonts
(nerdfonts.override { fonts = [ "Meslo" ]; })
roboto
];
# Pcmanfm configuration
environment.etc."xdg/pcmanfm/default/pcmanfm.conf".text = ''
[config]
bm_open_method=0
[volume]
mount_on_startup=0
mount_removable=0
autorun=0
[ui]
always_show_tabs=1
max_tab_chars=32
media_in_new_tab=0
desktop_folder_new_win=0
change_tab_on_drop=1
close_on_unmount=1
focus_previous=1
side_pane_mode=places
view_mode=list
show_hidden=1
sort=name;ascending;
toolbar=newwin;newtab;navigation;home;
show_statusbar=1
pathbar_mode_buttons=0
'';
environment.etc."xdg/libfm/libfm.conf".text = ''
[config]
single_click=0
use_trash=1
confirm_del=1
confirm_trash=1
advanced_mode=0
si_unit=0
force_startup_notify=1
backup_as_hidden=1
no_usb_trash=1
no_child_non_expandable=0
show_full_names=0
only_user_templates=0
drop_default_action=auto
terminal=${lib.optionalString (lib.elem pkgs.kitty config.environment.systemPackages) "kitty"}
archiver=file-roller
thumbnail_local=1
thumbnail_max=16384
[ui]
big_icon_size=48
small_icon_size=16
pane_icon_size=16
thumbnail_size=128
show_thumbnail=1
shadow_hidden=1
[places]
places_home=1
places_desktop=1
places_root=1
places_computer=1
places_trash=1
places_applications=1
places_network=1
places_unmounted=1
services.openssh.extraConfig = ''
X11Forwarding yes
'';
};
}

View file

@ -5,7 +5,23 @@
{ inputs, lib, pkgs, ... }:
let
inherit (pkgs) mkWrappedExecutable;
/*
* 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 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; [
@ -20,14 +36,9 @@ let
paths = [ pkgs.nix ] ++ wrappedNixExecutables false;
}).overrideAttrs {
version = pkgs.nix.version;
passthru.meta = pkgs.nix.meta;
};
in
{
imports = [
./module-overrides.nix
];
# kernel
boot.kernelPackages = pkgs.linuxPackages_latest;
@ -39,10 +50,7 @@ in
nix = {
package = wrappedNix;
channel.enable = false;
settings.experimental-features = [
"no-url-literals"
];
nixPath = [
settings.nix-path = [
"nixpkgs=${pkgs.selfExpr { useConfig = false; }}"
"systemNixpkgs=${pkgs.selfExpr { useConfig = true; name = "systemNixpkgs-self"; }}"
# don't garbage collect the nixpkgs input
@ -53,7 +61,6 @@ in
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
waypipe
wget
ffmpeg
yt-dlp
@ -67,27 +74,11 @@ in
programs.git.enable = true;
programs.git.config = {
commit.verbose = true;
init.defaultBranch = "main";
merge.conflictstyle = "diff3";
rerere.enabled = true;
};
# Use nix-index for command-not-found handler
programs.command-not-found.enable = false;
programs.nix-index = {
package = pkgs.nix-index.override {
nix-index-unwrapped = pkgs.nix-index-unwrapped.overrideAttrs (oldAttrs: {
patches = oldAttrs.patches or [] ++ [
../pkgs/by-name/ni/nix-index/cnfOutput.patch
];
});
};
enable = true;
enableBashIntegration = true;
};
# Enable fail2ban because of the OpenSSH server
services.fail2ban = {
enable = true;

View file

@ -59,17 +59,22 @@
"workspace-indicator@gnome-shell-extensions.gcampax.github.com"
"Vitals@CoreCoding.com"
"trayIconsReloaded@selfmade.pl"
"places-menu@gnome-shell-extensions.gcampax.github.com"
"apps-menu@gnome-shell-extensions.gcampax.github.com"
"top-bar-organizer@julian.gse.jsts.xyz"
"color-picker@tuberry"
];
favorite-apps = [
"kitty.desktop"
"pcmanfm.desktop"
(if builtins.elem pkgs.kitty config.environment.systemPackages then
"kitty.desktop"
else none)
"vivaldi-stable.desktop"
"code.desktop"
"org.gnome.Nautilus.desktop"
"steam.desktop"
"com.saivert.pwvucontrol.desktop"
(if config.programs.steam.enable then
"steam.desktop"
else none)
"pavucontrol.desktop"
];
};
@ -91,7 +96,6 @@
active-hint-border-radius = mkUint32 1;
gap-inner = mkUint32 2;
gap-outer = mkUint32 1;
hint-color-rgba = "rgb(161,192,235)";
show-skip-taskbar = true;
show-title = true;
smart-gaps = false;

View file

@ -1,11 +0,0 @@
[
"kitty",
"vivaldi-stable",
"pcmanfm",
"code",
"steam",
"vesktop",
"org.telegram.desktop",
"jitsi-meet-electron",
"com.saivert.pwvucontrol",
]

View file

@ -1,9 +0,0 @@
(
output: "all",
source: Path("@wallpaper@"),
filter_by_theme: true,
rotation_frequency: 300,
filter_method: Lanczos,
scaling_mode: Zoom,
sampling_method: Alphanumeric,
)

View file

@ -1,4 +0,0 @@
(
workspace_mode: OutputBound,
workspace_layout: Horizontal,
)

View file

@ -1,5 +0,0 @@
(
show_content: false,
show_mounted_drives: false,
show_trash: false,
)

View file

@ -1,5 +0,0 @@
Some((
wait_time: 1000,
transition_time: 200,
handle_size: 4,
))

View file

@ -1,5 +0,0 @@
Some([
"com.system76.CosmicAppList",
"com.system76.CosmicAppletMinimize",
"com.system76.CosmicPanelAppButton",
])

View file

@ -1,3 +0,0 @@
Some([
"com.system76.CosmicAppletTime",
])

View file

@ -1,14 +0,0 @@
Some(([
"com.system76.CosmicPanelAppButton",
"com.system76.CosmicAppletWorkspaces",
], [
"com.system76.CosmicAppletStatusArea",
"com.system76.CosmicAppletInputSources",
"com.system76.CosmicAppletTiling",
"com.system76.CosmicAppletAudio",
"com.system76.CosmicAppletNetwork",
"com.system76.CosmicAppletBattery",
"com.system76.CosmicAppletNotifications",
"com.system76.CosmicAppletBluetooth",
"com.system76.CosmicAppletPower",
]))

View file

@ -1,36 +0,0 @@
{
(
modifiers: [
Ctrl,
Alt,
],
key: "t",
description: Some("Open terminal"),
): Spawn("kitty"),
(
modifiers: [
Super,
Shift,
],
key: "s",
): System(Screenshot),
(
modifiers: [
Super,
Ctrl,
],
key: "l",
): System(LockScreen),
(
modifiers: [
Super,
],
): System(Launcher),
(
modifiers: [
Super,
Alt,
],
key: "g",
): ToggleSticky,
}

View file

@ -1,8 +0,0 @@
(
radius_0: (0.0, 0.0, 0.0, 0.0),
radius_xs: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
radius_s: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
radius_m: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
radius_l: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
radius_xl: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
)

View file

@ -1,8 +0,0 @@
(
radius_0: (0.0, 0.0, 0.0, 0.0),
radius_xs: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
radius_s: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
radius_m: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
radius_l: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
radius_xl: (@corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@, @corner_radii_theme@),
)

View file

@ -1,61 +0,0 @@
{
inputs,
lib,
pkgs,
self,
...
}:
let
cosmic-configuration = pkgs.substituteAllFiles {
name = "cosmic-configuration";
src = ./cosmic-config;
files = [ "." ]; # All files
postInstall = ''
mkdir -p $share/share/cosmic
cp -rt $share/share/cosmic $out/*
'';
outputs = [ "out" "share" ];
wallpaper = ../../media/wallpaper.png;
corner_radii_theme = "2.0";
corner_radii_panel = "2";
};
in
{
imports = [
"${inputs.cosmic-modules}/nixos/cosmic/module.nix"
"${self}/nix-os/generic/dconf.nix"
];
config = {
services.desktopManager.cosmic.enable = true;
environment.cosmic.excludePackages = with pkgs; [
cosmic-edit
cosmic-term
];
environment.systemPackages = with pkgs; [
(lib.hiPrio cosmic-configuration.share)
google-cursor
];
services.gnome.gnome-keyring.enable = true;
proot.dconf = {
rules."org/gnome/desktop/interface".cursor-theme = "GoogleDot-White";
profiles.user.rulesToApply = [
"org/gnome/desktop/interface"
];
};
environment.sessionVariables = {
XCURSOR_SIZE = "16";
XCURSOR_THEME = "GoogleDot-White";
};
environment.etc."xdg/gtk-3.0/settings.ini".text = ''
[Settings]
gtk-cursor-theme-name=GoogleDot-White
gtk-application-prefer-dark-theme=true
'';
};
}

View file

@ -68,7 +68,6 @@ in
gnome.seahorse
gnome.totem
gnome.yelp
gnome.nautilus
];
environment.systemPackages = with pkgs; [
@ -80,14 +79,9 @@ in
gnomeExtensions.top-bar-organizer
# unstablePkgs.gnomeExtensions.translate-indicator
# translate-shell
pavucontrol
#FIXME: Apply the cursor theme also in GTK3 config
google-cursor
];
environment.etc."xdg/gtk-3.0/settings.ini".text = ''
[Settings]
gtk-cursor-theme-name=${config.proot.dconf.rules."org/gnome/desktop/interface".cursor-theme}
'' + lib.optionalString (lib.hasInfix "dark" config.proot.dconf.rules."org/gnome/desktop/interface".color-scheme) ''
gtk-application-prefer-dark-theme=true
'';
};
}

View file

@ -1,10 +0,0 @@
{ inputs, lib, pkgs, ... }:
{
imports = [
"${inputs.cosmic-modules}/nixos/cosmic-greeter/module.nix"
];
config = {
services.displayManager.cosmic-greeter.enable = true;
};
}

View file

@ -1,91 +0,0 @@
{config, lib, options, pkgs, ... }:
let
cfg = config.programs.mpv;
opts = options.programs.mpv;
toMpvIniString = attrset: lib.pipe attrset [
(lib.mapAttrsToList (name: value: "${name}=${value}"))
(lib.concatStringsSep "\n")
];
configDir = pkgs.symlinkJoin {
name = "mpv-config-dir";
paths = lib.optional opts.settings.mpv.isDefined (pkgs.writeTextFile {
name = "mpv-config-dir-mpv.conf";
destination = "/share/mpv/mpv.conf";
text = toMpvIniString cfg.settings.mpv;
}) ++ lib.optional opts.settings.input.isDefined (pkgs.writeTextFile {
name = "mpv-config-dir-input.conf";
destination = "/share/mpv/input.conf";
text = cfg.settings.input;
}) ++ lib.mapAttrsToList (filename: opts: pkgs.writeTextFile {
name = "mpv-config-dir-script-opts-${filename}";
destination = "/share/mpv/script-opts/${filename}";
text = toMpvIniString opts;
}) cfg.settings.script-opts;
};
wrappedMpv = cfg.package.wrapper {
mpv = cfg.package;
youtubeSupport = cfg.youtubeSupport;
scripts = cfg.scripts;
extraMakeWrapperArgs = lib.optionals (lib.any (x: x) [
opts.settings.mpv.isDefined
opts.settings.input.isDefined
(lib.length (lib.attrNames cfg.settings.script-opts) > 0)
]) [
"--add-flags" "--config-dir='${configDir}/share/mpv'"
];
};
in
{
options.programs.mpv = {
enable = lib.mkEnableOption "mpv";
package = lib.mkPackageOption pkgs "mpv-unwrapped" {};
scripts = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [];
};
youtubeSupport = lib.mkEnableOption "yt-dlp support for mpv" // {
default = true;
};
settings = let
mpvini = lib.types.attrsOf lib.types.str;
in {
script-opts = lib.mkOption {
type = lib.types.attrsOf mpvini;
default = {};
example = {
"crop.conf".draw_crosshair = "yes";
};
description = ''
A map of script options for mpv scripts.
The key is the filename of the script, and the value is a map of options.
'';
};
input = lib.mkOption {
type = lib.types.separatedString "\n";
example = ''
Alt+1 set window-scale 0.125
'';
description = ''
A list of input commands to be added to the input.conf file.
'';
};
mpv = lib.mkOption {
type = mpvini;
example = {
keep-open = "yes";
osd-fractions = "yes";
};
description = ''
A map of mpv options.
'';
};
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ wrappedMpv ];
};
}

View file

@ -1,15 +0,0 @@
{ pkgs, ... }:
{
config = {
# Use pcscd for smartcard support
services.pcscd.enable = true;
environment.systemPackages = [(
pkgs.gnupg.overrideAttrs (superAttrs: {
configureFlags = superAttrs.configureFlags or []
++ [ "--disable-ccid-driver" ];
})
)];
};
}

View file

@ -1,27 +0,0 @@
{ lib, ... }:
let
moduleOverrides = [
# TODO: Remove after updating to nixos 25.05
{
# https://github.com/NixOS/nixpkgs/pull/359882
disabledModules = [
"system/boot/luksroot.nix"
];
replacementModules = [(builtins.fetchurl {
url = "https://raw.githubusercontent.com/amozeo/nixpkgs/728d5806fe6f975ba3843297332d12e13119fe86/nixos/modules/system/boot/luksroot.nix";
sha256 = "0s2k8k6rrlwn2zb02q6fkvswln8w4hvh02hm4krqvkh46amyasyy";
})];
}
];
toModule = entry: {
imports = entry.replacementModules;
disabledModules = entry.disabledModules;
_file = let
info = builtins.unsafeGetAttrPos "disabledModules" entry;
in "${info.file}:L${info.line}";
};
in
{
imports = lib.map toModule moduleOverrides;
}

View file

@ -1,14 +1,11 @@
{ config, lib, pkgs, ...}:
{
hardware.graphics = {
hardware.opengl = {
enable = true;
enable32Bit = true;
driSupport = true;
driSupport32Bit = true;
};
# Workaround for nvidia driver ghost display
boot.kernelParams = [ "nvidia_drm.fbdev=1" ];
services.xserver.videoDrivers = ["nvidia"];
hardware.nvidia = {
modesetting.enable = true;
@ -16,12 +13,10 @@
open = false;
nvidiaSettings = true;
package = config.boot.kernelPackages.nvidiaPackages.mkDriver {
version = "565.77";
sha256_64bit = "sha256-CnqnQsRrzzTXZpgkAtF7PbH9s7wbiTRNcM0SPByzFHw=";
sha256_aarch64 = "sha256-LSAYUnhfnK3rcuPe1dixOwAujSof19kNOfdRHE7bToE=";
openSha256 = "sha256-Fxo0t61KQDs71YA8u7arY+503wkAc1foaa51vi2Pl5I=";
settingsSha256 = "sha256-VUetj3LlOSz/LB+DDfMCN34uA4bNTTpjDrb6C6Iwukk=";
persistencedSha256 = "sha256-wnDjC099D8d9NJSp9D0CbsL+vfHXyJFYYgU3CwcqKww=";
version = "555.42.02";
sha256_64bit = "sha256-k7cI3ZDlKp4mT46jMkLaIrc2YUx1lh1wj/J4SVSHWyk=";
settingsSha256 = "sha256-rtDxQjClJ+gyrCLvdZlT56YyHQ4sbaL+d5tL4L4VfkA=";
persistencedSha256 = "";
};
};
nixpkgs.config.nvidia.acceptLicense = true;

View file

@ -15,6 +15,8 @@
action.id == "org.freedesktop.login1.inhibit-block-idle" ||
action.id == "org.freedesktop.login1.inhibit-block-shutdown" ||
action.id == "org.freedesktop.login1.inhibit-block-sleep" ||
action.id == "org.freedesktop.login1.inhibit-delay-shutdown" ||
action.id == "org.freedesktop.login1.inhibit-delay-sleep" ||
action.id == "org.freedesktop.login1.inhibit-handle-hibernate-key" ||
action.id == "org.freedesktop.login1.inhibit-handle-lid-switch" ||
action.id == "org.freedesktop.login1.inhibit-handle-power-key" ||

View file

@ -1,17 +0,0 @@
{
config = {
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
// Allow to start and stop wireguard client services
if (
action.id == "org.freedesktop.systemd1.manage-units" &&
subject.isInGroup("users") &&
action.lookup("unit") &&
action.lookup("unit").match(/^wg-quick-.*\.service$/)
) {
return polkit.Result.YES;
};
});
'';
};
}

View file

@ -1,10 +1,7 @@
{ pkgs, ... }:
{
config = {
services.nix-serve = {
enable = true;
package = pkgs.nix-serve-ng;
secretKeyFile = "/var/cache-priv-key.pem";
};
};

View file

@ -18,7 +18,7 @@ let
] ++ old.propagatedBuildInputs;
});
aliasDrag = pkgs.writeScriptBin "drag" ''
${pkgs.ripdrag}/bin/ripdrag -Axd $@
${unstablePkgs.ripdrag}/bin/ripdrag -Axd $@
'';
in
{
@ -47,7 +47,6 @@ 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
@ -65,7 +64,7 @@ in
set vcs_aware true
set show_hidden true
alias drag shell ${pkgs.ripdrag}/bin/ripdrag -Axd %p &
alias drag shell ${unstablePkgs.ripdrag}/bin/ripdrag -Axd %p &
map <C-d> drag
'';
@ -93,7 +92,6 @@ in
set expandtab
set autoindent
set updatetime=500
colorscheme vim
syntax on
set encoding=utf-8
@ -110,10 +108,10 @@ in
" vim-gitguter
set signcolumn=yes
highlight SignColumn NONE
highlight GitGutterAdd ctermfg=2 guifg=#2ea043
highlight GitGutterChange ctermfg=4 guifg=#0078d4
highlight GitGutterDelete ctermfg=1 guifg=#f85149
highlight SignColumn ctermbg=NONE
highlight GitGutterAdd ctermfg=2
highlight GitGutterChange ctermfg=4
highlight GitGutterDelete ctermfg=1
lua require('guess-indent').setup {}
'';

View file

@ -1,14 +1,8 @@
{
config,
lib,
pkgs,
self,
...
}:
{config, pkgs, lib, ...}:
let
cfg = config.unstable;
unstableOverlay = self.overlays.unstableWithMeta;
unstableOverlay = import ../pkgs/overlays/unstable.nix;
in
{
options.unstable = {

View file

@ -8,7 +8,6 @@
"application/xhtml+xml" = "vivaldi-stable.desktop";
"text/html" = "vivaldi-stable.desktop";
"x-scheme-handler/https" = "vivaldi-stable.desktop";
"application/pdf" = "vivaldi-stable.desktop";
# Audio
"audio/aiff" = "mpv.desktop";
@ -87,51 +86,51 @@
"video/x-sgi-movie" = "mpv.desktop";
# Image
"image/bmp" = "qimgv.desktop";
"image/cmu-raster" = "qimgv.desktop";
"image/fif" = "qimgv.desktop";
"image/florian" = "qimgv.desktop";
"image/g3fax" = "qimgv.desktop";
"image/gif" = "qimgv.desktop";
"image/ief" = "qimgv.desktop";
"image/jpeg" = "qimgv.desktop";
"image/jutvision" = "qimgv.desktop";
"image/naplps" = "qimgv.desktop";
"image/pict" = "qimgv.desktop";
"image/pjpeg" = "qimgv.desktop";
"image/png" = "qimgv.desktop";
"image/tiff" = "qimgv.desktop";
"image/vasa" = "qimgv.desktop";
"image/vnd.dwg" = "qimgv.desktop";
"image/vnd.fpx" = "qimgv.desktop";
"image/vnd.net-fpx" = "qimgv.desktop";
"image/vnd.rn-realflash" = "qimgv.desktop";
"image/vnd.rn-realpix" = "qimgv.desktop";
"image/vnd.wap.wbmp" = "qimgv.desktop";
"image/vnd.xiff" = "qimgv.desktop";
"image/x-cmu-raster" = "qimgv.desktop";
"image/x-dwg" = "qimgv.desktop";
"image/x-icon" = "qimgv.desktop";
"image/x-jg" = "qimgv.desktop";
"image/x-jps" = "qimgv.desktop";
"image/x-niff" = "qimgv.desktop";
"image/x-pcx" = "qimgv.desktop";
"image/x-pict" = "qimgv.desktop";
"image/x-portable-anymap" = "qimgv.desktop";
"image/x-portable-bitmap" = "qimgv.desktop";
"image/x-portable-graymap" = "qimgv.desktop";
"image/x-portable-greymap" = "qimgv.desktop";
"image/x-portable-pixmap" = "qimgv.desktop";
"image/x-quicktime" = "qimgv.desktop";
"image/x-rgb" = "qimgv.desktop";
"image/x-tiff" = "qimgv.desktop";
"image/x-windows-bmp" = "qimgv.desktop";
"image/x-xbitmap" = "qimgv.desktop";
"image/x-xbm" = "qimgv.desktop";
"image/x-xpixmap" = "qimgv.desktop";
"image/x-xwd" = "qimgv.desktop";
"image/x-xwindowdump" = "qimgv.desktop";
"image/xbm" = "qimgv.desktop";
"image/xpm" = "qimgv.desktop";
"image/bmp" = "org.gnome.Loupe.desktop";
"image/cmu-raster" = "org.gnome.Loupe.desktop";
"image/fif" = "org.gnome.Loupe.desktop";
"image/florian" = "org.gnome.Loupe.desktop";
"image/g3fax" = "org.gnome.Loupe.desktop";
"image/gif" = "org.gnome.Loupe.desktop";
"image/ief" = "org.gnome.Loupe.desktop";
"image/jpeg" = "org.gnome.Loupe.desktop";
"image/jutvision" = "org.gnome.Loupe.desktop";
"image/naplps" = "org.gnome.Loupe.desktop";
"image/pict" = "org.gnome.Loupe.desktop";
"image/pjpeg" = "org.gnome.Loupe.desktop";
"image/png" = "org.gnome.Loupe.desktop";
"image/tiff" = "org.gnome.Loupe.desktop";
"image/vasa" = "org.gnome.Loupe.desktop";
"image/vnd.dwg" = "org.gnome.Loupe.desktop";
"image/vnd.fpx" = "org.gnome.Loupe.desktop";
"image/vnd.net-fpx" = "org.gnome.Loupe.desktop";
"image/vnd.rn-realflash" = "org.gnome.Loupe.desktop";
"image/vnd.rn-realpix" = "org.gnome.Loupe.desktop";
"image/vnd.wap.wbmp" = "org.gnome.Loupe.desktop";
"image/vnd.xiff" = "org.gnome.Loupe.desktop";
"image/x-cmu-raster" = "org.gnome.Loupe.desktop";
"image/x-dwg" = "org.gnome.Loupe.desktop";
"image/x-icon" = "org.gnome.Loupe.desktop";
"image/x-jg" = "org.gnome.Loupe.desktop";
"image/x-jps" = "org.gnome.Loupe.desktop";
"image/x-niff" = "org.gnome.Loupe.desktop";
"image/x-pcx" = "org.gnome.Loupe.desktop";
"image/x-pict" = "org.gnome.Loupe.desktop";
"image/x-portable-anymap" = "org.gnome.Loupe.desktop";
"image/x-portable-bitmap" = "org.gnome.Loupe.desktop";
"image/x-portable-graymap" = "org.gnome.Loupe.desktop";
"image/x-portable-greymap" = "org.gnome.Loupe.desktop";
"image/x-portable-pixmap" = "org.gnome.Loupe.desktop";
"image/x-quicktime" = "org.gnome.Loupe.desktop";
"image/x-rgb" = "org.gnome.Loupe.desktop";
"image/x-tiff" = "org.gnome.Loupe.desktop";
"image/x-windows-bmp" = "org.gnome.Loupe.desktop";
"image/x-xbitmap" = "org.gnome.Loupe.desktop";
"image/x-xbm" = "org.gnome.Loupe.desktop";
"image/x-xpixmap" = "org.gnome.Loupe.desktop";
"image/x-xwd" = "org.gnome.Loupe.desktop";
"image/x-xwindowdump" = "org.gnome.Loupe.desktop";
"image/xbm" = "org.gnome.Loupe.desktop";
"image/xpm" = "org.gnome.Loupe.desktop";
};
}

View file

@ -1,21 +1,16 @@
{
inputs ? import ./inputs.nix {},
selfPath ? ./.
}:
{ inputs ? import ./inputs.nix {} }:
let
lib = (import "${inputs.nixpkgs}/lib").extend (import ./lib/overlays/version-info-fixup.nix { revision = inputs.lock.nixpkgs.revision; });
lib = (import "${inputs.nixpkgs}/lib").extend (import ./lib/overlays/version-info-fixup.nix { inherit inputs; });
self = {
inherit inputs lib self;
outPath = selfPath;
inherit lib inputs;
modifiedNixpkgs = import ./pkgs/top-level/impure.nix;
modifiedNixpkgsPure = import ./pkgs/top-level/default.nix;
overlays = {
cosmicPackages = import ./pkgs/overlays/cosmic-packages.nix { inherit inputs; };
selfExpr = import ./pkgs/overlays/selfExpr.nix { nixpkgsPath = inputs.nixpkgs; };
unstableWithMeta = import ./pkgs/overlays/unstable-with-meta.nix { unstableSource = inputs.nixpkgs-unstable; revision = inputs.lock.nixpkgs-unstable.revision; };
unstable = import ./pkgs/overlays/unstable.nix;
versionInfoFixup = import ./pkgs/overlays/version-info-fixup.nix { inherit inputs; };
};
nixosConfigurations = let
@ -23,30 +18,30 @@ self = {
filePaths = lib.pipe ./hosts [
builtins.readDir
( lib.filterAttrs (name: type:
( # regular .nix files
(type == "regular" && lib.hasSuffix ".nix" name)
|| # directories that contain a default.nix file
(type == "directory" && builtins.pathExists "${./.}/hosts/${name}/default.nix")
)
# 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.mapAttrs (name: type: {
name = if type == "directory" then name else builtins.substring 0 (builtins.stringLength name - 4) name;
(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 = "${self}/pkgs/top-level/impure.nix"; } )
( import ./pkgs/top-level/by-name-overlay.nix "${self}/pkgs/by-name" )
( 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
];
}
@ -54,7 +49,6 @@ self = {
specialArgs = { inherit self inputs; };
};
}))
builtins.attrValues
builtins.listToAttrs
];
};

View file

@ -1,31 +0,0 @@
{
lib,
stdenv,
}:
{
src,
script,
...
} @ args:
lib.hiPrio (stdenv.mkDerivation (
{
src = src;
name = if lib.isDerivation src
then "${src.name}-script-override"
else "${builtins.baseNameOf src}-script-override";
phases = [ "installPhase" "scriptOverridePhase" ];
installPhase = ''
runHook preInstall
cp -r $src $out
chmod u+w -R $out
runHook postInstall
'';
scriptOverridePhase = script;
} // lib.removeAttrs args [
"src"
"script"
]
))

View file

@ -1,22 +0,0 @@
{
lib,
makeWrapper,
stdenv
}:
/*
pkg: package - nixpkgs package
exe: string - executable (under bin) in pkg
wrapperArgs: string[] - arguments to pass to the wrapper
*/
{ pkg, exe ? pkg.meta.mainProgram, wrapperArgs }:
lib.hiPrio (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
'';
})

View file

@ -1,66 +0,0 @@
diff --git a/command-not-found.sh b/command-not-found.sh
index 5f30bad..3854297 100755
--- a/command-not-found.sh
+++ b/command-not-found.sh
@@ -73,51 +73,30 @@ EOF
else
if [ -e "$HOME/.nix-profile/manifest.json" ]; then
>&2 cat <<EOF
-The program '$cmd' is currently not installed. You can install it
-by typing:
- nix profile install $toplevel#$attrs
-
-Or run it once with:
- nix shell $toplevel#$attrs -c $cmd ...
+The program '$cmd' is not in your PATH. You can make it available in an
+ephemeral shell by typing:
+ nix shell $toplevel#$attrs
EOF
else
>&2 cat <<EOF
-The program '$cmd' is currently not installed. You can install it
-by typing:
- nix-env -iA $toplevel.$attrs
-
-Or run it once with:
- nix-shell -p $attrs --run '$cmd ...'
+The program '$cmd' is not in your PATH. You can make it available in an
+ephemeral shell by typing:
+ nix-shell -p $attrs
EOF
fi
fi
;;
*)
>&2 cat <<EOF
-The program '$cmd' is currently not installed. It is provided by
-several packages. You can install it by typing one of the following:
-EOF
-
- # ensure we get each element of attrs
- # in a cross platform way
- while read attr; do
- if [ -e "$HOME/.nix-profile/manifest.json" ]; then
- >&2 echo " nix profile install $toplevel#$attr"
- else
- >&2 echo " nix-env -iA $toplevel.$attr"
- fi
- done <<< "$attrs"
-
- >&2 cat <<EOF
-
-Or run it once with:
+The program '$cmd' is not in your PATH. You can make it available in an
+ephemeral shell by typing:
EOF
while read attr; do
if [ -e "$HOME/.nix-profile/manifest.json" ]; then
- >&2 echo " nix shell $toplevel#$attr -c $cmd ..."
+ >&2 echo " nix shell $toplevel#$attr"
else
- >&2 echo " nix-shell -p $attr --run '$cmd ...'"
+ >&2 echo " nix-shell -p $attr"
fi
done <<< "$attrs"
;;

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

@ -1,34 +0,0 @@
{
inputs ? import ../../inputs.nix {},
rustPlatform ? null,
}:
self: super:
let
nixos-cosmic = inputs.cosmic-modules;
# Pinned unstable nixpkgs from cosmic-modules
cosmicModulesLock = builtins.fromJSON (builtins.readFile "${nixos-cosmic}/flake.lock");
pinnedNixpkgsRev = cosmicModulesLock.nodes.nixpkgs.locked.rev;
pinnedNixpkgsNarHash = cosmicModulesLock.nodes.nixpkgs.locked.narHash;
futureNixpkgsSrc = builtins.fetchTarball {
name = "nixpkgs";
url = "https://github.com/NixOS/nixpkgs/archive/${pinnedNixpkgsRev}.tar.gz";
sha256 = pinnedNixpkgsNarHash;
};
# Initialize pinned nixpkgs
futureNixpkgs = let
extended = self.extend (import ./unstable-from-source.nix {
unstableSource = futureNixpkgsSrc;
});
in extended.unstable;
in
import "${nixos-cosmic}/pkgs" {
final = self;
prev = super;
rustPlatform = if rustPlatform != null then rustPlatform else futureNixpkgs.rustPlatform;
}

View file

@ -7,10 +7,7 @@ in
self: super: {
selfExpr = let
config = builtins.removeAttrs self.config [ "_undeclared" ];
configJson = self.lib.pipe config [
(self.lib.filterAttrsRecursive (_: v: !self.lib.isFunction v))
builtins.toJSON
];
configJson = builtins.toJSON config;
getSelfExpr = {
useConfig ? true,
@ -28,13 +25,11 @@ self: super: {
in ''
{ ... } @ args:
import ${nixpkgsPath} (
{
${self.lib.optionalString useConfig configText}
} // builtins.removeAttrs args (builtins.fromJSON '''
${removedAttrNamesText}
''')
)
import ${nixpkgsPath} {
${self.lib.optionalString useConfig configText}
} // builtins.removeAttrs args (builtins.fromJSON '''
${removedAttrNamesText}
''')
'';
mkNixpkgsChannel = args: self.writeTextFile {

View file

@ -1,36 +0,0 @@
{
unstableSource,
}:
self: super:
let
useUnstable = self.config.useUnstable or true;
sanitizePlatform = platformConfig: self.lib.removeAttrs platformConfig [
"emulator"
"emulatorAvailable"
"darwinSdkVersion"
"darwinMinVersion"
];
unstablePkgsForNixpkgs = nixpkgs: import unstableSource {
# localSystem -> pkgs.stdenv.buildPlatform
localSystem = sanitizePlatform 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 = sanitizePlatform nixpkgs.stdenv.hostPlatform;
});
in
{
unstable = if useUnstable then unstablePkgsForNixpkgs self else self;
}

View file

@ -1,16 +0,0 @@
{
unstableSource,
revision,
}: self: super:
let
version = builtins.readFile "${unstableSource}/lib/.version" + ".git." + builtins.substring 0 12 revision;
useUnstable = self.config.useUnstable or true;
in
import ./unstable-from-source.nix {
inherit unstableSource;
} self super // {
unstableVersion = self.lib.optionalString useUnstable version;
unstableRevision = self.lib.optionalString useUnstable revision;
}

View file

@ -0,0 +1,45 @@
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 ??
crossSystem = nixpkgs.stdenv.hostPlatform;
# 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.
};
in
{
unstable = if useUnstable then unstablePkgsForNixpkgs self else self;
unstableVersion = self.lib.optionalString useUnstable nixpkgsVersion;
unstableRevision = self.lib.optionalString useUnstable nixpkgsRevision;
}

View file

@ -1,12 +1,5 @@
{ inputs ? import ../../inputs.nix {} }:
self: super: {
lib = super.lib.extend (import ../../lib/overlays/version-info-fixup.nix { revision = inputs.lock.nixpkgs.revision; });
} //
super.lib.optionalAttrs (super ? unstable && super ? unstableRevision) {
unstable = super.unstable // {
lib = super.unstable.lib.extend (import ../../lib/overlays/version-info-fixup.nix {
revision = super.unstableRevision;
});
};
lib = super.lib.extend (import ../../lib/overlays/version-info-fixup.nix { inherit inputs; });
}

View file

@ -1,50 +0,0 @@
# Modified copy of github:NixOS/nixpkgs pkgs/top-level/by-name-overlay.nix
# as of commit c0d0be00d4ecc4b51d2d6948e37466194c1e6c51
# This file turns the pkgs/by-name directory into an overlay that adds all the defined packages.
# No validity checks are done here.
# Type: Path -> Overlay
baseDirectory:
let
lib = (import ../../outputs.nix {}).lib;
inherit (builtins)
readDir
;
inherit (lib.attrsets)
mapAttrs
mapAttrsToList
mergeAttrsList
;
# Package files for a single shard
# Type: String -> String -> String -> AttrsOf Path
namesForShard = nixFilename: shard: type:
if type != "directory" then
# Ignore all non-directories.
{ }
else
mapAttrs
(name: _: baseDirectory + "/${shard}/${name}/${nixFilename}")
(readDir (baseDirectory + "/${shard}"));
# The attribute set mapping names to the package files defining them
# Type: String -> AttrsOf Path
packageFiles = nixFilename: lib.pipe baseDirectory [
readDir
(mapAttrsToList (namesForShard nixFilename))
mergeAttrsList
# Filter out paths that don't have a ${nixFilename} file
(lib.filterAttrs (_: lib.pathExists))
];
in
self: super:
mapAttrs (name: file:
self.callPackage file { inherit self super; package = super.${name}; }
) (packageFiles "override.nix")
// mapAttrs (name: file:
self.callPackage file { }
) (packageFiles "package.nix")

View file

@ -12,11 +12,10 @@ let
options = (builtins.removeAttrs args attrsToRemove) // {
overlays = (args.overlays or []) ++ [
# ../.. should be nix store path that represents self in outputs.nix that is gc-rooted by this point
( import ../overlays/selfExpr.nix { nixpkgsPath = "${builtins.toString ../..}/pkgs/top-level/impure.nix"; } )
( import ../overlays/unstable-with-meta.nix { unstableSource = inputs.nixpkgs-unstable; revision = inputs.lock.nixpkgs-unstable.revision; } )
( import ../overlays/selfExpr.nix { nixpkgsPath = ./impure.nix; } )
( import ../overlays/unstable.nix )
( import ../overlays/version-info-fixup.nix { inherit inputs; } )
( import ./by-name-overlay.nix ../by-name )
( import "${inputs.nixpkgs}/pkgs/top-level/by-name-overlay.nix" ../by-name )
];
};
in