├── .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 "<<< NixOS Stage 1 >>>" 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 --------------------------------------------------------------------------------