├── .gitignore
├── README.md
├── home-manager
├── config
│ ├── alacritty.nix
│ ├── bash-scripts
│ │ ├── dmount
│ │ ├── mdownload
│ │ └── passwords.kbx
│ ├── bashrc
│ ├── bashrc.nix
│ ├── git.nix
│ ├── neovim.nix
│ ├── theme.nix
│ ├── waybar.nix
│ └── yt-dlp.nix
└── home.nix
├── nixos
├── audio
│ ├── bluetooth.nix
│ └── general.nix
├── configuration.nix
├── hardware-optimization
│ ├── framework-specific.nix
│ ├── ssd.nix
│ └── video-acceleration.nix
├── networking
│ └── networks.nix
├── silent-boot
│ ├── boot.nix
│ ├── etc-silent.nix
│ ├── stage-1-init-silent.sh
│ ├── stage-1-silent.nix
│ ├── stage-2-init-silent.sh
│ └── stage-2-silent.nix
└── wayland
│ ├── general.nix
│ ├── login-manager.nix
│ ├── sway
│ └── config
│ └── window-manager.nix
├── preview.png
└── wallpaper.png
/.gitignore:
--------------------------------------------------------------------------------
1 | ./nixos/networking/networks.nix
2 | ./home-manager/config/bash-scripts/passwords.kbx
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # NixOS Config
2 |
3 |
4 |
5 |
Minimal Sway NixOS rice with full silent boot
6 |
7 | ## Installation
8 | Install nixos with this guide (make sure to use systemd boot)
9 | https://nixos.org/manual/nixos/stable/
10 | Clone this repository (logged in as user)
11 | ```
12 | cd ~
13 | ```
14 | ```
15 | git clone https://github.com/smravec/nixos-config
16 | ```
17 | ### Nixos
18 | Go to ``nixos/networking/networks.nix`` and setup wifi (in the cloned repository)
19 | Copy ``/etc/nixos/hardware-configuration.nix`` to ``nixos/hardware-optimization``
20 | ```
21 | cp /etc/nixos/hardware-configuration.nix ~/nixos-config/nixos/hardware-optimization/
22 | ```
23 | Symlink this repository to ``/etc``
24 | ```
25 | cd /etc
26 | ```
27 | ```
28 | sudo rm -rf nixos
29 | ```
30 | ```
31 | sudo ln -s ~/nixos-config/nixos/ .
32 | ```
33 | Rebuild your system
34 | ```
35 | sudo nixos-rebuild switch
36 | ```
37 | ### Home manager
38 | Download home-manager standalone ( after adding the home-manager channel reboot to refresh the $NIX_PATH var )
39 | https://nix-community.github.io/home-manager/index.html#sec-install-standalone
40 | Symlink ``home-manager`` directory to ``~/.config``
41 | ```
42 | cd ~/.config
43 | ```
44 | ```
45 | rm -rf nixpkgs
46 | ```
47 | ```
48 | ln -s ~/nixos-config/home-manager/ nixpkgs
49 | ```
50 | Add unstable channel
51 | https://nix-community.github.io/home-manager/index.html#_how_do_i_install_packages_from_nixpkgs_unstable
52 | Rebuild home-manager
53 | ```
54 | home-manager switch
55 | ```
56 | ### Sway
57 | Symlink sway config
58 | ```
59 | cd ~/.config
60 | ```
61 | ```
62 | ln -s ~/nixos-config/nixos/wayland/sway/ .
63 | ```
64 | ***PS: This config is made for the Framework laptop 11th gen***
65 |
--------------------------------------------------------------------------------
/home-manager/config/alacritty.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | programs.alacritty.enable = true;
4 |
5 | programs.alacritty.settings = {
6 | env = {
7 | TERM = "alacritty";
8 | };
9 |
10 | working_directory = "/home/simon/Desktop";
11 |
12 | window = {
13 | padding = {
14 | x = 20;
15 | y = 20;
16 | };
17 | };
18 |
19 | scrolling = {
20 | history = 10000;
21 | multiplier = 3;
22 | };
23 |
24 | font = {
25 | normal = {
26 | family = "JetBrains Mono";
27 | style = "Regular";
28 | };
29 |
30 | size = 9;
31 | builtin_box_drawing = true;
32 | draw_bold_text_with_bright_colors = false;
33 | };
34 |
35 | colors = {
36 | primary = {
37 | background = "#111111";
38 | foreground = "#ffffff";
39 | };
40 |
41 | cursor = {
42 | text = "CellBackground";
43 | cursor = "CellForeground";
44 | };
45 |
46 | vi_mode_cursor = {
47 | text = "CellBackground";
48 | cursor = "CellForeground";
49 | };
50 |
51 | normal = {
52 | black = "#111111";
53 | red = "#d40b0e";
54 | green = "#52ff80";
55 | yellow = "#fff642";
56 | blue = "#1a93c7";
57 | magenta = "#db1d00";
58 | cyan = "#5ae8e1";
59 | white = "#ffffff";
60 | };
61 |
62 | transparent_background_colors = true;
63 | };
64 |
65 | live_config_reload = true;
66 |
67 | key_bindings = [
68 | {
69 | key = "C";
70 | mods = "Control | Shift";
71 | chars = "\\x03";
72 | }
73 | {
74 | key = "C";
75 | mods = "Control";
76 | action = "Copy";
77 | }
78 | {
79 | key = "V";
80 | mods = "Control";
81 | action = "Paste";
82 | }
83 | {
84 | key = "O";
85 | mods = "Control";
86 | action = "ScrollHalfPageUp";
87 | }
88 | {
89 | key = "P";
90 | mods = "Control";
91 | action = "ScrollHalfPageDown";
92 | }
93 | {
94 | key = "Equals";
95 | mods = "Control";
96 | action = "IncreaseFontSize";
97 | }
98 | {
99 | key = "Plus";
100 | mods = "Control";
101 | action = "IncreaseFontSize";
102 | }
103 | {
104 | key = "Minus";
105 | mods = "Control";
106 | action = "DecreaseFontSize";
107 | }
108 | ];
109 |
110 | debug = {
111 | render_timer = false;
112 | persistent_logging = false;
113 | log_level = "Warn";
114 | print_events = false;
115 | };
116 | };
117 | }
118 |
--------------------------------------------------------------------------------
/home-manager/config/bash-scripts/dmount:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # dmount or default mount, mounts media at /mnt
4 | # that can be edited without root permissions
5 |
6 | echo "Available devices are:"
7 | lsblk
8 |
9 | read -e -p "input device name: " device
10 | sudo mount -o gid=wheel,fmask=113,dmask=002 /dev/$device /mnt
11 |
--------------------------------------------------------------------------------
/home-manager/config/bash-scripts/mdownload:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #Script to download video or audio from yt
4 |
5 | read -e -p "audio(0) or video(1): " media_type
6 | read -e -p "url: " url
7 | read -e -p "media name: " name
8 | read -e -p "everything is good?" check
9 |
10 | if [ "$media_type" = "0" ]; then
11 | echo "Installing audio ..."
12 | yt-dlp --extract-audio --audio-format mp3 $url -P "~/Desktop/Music" -o "$artist-$name.mp3"
13 | elif [ "$media_type" = "1" ]; then
14 | echo "Installing video ..."
15 | yt-dlp $url -P "~/Desktop/Videos" -o "$name"
16 | else
17 | echo "Invalid media type"
18 | fi
19 |
--------------------------------------------------------------------------------
/home-manager/config/bash-scripts/passwords.kbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smravec/nixos-config/f32f40ad80b38222493df36b4e59d79484e44def/home-manager/config/bash-scripts/passwords.kbx
--------------------------------------------------------------------------------
/home-manager/config/bashrc:
--------------------------------------------------------------------------------
1 | #
2 | # ~/.bashrc
3 | #
4 |
5 | # If not running interactively, don't do anything
6 | [[ $- != *i* ]] && return
7 |
8 | HISTSIZE= HISTFILESIZE=
9 |
10 | export PS1="\[$(tput bold)\]\[\033[38;5;231m\][\[$(tput sgr0)\]\[\033[38;5;117m\]\u\[$(tput sgr0)\]\[\033[38;5;231m\]@\[$(tput sgr0)\]\[\033[38;5;117m\]\h\[$(tput sgr0)\] \[$(tput sgr0)\]\[\033[38;5;39m\]\w\[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;231m\]]\[$(tput sgr0)\] \[$(tput sgr0)\]\[\033[38;5;229m\]\$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/')\[$(tput sgr0)\]\n\[$(tput sgr0)\]"
11 |
12 | set -o vi
13 |
14 | #Global path
15 | export PATH=$PATH:~/.local/bin/
16 | export PATH=$PATH:~/nixos-config/home-manager/config/bash-scripts
17 |
18 | #Aliases
19 | alias ls="ls --color -la"
20 | alias vim="nvim"
21 | alias passwords="kpcli --kdb=/home/simon/nixos-config/home-manager/config/bash-scripts/passwords.kbx"
22 |
--------------------------------------------------------------------------------
/home-manager/config/bashrc.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | programs.bash.enable = true;
4 | programs.bash.bashrcExtra = (builtins.readFile ./bashrc);
5 | }
6 |
--------------------------------------------------------------------------------
/home-manager/config/git.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | programs.git = {
4 | enable = true;
5 | userName = "Simon Mravec";
6 | userEmail = "simon.mravec@gmail.com";
7 | extraConfig = {
8 | init.defaultBranch = "main";
9 | pull.rebase = false;
10 | };
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/home-manager/config/neovim.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | #Some useful keybinds
4 | #$ go to end of the line
5 | #0 go to start of the line
6 | #shift + g go to bottom of the file
7 | #g + g go to start of the file
8 | #shift + up/down arrow scroll faster
9 | programs.neovim.enable = true;
10 |
11 | #Autocompletion
12 | #ctrl + y to autocomplete
13 | programs.neovim.coc.enable = true;
14 |
15 | programs.neovim.plugins = [
16 | #Theme
17 | { plugin = pkgs.vimPlugins.onehalf;
18 | config = ''
19 | set background=dark
20 | colorscheme onehalfdark
21 | let g:airline_theme='onehalfdark'
22 | hi Normal guibg=NONE ctermbg=NONE
23 | hi LineNr guibg=NONE ctermbg=NONE
24 | hi SignColumn guibg=NONE ctermbg=NONE
25 | hi EndOfBuffer guibg=NONE ctermbg=NONE
26 | hi Visual cterm=none ctermbg=darkgrey ctermfg=white
27 | '';
28 | }
29 |
30 | #File browser
31 | #ctrl + b to open
32 | #ctrl + w + w to switch focus
33 | { plugin = pkgs.vimPlugins.nerdtree;
34 | config = ''
35 | nnoremap :NERDTreeToggle
36 | let g:NERDTreeShowHidden = 1
37 | let g:NERDTreeMinimalUI = 1
38 | let g:NERDTreeIgnore = []
39 | let g:NERDTreeStatusline = ""
40 | highlight NERDTreeCWD ctermfg=white
41 | " Exit Vim if NERDTree is the only window remaining in the only tab.
42 | autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif
43 | '';
44 | }
45 |
46 | #Icons
47 | pkgs.vimPlugins.vim-devicons
48 |
49 | #Language support
50 | pkgs.vimPlugins.vim-nix
51 | pkgs.vimPlugins.coc-python
52 | pkgs.vimPlugins.coc-go
53 | pkgs.vimPlugins.vim-javascript
54 | pkgs.vimPlugins.coc-css
55 | pkgs.vimPlugins.coc-emmet
56 | pkgs.vimPlugins.coc-html
57 | pkgs.vimPlugins.coc-json
58 | ];
59 |
60 | programs.neovim.extraConfig = ''
61 | set number
62 | syntax on
63 | set shiftwidth=2
64 | set smarttab
65 | set clipboard+=unnamedplus
66 | '';
67 | }
68 |
--------------------------------------------------------------------------------
/home-manager/config/theme.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 |
4 | home.packages = [ pkgs.dconf ];
5 | gtk.enable = true;
6 |
7 | gtk.cursorTheme.package = pkgs.capitaine-cursors;
8 | gtk.cursorTheme.name = "capitaine-cursors-white";
9 | gtk.cursorTheme.size = 24;
10 |
11 | home.pointerCursor.package = pkgs.capitaine-cursors;
12 | home.pointerCursor.name = "capitaine-cursors-white";
13 | home.pointerCursor.size = 24;
14 | home.pointerCursor.x11.defaultCursor = "capitaine-cursors-white";
15 |
16 | xsession.enable = true;
17 |
18 | home.pointerCursor.x11.enable = true;
19 |
20 | gtk.iconTheme.package = pkgs.whitesur-icon-theme;
21 | gtk.iconTheme.name = "WhiteSur-dark";
22 |
23 | gtk.theme.package = pkgs.whitesur-gtk-theme;
24 | gtk.theme.name = "WhiteSur-Dark" ;
25 |
26 | gtk.gtk3.extraConfig = {
27 | gtk-dialogs-use-header=false;
28 | gtk-cursor-theme-size=0;
29 | gtk-toolbar-style="GTK_TOOLBAR_BOTH_HORIZ";
30 | gtk-toolbar-icon-size="GTK_ICON_SIZE_LARGE_TOOLBAR";
31 | gtk-button-images=0;
32 | gtk-menu-images=0;
33 | gtk-enable-event-sounds=0;
34 | gtk-enable-input-feedback-sounds=1;
35 | gtk-xft-antialias=1;
36 | gtk-xft-hinting=1;
37 | gtk-xft-hintstyle="hintslight";
38 | gtk-xft-rgba="none";
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/home-manager/config/waybar.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | programs.waybar.enable = true;
4 |
5 | programs.waybar.settings = {
6 | mainBar = {
7 | layer = "top";
8 | position = "top";
9 | height = 26;
10 | output = [
11 | "eDP-1"
12 | ];
13 |
14 | modules-left = [ "custom/logo" "sway/workspaces" "sway/mode" ];
15 | modules-right = [ "sway/language" "clock" "battery" ];
16 |
17 | "custom/logo" = {
18 | format = "";
19 | tooltip = false;
20 | on-click = ''bemenu-run --accept-single -n -p "Launch" --hp 4 --hf "#ffffff" --sf "#ffffff" --tf "#ffffff" '';
21 | };
22 |
23 | "sway/workspaces" = {
24 | disable-scroll = true;
25 | all-outputs = true;
26 | persistent_workspaces = {
27 | "1" = [];
28 | "2" = [];
29 | "3" = [];
30 | "4" = [];
31 | };
32 | disable-click = true;
33 | };
34 |
35 | "sway/mode" = {
36 | tooltip = false;
37 | };
38 |
39 | "sway/language" = {
40 | format = "{shortDescription}";
41 | tooltip = false;
42 | on-click = ''swaymsg input "1:1:AT_Translated_Set_2_keyboard" xkb_switch_layout next'';
43 |
44 | };
45 |
46 | "clock" = {
47 | interval = 60;
48 | format = "{:%a %d/%m %I:%M}";
49 | };
50 |
51 | "battery" = {
52 | tooltip = false;
53 | };
54 | };
55 | };
56 |
57 | programs.waybar.style = ''
58 |
59 | * {
60 | border: none;
61 | border-radius: 0;
62 | padding: 0;
63 | margin: 0;
64 | font-size: 11px;
65 | }
66 |
67 | window#waybar {
68 | background: #292828;
69 | color: #ffffff;
70 | }
71 |
72 | #custom-logo {
73 | font-size: 18px;
74 | margin: 0;
75 | margin-left: 7px;
76 | margin-right: 12px;
77 | padding: 0;
78 | font-family: NotoSans Nerd Font Mono;
79 | }
80 |
81 | #workspaces button {
82 | margin-right: 10px;
83 | color: #ffffff;
84 | }
85 | #workspaces button:hover, #workspaces button:active {
86 | background-color: #292828;
87 | color: #ffffff;
88 | }
89 | #workspaces button.focused {
90 | background-color: #383737;
91 | }
92 |
93 | #language {
94 | margin-right: 7px;
95 | }
96 |
97 | #battery {
98 | margin-left: 7px;
99 | margin-right: 3px;
100 | }
101 | '';
102 | }
103 |
--------------------------------------------------------------------------------
/home-manager/config/yt-dlp.nix:
--------------------------------------------------------------------------------
1 | { pkgs, config, ... }:
2 |
3 | let
4 |
5 | pkgsUnstable = import {};
6 |
7 | in
8 |
9 | {
10 | home.packages = [
11 | pkgsUnstable.yt-dlp
12 | ];
13 |
14 | # …
15 | }
16 |
--------------------------------------------------------------------------------
/home-manager/home.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 | {
3 | imports = [
4 | #Git
5 | ./config/git.nix
6 |
7 | #Theme (cursor theme, gtk theme, ... )
8 | ./config/theme.nix
9 |
10 | #Bash
11 | ./config/bashrc.nix
12 |
13 | #Alacritty
14 | ./config/alacritty.nix
15 |
16 | #Neovim
17 | ./config/neovim.nix
18 |
19 | #Waybar
20 | ./config/waybar.nix
21 |
22 | #Yt-dlp
23 | ./config/yt-dlp.nix
24 | ];
25 |
26 | home.packages = with pkgs; [
27 | #Text editor
28 | vscodium
29 |
30 | #Browser
31 | firefox
32 | chromium
33 | qutebrowser
34 |
35 | #CLI program
36 | kpcli #password manager
37 | acpi #battery status
38 | pulsemixer #audio manager
39 | cmatrix #!!!
40 | imv #image viewer
41 | nix-prefetch-github #get hash and head from github repo
42 |
43 | #Color palette
44 | eyedropper
45 |
46 | #App launcher
47 | bemenu
48 |
49 | #File browser
50 | xfce.thunar
51 |
52 | #Video viewer
53 | haruna
54 |
55 | #Video editor
56 | shotcut
57 |
58 | #Image editor
59 | pinta
60 | inkscape
61 |
62 | #Messaging app
63 | signal-desktop
64 |
65 | #Office suite
66 | libreoffice
67 |
68 | #Font
69 | jetbrains-mono
70 | nerdfonts
71 | ];
72 |
73 | home.username = "simon";
74 | home.homeDirectory = "/home/simon";
75 | home.stateVersion = "22.11";
76 | programs.home-manager.enable = true;
77 | }
78 |
--------------------------------------------------------------------------------
/nixos/audio/bluetooth.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 |
4 | hardware.bluetooth.enable = true;
5 |
6 | services.pipewire.media-session.config.bluez-monitor.rules = [
7 | {
8 | # Matches all cards
9 | matches = [{ "device.name" = "~bluez_card.*"; }];
10 | actions = {
11 | "update-props" = {
12 | "bluez5.auto-connect" = [ "hfp_hf" "hsp_hs" "a2dp_sink" ];
13 | };
14 | };
15 | }
16 | {
17 | matches = [
18 | #Matches all sources
19 | { "node.name" = "~bluez_input.*"; }
20 | #Matches all outputs
21 | { "node.name" = "~bluez_output.*"; }
22 | ];
23 | actions = {
24 | "node.pause-on-idle" = false;
25 | };
26 | }
27 | ];
28 |
29 | environment.etc = {
30 | "wireplumber/bluetooth.lua.d/51-bluez-config.lua".text = ''
31 | bluez_monitor.properties = {
32 | ["bluez5.enable-sbc-xq"] = true,
33 | ["bluez5.enable-msbc"] = true,
34 | ["bluez5.enable-hw-volume"] = true,
35 | ["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]"
36 | }
37 | '';
38 | };
39 | }
40 |
--------------------------------------------------------------------------------
/nixos/audio/general.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | security.rtkit.enable = true;
4 | services.pipewire = {
5 | enable = true;
6 | alsa.enable = true;
7 | alsa.support32Bit = true;
8 | pulse.enable = true;
9 | jack.enable = true;
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/nixos/configuration.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ... }:
2 | {
3 | #silent boot
4 | disabledModules = ["system/boot/stage-2.nix" "system/boot/stage-1.nix" "system/etc/etc.nix"];
5 |
6 | imports =
7 | [
8 | #silent boot
9 | ./silent-boot/stage-2-silent.nix
10 | ./silent-boot/stage-1-silent.nix
11 | ./silent-boot/etc-silent.nix
12 | ./silent-boot/boot.nix
13 |
14 | #hardware optimization
15 | ./hardware-optimization/framework-specific.nix
16 | ./hardware-optimization/hardware-configuration.nix
17 | ./hardware-optimization/video-acceleration.nix
18 | ./hardware-optimization/ssd.nix
19 |
20 | #audio
21 | ./audio/general.nix
22 | ./audio/bluetooth.nix
23 |
24 | #networking
25 | ./networking/networks.nix
26 |
27 | #wayland
28 | ./wayland/general.nix
29 | ./wayland/window-manager.nix
30 | ./wayland/login-manager.nix
31 | ];
32 |
33 | time.timeZone = "Europe/Bratislava";
34 |
35 | environment.sessionVariables = rec {
36 | XDG_CONFIG_HOME = "\${HOME}/.config";
37 | XCURSOR_SIZE = "24";
38 | };
39 |
40 | users.users.simon = {
41 | isNormalUser = true;
42 | extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
43 | };
44 |
45 | environment.systemPackages = with pkgs; [
46 | vim
47 | wget
48 | tmux
49 | freshfetch
50 | ];
51 |
52 | #programs.mtr.enable = true;
53 | #programs.gnupg.agent = {
54 | # enable = true;
55 | # enableSSHSupport = true;
56 | #};
57 |
58 | #services.openssh.enable = true;
59 | services.printing.enable = true;
60 |
61 | system.stateVersion = "22.11";
62 | }
63 |
--------------------------------------------------------------------------------
/nixos/hardware-optimization/framework-specific.nix:
--------------------------------------------------------------------------------
1 | { lib, pkgs, ... }: {
2 | imports = [
3 | ./ssd.nix
4 | ];
5 |
6 | boot.kernelParams = [
7 | # For Power consumption
8 | # https://kvark.github.io/linux/framework/2021/10/17/framework-nixos.html
9 | "mem_sleep_default=deep"
10 | # For Power consumption
11 | # https://community.frame.work/t/linux-battery-life-tuning/6665/156
12 | "nvme.noacpi=1"
13 | ];
14 |
15 | # Requires at least 5.16 for working wi-fi and bluetooth.
16 | # https://community.frame.work/t/using-the-ax210-with-linux-on-the-framework-laptop/1844/89
17 | boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "5.16") (lib.mkDefault pkgs.linuxPackages_latest);
18 |
19 | # Fix TRRS headphones missing a mic
20 | # https://community.frame.work/t/headset-microphone-on-linux/12387/3
21 | boot.extraModprobeConfig = ''
22 | options snd-hda-intel model=dell-headset-multi
23 | '';
24 |
25 | # For fingerprint support
26 | #services.fprintd.enable = lib.mkDefault true;
27 |
28 | # Custom udev rules
29 | services.udev.extraRules = ''
30 | # Fix headphone noise when on powersave
31 | # https://community.frame.work/t/headphone-jack-intermittent-noise/5246/55
32 | SUBSYSTEM=="pci", ATTR{vendor}=="0x8086", ATTR{device}=="0xa0e0", ATTR{power/control}="on"
33 | # Ethernet expansion card support
34 | #ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0bda", ATTR{idProduct}=="8156", ATTR{power/autosuspend}="20"
35 | '';
36 |
37 | # Mis-detected by nixos-generate-config
38 | # https://github.com/NixOS/nixpkgs/issues/171093
39 | # https://wiki.archlinux.org/title/Framework_Laptop#Changing_the_brightness_of_the_monitor_does_not_work
40 | hardware.acpilight.enable = lib.mkDefault true;
41 |
42 | # Needed for desktop environments to detect/manage display brightness
43 | hardware.sensor.iio.enable = lib.mkDefault true;
44 |
45 | # HiDPI
46 | # Leaving here for documentation
47 | #hardware.video.hidpi.enable = lib.mkDefault true;
48 |
49 | # Fix font sizes in X
50 | #services.xserver.dpi = 200;
51 | }
52 |
--------------------------------------------------------------------------------
/nixos/hardware-optimization/ssd.nix:
--------------------------------------------------------------------------------
1 | { lib, ... }:
2 |
3 | {
4 | services.fstrim.enable = lib.mkDefault true;
5 | }
6 |
--------------------------------------------------------------------------------
/nixos/hardware-optimization/video-acceleration.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | nixpkgs.config.packageOverrides = pkgs: {
4 | vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
5 | };
6 | }
7 |
--------------------------------------------------------------------------------
/nixos/networking/networks.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | networking.hostName = "framework";
4 | networking.wireless.enable = true;
5 | networking.wireless.userControlled.enable = true;
6 |
7 | networking.firewall.enable = false;
8 | #networking.firewall.allowedUDPPorts = [...];
9 | #networking.firewall.allowedTCPPorts = [...];
10 |
11 | #networking.proxy.default = "http://user:password@proxy:port/";
12 | #networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
13 |
14 | #Define your networks here
15 | #Syntax :
16 | #networking.wireless.networks.Network-Name.psk = "password";
17 | }
18 |
--------------------------------------------------------------------------------
/nixos/silent-boot/boot.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | boot.loader.systemd-boot.enable = true;
4 | boot.loader.efi.canTouchEfiVariables = true;
5 | boot.loader.systemd-boot.editor = false;
6 | boot.loader.timeout = 0;
7 | boot.kernelParams = ["quiet" "rd.systemd.show_status=false" "rd.udev.log_level=3" "udev.log_priority=3"];
8 | boot.consoleLogLevel = 0;
9 | boot.initrd.verbose = false;
10 | boot.initrd.systemd.enable = true;
11 | systemd.watchdog.rebootTime = "0";
12 |
13 | i18n.defaultLocale = "en_US.UTF-8";
14 | console = {
15 | font = "ter-v32n";
16 | keyMap = "us";
17 | packages = with pkgs; [ terminus_font ];
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/nixos/silent-boot/etc-silent.nix:
--------------------------------------------------------------------------------
1 | # Management of static files in /etc.
2 |
3 | { config, lib, pkgs, ... }:
4 |
5 | with lib;
6 |
7 | let
8 |
9 | etc' = filter (f: f.enable) (attrValues config.environment.etc);
10 |
11 | etc = pkgs.runCommandLocal "etc" {
12 | # This is needed for the systemd module
13 | passthru.targets = map (x: x.target) etc';
14 | } /* sh */ ''
15 | set -euo pipefail
16 |
17 | makeEtcEntry() {
18 | src="$1"
19 | target="$2"
20 | mode="$3"
21 | user="$4"
22 | group="$5"
23 |
24 | if [[ "$src" = *'*'* ]]; then
25 | # If the source name contains '*', perform globbing.
26 | mkdir -p "$out/etc/$target"
27 | for fn in $src; do
28 | ln -s "$fn" "$out/etc/$target/"
29 | done
30 | else
31 |
32 | mkdir -p "$out/etc/$(dirname "$target")"
33 | if ! [ -e "$out/etc/$target" ]; then
34 | ln -s "$src" "$out/etc/$target"
35 | else
36 | echo "duplicate entry $target -> $src"
37 | if [ "$(readlink "$out/etc/$target")" != "$src" ]; then
38 | echo "mismatched duplicate entry $(readlink "$out/etc/$target") <-> $src"
39 | ret=1
40 |
41 | continue
42 | fi
43 | fi
44 |
45 | if [ "$mode" != symlink ]; then
46 | echo "$mode" > "$out/etc/$target.mode"
47 | echo "$user" > "$out/etc/$target.uid"
48 | echo "$group" > "$out/etc/$target.gid"
49 | fi
50 | fi
51 | }
52 |
53 | mkdir -p "$out/etc"
54 | ${concatMapStringsSep "\n" (etcEntry: escapeShellArgs [
55 | "makeEtcEntry"
56 | # Force local source paths to be added to the store
57 | "${etcEntry.source}"
58 | etcEntry.target
59 | etcEntry.mode
60 | etcEntry.user
61 | etcEntry.group
62 | ]) etc'}
63 | '';
64 |
65 | in
66 |
67 | {
68 |
69 | imports = [ /nix/var/nix/profiles/per-user/root/channels/nixos/nixos/modules/system/build.nix ];
70 |
71 | ###### interface
72 |
73 | options = {
74 |
75 | environment.etc = mkOption {
76 | default = {};
77 | example = literalExpression ''
78 | { example-configuration-file =
79 | { source = "/nix/store/.../etc/dir/file.conf.example";
80 | mode = "0440";
81 | };
82 | "default/useradd".text = "GROUP=100 ...";
83 | }
84 | '';
85 | description = lib.mdDoc ''
86 | Set of files that have to be linked in {file}`/etc`.
87 | '';
88 |
89 | type = with types; attrsOf (submodule (
90 | { name, config, options, ... }:
91 | { options = {
92 |
93 | enable = mkOption {
94 | type = types.bool;
95 | default = true;
96 | description = lib.mdDoc ''
97 | Whether this /etc file should be generated. This
98 | option allows specific /etc files to be disabled.
99 | '';
100 | };
101 |
102 | target = mkOption {
103 | type = types.str;
104 | description = lib.mdDoc ''
105 | Name of symlink (relative to
106 | {file}`/etc`). Defaults to the attribute
107 | name.
108 | '';
109 | };
110 |
111 | text = mkOption {
112 | default = null;
113 | type = types.nullOr types.lines;
114 | description = lib.mdDoc "Text of the file.";
115 | };
116 |
117 | source = mkOption {
118 | type = types.path;
119 | description = lib.mdDoc "Path of the source file.";
120 | };
121 |
122 | mode = mkOption {
123 | type = types.str;
124 | default = "symlink";
125 | example = "0600";
126 | description = lib.mdDoc ''
127 | If set to something else than `symlink`,
128 | the file is copied instead of symlinked, with the given
129 | file mode.
130 | '';
131 | };
132 |
133 | uid = mkOption {
134 | default = 0;
135 | type = types.int;
136 | description = lib.mdDoc ''
137 | UID of created file. Only takes effect when the file is
138 | copied (that is, the mode is not 'symlink').
139 | '';
140 | };
141 |
142 | gid = mkOption {
143 | default = 0;
144 | type = types.int;
145 | description = lib.mdDoc ''
146 | GID of created file. Only takes effect when the file is
147 | copied (that is, the mode is not 'symlink').
148 | '';
149 | };
150 |
151 | user = mkOption {
152 | default = "+${toString config.uid}";
153 | type = types.str;
154 | description = lib.mdDoc ''
155 | User name of created file.
156 | Only takes effect when the file is copied (that is, the mode is not 'symlink').
157 | Changing this option takes precedence over `uid`.
158 | '';
159 | };
160 |
161 | group = mkOption {
162 | default = "+${toString config.gid}";
163 | type = types.str;
164 | description = lib.mdDoc ''
165 | Group name of created file.
166 | Only takes effect when the file is copied (that is, the mode is not 'symlink').
167 | Changing this option takes precedence over `gid`.
168 | '';
169 | };
170 |
171 | };
172 |
173 | config = {
174 | target = mkDefault name;
175 | source = mkIf (config.text != null) (
176 | let name' = "etc-" + baseNameOf name;
177 | in mkDerivedConfig options.text (pkgs.writeText name')
178 | );
179 | };
180 |
181 | }));
182 |
183 | };
184 |
185 | };
186 |
187 |
188 | ###### implementation
189 |
190 | config = {
191 |
192 | system.build.etc = etc;
193 | system.build.etcActivationCommands =
194 | ''
195 | # Set up the statically computed bits of /etc.
196 | #echo "setting up /etc..."
197 | ${pkgs.perl.withPackages (p: [ p.FileSlurp ])}/bin/perl ${/nix/var/nix/profiles/per-user/root/channels/nixos/nixos/modules/system/etc/setup-etc.pl} ${etc}/etc
198 | '';
199 | };
200 |
201 | }
202 |
--------------------------------------------------------------------------------
/nixos/silent-boot/stage-1-init-silent.sh:
--------------------------------------------------------------------------------
1 | #! @shell@
2 |
3 | targetRoot=/mnt-root
4 | console=tty1
5 | verbose="@verbose@"
6 |
7 | info() {
8 | if [[ -n "$verbose" ]]; then
9 | echo "test"
10 | fi
11 | }
12 |
13 | extraUtils="@extraUtils@"
14 | export LD_LIBRARY_PATH=@extraUtils@/lib
15 | export PATH=@extraUtils@/bin
16 | ln -s @extraUtils@/bin /bin
17 | # hardcoded in util-linux's mount helper search path `/run/wrappers/bin:/run/current-system/sw/bin:/sbin`
18 | ln -s @extraUtils@/bin /sbin
19 |
20 | # Copy the secrets to their needed location
21 | if [ -d "@extraUtils@/secrets" ]; then
22 | for secret in $(cd "@extraUtils@/secrets"; find . -type f); do
23 | mkdir -p $(dirname "/$secret")
24 | ln -s "@extraUtils@/secrets/$secret" "$secret"
25 | done
26 | fi
27 |
28 | # Stop LVM complaining about fd3
29 | export LVM_SUPPRESS_FD_WARNINGS=true
30 |
31 | fail() {
32 | if [ -n "$panicOnFail" ]; then exit 1; fi
33 |
34 | @preFailCommands@
35 |
36 | # If starting stage 2 failed, allow the user to repair the problem
37 | # in an interactive shell.
38 | cat </dev/$console 2>/dev/$console"
60 | elif [ -n "$allowShell" -a "$reply" = i ]; then
61 | #echo "Starting interactive shell..."
62 | setsid @shell@ -c "exec @shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
63 | elif [ "$reply" = r ]; then
64 | #echo "Rebooting..."
65 | reboot -f
66 | else
67 | info "Continuing..."
68 | fi
69 | }
70 |
71 | trap 'fail' 0
72 |
73 |
74 | # Print a greeting.
75 | info
76 | info "[1;32m<<< NixOS Stage 1 >>>[0m"
77 | info
78 | echo "."
79 | # Make several required directories.
80 | mkdir -p /etc/udev
81 | touch /etc/fstab # to shut up mount
82 | ln -s /proc/mounts /etc/mtab # to shut up mke2fs
83 | touch /etc/udev/hwdb.bin # to shut up udev
84 | touch /etc/initrd-release
85 |
86 | # Function for waiting for device(s) to appear.
87 | waitDevice() {
88 | local device="$1"
89 | # Split device string using ':' as a delimiter as bcachefs
90 | # uses this for multi-device filesystems, i.e. /dev/sda1:/dev/sda2:/dev/sda3
91 | local IFS=':'
92 |
93 | # USB storage devices tend to appear with some delay. It would be
94 | # great if we had a way to synchronously wait for them, but
95 | # alas... So just wait for a few seconds for the device to
96 | # appear.
97 | for dev in $device; do
98 | if test ! -e $dev; then
99 | echo -n "waiting for device $dev to appear..."
100 | try=20
101 | while [ $try -gt 0 ]; do
102 | sleep 1
103 | # also re-try lvm activation now that new block devices might have appeared
104 | lvm vgchange -ay
105 | # and tell udev to create nodes for the new LVs
106 | udevadm trigger --action=add
107 | if test -e $dev; then break; fi
108 | #echo -n "."
109 | try=$((try - 1))
110 | done
111 | echo
112 | [ $try -ne 0 ]
113 | fi
114 | done
115 | }
116 |
117 | # Mount special file systems.
118 | specialMount() {
119 | local device="$1"
120 | local mountPoint="$2"
121 | local options="$3"
122 | local fsType="$4"
123 |
124 | mkdir -m 0755 -p "$mountPoint"
125 | mount -n -t "$fsType" -o "$options" "$device" "$mountPoint"
126 | }
127 | source @earlyMountScript@
128 |
129 | # Copy initrd secrets from /.initrd-secrets to their actual destinations
130 | if [ -d "/.initrd-secrets" ]; then
131 | #
132 | # Secrets are named by their full destination pathname and stored
133 | # under /.initrd-secrets/
134 | #
135 | for secret in $(cd "/.initrd-secrets"; find . -type f); do
136 | mkdir -p $(dirname "/$secret")
137 | cp "/.initrd-secrets/$secret" "$secret"
138 | done
139 | fi
140 |
141 | # Log the script output to /dev/kmsg or /run/log/stage-1-init.log.
142 | mkdir -p /tmp
143 | mkfifo /tmp/stage-1-init.log.fifo
144 | logOutFd=8 && logErrFd=9
145 | eval "exec $logOutFd>&1 $logErrFd>&2"
146 | if test -w /dev/kmsg; then
147 | tee -i < /tmp/stage-1-init.log.fifo /proc/self/fd/"$logOutFd" | while read -r line; do
148 | if test -n "$line"; then
149 | echo "<7>stage-1-init: [$(date)] $line" > /dev/kmsg
150 | fi
151 | done &
152 | else
153 | mkdir -p /run/log
154 | tee -i < /tmp/stage-1-init.log.fifo /run/log/stage-1-init.log &
155 | fi
156 | exec > /tmp/stage-1-init.log.fifo 2>&1
157 |
158 |
159 | # Process the kernel command line.
160 | export stage2Init=/init
161 | for o in $(cat /proc/cmdline); do
162 | case $o in
163 | console=*)
164 | set -- $(IFS==; echo $o)
165 | params=$2
166 | set -- $(IFS=,; echo $params)
167 | console=$1
168 | ;;
169 | init=*)
170 | set -- $(IFS==; echo $o)
171 | stage2Init=$2
172 | ;;
173 | boot.persistence=*)
174 | set -- $(IFS==; echo $o)
175 | persistence=$2
176 | ;;
177 | boot.persistence.opt=*)
178 | set -- $(IFS==; echo $o)
179 | persistence_opt=$2
180 | ;;
181 | boot.trace|debugtrace)
182 | # Show each command.
183 | set -x
184 | ;;
185 | boot.shell_on_fail)
186 | allowShell=1
187 | ;;
188 | boot.debug1|debug1) # stop right away
189 | allowShell=1
190 | fail
191 | ;;
192 | boot.debug1devices) # stop after loading modules and creating device nodes
193 | allowShell=1
194 | debug1devices=1
195 | ;;
196 | boot.debug1mounts) # stop after mounting file systems
197 | allowShell=1
198 | debug1mounts=1
199 | ;;
200 | boot.panic_on_fail|stage1panic=1)
201 | panicOnFail=1
202 | ;;
203 | root=*)
204 | # If a root device is specified on the kernel command
205 | # line, make it available through the symlink /dev/root.
206 | # Recognise LABEL= and UUID= to support UNetbootin.
207 | set -- $(IFS==; echo $o)
208 | if [ $2 = "LABEL" ]; then
209 | root="/dev/disk/by-label/$3"
210 | elif [ $2 = "UUID" ]; then
211 | root="/dev/disk/by-uuid/$3"
212 | else
213 | root=$2
214 | fi
215 | ln -s "$root" /dev/root
216 | ;;
217 | copytoram)
218 | copytoram=1
219 | ;;
220 | findiso=*)
221 | # if an iso name is supplied, try to find the device where
222 | # the iso resides on
223 | set -- $(IFS==; echo $o)
224 | isoPath=$2
225 | ;;
226 | esac
227 | done
228 |
229 | # Set hostid before modules are loaded.
230 | # This is needed by the spl/zfs modules.
231 | @setHostId@
232 |
233 | # Load the required kernel modules.
234 | mkdir -p /lib
235 | ln -s @modulesClosure@/lib/modules /lib/modules
236 | ln -s @modulesClosure@/lib/firmware /lib/firmware
237 | # see comment in stage-1.nix for explanation
238 | echo @extraUtils@/bin/modprobe-kernel > /proc/sys/kernel/modprobe
239 | for i in @kernelModules@; do
240 | info "loading module $(basename $i)..."
241 | modprobe $i
242 | done
243 |
244 |
245 | # Create device nodes in /dev.
246 | @preDeviceCommands@
247 | info "running udev..."
248 | ln -sfn /proc/self/fd /dev/fd
249 | ln -sfn /proc/self/fd/0 /dev/stdin
250 | ln -sfn /proc/self/fd/1 /dev/stdout
251 | ln -sfn /proc/self/fd/2 /dev/stderr
252 | mkdir -p /etc/systemd
253 | ln -sfn @linkUnits@ /etc/systemd/network
254 | mkdir -p /etc/udev
255 | ln -sfn @udevRules@ /etc/udev/rules.d
256 | mkdir -p /dev/.mdadm
257 | systemd-udevd --daemon
258 | udevadm trigger --action=add
259 | udevadm settle
260 |
261 |
262 | # XXX: Use case usb->lvm will still fail, usb->luks->lvm is covered
263 | @preLVMCommands@
264 |
265 | info "starting device mapper and LVM..."
266 | lvm vgchange -ay
267 |
268 | if test -n "$debug1devices"; then fail; fi
269 |
270 |
271 | @postDeviceCommands@
272 |
273 |
274 | # Check the specified file system, if appropriate.
275 | checkFS() {
276 | local device="$1"
277 | local fsType="$2"
278 |
279 | # Only check block devices.
280 | if [ ! -b "$device" ]; then return 0; fi
281 |
282 | # Don't check ROM filesystems.
283 | if [ "$fsType" = iso9660 -o "$fsType" = udf ]; then return 0; fi
284 |
285 | # Don't check resilient COWs as they validate the fs structures at mount time
286 | if [ "$fsType" = btrfs -o "$fsType" = zfs -o "$fsType" = bcachefs ]; then return 0; fi
287 |
288 | # Skip fsck for apfs as the fsck utility does not support repairing the filesystem (no -a option)
289 | if [ "$fsType" = apfs ]; then return 0; fi
290 |
291 | # Skip fsck for nilfs2 - not needed by design and no fsck tool for this filesystem.
292 | if [ "$fsType" = nilfs2 ]; then return 0; fi
293 |
294 | # Skip fsck for inherently readonly filesystems.
295 | if [ "$fsType" = squashfs ]; then return 0; fi
296 |
297 | # If we couldn't figure out the FS type, then skip fsck.
298 | if [ "$fsType" = auto ]; then
299 | #echo 'cannot check filesystem with type "auto"!'
300 | return 0
301 | fi
302 |
303 | # Device might be already mounted manually
304 | # e.g. NBD-device or the host filesystem of the file which contains encrypted root fs
305 | if mount | grep -q "^$device on "; then
306 | #echo "skip checking already mounted $device"
307 | return 0
308 | fi
309 |
310 | # Optionally, skip fsck on journaling filesystems. This option is
311 | # a hack - it's mostly because e2fsck on ext3 takes much longer to
312 | # recover the journal than the ext3 implementation in the kernel
313 | # does (minutes versus seconds).
314 | if test -z "@checkJournalingFS@" -a \
315 | \( "$fsType" = ext3 -o "$fsType" = ext4 -o "$fsType" = reiserfs \
316 | -o "$fsType" = xfs -o "$fsType" = jfs -o "$fsType" = f2fs \)
317 | then
318 | return 0
319 | fi
320 |
321 | #echo "checking $device..."
322 |
323 | fsck -V -a "$device"
324 | fsckResult=$?
325 |
326 | if test $(($fsckResult | 2)) = $fsckResult; then
327 | #echo "fsck finished, rebooting..."
328 | sleep 3
329 | reboot -f
330 | fi
331 |
332 | if test $(($fsckResult | 4)) = $fsckResult; then
333 | #echo "$device has unrepaired errors, please fix them manually."
334 | fail
335 | fi
336 |
337 | if test $fsckResult -ge 8; then
338 | #echo "fsck on $device failed."
339 | fail
340 | fi
341 |
342 | return 0
343 | }
344 |
345 | escapeFstab() {
346 | local original="$1"
347 |
348 | # Replace space
349 | local escaped="${original// /\\040}"
350 | # Replace tab
351 | echo "${escaped//$'\t'/\\011}"
352 | }
353 |
354 | # Function for mounting a file system.
355 | mountFS() {
356 | local device="$1"
357 | local mountPoint="$2"
358 | local options="$3"
359 | local fsType="$4"
360 |
361 | if [ "$fsType" = auto ]; then
362 | fsType=$(blkid -o value -s TYPE "$device")
363 | if [ -z "$fsType" ]; then fsType=auto; fi
364 | fi
365 |
366 | # Filter out x- options, which busybox doesn't do yet.
367 | local optionsFiltered="$(IFS=,; for i in $options; do if [ "${i:0:2}" != "x-" ]; then echo -n $i,; fi; done)"
368 | # Prefix (lower|upper|work)dir with /mnt-root (overlayfs)
369 | local optionsPrefixed="$( echo "$optionsFiltered" | sed -E 's#\<(lowerdir|upperdir|workdir)=#\1=/mnt-root#g' )"
370 |
371 | echo "$device /mnt-root$mountPoint $fsType $optionsPrefixed" >> /etc/fstab
372 |
373 | checkFS "$device" "$fsType"
374 |
375 | # Optionally resize the filesystem.
376 | case $options in
377 | *x-nixos.autoresize*)
378 | if [ "$fsType" = ext2 -o "$fsType" = ext3 -o "$fsType" = ext4 ]; then
379 | modprobe "$fsType"
380 | #echo "resizing $device..."
381 | e2fsck -fp "$device"
382 | resize2fs "$device"
383 | elif [ "$fsType" = f2fs ]; then
384 | #echo "resizing $device..."
385 | fsck.f2fs -fp "$device"
386 | resize.f2fs "$device"
387 | fi
388 | ;;
389 | esac
390 |
391 | # Create backing directories for overlayfs
392 | if [ "$fsType" = overlay ]; then
393 | for i in upper work; do
394 | dir="$( echo "$optionsPrefixed" | grep -o "${i}dir=[^,]*" )"
395 | mkdir -m 0700 -p "${dir##*=}"
396 | done
397 | fi
398 |
399 | info "mounting $device on $mountPoint..."
400 |
401 | mkdir -p "/mnt-root$mountPoint"
402 |
403 | # For ZFS and CIFS mounts, retry a few times before giving up.
404 | # We do this for ZFS as a workaround for issue NixOS/nixpkgs#25383.
405 | local n=0
406 | while true; do
407 | mount "/mnt-root$mountPoint" && break
408 | if [ \( "$fsType" != cifs -a "$fsType" != zfs \) -o "$n" -ge 10 ]; then fail; break; fi
409 | echo "retrying..."
410 | sleep 1
411 | n=$((n + 1))
412 | done
413 |
414 | [ "$mountPoint" == "/" ] &&
415 | [ -f "/mnt-root/etc/NIXOS_LUSTRATE" ] &&
416 | lustrateRoot "/mnt-root"
417 |
418 | true
419 | }
420 |
421 | lustrateRoot () {
422 | local root="$1"
423 |
424 | echo
425 | echo -e "\e[1;33m<<< NixOS is now lustrating the root filesystem (cruft goes to /old-root) >>>\e[0m"
426 | echo
427 |
428 | mkdir -m 0755 -p "$root/old-root.tmp"
429 |
430 | echo
431 | echo "Moving impurities out of the way:"
432 | for d in "$root"/*
433 | do
434 | [ "$d" == "$root/nix" ] && continue
435 | [ "$d" == "$root/boot" ] && continue # Don't render the system unbootable
436 | [ "$d" == "$root/old-root.tmp" ] && continue
437 |
438 | mv -v "$d" "$root/old-root.tmp"
439 | done
440 |
441 | # Use .tmp to make sure subsequent invokations don't clash
442 | mv -v "$root/old-root.tmp" "$root/old-root"
443 |
444 | mkdir -m 0755 -p "$root/etc"
445 | touch "$root/etc/NIXOS"
446 |
447 | exec 4< "$root/old-root/etc/NIXOS_LUSTRATE"
448 |
449 | echo
450 | echo "Restoring selected impurities:"
451 | while read -u 4 keeper; do
452 | dirname="$(dirname "$keeper")"
453 | mkdir -m 0755 -p "$root/$dirname"
454 | cp -av "$root/old-root/$keeper" "$root/$keeper"
455 | done
456 |
457 | exec 4>&-
458 | }
459 |
460 |
461 |
462 | if test -e /sys/power/resume -a -e /sys/power/disk; then
463 | if test -n "@resumeDevice@" && waitDevice "@resumeDevice@"; then
464 | resumeDev="@resumeDevice@"
465 | resumeInfo="$(udevadm info -q property "$resumeDev" )"
466 | else
467 | for sd in @resumeDevices@; do
468 | # Try to detect resume device. According to Ubuntu bug:
469 | # https://bugs.launchpad.net/ubuntu/+source/pm-utils/+bug/923326/comments/1
470 | # when there are multiple swap devices, we can't know where the hibernate
471 | # image will reside. We can check all of them for swsuspend blkid.
472 | if waitDevice "$sd"; then
473 | resumeInfo="$(udevadm info -q property "$sd")"
474 | if [ "$(echo "$resumeInfo" | sed -n 's/^ID_FS_TYPE=//p')" = "swsuspend" ]; then
475 | resumeDev="$sd"
476 | break
477 | fi
478 | fi
479 | done
480 | fi
481 | if test -n "$resumeDev"; then
482 | resumeMajor="$(echo "$resumeInfo" | sed -n 's/^MAJOR=//p')"
483 | resumeMinor="$(echo "$resumeInfo" | sed -n 's/^MINOR=//p')"
484 | echo "$resumeMajor:$resumeMinor" > /sys/power/resume 2> /dev/null || echo "failed to resume..."
485 | fi
486 | fi
487 |
488 | # If we have a path to an iso file, find the iso and link it to /dev/root
489 | if [ -n "$isoPath" ]; then
490 | mkdir -p /findiso
491 |
492 | for delay in 5 10; do
493 | blkid | while read -r line; do
494 | device=$(echo "$line" | sed 's/:.*//')
495 | type=$(echo "$line" | sed 's/.*TYPE="\([^"]*\)".*/\1/')
496 |
497 | mount -t "$type" "$device" /findiso
498 | if [ -e "/findiso$isoPath" ]; then
499 | ln -sf "/findiso$isoPath" /dev/root
500 | break 2
501 | else
502 | umount /findiso
503 | fi
504 | done
505 |
506 | sleep "$delay"
507 | done
508 | fi
509 |
510 | # Try to find and mount the root device.
511 | mkdir -p $targetRoot
512 |
513 | exec 3< @fsInfo@
514 |
515 | while read -u 3 mountPoint; do
516 | read -u 3 device
517 | read -u 3 fsType
518 | read -u 3 options
519 |
520 | # !!! Really quick hack to support bind mounts, i.e., where the
521 | # "device" should be taken relative to /mnt-root, not /. Assume
522 | # that every device that starts with / but doesn't start with /dev
523 | # is a bind mount.
524 | pseudoDevice=
525 | case $device in
526 | /dev/*)
527 | ;;
528 | //*)
529 | # Don't touch SMB/CIFS paths.
530 | pseudoDevice=1
531 | ;;
532 | /*)
533 | device=/mnt-root$device
534 | ;;
535 | *)
536 | # Not an absolute path; assume that it's a pseudo-device
537 | # like an NFS path (e.g. "server:/path").
538 | pseudoDevice=1
539 | ;;
540 | esac
541 |
542 | if test -z "$pseudoDevice" && ! waitDevice "$device"; then
543 | # If it doesn't appear, try to mount it anyway (and
544 | # probably fail). This is a fallback for non-device "devices"
545 | # that we don't properly recognise.
546 | echo "Timed out waiting for device $device, trying to mount anyway."
547 | fi
548 |
549 | # Wait once more for the udev queue to empty, just in case it's
550 | # doing something with $device right now.
551 | udevadm settle
552 |
553 | # If copytoram is enabled: skip mounting the ISO and copy its content to a tmpfs.
554 | if [ -n "$copytoram" ] && [ "$device" = /dev/root ] && [ "$mountPoint" = /iso ]; then
555 | fsType=$(blkid -o value -s TYPE "$device")
556 | fsSize=$(blockdev --getsize64 "$device" || stat -Lc '%s' "$device")
557 |
558 | mkdir -p /tmp-iso
559 | mount -t "$fsType" /dev/root /tmp-iso
560 | mountFS tmpfs /iso size="$fsSize" tmpfs
561 |
562 | cp -r /tmp-iso/* /mnt-root/iso/
563 |
564 | umount /tmp-iso
565 | rmdir /tmp-iso
566 | if [ -n "$isoPath" ] && [ $fsType = "iso9660" ] && mountpoint -q /findiso; then
567 | umount /findiso
568 | fi
569 | continue
570 | fi
571 |
572 | if [ "$mountPoint" = / ] && [ "$device" = tmpfs ] && [ ! -z "$persistence" ]; then
573 | #echo persistence...
574 | waitDevice "$persistence"
575 | #echo enabling persistence...
576 | mountFS "$persistence" "$mountPoint" "$persistence_opt" "auto"
577 | continue
578 | fi
579 |
580 | mountFS "$device" "$(escapeFstab "$mountPoint")" "$(escapeFstab "$options")" "$fsType"
581 | done
582 |
583 | exec 3>&-
584 |
585 |
586 | @postMountCommands@
587 |
588 |
589 | # Emit a udev rule for /dev/root to prevent systemd from complaining.
590 | if [ -e /mnt-root/iso ]; then
591 | eval $(udevadm info --export --export-prefix=ROOT_ --device-id-of-file=/mnt-root/iso)
592 | else
593 | eval $(udevadm info --export --export-prefix=ROOT_ --device-id-of-file=$targetRoot)
594 | fi
595 | if [ "$ROOT_MAJOR" -a "$ROOT_MINOR" -a "$ROOT_MAJOR" != 0 ]; then
596 | mkdir -p /run/udev/rules.d
597 | echo 'ACTION=="add|change", SUBSYSTEM=="block", ENV{MAJOR}=="'$ROOT_MAJOR'", ENV{MINOR}=="'$ROOT_MINOR'", SYMLINK+="root"' > /run/udev/rules.d/61-dev-root-link.rules
598 | fi
599 |
600 |
601 | # Stop udevd.
602 | udevadm control --exit
603 |
604 | # Reset the logging file descriptors.
605 | # Do this just before pkill, which will kill the tee process.
606 | exec 1>&$logOutFd 2>&$logErrFd
607 | eval "exec $logOutFd>&- $logErrFd>&-"
608 |
609 | # Kill any remaining processes, just to be sure we're not taking any
610 | # with us into stage 2. But keep storage daemons like unionfs-fuse.
611 | #
612 | # Storage daemons are distinguished by an @ in front of their command line:
613 | # https://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/
614 | for pid in $(pgrep -v -f '^@'); do
615 | # Make sure we don't kill kernel processes, see #15226 and:
616 | # http://stackoverflow.com/questions/12213445/identifying-kernel-threads
617 | readlink "/proc/$pid/exe" &> /dev/null || continue
618 | # Try to avoid killing ourselves.
619 | [ $pid -eq $$ ] && continue
620 | kill -9 "$pid"
621 | done
622 |
623 | if test -n "$debug1mounts"; then fail; fi
624 |
625 |
626 | # Restore /proc/sys/kernel/modprobe to its original value.
627 | echo /sbin/modprobe > /proc/sys/kernel/modprobe
628 |
629 |
630 | # Start stage 2. `switch_root' deletes all files in the ramfs on the
631 | # current root. The path has to be valid in the chroot not outside.
632 | if [ ! -e "$targetRoot/$stage2Init" ]; then
633 | stage2Check=${stage2Init}
634 | while [ "$stage2Check" != "${stage2Check%/*}" ] && [ ! -L "$targetRoot/$stage2Check" ]; do
635 | stage2Check=${stage2Check%/*}
636 | done
637 | if [ ! -L "$targetRoot/$stage2Check" ]; then
638 | echo "stage 2 init script ($targetRoot/$stage2Init) not found"
639 | fail
640 | fi
641 | fi
642 |
643 | mkdir -m 0755 -p $targetRoot/proc $targetRoot/sys $targetRoot/dev $targetRoot/run
644 |
645 | mount --move /proc $targetRoot/proc
646 | mount --move /sys $targetRoot/sys
647 | mount --move /dev $targetRoot/dev
648 | mount --move /run $targetRoot/run
649 |
650 | exec env -i $(type -P switch_root) "$targetRoot" "$stage2Init"
651 |
652 | fail # should never be reached
653 |
--------------------------------------------------------------------------------
/nixos/silent-boot/stage-1-silent.nix:
--------------------------------------------------------------------------------
1 | # This module builds the initial ramdisk, which contains an init
2 | # script that performs the first stage of booting the system: it loads
3 | # the modules necessary to mount the root file system, then calls the
4 | # init in the root file system to start the second boot stage.
5 |
6 | { config, lib, utils, pkgs, ... }:
7 |
8 | with lib;
9 |
10 | let
11 |
12 | udev = config.systemd.package;
13 |
14 | kernel-name = config.boot.kernelPackages.kernel.name or "kernel";
15 |
16 | modulesTree = config.system.modulesTree.override { name = kernel-name + "-modules"; };
17 | firmware = config.hardware.firmware;
18 |
19 |
20 | # Determine the set of modules that we need to mount the root FS.
21 | modulesClosure = pkgs.makeModulesClosure {
22 | rootModules = config.boot.initrd.availableKernelModules ++ config.boot.initrd.kernelModules;
23 | kernel = modulesTree;
24 | firmware = firmware;
25 | allowMissing = false;
26 | };
27 |
28 |
29 | # The initrd only has to mount `/` or any FS marked as necessary for
30 | # booting (such as the FS containing `/nix/store`, or an FS needed for
31 | # mounting `/`, like `/` on a loopback).
32 | fileSystems = filter utils.fsNeededForBoot config.system.build.fileSystems;
33 |
34 | # Determine whether zfs-mount(8) is needed.
35 | zfsRequiresMountHelper = any (fs: lib.elem "zfsutil" fs.options) fileSystems;
36 |
37 | # A utility for enumerating the shared-library dependencies of a program
38 | findLibs = pkgs.buildPackages.writeShellScriptBin "find-libs" ''
39 | set -euo pipefail
40 |
41 | declare -A seen
42 | left=()
43 |
44 | patchelf="${pkgs.buildPackages.patchelf}/bin/patchelf"
45 |
46 | function add_needed {
47 | rpath="$($patchelf --print-rpath $1)"
48 | dir="$(dirname $1)"
49 | for lib in $($patchelf --print-needed $1); do
50 | left+=("$lib" "$rpath" "$dir")
51 | done
52 | }
53 |
54 | add_needed "$1"
55 |
56 | while [ ''${#left[@]} -ne 0 ]; do
57 | next=''${left[0]}
58 | rpath=''${left[1]}
59 | ORIGIN=''${left[2]}
60 | left=("''${left[@]:3}")
61 | if [ -z ''${seen[$next]+x} ]; then
62 | seen[$next]=1
63 |
64 | # Ignore the dynamic linker which for some reason appears as a DT_NEEDED of glibc but isn't in glibc's RPATH.
65 | case "$next" in
66 | ld*.so.?) continue;;
67 | esac
68 |
69 | IFS=: read -ra paths <<< $rpath
70 | res=
71 | for path in "''${paths[@]}"; do
72 | path=$(eval "echo $path")
73 | if [ -f "$path/$next" ]; then
74 | res="$path/$next"
75 | echo "$res"
76 | add_needed "$res"
77 | break
78 | fi
79 | done
80 | if [ -z "$res" ]; then
81 | echo "Couldn't satisfy dependency $next" >&2
82 | exit 1
83 | fi
84 | fi
85 | done
86 | '';
87 |
88 | # Some additional utilities needed in stage 1, like mount, lvm, fsck
89 | # etc. We don't want to bring in all of those packages, so we just
90 | # copy what we need. Instead of using statically linked binaries,
91 | # we just copy what we need from Glibc and use patchelf to make it
92 | # work.
93 | extraUtils = pkgs.runCommandCC "extra-utils"
94 | { nativeBuildInputs = [pkgs.buildPackages.nukeReferences];
95 | allowedReferences = [ "out" ]; # prevent accidents like glibc being included in the initrd
96 | }
97 | ''
98 | set +o pipefail
99 |
100 | mkdir -p $out/bin $out/lib
101 | ln -s $out/bin $out/sbin
102 |
103 | copy_bin_and_libs () {
104 | [ -f "$out/bin/$(basename $1)" ] && rm "$out/bin/$(basename $1)"
105 | cp -pdv $1 $out/bin
106 | }
107 |
108 | # Copy BusyBox.
109 | for BIN in ${pkgs.busybox}/{s,}bin/*; do
110 | copy_bin_and_libs $BIN
111 | done
112 |
113 | ${optionalString zfsRequiresMountHelper ''
114 | # Filesystems using the "zfsutil" option are mounted regardless of the
115 | # mount.zfs(8) helper, but it is required to ensure that ZFS properties
116 | # are used as mount options.
117 | #
118 | # BusyBox does not use the ZFS helper in the first place.
119 | # util-linux searches /sbin/ as last path for helpers (stage-1-init.sh
120 | # must symlink it to the store PATH).
121 | # Without helper program, both `mount`s silently fails back to internal
122 | # code, using default options and effectively ignore security relevant
123 | # ZFS properties such as `setuid=off` and `exec=off` (unless manually
124 | # duplicated in `fileSystems.*.options`, defeating "zfsutil"'s purpose).
125 | copy_bin_and_libs ${pkgs.util-linux}/bin/mount
126 | copy_bin_and_libs ${pkgs.zfs}/bin/mount.zfs
127 | ''}
128 |
129 | # Copy some util-linux stuff.
130 | copy_bin_and_libs ${pkgs.util-linux}/sbin/blkid
131 |
132 | # Copy dmsetup and lvm.
133 | copy_bin_and_libs ${getBin pkgs.lvm2}/bin/dmsetup
134 | copy_bin_and_libs ${getBin pkgs.lvm2}/bin/lvm
135 |
136 | # Add RAID mdadm tool.
137 | copy_bin_and_libs ${pkgs.mdadm}/sbin/mdadm
138 | copy_bin_and_libs ${pkgs.mdadm}/sbin/mdmon
139 |
140 | # Copy udev.
141 | copy_bin_and_libs ${udev}/bin/udevadm
142 | copy_bin_and_libs ${udev}/lib/systemd/systemd-sysctl
143 | for BIN in ${udev}/lib/udev/*_id; do
144 | copy_bin_and_libs $BIN
145 | done
146 | # systemd-udevd is only a symlink to udevadm these days
147 | ln -sf udevadm $out/bin/systemd-udevd
148 |
149 | # Copy modprobe.
150 | copy_bin_and_libs ${pkgs.kmod}/bin/kmod
151 | ln -sf kmod $out/bin/modprobe
152 |
153 | # Dirty hack to make sure the kernel properly loads modules
154 | # such as ext4 on demand (e.g. on a `mount(2)` syscall). This is necessary
155 | # because `kmod` isn't linked against `libpthread.so.0` anymore (since
156 | # it was merged into `libc.so.6` since version `2.34`), but still needs
157 | # to access it for some reason. This is not an issue in stage-1 itself
158 | # because of the `LD_LIBRARY_PATH`-variable and anytime later because the rpath of
159 | # kmod/modprobe points to glibc's `$out/lib` where `libpthread.so.6` exists.
160 | # However, this is a problem when the kernel calls `modprobe` inside
161 | # the initial ramdisk because it doesn't know about the
162 | # `LD_LIBRARY_PATH` and the rpath was nuked.
163 | #
164 | # Also, we can't use `makeWrapper` here because `kmod` only does
165 | # `modprobe` functionality if `argv[0] == "modprobe"`.
166 | cat >$out/bin/modprobe-kernel <&1 | grep -q "mount from util-linux"
245 | $out/bin/mount.zfs -h 2>&1 | grep -q "Usage: mount.zfs"
246 | '' else ''
247 | $out/bin/mount --help 2>&1 | grep -q "BusyBox"
248 | ''}
249 | $out/bin/blkid -V 2>&1 | grep -q 'libblkid'
250 | $out/bin/udevadm --version
251 | $out/bin/dmsetup --version 2>&1 | tee -a log | grep -q "version:"
252 | LVM_SYSTEM_DIR=$out $out/bin/lvm version 2>&1 | tee -a log | grep -q "LVM"
253 | $out/bin/mdadm --version
254 | ${optionalString config.services.multipath.enable ''
255 | ($out/bin/multipath || true) 2>&1 | grep -q 'need to be root'
256 | ($out/bin/multipathd || true) 2>&1 | grep -q 'need to be root'
257 | ''}
258 |
259 | ${config.boot.initrd.extraUtilsCommandsTest}
260 | fi
261 | ''; # */
262 |
263 |
264 | # Networkd link files are used early by udev to set up interfaces early.
265 | # This must be done in stage 1 to avoid race conditions between udev and
266 | # network daemons.
267 | linkUnits = pkgs.runCommand "link-units" {
268 | allowedReferences = [ extraUtils ];
269 | preferLocalBuild = true;
270 | } (''
271 | mkdir -p $out
272 | cp -v ${udev}/lib/systemd/network/*.link $out/
273 | '' + (
274 | let
275 | links = filterAttrs (n: v: hasSuffix ".link" n) config.systemd.network.units;
276 | files = mapAttrsToList (n: v: "${v.unit}/${n}") links;
277 | in
278 | concatMapStringsSep "\n" (file: "cp -v ${file} $out/") files
279 | ));
280 |
281 | udevRules = pkgs.runCommand "udev-rules" {
282 | allowedReferences = [ extraUtils ];
283 | preferLocalBuild = true;
284 | } ''
285 | mkdir -p $out
286 |
287 | cp -v ${udev}/lib/udev/rules.d/60-cdrom_id.rules $out/
288 | cp -v ${udev}/lib/udev/rules.d/60-persistent-storage.rules $out/
289 | cp -v ${udev}/lib/udev/rules.d/75-net-description.rules $out/
290 | cp -v ${udev}/lib/udev/rules.d/80-drivers.rules $out/
291 | cp -v ${udev}/lib/udev/rules.d/80-net-setup-link.rules $out/
292 | cp -v ${pkgs.lvm2}/lib/udev/rules.d/*.rules $out/
293 | ${config.boot.initrd.extraUdevRulesCommands}
294 |
295 | for i in $out/*.rules; do
296 | substituteInPlace $i \
297 | --replace ata_id ${extraUtils}/bin/ata_id \
298 | --replace scsi_id ${extraUtils}/bin/scsi_id \
299 | --replace cdrom_id ${extraUtils}/bin/cdrom_id \
300 | --replace ${pkgs.coreutils}/bin/basename ${extraUtils}/bin/basename \
301 | --replace ${pkgs.util-linux}/bin/blkid ${extraUtils}/bin/blkid \
302 | --replace ${getBin pkgs.lvm2}/bin ${extraUtils}/bin \
303 | --replace ${pkgs.mdadm}/sbin ${extraUtils}/sbin \
304 | --replace ${pkgs.bash}/bin/sh ${extraUtils}/bin/sh \
305 | --replace ${udev} ${extraUtils}
306 | done
307 |
308 | # Work around a bug in QEMU, which doesn't implement the "READ
309 | # DISC INFORMATION" SCSI command:
310 | # https://bugzilla.redhat.com/show_bug.cgi?id=609049
311 | # As a result, `cdrom_id' doesn't print
312 | # ID_CDROM_MEDIA_TRACK_COUNT_DATA, which in turn prevents the
313 | # /dev/disk/by-label symlinks from being created. We need these
314 | # in the NixOS installation CD, so use ID_CDROM_MEDIA in the
315 | # corresponding udev rules for now. This was the behaviour in
316 | # udev <= 154. See also
317 | # http://www.spinics.net/lists/hotplug/msg03935.html
318 | substituteInPlace $out/60-persistent-storage.rules \
319 | --replace ID_CDROM_MEDIA_TRACK_COUNT_DATA ID_CDROM_MEDIA
320 | ''; # */
321 |
322 |
323 | # The init script of boot stage 1 (loading kernel modules for
324 | # mounting the root FS).
325 | bootStage1 = pkgs.substituteAll {
326 | src = ./stage-1-init-silent.sh;
327 |
328 | shell = "${extraUtils}/bin/ash";
329 |
330 | isExecutable = true;
331 |
332 | postInstall = ''
333 | echo checking syntax
334 | # check both with bash
335 | ${pkgs.buildPackages.bash}/bin/sh -n $target
336 | # and with ash shell, just in case
337 | ${pkgs.buildPackages.busybox}/bin/ash -n $target
338 | '';
339 |
340 | inherit linkUnits udevRules extraUtils modulesClosure;
341 |
342 | inherit (config.boot) resumeDevice;
343 |
344 | inherit (config.system.build) earlyMountScript;
345 |
346 | inherit (config.boot.initrd) checkJournalingFS verbose
347 | preLVMCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules;
348 |
349 | resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
350 | (filter (sd: hasPrefix "/dev/" sd.device && !sd.randomEncryption.enable
351 | # Don't include zram devices
352 | && !(hasPrefix "/dev/zram" sd.device)
353 | ) config.swapDevices);
354 |
355 | fsInfo =
356 | let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType (builtins.concatStringsSep "," fs.options) ];
357 | in pkgs.writeText "initrd-fsinfo" (concatStringsSep "\n" (concatMap f fileSystems));
358 |
359 | setHostId = optionalString (config.networking.hostId != null) ''
360 | hi="${config.networking.hostId}"
361 | ${if pkgs.stdenv.isBigEndian then ''
362 | echo -ne "\x''${hi:0:2}\x''${hi:2:2}\x''${hi:4:2}\x''${hi:6:2}" > /etc/hostid
363 | '' else ''
364 | echo -ne "\x''${hi:6:2}\x''${hi:4:2}\x''${hi:2:2}\x''${hi:0:2}" > /etc/hostid
365 | ''}
366 | '';
367 | };
368 |
369 |
370 | # The closure of the init script of boot stage 1 is what we put in
371 | # the initial RAM disk.
372 | initialRamdisk = pkgs.makeInitrd {
373 | name = "initrd-${kernel-name}";
374 | inherit (config.boot.initrd) compressor compressorArgs prepend;
375 |
376 | contents =
377 | [ { object = bootStage1;
378 | symlink = "/init";
379 | }
380 | { object = pkgs.writeText "mdadm.conf" config.boot.initrd.services.swraid.mdadmConf;
381 | symlink = "/etc/mdadm.conf";
382 | }
383 | { object = pkgs.runCommand "initrd-kmod-blacklist-ubuntu" {
384 | src = "${pkgs.kmod-blacklist-ubuntu}/modprobe.conf";
385 | preferLocalBuild = true;
386 | } ''
387 | target=$out
388 | ${pkgs.buildPackages.perl}/bin/perl -0pe 's/## file: iwlwifi.conf(.+?)##/##/s;' $src > $out
389 | '';
390 | symlink = "/etc/modprobe.d/ubuntu.conf";
391 | }
392 | { object = config.environment.etc."modprobe.d/nixos.conf".source;
393 | symlink = "/etc/modprobe.d/nixos.conf";
394 | }
395 | { object = pkgs.kmod-debian-aliases;
396 | symlink = "/etc/modprobe.d/debian.conf";
397 | }
398 | ] ++ lib.optionals config.services.multipath.enable [
399 | { object = pkgs.runCommand "multipath.conf" {
400 | src = config.environment.etc."multipath.conf".text;
401 | preferLocalBuild = true;
402 | } ''
403 | target=$out
404 | printf "$src" > $out
405 | substituteInPlace $out \
406 | --replace ${config.services.multipath.package}/lib ${extraUtils}/lib
407 | '';
408 | symlink = "/etc/multipath.conf";
409 | }
410 | ] ++ (lib.mapAttrsToList
411 | (symlink: options:
412 | {
413 | inherit symlink;
414 | object = options.source;
415 | }
416 | )
417 | config.boot.initrd.extraFiles);
418 | };
419 |
420 | # Script to add secret files to the initrd at bootloader update time
421 | initialRamdiskSecretAppender =
422 | let
423 | compressorExe = initialRamdisk.compressorExecutableFunction pkgs;
424 | in pkgs.writeScriptBin "append-initrd-secrets"
425 | ''
426 | #!${pkgs.bash}/bin/bash -e
427 | function usage {
428 | echo "USAGE: $0 INITRD_FILE" >&2
429 | echo "Appends this configuration's secrets to INITRD_FILE" >&2
430 | }
431 |
432 | if [ $# -ne 1 ]; then
433 | usage
434 | exit 1
435 | fi
436 |
437 | if [ "$1"x = "--helpx" ]; then
438 | usage
439 | exit 0
440 | fi
441 |
442 | ${lib.optionalString (config.boot.initrd.secrets == {})
443 | "exit 0"}
444 |
445 | export PATH=${pkgs.coreutils}/bin:${pkgs.libarchive}/bin:${pkgs.gzip}/bin:${pkgs.findutils}/bin
446 |
447 | function cleanup {
448 | if [ -n "$tmp" -a -d "$tmp" ]; then
449 | rm -fR "$tmp"
450 | fi
451 | }
452 | trap cleanup EXIT
453 |
454 | tmp=$(mktemp -d ''${TMPDIR:-/tmp}/initrd-secrets.XXXXXXXXXX)
455 |
456 | ${lib.concatStringsSep "\n" (mapAttrsToList (dest: source:
457 | let source' = if source == null then dest else toString source; in
458 | ''
459 | mkdir -p $(dirname "$tmp/.initrd-secrets/${dest}")
460 | cp -a ${source'} "$tmp/.initrd-secrets/${dest}"
461 | ''
462 | ) config.boot.initrd.secrets)
463 | }
464 |
465 | (cd "$tmp" && find . -print0 | sort -z | bsdtar --uid 0 --gid 0 -cnf - -T - | bsdtar --null -cf - --format=newc @-) | \
466 | ${compressorExe} ${lib.escapeShellArgs initialRamdisk.compressorArgs} >> "$1"
467 | '';
468 |
469 | in
470 |
471 | {
472 | options = {
473 |
474 | boot.resumeDevice = mkOption {
475 | type = types.str;
476 | default = "";
477 | example = "/dev/sda3";
478 | description = lib.mdDoc ''
479 | Device for manual resume attempt during boot. This should be used primarily
480 | if you want to resume from file. If left empty, the swap partitions are used.
481 | Specify here the device where the file resides.
482 | You should also use {var}`boot.kernelParams` to specify
483 | `«resume_offset»`.
484 | '';
485 | };
486 |
487 | boot.initrd.enable = mkOption {
488 | type = types.bool;
489 | default = !config.boot.isContainer;
490 | defaultText = literalExpression "!config.boot.isContainer";
491 | description = lib.mdDoc ''
492 | Whether to enable the NixOS initial RAM disk (initrd). This may be
493 | needed to perform some initialisation tasks (like mounting
494 | network/encrypted file systems) before continuing the boot process.
495 | '';
496 | };
497 |
498 | boot.initrd.extraFiles = mkOption {
499 | default = { };
500 | type = types.attrsOf
501 | (types.submodule {
502 | options = {
503 | source = mkOption {
504 | type = types.package;
505 | description = lib.mdDoc "The object to make available inside the initrd.";
506 | };
507 | };
508 | });
509 | description = lib.mdDoc ''
510 | Extra files to link and copy in to the initrd.
511 | '';
512 | };
513 |
514 | boot.initrd.prepend = mkOption {
515 | default = [ ];
516 | type = types.listOf types.str;
517 | description = lib.mdDoc ''
518 | Other initrd files to prepend to the final initrd we are building.
519 | '';
520 | };
521 |
522 | boot.initrd.checkJournalingFS = mkOption {
523 | default = true;
524 | type = types.bool;
525 | description = lib.mdDoc ''
526 | Whether to run {command}`fsck` on journaling filesystems such as ext3.
527 | '';
528 | };
529 |
530 | boot.initrd.preLVMCommands = mkOption {
531 | default = "";
532 | type = types.lines;
533 | description = lib.mdDoc ''
534 | Shell commands to be executed immediately before LVM discovery.
535 | '';
536 | };
537 |
538 | boot.initrd.preDeviceCommands = mkOption {
539 | default = "";
540 | type = types.lines;
541 | description = lib.mdDoc ''
542 | Shell commands to be executed before udev is started to create
543 | device nodes.
544 | '';
545 | };
546 |
547 | boot.initrd.postDeviceCommands = mkOption {
548 | default = "";
549 | type = types.lines;
550 | description = lib.mdDoc ''
551 | Shell commands to be executed immediately after stage 1 of the
552 | boot has loaded kernel modules and created device nodes in
553 | {file}`/dev`.
554 | '';
555 | };
556 |
557 | boot.initrd.postMountCommands = mkOption {
558 | default = "";
559 | type = types.lines;
560 | description = lib.mdDoc ''
561 | Shell commands to be executed immediately after the stage 1
562 | filesystems have been mounted.
563 | '';
564 | };
565 |
566 | boot.initrd.preFailCommands = mkOption {
567 | default = "";
568 | type = types.lines;
569 | description = lib.mdDoc ''
570 | Shell commands to be executed before the failure prompt is shown.
571 | '';
572 | };
573 |
574 | boot.initrd.extraUtilsCommands = mkOption {
575 | internal = true;
576 | default = "";
577 | type = types.lines;
578 | description = lib.mdDoc ''
579 | Shell commands to be executed in the builder of the
580 | extra-utils derivation. This can be used to provide
581 | additional utilities in the initial ramdisk.
582 | '';
583 | };
584 |
585 | boot.initrd.extraUtilsCommandsTest = mkOption {
586 | internal = true;
587 | default = "";
588 | type = types.lines;
589 | description = lib.mdDoc ''
590 | Shell commands to be executed in the builder of the
591 | extra-utils derivation after patchelf has done its
592 | job. This can be used to test additional utilities
593 | copied in extraUtilsCommands.
594 | '';
595 | };
596 |
597 | boot.initrd.extraUdevRulesCommands = mkOption {
598 | internal = true;
599 | default = "";
600 | type = types.lines;
601 | description = lib.mdDoc ''
602 | Shell commands to be executed in the builder of the
603 | udev-rules derivation. This can be used to add
604 | additional udev rules in the initial ramdisk.
605 | '';
606 | };
607 |
608 | boot.initrd.compressor = mkOption {
609 | default = (
610 | if lib.versionAtLeast config.boot.kernelPackages.kernel.version "5.9"
611 | then "zstd"
612 | else "gzip"
613 | );
614 | defaultText = literalMD "`zstd` if the kernel supports it (5.9+), `gzip` if not";
615 | type = types.either types.str (types.functionTo types.str);
616 | description = lib.mdDoc ''
617 | The compressor to use on the initrd image. May be any of:
618 |
619 | - The name of one of the predefined compressors, see {file}`pkgs/build-support/kernel/initrd-compressor-meta.nix` for the definitions.
620 | - A function which, given the nixpkgs package set, returns the path to a compressor tool, e.g. `pkgs: "''${pkgs.pigz}/bin/pigz"`
621 | - (not recommended, because it does not work when cross-compiling) the full path to a compressor tool, e.g. `"''${pkgs.pigz}/bin/pigz"`
622 |
623 | The given program should read data from stdin and write it to stdout compressed.
624 | '';
625 | example = "xz";
626 | };
627 |
628 | boot.initrd.compressorArgs = mkOption {
629 | default = null;
630 | type = types.nullOr (types.listOf types.str);
631 | description = lib.mdDoc "Arguments to pass to the compressor for the initrd image, or null to use the compressor's defaults.";
632 | };
633 |
634 | boot.initrd.secrets = mkOption
635 | { default = {};
636 | type = types.attrsOf (types.nullOr types.path);
637 | description =
638 | lib.mdDoc ''
639 | Secrets to append to the initrd. The attribute name is the
640 | path the secret should have inside the initrd, the value
641 | is the path it should be copied from (or null for the same
642 | path inside and out).
643 | '';
644 | example = literalExpression
645 | ''
646 | { "/etc/dropbear/dropbear_rsa_host_key" =
647 | ./secret-dropbear-key;
648 | }
649 | '';
650 | };
651 |
652 | boot.initrd.supportedFilesystems = mkOption {
653 | default = [ ];
654 | example = [ "btrfs" ];
655 | type = types.listOf types.str;
656 | description = lib.mdDoc "Names of supported filesystem types in the initial ramdisk.";
657 | };
658 |
659 | boot.initrd.verbose = mkOption {
660 | default = false;
661 | type = types.bool;
662 | description =
663 | lib.mdDoc ''
664 | Verbosity of the initrd. Please note that disabling verbosity removes
665 | only the mandatory messages generated by the NixOS scripts. For a
666 | completely silent boot, you might also want to set the two following
667 | configuration options:
668 |
669 | - `boot.consoleLogLevel = 0;`
670 | - `boot.kernelParams = [ "quiet" "udev.log_level=3" ];`
671 | '';
672 | };
673 |
674 | boot.loader.supportsInitrdSecrets = mkOption
675 | { internal = true;
676 | default = false;
677 | type = types.bool;
678 | description =
679 | lib.mdDoc ''
680 | Whether the bootloader setup runs append-initrd-secrets.
681 | If not, any needed secrets must be copied into the initrd
682 | and thus added to the store.
683 | '';
684 | };
685 |
686 | fileSystems = mkOption {
687 | type = with lib.types; attrsOf (submodule {
688 | options.neededForBoot = mkOption {
689 | default = false;
690 | type = types.bool;
691 | description = lib.mdDoc ''
692 | If set, this file system will be mounted in the initial ramdisk.
693 | Note that the file system will always be mounted in the initial
694 | ramdisk if its mount point is one of the following:
695 | ${concatStringsSep ", " (
696 | forEach utils.pathsNeededForBoot (i: "{file}`${i}`")
697 | )}.
698 | '';
699 | };
700 | });
701 | };
702 |
703 | };
704 |
705 | config = mkIf config.boot.initrd.enable {
706 | assertions = [
707 | { assertion = any (fs: fs.mountPoint == "/") fileSystems;
708 | message = "The ‘fileSystems’ option does not specify your root file system.";
709 | }
710 | { assertion = let inherit (config.boot) resumeDevice; in
711 | resumeDevice == "" || builtins.substring 0 1 resumeDevice == "/";
712 | message = "boot.resumeDevice has to be an absolute path."
713 | + " Old \"x:y\" style is no longer supported.";
714 | }
715 | # TODO: remove when #85000 is fixed
716 | { assertion = !config.boot.loader.supportsInitrdSecrets ->
717 | all (source:
718 | builtins.isPath source ||
719 | (builtins.isString source && hasPrefix builtins.storeDir source))
720 | (attrValues config.boot.initrd.secrets);
721 | message = ''
722 | boot.loader.initrd.secrets values must be unquoted paths when
723 | using a bootloader that doesn't natively support initrd
724 | secrets, e.g.:
725 |
726 | boot.initrd.secrets = {
727 | "/etc/secret" = /path/to/secret;
728 | };
729 |
730 | Note that this will result in all secrets being stored
731 | world-readable in the Nix store!
732 | '';
733 | }
734 | ];
735 |
736 | system.build = mkMerge [
737 | { inherit bootStage1 initialRamdiskSecretAppender extraUtils; }
738 |
739 | # generated in nixos/modules/system/boot/systemd/initrd.nix
740 | (mkIf (!config.boot.initrd.systemd.enable) { inherit initialRamdisk; })
741 | ];
742 |
743 | system.requiredKernelConfig = with config.lib.kernelConfig; [
744 | (isYes "TMPFS")
745 | (isYes "BLK_DEV_INITRD")
746 | ];
747 |
748 | boot.initrd.supportedFilesystems = map (fs: fs.fsType) fileSystems;
749 | };
750 |
751 | imports = [
752 | (mkRenamedOptionModule [ "boot" "initrd" "mdadmConf" ] [ "boot" "initrd" "services" "swraid" "mdadmConf" ])
753 | ];
754 | }
755 |
--------------------------------------------------------------------------------
/nixos/silent-boot/stage-2-init-silent.sh:
--------------------------------------------------------------------------------
1 | #! @shell@
2 |
3 | systemConfig=@systemConfig@
4 |
5 | export HOME=/root PATH="@path@"
6 |
7 |
8 | if [ "${IN_NIXOS_SYSTEMD_STAGE1:-}" != true ]; then
9 | # Process the kernel command line.
10 | for o in $(>>\e[0m"
23 | #echo
24 |
25 |
26 | # Normally, stage 1 mounts the root filesystem read/writable.
27 | # However, in some environments, stage 2 is executed directly, and the
28 | # root is read-only. So make it writable here.
29 | if [ -z "$container" ]; then
30 | mount -n -o remount,rw none /
31 | fi
32 | fi
33 |
34 |
35 | # Likewise, stage 1 mounts /proc, /dev and /sys, so if we don't have a
36 | # stage 1, we need to do that here.
37 | if [ ! -e /proc/1 ]; then
38 | specialMount() {
39 | local device="$1"
40 | local mountPoint="$2"
41 | local options="$3"
42 | local fsType="$4"
43 |
44 | # We must not overwrite this mount because it's bind-mounted
45 | # from stage 1's /run
46 | if [ "${IN_NIXOS_SYSTEMD_STAGE1:-}" = true ] && [ "${mountPoint}" = /run ]; then
47 | return
48 | fi
49 |
50 | install -m 0755 -d "$mountPoint"
51 | mount -n -t "$fsType" -o "$options" "$device" "$mountPoint"
52 | }
53 | source @earlyMountScript@
54 | fi
55 |
56 |
57 | #if [ "${IN_NIXOS_SYSTEMD_STAGE1:-}" = true ]; then
58 | # echo "booting system configuration ${systemConfig}"
59 | #else
60 | # echo "booting system configuration $systemConfig" > /dev/kmsg
61 | #fi
62 |
63 |
64 | # Make /nix/store a read-only bind mount to enforce immutability of
65 | # the Nix store. Note that we can't use "chown root:nixbld" here
66 | # because users/groups might not exist yet.
67 | # Silence chown/chmod to fail gracefully on a readonly filesystem
68 | # like squashfs.
69 | chown -f 0:30000 /nix/store
70 | chmod -f 1775 /nix/store
71 | if [ -n "@readOnlyStore@" ]; then
72 | if ! [[ "$(findmnt --noheadings --output OPTIONS /nix/store)" =~ ro(,|$) ]]; then
73 | if [ -z "$container" ]; then
74 | mount --bind /nix/store /nix/store
75 | else
76 | mount --rbind /nix/store /nix/store
77 | fi
78 | mount -o remount,ro,bind /nix/store
79 | fi
80 | fi
81 |
82 |
83 | if [ "${IN_NIXOS_SYSTEMD_STAGE1:-}" != true ]; then
84 | # Use /etc/resolv.conf supplied by systemd-nspawn, if applicable.
85 | if [ -n "@useHostResolvConf@" ] && [ -e /etc/resolv.conf ]; then
86 | resolvconf -m 1000 -a host &1 {logErrFd}>&2
93 | if test -w /dev/kmsg; then
94 | exec > >(tee -i /proc/self/fd/"$logOutFd" | while read -r line; do
95 | if test -n "$line"; then
96 | echo "<7>stage-2-init: $line" > /dev/kmsg
97 | fi
98 | done) 2>&1
99 | else
100 | mkdir -p /run/log
101 | exec > >(tee -i /run/log/stage-2-init.log) 2>&1
102 | fi
103 | fi
104 |
105 |
106 | # Required by the activation script
107 | install -m 0755 -d /etc /etc/nixos
108 | install -m 01777 -d /tmp
109 |
110 |
111 | # Run the script that performs all configuration activation that does
112 | # not have to be done at boot time.
113 | #echo "running activation script..."
114 | $systemConfig/activate
115 |
116 |
117 | # Record the boot configuration.
118 | ln -sfn "$systemConfig" /run/booted-system
119 |
120 |
121 | # Run any user-specified commands.
122 | @shell@ @postBootCommands@
123 |
124 |
125 | # Ensure systemd doesn't try to populate /etc, by forcing its first-boot
126 | # heuristic off. It doesn't matter what's in /etc/machine-id for this purpose,
127 | # and systemd will immediately fill in the file when it starts, so just
128 | # creating it is enough. This `: >>` pattern avoids forking and avoids changing
129 | # the mtime if the file already exists.
130 | : >> /etc/machine-id
131 |
132 |
133 | # No need to restore the stdout/stderr streams we never redirected and
134 | # especially no need to start systemd
135 | if [ "${IN_NIXOS_SYSTEMD_STAGE1:-}" != true ]; then
136 | # Reset the logging file descriptors.
137 | exec 1>&$logOutFd 2>&$logErrFd
138 | exec {logOutFd}>&- {logErrFd}>&-
139 |
140 |
141 | # Start systemd in a clean environment.
142 | #echo "starting systemd..."
143 | exec @systemdExecutable@ "$@"
144 | fi
145 |
--------------------------------------------------------------------------------
/nixos/silent-boot/stage-2-silent.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | with lib;
4 |
5 | let
6 |
7 | useHostResolvConf = config.networking.resolvconf.enable && config.networking.useHostResolvConf;
8 |
9 | bootStage2 = pkgs.substituteAll {
10 | src = ./stage-2-init-silent.sh;
11 | shellDebug = "${pkgs.bashInteractive}/bin/bash";
12 | shell = "${pkgs.bash}/bin/bash";
13 | inherit (config.boot) systemdExecutable extraSystemdUnitPaths;
14 | isExecutable = true;
15 | inherit (config.nix) readOnlyStore;
16 | inherit useHostResolvConf;
17 | inherit (config.system.build) earlyMountScript;
18 | path = lib.makeBinPath ([
19 | pkgs.coreutils
20 | pkgs.util-linux
21 | ] ++ lib.optional useHostResolvConf pkgs.openresolv);
22 | postBootCommands = pkgs.writeText "local-cmds"
23 | ''
24 | ${config.boot.postBootCommands}
25 | ${config.powerManagement.powerUpCommands}
26 | '';
27 | };
28 |
29 | in
30 |
31 | {
32 | options = {
33 |
34 | boot = {
35 |
36 | postBootCommands = mkOption {
37 | default = "";
38 | example = "rm -f /var/log/messages";
39 | type = types.lines;
40 | description = lib.mdDoc ''
41 | Shell commands to be executed just before systemd is started.
42 | '';
43 | };
44 |
45 | systemdExecutable = mkOption {
46 | default = "/run/current-system/systemd/lib/systemd/systemd";
47 | type = types.str;
48 | description = lib.mdDoc ''
49 | The program to execute to start systemd.
50 | '';
51 | };
52 |
53 | extraSystemdUnitPaths = mkOption {
54 | default = [];
55 | type = types.listOf types.str;
56 | description = lib.mdDoc ''
57 | Additional paths that get appended to the SYSTEMD_UNIT_PATH environment variable
58 | that can contain mutable unit files.
59 | '';
60 | };
61 | };
62 |
63 | };
64 |
65 |
66 | config = {
67 |
68 | system.build.bootStage2 = bootStage2;
69 |
70 | };
71 | }
72 |
--------------------------------------------------------------------------------
/nixos/wayland/general.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, ...}:
2 | {
3 | environment.extraInit = ''
4 | #Turn off gui for ssh auth
5 | unset -v SSH_ASKPASS
6 | '';
7 | users.users.simon.extraGroups = [ "video" ];
8 | programs.light.enable = true;
9 | }
10 |
--------------------------------------------------------------------------------
/nixos/wayland/login-manager.nix:
--------------------------------------------------------------------------------
1 | {config, pkgs, ...}:
2 | {
3 | services.greetd = {
4 | enable = true;
5 | settings = rec {
6 | initial_session = {
7 | command = "${pkgs.sway}/bin/sway";
8 | user = "simon";
9 | };
10 | default_session = initial_session;
11 | };
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/nixos/wayland/sway/config:
--------------------------------------------------------------------------------
1 | # Logo key. Use Mod1 for Alt.
2 | set $mod Mod4
3 | # Home row direction keys, like vim
4 | set $left h
5 | set $down j
6 | set $up k
7 | set $right l
8 |
9 | # Terminal
10 | set $term alacritty
11 |
12 | # Colors
13 | # class border backgr. text indicator child_border
14 | client.focused #999999 #5f676a #999999 #999999 #999999
15 | client.focused_inactive #999999 #5f676a #999999 #999999 #999999
16 | client.unfocused #333333 #222222 #888888 #292d2e #1f1e1e
17 | client.urgent #999999 #5f676a #999999 #999999 #999999
18 | client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c
19 |
20 | client.background #ffffff
21 |
22 | default_border pixel 1
23 |
24 | # Wallpaper
25 | output * bg /home/simon/nixos-config/wallpaper.png fill
26 |
27 | # Key bindings
28 | # Start a terminal
29 | bindsym $mod+Return exec $term
30 |
31 | # Kill focused window
32 | bindsym $mod+Shift+q kill
33 |
34 | # Drag floating windows by holding down $mod and left mouse button.
35 | # Resize them with right mouse button + $mod.
36 | # Despite the name, also works for non-floating windows.
37 | # Change normal to inverse to use left mouse button for resizing and right
38 | # mouse button for dragging.
39 | floating_modifier $mod normal
40 |
41 | # Reload the configuration file
42 | bindsym $mod+Shift+c reload
43 |
44 | # Screenshots
45 | bindsym $mod+s exec grim -g "$(slurp)" ~/Desktop/Pictures/Screenshots/Screenshot-$(date +'%H:%M:%S.png')
46 |
47 |
48 | # Moving around:
49 | # Move your focus around
50 | bindsym $mod+$left focus left
51 | bindsym $mod+$down focus down
52 | bindsym $mod+$up focus up
53 | bindsym $mod+$right focus right
54 | # Or use $mod+[up|down|left|right]
55 | bindsym $mod+Left focus left
56 | bindsym $mod+Down focus down
57 | bindsym $mod+Up focus up
58 | bindsym $mod+Right focus right
59 |
60 | # Move the focused window with the same, but add Shift
61 | bindsym $mod+Shift+$left move left
62 | bindsym $mod+Shift+$down move down
63 | bindsym $mod+Shift+$up move up
64 | bindsym $mod+Shift+$right move right
65 | # Ditto, with arrow keys
66 | bindsym $mod+Shift+Left move left
67 | bindsym $mod+Shift+Down move down
68 | bindsym $mod+Shift+Up move up
69 | bindsym $mod+Shift+Right move right
70 |
71 | # Workspaces:
72 | # Switch to workspace
73 | bindsym $mod+1 workspace number 1
74 | bindsym $mod+2 workspace number 2
75 | bindsym $mod+3 workspace number 3
76 | bindsym $mod+4 workspace number 4
77 | # Move focused container to workspace
78 | bindsym $mod+Shift+1 move container to workspace number 1
79 | bindsym $mod+Shift+2 move container to workspace number 2
80 | bindsym $mod+Shift+3 move container to workspace number 3
81 | bindsym $mod+Shift+4 move container to workspace number 4
82 |
83 | # Media keys
84 | # Brightness
85 | bindsym XF86MonBrightnessDown exec light -U 10
86 | bindsym XF86MonBrightnessUp exec light -A 10
87 |
88 | # Volume
89 | bindsym XF86AudioMute exec 'pulsemixer --toggle-mute'
90 |
91 | # Git token (paste it into "")
92 | bindsym $mod+g exec wl-copy ""
93 |
94 | # Layout stuff:
95 | # Split verticaly =
96 | bindsym $mod+v splitv
97 |
98 | # Split horizontaly ||
99 | #bindsym $mod+h splith
100 |
101 | # Make the current focus fullscreen
102 | bindsym $mod+f fullscreen
103 |
104 | # Toggle the current focus between tiling and floating mode
105 | bindsym $mod+Shift+space floating toggle
106 |
107 | # Resizing containers:
108 | mode "resize" {
109 | bindsym $left resize shrink width 10px
110 | bindsym $down resize grow height 10px
111 | bindsym $up resize shrink height 10px
112 | bindsym $right resize grow width 10px
113 |
114 | # Ditto, with arrow keys
115 | bindsym Left resize shrink width 10px
116 | bindsym Down resize grow height 10px
117 | bindsym Up resize shrink height 10px
118 | bindsym Right resize grow width 10px
119 |
120 | # Return to default mode
121 | bindsym Return mode "default"
122 | bindsym Escape mode "default"
123 | }
124 | bindsym $mod+r mode "resize"
125 |
126 | input "type:touchpad" {
127 | dwt enabled
128 | tap enabled
129 | middle_emulation enabled
130 | }
131 |
132 | input "1:1:AT_Translated_Set_2_keyboard" {
133 | xkb_layout "us,sk"
134 | }
135 |
136 | # Waybar
137 | exec waybar &
138 |
139 | # Startup
140 | assign [app_id="terminal1"] workspace number 2
141 | assign [app_id="qutebrowser"] workspace number 3
142 | assign [app_id="codium-url-handler"] workspace number 4
143 |
144 | exec alacritty --class "terminal1" &
145 | exec qutebrowser &
146 | exec codium --ozone-platform-hint=auto &
147 |
148 | #Window rules
149 | for_window [app_id="com.github.finefindus.eyedropper"] floating enable
150 |
151 | # Fixes
152 | exec dbus-sway-environment
153 | exec configure-gtk
154 | exec systemctl --user import-environment
155 |
156 | include @sysconfdir@/sway/config.d/*
157 |
--------------------------------------------------------------------------------
/nixos/wayland/window-manager.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 |
3 | let
4 | dbus-sway-environment = pkgs.writeTextFile {
5 | name = "dbus-sway-environment";
6 | destination = "/bin/dbus-sway-enviroment";
7 | executable = true;
8 |
9 | text = ''
10 | dbus-update-activation-enviroment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
11 | systemctl --user stop pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
12 | systemctl --user start pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
13 | '';
14 | };
15 |
16 | configure-gtk = pkgs.writeTextFile {
17 | name = "configure-gtk";
18 | destination = "/bin/configure/-gtk";
19 | executable = true;
20 | text =
21 | let
22 | schema = pkgs.gsettings-desktop-schemas;
23 | datadir = "${schema}/share/gsetting-schemas/${schema.name}";
24 | in
25 | ''
26 | export XDG_DATA_DIRS=${datadir}:$XDG_DATA_DIRS
27 | gnome_schema=org.gnome.desktop.interface
28 | gsettings set $gnome_schema gtk-theme 'WhiteSur-dark'
29 | gsettings set $gnome_schema cursor-theme 'capitaine-cursors-white'
30 | '';
31 | };
32 |
33 | in
34 | {
35 | environment.systemPackages = with pkgs; [
36 | alacritty
37 | sway
38 | dbus-sway-environment
39 | configure-gtk
40 | wayland
41 | xdg-utils
42 | glib
43 | whitesur-icon-theme
44 | grim
45 | slurp
46 | wl-clipboard
47 | capitaine-cursors
48 | ];
49 |
50 | services.dbus.enable = true;
51 |
52 | xdg.portal = {
53 | enable = true;
54 | wlr.enable = true;
55 | extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
56 | };
57 |
58 | programs.sway = {
59 | enable = true;
60 | wrapperFeatures.gtk = true;
61 | };
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smravec/nixos-config/f32f40ad80b38222493df36b4e59d79484e44def/preview.png
--------------------------------------------------------------------------------
/wallpaper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smravec/nixos-config/f32f40ad80b38222493df36b4e59d79484e44def/wallpaper.png
--------------------------------------------------------------------------------