From d011815d0547061530cc6ef088a600c00891807d Mon Sep 17 00:00:00 2001 From: Sijmen Date: Sun, 18 Jun 2023 16:18:01 +0200 Subject: [PATCH] Bunch of changes I really cant be bothered to write a commit message for --- common/configuration.nix | 27 ++- common/home-manager.nix | 373 +------------------------------ common/home-manager/accounts.nix | 39 ++++ common/home-manager/gtk.nix | 1 + common/home-manager/home.nix | 37 ++- common/home-manager/programs.nix | 283 +++++++++++++++++++++++ common/home-manager/services.nix | 34 +++ common/home-manager/systemd.nix | 11 + common/home-manager/wayland.nix | 88 ++++++++ common/nvim.lua | 2 + framework/configuration.nix | 110 +++++---- framework/dmenu-bluetooth | 357 +++++++++++++++++++++++++++++ framework/nmcli_dmenu | 309 +++++++++++++++++++++++++ framework/sources.json | 27 +++ framework/sources.nix | 194 ++++++++++++++++ 15 files changed, 1470 insertions(+), 422 deletions(-) create mode 100644 common/home-manager/accounts.nix create mode 100644 common/home-manager/programs.nix create mode 100644 common/home-manager/services.nix create mode 100644 common/home-manager/systemd.nix create mode 100644 common/home-manager/wayland.nix create mode 100755 framework/dmenu-bluetooth create mode 100755 framework/nmcli_dmenu create mode 100644 framework/sources.json create mode 100644 framework/sources.nix diff --git a/common/configuration.nix b/common/configuration.nix index 2ecfa44..7974897 100644 --- a/common/configuration.nix +++ b/common/configuration.nix @@ -5,7 +5,18 @@ ./home-manager.nix ]; - nix.settings.experimental-features = [ "nix-command" "flakes" ]; + nix = { + settings = { + experimental-features = [ "nix-command" "flakes" ]; + auto-optimise-store = true; + }; + gc = { + automatic = true; + dates = "daily"; + options = "--delete-older-than 14d"; + }; + }; + nixpkgs.config.allowUnfree = true; time.timeZone = "Europe/Amsterdam"; @@ -36,8 +47,11 @@ isNormalUser = true; extraGroups = [ "wheel" "docker" "wireshark" "video" "dialout" "libvirt" ]; description = "Sijmen"; + shell = pkgs.zsh; }; + programs.zsh.enable = true; + services = { pipewire.enable = true; gvfs.enable = true; @@ -58,18 +72,17 @@ }; }; - syncthing = { - enable = true; - user = "sijmen"; - dataDir = config.users.users.sijmen.home; - }; + #syncthing = { + #enable = true; + #user = "sijmen"; + #dataDir = config.users.users.sijmen.home; + #}; }; fonts.fonts = with pkgs; [ corefonts dejavu_fonts iosevka - nerdfonts noto-fonts noto-fonts-cjk noto-fonts-emoji diff --git a/common/home-manager.nix b/common/home-manager.nix index 1914b5a..326816c 100644 --- a/common/home-manager.nix +++ b/common/home-manager.nix @@ -1,381 +1,20 @@ { config, pkgs, lib, ... }: { - imports = [ - - ]; + imports = []; home-manager.users.sijmen = { imports = [ ./home-manager/home.nix ./home-manager/gtk.nix + ./home-manager/systemd.nix + ./home-manager/programs.nix + ./home-manager/wayland.nix + ./home-manager/services.nix + ./home-manager/accounts.nix ]; nixpkgs.config.allowUnfree = true; home.stateVersion = config.system.stateVersion; - - programs = { - bash = { - enable = true; - initExtra = '' - source ${pkgs.fetchurl { - url = "https://raw.githubusercontent.com/rupa/z/b82ac78a2d4457d2ca09973332638f123f065fd1/z.sh"; - sha256 = "98e4438cd31afb3ce594130335e7fbd8be5d75d9a53e4f3e084d97e6b8d19b0e"; - }} - - # SSH agent - eval $(${pkgs.openssh}/bin/ssh-agent) > /dev/null - trap 'test -n "$SSH_AUTH_SOCK" && eval $(${pkgs.openssh}/bin/ssh-agent -k)' 0 - ''; - sessionVariables = { - PYTHON_KEYRING_BACKEND = "keyring.backends.null.Keyring"; - }; - }; - - firefox = { - enable = true; - package = pkgs.firefox-wayland; - }; - - ncmpcpp = { - enable = true; - settings = { - colors_enabled = false; - }; - }; - - foot = { - enable = true; - settings = { - main = { - term = "xterm-256color"; - font = "Iosevka:size=12"; - }; - - colors = { - background = "fafafa"; - foreground = "383a42"; - - regular0 = "383a42"; - regular1 = "e45649"; - regular2 = "50a14f"; - regular3 = "c18401"; - regular4 = "0184bc"; - regular5 = "a626a4"; - regular6 = "0997b3"; - regular7 = "fafafa"; - - bright0 = "383a42"; - bright1 = "e45649"; - bright2 = "50a14f"; - bright3 = "c18401"; - bright4 = "0184bc"; - bright5 = "a626a4"; - bright6 = "0997b3"; - bright7 = "fafafa"; - }; - }; - }; - - git = { - enable = true; - lfs.enable = true; - package = pkgs.gitAndTools.gitFull; - - userName = "Sijmen"; - userEmail = "me@sijman.nl"; - - signing = { - signByDefault = true; - key = "0xDAF7821E067D9C48"; - }; - - extraConfig = { - fetch.prune = true; - init.defaultBranch = "main"; - pull.rebase = true; - push.autoSetupRemote = true; - safe.directory = [ "/etc/nixos" ]; - }; - }; - - mpv = { - enable = true; - config = { - script-opts = "ytdl_hook-ytdl_path=${pkgs.yt-dlp}/bin/yt-dlp"; - }; - }; - - neovim = { - enable = true; - vimAlias = true; - - extraConfig = '' - luafile /etc/nixos/common/nvim.lua - ''; - - extraPackages = with pkgs; [ - gcc - rnix-lsp - nodePackages.pyright - ]; - - plugins = with pkgs.vimPlugins; [ - bufferline-nvim - cmp-nvim-lsp - cmp_luasnip - ctrlp-vim - galaxyline-nvim - indentLine - leap-nvim - lualine-nvim - luasnip - neorg - nvim-cmp - nvim-colorizer-lua - nvim-lspconfig - nvim-tree-lua - nvim-treesitter.withAllGrammars - nvim-web-devicons - onehalf - pears-nvim - plenary-nvim - vim-closetag - vim-nix - vim-startify - vim-startuptime - ]; - }; - - tmux = { - enable = true; - prefix = "C-a"; - extraConfig = '' - set -g mouse on - set-option -g set-titles on - set-option -g set-titles-string "#W" - ''; - }; - - yt-dlp = { - enable = true; - settings = { - sponsorblock-mark = "sponsor,selfpromo,intro,outro,poi_highlight"; - }; - }; - - waybar = { - enable = true; - }; - - beets = { - enable = true; - settings = { - paths.default = "$albumartist/$year - $album%aunique{}/$track $title"; - }; - }; - - ssh = { - enable = true; - matchBlocks = { - # Home - "rpi" = { - user = "root"; - hostname = "cloud.sijmenschoon.nl"; - }; - "desktop" = { - user = "vijfhoek"; - hostname = "192.168.1.99"; - proxyJump = "cloud.sijmenschoon.nl"; - }; - "nas" = { - user = "sijmen"; - hostname = "192.168.1.123"; - proxyJump = "cloud.sijmenschoon.nl"; - }; - # Servers - "hermes" = { - user = "ubuntu"; - hostname = "hermes.sijmenschoon.nl"; - }; - # Scintilla - "linscin" = { - user = "sijmens"; - hostname = "linscin.scintilla.utwente.nl"; - }; - "britt" = { - user = "sijmens"; - hostname = "britt.scintilla.utwente.nl"; - proxyJump = "linscin"; - }; - "*.scintilla.utwente.nl" = { - user = "sijmens"; - }; - "*.scintilla.nl" = { - user = "sijmens"; - }; - # Uni - "xoc2" = { - user = "s2639149"; - hostname = "xoc2.ewi.utwente.nl"; - proxyJump = "sijmens@linscin.scintilla.utwente.nl"; - }; - "noc2" = { - user = "s2639149"; - hostname = "noc2.ewi.utwente.nl"; - proxyJump = "sijmens@linscin.scintilla.utwente.nl"; - }; - "hidde" = { - user = "hidde"; - hostname = "84.245.15.16"; - }; - }; - extraConfig = '' - AddKeysToAgent 15m - ''; - }; - - alot.enable = true; - chromium.enable = true; - gpg.enable = true; - home-manager.enable = true; - mbsync.enable = true; - msmtp.enable = true; - password-store.enable = true; - }; - - wayland.windowManager.sway = { - enable = true; - config = let - scintillaDellOutput = { pos = "0 0"; }; - scintillaHpOutput = { pos = "0 120"; }; - in rec { - modifier = "Mod4"; - terminal = "foot"; - fonts = { - names = [ "Ubuntu" ]; - style = "Regular"; - size = 11.0; - }; - input = { - "type:touchpad" = { - natural_scroll = "enabled"; - dwt = "disabled"; - click_method = "clickfinger"; - }; - "type:keyboard" = { - xkb_layout = "us,kr"; - xkb_options = "grp:alt_caps_toggle"; - }; - "type:mouse" = { - accel_profile = "flat"; - }; - }; - output = { - "*" = { - bg = "~/Pictures/berg.jpg fill"; - subpixel = "none"; - }; - "Unknown 0x095F 0x00000000" = { pos = "92 1200"; scale = "1.3"; }; # framework - "Dell Inc. DELL U2410 F525M13318GL" = scintillaDellOutput; # bibi - "Dell Inc. DELL U2410 F525M12P08RL" = scintillaDellOutput; # fabienne - "Hewlett Packard HP E222 CNK6110ZM2" = scintillaHpOutput; # floortje - "Hewlett Packard HP E222 CNK6110ZM7" = scintillaHpOutput; - "Hewlett Packard HP E222 CNK6110ZMF" = scintillaHpOutput; # tamara - "Hewlett Packard HP E222 CNK6110ZR8" = scintillaHpOutput; # megan - "Hewlett Packard HP E222 CNK611104P" = scintillaHpOutput; # charissa - "Hewlett Packard HP E222 CNK611104X" = scintillaHpOutput; - "Hewlett Packard HP E222 CNK6111052" = scintillaHpOutput; # ilona - "Goldstar Company Ltd LG Ultra HD 0x00008520" = { mode = "2560x1440@60Hz"; }; # thuis rechts - "Dell Inc. DELL S2722DGM 3P84Z83" = { mode = "2560x1440@144Hz"; }; # thuis links (hdmi) - }; - keybindings = lib.mkOptionDefault { - XF86MonBrightnessDown = "exec ${pkgs.light}/bin/light -U 5"; - XF86MonBrightnessUp = "exec ${pkgs.light}/bin/light -A 5"; - "shift+XF86MonBrightnessDown" = "exec ${pkgs.light}/bin/light -U 1"; - "shift+XF86MonBrightnessUp" = "exec ${pkgs.light}/bin/light -A 1"; - XF86AudioRaiseVolume = "exec '${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ +5%'"; - XF86AudioLowerVolume = "exec '${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ -5%'"; - XF86AudioMute = "exec '${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle'"; - Print = "exec '${pkgs.grim}/bin/grim -g \"$(${pkgs.slurp}/bin/slurp)\" - | wl-copy -t image/png'"; - - "${modifier}+alt+l" = "exec '${pkgs.swaylock}/bin/swaylock -c 000000 -i eDP-1:Pictures/vista32.jpg'"; - "${modifier}+ctrl+Return" = "exec '${pkgs.gnome.nautilus}/bin/nautilus'"; - - "${modifier}+ctrl+Down" = "move workspace to down"; - "${modifier}+ctrl+Up" = "move workspace to up"; - "${modifier}+ctrl+Left" = "move workspace to left"; - "${modifier}+ctrl+Right" = "move workspace to right"; - "${modifier}+ctrl+j" = "move workspace to down"; - "${modifier}+ctrl+k" = "move workspace to up"; - "${modifier}+ctrl+h" = "move workspace to left"; - "${modifier}+ctrl+l" = "move workspace to right"; - - "${modifier}+ctrl+f" = "exec '${pkgs.python3}/bin/python /etc/nixos/common/sway/next_free.py | xargs swaymsg -- workspace number'"; - "${modifier}+comma" = "workspace prev_on_output"; - "${modifier}+period" = "workspace next_on_output"; - }; - }; - }; - - services = { - gpg-agent = { - enable = true; - pinentryFlavor = "qt"; - }; - - gnome-keyring = { - enable = true; - components = ["secrets" "ssh"]; - }; - - mpd = { - enable = true; - musicDirectory = "/home/sijmen/Music"; - }; - - mako = { - enable = true; - font = "Ubuntu 11"; - defaultTimeout = 5000; - groupBy = "app-name,summary"; - }; - }; - - accounts.email.accounts.Personal = { - primary = true; - - address = "me@sijmenschoon.nl"; - aliases = [ "me@sijman.nl" "me@vijf.life" "info@sijmenschoon.nl" ]; - realName = "Sijmen Schoon"; - - userName = "me@sijmenschoon.nl"; - passwordCommand = "pass show email/personal"; - - imap.host = "imap.soverin.net"; - smtp.host = "smtp.soverin.net"; - - folders.inbox = "INBOX"; - - mbsync = { - enable = true; - create = "maildir"; - }; - - msmtp.enable = true; - }; - - accounts.email.accounts.Scintilla = { - primary = false; - - address = "sijmens@scintilla.utwente.nl"; - aliases = [ "sschoon@scintilla.utwente.nl" ]; - realName = "Sijmen Schoon"; - - userName = "sijmens"; - passwordCommand = "pass show email/scintilla"; - - folders.inbox = "INBOX"; - }; }; } diff --git a/common/home-manager/accounts.nix b/common/home-manager/accounts.nix new file mode 100644 index 0000000..5076101 --- /dev/null +++ b/common/home-manager/accounts.nix @@ -0,0 +1,39 @@ +{ + accounts.email.accounts = { + Personal = { + primary = true; + + address = "me@sijmenschoon.nl"; + aliases = [ "me@sijman.nl" "me@vijf.life" "info@sijmenschoon.nl" ]; + realName = "Sijmen Schoon"; + + userName = "me@sijmenschoon.nl"; + passwordCommand = "pass show email/personal"; + + imap.host = "imap.soverin.net"; + smtp.host = "smtp.soverin.net"; + + folders.inbox = "INBOX"; + + mbsync = { + enable = true; + create = "maildir"; + }; + + msmtp.enable = true; + }; + + Scintilla = { + primary = false; + + address = "sijmens@scintilla.utwente.nl"; + aliases = [ "sschoon@scintilla.utwente.nl" ]; + realName = "Sijmen Schoon"; + + userName = "sijmens"; + passwordCommand = "pass show email/scintilla"; + + folders.inbox = "INBOX"; + }; + }; +} diff --git a/common/home-manager/gtk.nix b/common/home-manager/gtk.nix index 2951dd9..856d9b1 100644 --- a/common/home-manager/gtk.nix +++ b/common/home-manager/gtk.nix @@ -21,6 +21,7 @@ "smb://192.168.1.123/docs/ NAS" "smb://192.168.1.123/docs/users/sijmen sijmen" "smb://192.168.1.123/docs/media Media" + "sftp://sijmen@10.100.0.1/home/sijmen RPi" "sftp://sijmens@virtuscin.scintilla.utwente.nl/data Scintilla" "sftp://sijmens@virtuscin.scintilla.utwente.nl/data/commissies/spock/SPOCK7 SPOCK7" "sftp://sijmens@virtuscin.scintilla.utwente.nl/data/commissies/sot sot" diff --git a/common/home-manager/home.nix b/common/home-manager/home.nix index b1c5a90..e7e3f56 100644 --- a/common/home-manager/home.nix +++ b/common/home-manager/home.nix @@ -14,13 +14,19 @@ # Programming bacon colordiff + podman-compose docker-compose sublime-merge tig vscode-fhs - poetry cargo + cargo-outdated + clang + poetry + rust-analyzer + rustc + rustfmt # Graphics gimp @@ -31,14 +37,12 @@ # Internet discord element-desktop - gnome.epiphany - httpie wget - remmina x2goclient + transmission-gtk # Sound & Video cantata @@ -46,15 +50,22 @@ pavucontrol spotify ncmpcpp + mpdevil + squeezelite + mediainfo + mpc-cli # Gaming - prismlauncher + #prismlauncher heroic + #factorio # System Tools + dig borgbackup dconf dmenu + rofi-wayland grim light screen @@ -68,10 +79,14 @@ yubikey-manager watchexec wine + xdg-utils xfce.thunar gnome.nautilus nnn + + niv home-manager + nix-index gnome.evince gnome.gnome-characters @@ -100,10 +115,11 @@ unzip zip + # Misc php python311 python311Packages.i3ipc - ruby + kicad ]; shellAliases = { @@ -144,7 +160,9 @@ gf = "${pkgs.git}/bin/git fetch"; gfp = "${pkgs.git}/bin/git fetch --prune"; gl = "${pkgs.git}/bin/git pull"; + glr = "${pkgs.git}/bin/git pull --rebase"; gla = "${pkgs.git}/bin/git pull --autostash"; + glra = "${pkgs.git}/bin/git pull --rebase --autostash"; gp = "${pkgs.git}/bin/git push"; gpf = "${pkgs.git}/bin/git push --force-with-lease"; gr = "${pkgs.git}/bin/git reset"; @@ -157,8 +175,11 @@ tigs = "${pkgs.tig}/bin/tig status"; oath = "${pkgs.yubikey-manager}/bin/ykman oath accounts code"; - dc = "${pkgs.docker-compose}/bin/docker-compose"; - dclf = "${pkgs.docker-compose}/bin/docker-compose logs --tail 100 -f"; + pc = "${pkgs.podman-compose}/bin/podman-compose"; + pce = "${pkgs.podman-compose}/bin/podman-compose exec"; + pclf = "${pkgs.podman-compose}/bin/podman-compose logs --tail 100 -f"; + + pr = "${pkgs.poetry}/bin/poetry run"; }; pointerCursor = { diff --git a/common/home-manager/programs.nix b/common/home-manager/programs.nix new file mode 100644 index 0000000..b119d4e --- /dev/null +++ b/common/home-manager/programs.nix @@ -0,0 +1,283 @@ +{ pkgs, ... }: + +{ + programs = { + bash = { + enable = true; + initExtra = '' + source ${pkgs.fetchurl { + url = "https://raw.githubusercontent.com/rupa/z/b82ac78a2d4457d2ca09973332638f123f065fd1/z.sh"; + sha256 = "98e4438cd31afb3ce594130335e7fbd8be5d75d9a53e4f3e084d97e6b8d19b0e"; + }} + + # SSH agent + eval $(${pkgs.openssh}/bin/ssh-agent) > /dev/null + trap 'test -n "$SSH_AUTH_SOCK" && eval $(${pkgs.openssh}/bin/ssh-agent -k)' 0 + ''; + sessionVariables = { + PYTHON_KEYRING_BACKEND = "keyring.backends.null.Keyring"; + }; + }; + + zsh = { + enable = true; + enableAutosuggestions = true; + enableSyntaxHighlighting = true; + prezto.enable = true; + autocd = true; + plugins = [ + { + name = "zsh-nix-shell"; + file = "nix-shell.plugin.zsh"; + src = pkgs.fetchFromGitHub { + owner = "chisui"; + repo = "zsh-nix-shell"; + rev = "v0.5.0"; + sha256 = "0za4aiwwrlawnia4f29msk822rj9bgcygw6a8a6iikiwzjjz0g91"; + }; + } + ]; + initExtra = '' + source ${pkgs.fetchurl { + url = "https://raw.githubusercontent.com/agkozak/zsh-z/master/zsh-z.plugin.zsh"; + sha256 = "8be9f089d8bb596a2679f9127f37276a8c1aeba9b5047456923d49eb2af61156"; + }} + + # SSH agent + eval $(${pkgs.openssh}/bin/ssh-agent) > /dev/null + trap 'test -n "$SSH_AUTH_SOCK" && eval $(${pkgs.openssh}/bin/ssh-agent -k)' 0 + + setopt rm_star_silent + ''; + }; + + firefox = { + enable = true; + package = pkgs.firefox-wayland; + }; + + ncmpcpp = { + enable = true; + settings = { + colors_enabled = false; + }; + }; + + foot = { + enable = true; + settings = { + main = { + term = "xterm-256color"; + font = "Iosevka:size=12"; + }; + + colors = { + background = "fafafa"; + foreground = "383a42"; + + regular0 = "383a42"; + regular1 = "e45649"; + regular2 = "50a14f"; + regular3 = "c18401"; + regular4 = "0184bc"; + regular5 = "a626a4"; + regular6 = "0997b3"; + regular7 = "fafafa"; + + bright0 = "383a42"; + bright1 = "e45649"; + bright2 = "50a14f"; + bright3 = "c18401"; + bright4 = "0184bc"; + bright5 = "a626a4"; + bright6 = "0997b3"; + bright7 = "fafafa"; + }; + }; + }; + + git = { + enable = true; + lfs.enable = true; + package = pkgs.gitAndTools.gitFull; + + userName = "Sijmen"; + userEmail = "me@sijman.nl"; + + signing = { + signByDefault = true; + key = "0xDAF7821E067D9C48"; + }; + + extraConfig = { + fetch.prune = true; + init.defaultBranch = "main"; + pull.ff = "only"; + push.autoSetupRemote = true; + safe.directory = [ "/etc/nixos" ]; + core.editor = "vim"; + + alias = { + duw = "push"; + vertakking = "branch"; + tak = "branch"; + schakel = "switch"; + committeer = "commit"; + voegtoe = "add"; + afstand = "remote"; + }; + }; + }; + + mpv = { + enable = true; + config = { + script-opts = "ytdl_hook-ytdl_path=${pkgs.yt-dlp}/bin/yt-dlp"; + profile = "gpu-hq"; + hwdec = true; + }; + }; + + neovim = { + enable = true; + vimAlias = true; + + extraConfig = '' + luafile /etc/nixos/common/nvim.lua + ''; + + extraPackages = with pkgs; [ + gcc + rnix-lsp + nodePackages.pyright + ]; + + plugins = with pkgs.vimPlugins; [ + bufferline-nvim + cmp-nvim-lsp + cmp_luasnip + ctrlp-vim + galaxyline-nvim + indentLine + leap-nvim + lualine-nvim + luasnip + markdown-preview-nvim + neorg + nvim-cmp + nvim-colorizer-lua + nvim-lspconfig + nvim-tree-lua + nvim-treesitter.withAllGrammars + nvim-web-devicons + onehalf + pears-nvim + plenary-nvim + vim-closetag + vim-nix + vim-startify + vim-startuptime + ]; + }; + + tmux = { + enable = true; + prefix = "C-a"; + extraConfig = '' + set -g mouse on + set-option -g set-titles on + set-option -g set-titles-string "#W" + ''; + }; + + yt-dlp = { + enable = true; + settings = { + sponsorblock-mark = "sponsor,selfpromo,intro,outro,poi_highlight"; + }; + }; + + waybar = { + enable = true; + }; + + beets = { + enable = true; + settings = { + paths.default = "$albumartist/$year - $album%aunique{}/$track $title"; + import.autotag = false; + plugins = [ "fetchart" ]; + }; + }; + + ssh = { + enable = true; + matchBlocks = { + # Home + "rpi" = { + user = "sijmen"; + hostname = "10.100.0.1"; + identityFile = "/home/sijmen/.ssh/id_ed25519_plain"; + }; + "desktop" = { + user = "vijfhoek"; + hostname = "192.168.1.99"; + proxyJump = "cloud.sijmenschoon.nl"; + }; + "nas" = { + user = "sijmen"; + hostname = "192.168.1.123"; + proxyJump = "cloud.sijmenschoon.nl"; + }; + # Servers + "hermes" = { + user = "ubuntu"; + hostname = "hermes.sijmenschoon.nl"; + }; + # Scintilla + "linscin" = { + user = "sijmens"; + hostname = "linscin.scintilla.utwente.nl"; + }; + "britt" = { + user = "sijmens"; + hostname = "britt.scintilla.utwente.nl"; + proxyJump = "linscin"; + }; + "alexia" = { + user = "sijmens"; + hostname = "alexia.scintilla.utwente.nl"; + proxyJump = "linscin"; + }; + "*.scintilla.utwente.nl" = { + user = "sijmens"; + }; + "*.scintilla.nl" = { + user = "sijmens"; + }; + # Uni + "xoc2" = { + user = "s2639149"; + hostname = "xoc2.ewi.utwente.nl"; + proxyJump = "sijmens@linscin.scintilla.utwente.nl"; + }; + "noc2" = { + user = "s2639149"; + hostname = "noc2.ewi.utwente.nl"; + proxyJump = "sijmens@linscin.scintilla.utwente.nl"; + }; + }; + extraConfig = '' + AddKeysToAgent 15m + ''; + }; + + alot.enable = true; + chromium.enable = true; + gpg.enable = true; + home-manager.enable = true; + mbsync.enable = true; + msmtp.enable = true; + password-store.enable = true; + }; +} diff --git a/common/home-manager/services.nix b/common/home-manager/services.nix new file mode 100644 index 0000000..24fcd93 --- /dev/null +++ b/common/home-manager/services.nix @@ -0,0 +1,34 @@ +{ + services = { + gpg-agent = { + enable = true; + pinentryFlavor = "qt"; + }; + + gnome-keyring = { + enable = true; + components = ["secrets" "ssh"]; + }; + + mpd = { + enable = true; + musicDirectory = "/home/sijmen/Music"; + extraConfig = '' + password "123@read,add,control,admin" + default_permissions "" + + audio_output { + type "pulse" + name "pulse" + } + ''; + }; + + mako = { + enable = true; + font = "Ubuntu 11"; + defaultTimeout = 5000; + groupBy = "app-name,summary"; + }; + }; +} diff --git a/common/home-manager/systemd.nix b/common/home-manager/systemd.nix new file mode 100644 index 0000000..fed507f --- /dev/null +++ b/common/home-manager/systemd.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: + +{ + systemd.user.services = { + swaylock = { + Unit.Description = "Lock screen on suspend"; + Service.ExecStart = + "${pkgs.swaylock}/bin/swaylock -c 000000 -i eDP-1:/home/sijmen/Pictures/vista32.jpg"; + }; + }; +} diff --git a/common/home-manager/wayland.nix b/common/home-manager/wayland.nix new file mode 100644 index 0000000..b18dd2e --- /dev/null +++ b/common/home-manager/wayland.nix @@ -0,0 +1,88 @@ +{ pkgs, lib, ... }: + +{ + wayland.windowManager.sway = { + enable = true; + config = let + scintillaDellOutput = { pos = "0 0"; }; + scintillaHpOutput = { pos = "0 120"; }; + in rec { + modifier = "Mod4"; + terminal = "foot"; + fonts = { + names = [ "Ubuntu" ]; + style = "Regular"; + size = 11.0; + }; + input = { + "type:touchpad" = { + natural_scroll = "enabled"; + dwt = "disabled"; + click_method = "clickfinger"; + scroll_factor = "0.25"; + }; + "type:keyboard" = { + xkb_layout = "us,kr"; + xkb_options = "grp:alt_caps_toggle"; + }; + "type:mouse" = { + accel_profile = "flat"; + }; + }; + output = { + "*" = { + bg = "~/Pictures/berg.jpg fill"; + subpixel = "none"; + }; + "BOE 0x095F Unknown" = { pos = "92 1200"; scale = "1.3"; }; # framework + "Dell Inc. DELL U2410 F525M13318GL" = scintillaDellOutput; # bibi + "Dell Inc. DELL U2410 F525M12P08RL" = scintillaDellOutput; # fabienne + "Hewlett Packard HP E222 CNK6110ZM2" = scintillaHpOutput; # floortje + "Hewlett Packard HP E222 CNK6110ZM7" = scintillaHpOutput; + "Hewlett Packard HP E222 CNK6110ZMF" = scintillaHpOutput; # tamara + "Hewlett Packard HP E222 CNK6110ZMQ" = scintillaHpOutput; # patricia + "Hewlett Packard HP E222 CNK6110ZR8" = scintillaHpOutput; # megan + "Hewlett Packard HP E222 CNK611103Z" = scintillaHpOutput; # katy + "Hewlett Packard HP E222 CNK611104P" = scintillaHpOutput; # charissa + "Hewlett Packard HP E222 CNK611104X" = scintillaHpOutput; + "Hewlett Packard HP E222 CNK6111051" = scintillaHpOutput; # kim + "Hewlett Packard HP E222 CNK6111052" = scintillaHpOutput; # ilona + "Goldstar Company Ltd LG Ultra HD 0x00008520" = { mode = "2560x1440@60Hz"; }; # thuis rechts + "Dell Inc. DELL S2722DGM 3P84Z83" = { pos = "-228 -240"; mode = "2560x1440@144Hz"; }; # thuis links (hdmi) + }; + keybindings = lib.mkOptionDefault { + XF86MonBrightnessDown = "exec ${pkgs.light}/bin/light -U 5"; + XF86MonBrightnessUp = "exec ${pkgs.light}/bin/light -A 5"; + "shift+XF86MonBrightnessDown" = "exec ${pkgs.light}/bin/light -U 1"; + "shift+XF86MonBrightnessUp" = "exec ${pkgs.light}/bin/light -A 1"; + XF86AudioRaiseVolume = "exec '${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ +5%'"; + XF86AudioLowerVolume = "exec '${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ -5%'"; + XF86AudioMute = "exec '${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle'"; + Print = "exec '${pkgs.grim}/bin/grim -g \"$(${pkgs.slurp}/bin/slurp)\" - | wl-copy -t image/png'"; + "shift+Print" = "exec '${pkgs.grim}/bin/grim - | wl-copy -t image/png'"; + + "${modifier}+d" = "exec '${pkgs.rofi-wayland}/bin/rofi -show drun'"; + "${modifier}+shift+b" = "exec '/etc/nixos/framework/dmenu-bluetooth --connected-icon'"; + + "${modifier}+alt+l" = "exec '${pkgs.swaylock}/bin/swaylock -c 000000 -i eDP-1:Pictures/vista32.jpg'"; + "${modifier}+ctrl+Return" = "exec '${pkgs.gnome.nautilus}/bin/nautilus'"; + + "${modifier}+ctrl+Down" = "move workspace to down"; + "${modifier}+ctrl+Up" = "move workspace to up"; + "${modifier}+ctrl+Left" = "move workspace to left"; + "${modifier}+ctrl+Right" = "move workspace to right"; + "${modifier}+ctrl+j" = "move workspace to down"; + "${modifier}+ctrl+k" = "move workspace to up"; + "${modifier}+ctrl+h" = "move workspace to left"; + "${modifier}+ctrl+l" = "move workspace to right"; + + "${modifier}+ctrl+f" = "exec '${pkgs.python3}/bin/python /etc/nixos/common/sway/next_free.py | xargs swaymsg -- workspace number'"; + "${modifier}+comma" = "workspace prev_on_output"; + "${modifier}+period" = "workspace next_on_output"; + }; + startup = [ + { command = "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1"; } + ]; + }; + }; +} diff --git a/common/nvim.lua b/common/nvim.lua index 4f9d148..28f1436 100644 --- a/common/nvim.lua +++ b/common/nvim.lua @@ -9,6 +9,8 @@ vim.cmd [[ autocmd Filetype json \ let g:indentLine_setConceal = 0 | \ let g:vim_json_syntax_conceal = 0 + + let g:ctrlp_user_command = ['.git/', 'git --git-dir=%s/.git ls-files -oc --exclude-standard'] ]] g.mapleader = ' ' diff --git a/framework/configuration.nix b/framework/configuration.nix index 73954d2..93af87e 100644 --- a/framework/configuration.nix +++ b/framework/configuration.nix @@ -1,6 +1,8 @@ { config, pkgs, ... }: let + sources = import ./sources.nix; + #lanzaboote = import sources.lanzaboote; greetdSwayConfig = pkgs.writeText "greetd-sway-config" '' # `-l` activates layer-shell mode. Notice that `swaymsg exit` will run after gtkgreet. exec "${pkgs.greetd.gtkgreet}/bin/gtkgreet -l -c sway; swaymsg exit" @@ -15,15 +17,15 @@ in imports = [ ./hardware-configuration.nix + #lanzaboote.nixosModules.lanzaboote ../common/configuration.nix ]; virtualisation = { - virtualisation.docker.enable = true; - virtualisation.libvirtd.enable = true; - virtualisation.spiceUSBRedirection.enable = true; - #virtualisation.waydroid.enable = true; - #virtualisation.lxd.enable = true; + #podman.enable = true; + #podman.dockerCompat = true; + # libvirtd.enable = true; + # spiceUSBRedirection.enable = true; }; hardware = { @@ -37,6 +39,8 @@ in }; boot = { + #bootspec.enable = false; + loader = { efi.canTouchEfiVariables = true; @@ -47,13 +51,18 @@ in }; }; + #lanzaboote = { + # enable = false; + # pkiBundle = "/etc/secureboot"; + #}; + kernelPackages = pkgs.linuxPackages_latest; kernelParams = [ "quiet" "splash" "vga=current" "udev.log_level=3" - "i915.enable_psr=1" + "i915.enable_psr=2" "nvme.noacpi=1" "resume=/dev/disk/by-uuid/7e88d61f-5581-45fb-82f1-29a0e0caf4c0" ]; @@ -70,7 +79,10 @@ in networking = { hostName = "sijmen-framework"; - networkmanager.enable = true; + networkmanager = { + enable = true; + unmanaged = [ "wg0" "virbr0" ]; + }; firewall = { allowedTCPPorts = [ 22 # ssh @@ -96,10 +108,16 @@ in peers = [{ publicKey = "zu9vXxxg4wm0R4yWQ2HPaAwJbizuccGYbBB/StwSsm4="; allowedIPs = [ "10.100.0.0/24" ]; - endpoint = "143.178.219.107:51820"; + endpoint = "cloud.sijmenschoon.nl:51820"; persistentKeepalive = 25; }]; }; + + extraHosts = '' + #127.0.0.3 youtube.com + #127.0.0.3 www.youtube.com + #127.0.0.3 i.ytimg.com + ''; }; environment.etc."greetd/environments".text = '' @@ -141,9 +159,22 @@ in tlp = { enable = true; settings = { - CPU_ENERGY_PERF_POLICY_ON_AC = "64"; - CPU_ENERGY_PERF_POLICY_ON_BAT = "140"; + INTEL_GPU_MIN_FREQ_ON_AC = "100"; + INTEL_GPU_MIN_FREQ_ON_BAT = "100"; + PCIE_ASPM_ON_BAT = "powersupersave"; + RUNTIME_PM_ON_BAT = "1"; + + CPU_ENERGY_PERF_POLICY_ON_AC = "64"; + CPU_ENERGY_PERF_POLICY_ON_BAT = "balance_power"; + CPU_BOOST_ON_BAT = "0"; + CPU_HWP_DYN_BOOST_ON_BAT = "0"; + SCHED_POWERSAVE_ON_BAT = "1"; + NMI_WATCHDOG = "0"; + + USB_AUTOSUSPEND = "1"; + USB_EXCLUDE_AUDIO = "1"; + USB_EXCLUDE_BTUSB = "0"; # Bus 001 Device 040: ID 1050:0407 Yubico.com Yubikey 4/5 OTP+U2F+CCID # Bus 001 Device 038: ID 32ac:0002 Framework HDMI Expansion Card @@ -164,37 +195,24 @@ in power-profiles-daemon.enable = false; }; - security.pam.services.login.fprintAuth = true; - security.pam.services.swaylock = {}; - security.polkit.enable = true; - - environment = { - gnome.excludePackages = (with pkgs; [ - gnome-photos - gnome-tour - ]) ++ (with pkgs.gnome; [ - atomix # puzzle game - cheese # webcam - epiphany # web browser - geary # email reader - gnome-calendar - gnome-music - hitori # sudoku game - iagno # go game - tali # poker game - totem # video player - ]); - - systemPackages = with pkgs; [ - gnome.adwaita-icon-theme - ifuse - libimobiledevice - libheif - ]; + security = { + pam.services.login.fprintAuth = true; + pam.services.swaylock = {}; + polkit.enable = true; }; + environment.systemPackages = with pkgs; [ + gnome.adwaita-icon-theme + ifuse + libimobiledevice + libheif + sbctl + polkit + polkit_gnome + ]; + programs.steam = { - enable = true; + #enable = true; remotePlay.openFirewall = true; dedicatedServer.openFirewall = true; }; @@ -203,10 +221,22 @@ in packageOverrides = pkgs: { vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; }; }; - permittedInsecurePackages = [ "electron-18.1.0" ]; }; - home-manager.users.sijmen.imports = [ ../common/dconf.nix ]; + #home-manager.users.sijmen.imports = [ ../common/dconf.nix ]; + + systemd.services."suspend" = { + enable = true; + # TODO Should be `before`, but then fingerprint reader doesn't work + after = [ "suspend.target" ]; + wantedBy = [ "suspend.target" ]; + serviceConfig = { + # TODO Make username agnostic + ExecStart = + "${pkgs.systemd}/bin/systemctl --user --machine=sijmen@ start --wait swaylock"; + Type = "oneshot"; + }; + }; system.stateVersion = "22.05"; } diff --git a/framework/dmenu-bluetooth b/framework/dmenu-bluetooth new file mode 100755 index 0000000..c25770a --- /dev/null +++ b/framework/dmenu-bluetooth @@ -0,0 +1,357 @@ +#!/usr/bin/env bash +# _ _ _ _ _ _ +# __| |_ __ ___ ___ _ __ _ _ | |__ | |_ _ ___| |_ ___ ___ | |_ | |__ +# / _` | '_ ` _ \ / _ \ '_ \| | | |_____| '_ \| | | | |/ _ \ __/ _ \ / _ \| __|| '_ \ +# | (_| | | | | | | __/ | | | |_| |_____| |_) | | |_| | __/ || (_) | (_) | |_ | | | | +# \__,_|_| |_| |_|\___|_| |_|\__,_| |_.__/|_|\__,_|\___|\__\___/ \___/ \__||_| |_| +# +# Author: Nick Clyde (clydedroid) +# dmenu support by: Layerex +# +# A script that generates a dmenu menu that uses bluetoothctl to +# connect to bluetooth devices and display status info. +# +# Inspired by networkmanager-dmenu (https://github.com/firecat53/networkmanager-dmenu) +# Thanks to x70b1 (https://github.com/polybar/polybar-scripts/tree/master/polybar-scripts/system-bluetooth-bluetoothctl) +# +# Depends on: +# Arch repositories: dmenu, bluez-utils (contains bluetoothctl) + +# Constants +divider="---------" +goback="Back" +connected_icon="" + +# Checks if bluetooth controller is powered on +power_on() { + if bluetoothctl show | grep -F -q "Powered: yes"; then + return 0 + else + return 1 + fi +} + +# Toggles power state +toggle_power() { + if power_on; then + bluetoothctl power off + show_menu + else + if rfkill list bluetooth | grep -F -q 'blocked: yes'; then + rfkill unblock bluetooth && sleep 3 + fi + bluetoothctl power on + show_menu + fi +} + +# Checks if controller is scanning for new devices +scan_on() { + if bluetoothctl show | grep -F -q "Discovering: yes"; then + echo "Scan: on" + return 0 + else + echo "Scan: off" + return 1 + fi +} + +# Toggles scanning state +toggle_scan() { + if scan_on; then + kill $(pgrep -f "bluetoothctl scan on") + bluetoothctl scan off + show_menu + else + bluetoothctl scan on & + echo "Scanning..." + sleep 5 + show_menu + fi +} + +# Checks if controller is able to pair to devices +pairable_on() { + if bluetoothctl show | grep -F -q "Pairable: yes"; then + echo "Pairable: on" + return 0 + else + echo "Pairable: off" + return 1 + fi +} + +# Toggles pairable state +toggle_pairable() { + if pairable_on; then + bluetoothctl pairable off + show_menu + else + bluetoothctl pairable on + show_menu + fi +} + +# Checks if controller is discoverable by other devices +discoverable_on() { + if bluetoothctl show | grep -F -q "Discoverable: yes"; then + echo "Discoverable: on" + return 0 + else + echo "Discoverable: off" + return 1 + fi +} + +# Toggles discoverable state +toggle_discoverable() { + if discoverable_on; then + bluetoothctl discoverable off + show_menu + else + bluetoothctl discoverable on + show_menu + fi +} + +# Checks if a device is connected +device_connected() { + device_info=$(bluetoothctl info "$1") + if echo "$device_info" | grep -F -q "Connected: yes"; then + return 0 + else + return 1 + fi +} + +# Toggles device connection +toggle_connection() { + if device_connected "$1"; then + bluetoothctl disconnect "$1" + # device_menu "$device" + else + bluetoothctl connect "$1" + # device_menu "$device" + fi +} + +# Checks if a device is paired +device_paired() { + device_info=$(bluetoothctl info "$1") + if echo "$device_info" | grep -F -q "Paired: yes"; then + echo "Paired: yes" + return 0 + else + echo "Paired: no" + return 1 + fi +} + +# Toggles device paired state +toggle_paired() { + if device_paired "$1"; then + bluetoothctl remove "$1" + device_menu "$device" + else + bluetoothctl pair "$1" + device_menu "$device" + fi +} + +# Checks if a device is trusted +device_trusted() { + device_info=$(bluetoothctl info "$1") + if echo "$device_info" | grep -F -q "Trusted: yes"; then + echo "Trusted: yes" + return 0 + else + echo "Trusted: no" + return 1 + fi +} + +# Toggles device connection +toggle_trust() { + if device_trusted "$1"; then + bluetoothctl untrust "$1" + device_menu "$device" + else + bluetoothctl trust "$1" + device_menu "$device" + fi +} + +# Prints a short string with the current bluetooth status +# Useful for status bars like polybar, etc. +print_status() { + if power_on; then + printf '' + + mapfile -t paired_devices < <(bluetoothctl paired-devices | grep -F Device | cut -d ' ' -f 2) + counter=0 + + for device in "${paired_devices[@]}"; do + if device_connected "$device"; then + device_alias="$(bluetoothctl info "$device" | grep -F "Alias" | cut -d ' ' -f 2-)" + + if [ $counter -gt 0 ]; then + printf ", %s" "$device_alias" + else + printf " %s" "$device_alias" + fi + + ((counter++)) + fi + done + printf "\n" + else + echo "" + fi +} + +# A submenu for a specific device that allows connecting, pairing, and trusting +device_menu() { + device=$1 + + # Get device name and mac address + device_name="$(echo "$device" | cut -d ' ' -f 3-)" + mac="$(echo "$device" | cut -d ' ' -f 2)" + + # Build options + if device_connected "$mac"; then + connected="Connected: yes" + else + connected="Connected: no" + fi + paired=$(device_paired "$mac") + trusted=$(device_trusted "$mac") + options="$connected\n$paired\n$trusted\n$divider\n$goback\nExit" + + # Open dmenu menu, read chosen option + chosen="$(echo -e "$options" | run_dmenu "$device_name")" + + # Match chosen option to command + case $chosen in + "" | "$divider") + echo "No option chosen." + ;; + "$connected") + toggle_connection "$mac" + ;; + "$paired") + toggle_paired "$mac" + ;; + "$trusted") + toggle_trust "$mac" + ;; + "$goback") + show_menu + ;; + esac +} + +# Opens a dmenu menu with current bluetooth status and options to connect +show_menu() { + # Get menu options + if power_on; then + power="Power: on" + + # Human-readable names of devices, one per line + # If scan is off, will only list paired devices + if [[ -n $connected_icon ]]; then + devices=$(bluetoothctl devices | grep -F Device | while read -r device; do + device_name="$(echo "$device" | cut -d ' ' -f 3-)" + mac="$(echo "$device" | cut -d ' ' -f 2)" + icon="" + + if device_connected "$mac" && [[ -n $connected_icon ]]; then + icon=" $connected_icon" + fi + + echo "$device_name${icon}" + done) + else + devices=$(bluetoothctl devices | grep -F Device | cut -d ' ' -f 3-) + fi + + # Get controller flags + scan=$(scan_on) + pairable=$(pairable_on) + discoverable=$(discoverable_on) + + # Options passed to dmenu + options="$devices\n$divider\n$power\n$scan\n$pairable\n$discoverable\nExit" + else + power="Power: off" + options="$power\nExit" + fi + + # Open dmenu menu, read chosen option + chosen="$(echo -e "$options" | run_dmenu "Bluetooth")" + + # Match chosen option to command + case $chosen in + "" | "$divider") + echo "No option chosen." + ;; + "$power") + toggle_power + ;; + "$scan") + toggle_scan + ;; + "$discoverable") + toggle_discoverable + ;; + "$pairable") + toggle_pairable + ;; + *) + if [[ -n $connected_icon ]]; then + chosen="${chosen%% ${connected_icon}}" + fi + device=$(bluetoothctl devices | grep -F "$chosen") + # Open a submenu if a device is selected + if [[ $device ]]; then device_menu "$device"; fi + ;; + esac +} + +original_args=("$@") + +# dmenu command to pipe into. Extra arguments to dmenu-bluetooth are passed through to dmenu. This +# allows the user to set fonts, sizes, colours, etc. +run_dmenu() { + rofi -dmenu "${original_args[@]}" -i -p "$1" +} + +print_help() { + echo "usage: $0 [--help] [--status] [--connected-icon [ICON]]" + echo "" + echo "A script that generates a dmenu menu that uses bluetoothctl to connect to bluetooth devices and display status info." + echo "" + echo "options:" + echo "--help show this help message and exit" + echo "--connected-icon [ICON] add icon on device list next to connected devices" + echo "--status print a short string about current bluetooth status and exit" +} + +case "$1" in + --help) + print_help + ;; + --connected-icon) + if [[ -z $2 ]]; then + connected_icon="" + else + connected_icon="$2" + fi + show_menu + ;; + --status) + print_status + ;; + *) + show_menu + ;; +esac diff --git a/framework/nmcli_dmenu b/framework/nmcli_dmenu new file mode 100755 index 0000000..a29f726 --- /dev/null +++ b/framework/nmcli_dmenu @@ -0,0 +1,309 @@ +#!/usr/bin/env python +"""NetworkManager command line dmenu script. + +To add new connections or enable/disable networking requires policykit +permissions setup per: +https://wiki.archlinux.org/index.php/NetworkManager#Set_up_PolicyKit_permissions + +OR running the script as root + +Add dmenu formatting options and default terminal if desired to +~/.config/networkmanager-dmenu/config.ini + +""" +import itertools +from os.path import expanduser +from subprocess import Popen, PIPE +import sys +try: + import configparser as configparser +except ImportError: + import ConfigParser as configparser + + +def dmenu_cmd(num_lines, prompt="Networks"): + """Parse config.ini if it exists and add options to the dmenu command + + Args: args - num_lines: number of lines to display + prompt: prompt to show + Returns: command invocation (as a list of strings) for + dmenu -l -p -i ... + + """ + return ["rofi", "-dmenu", "-i", "-l", str(num_lines), "-p", str(prompt)] + + +def choose_adapter(): + """If there is more than one wifi adapter installed, ask which one to use + + """ + adps = ["nmcli", "device", "status"] + a = Popen(adps, stdout=PIPE).communicate()[0].decode().split('\n') + all_adps = [i.split()[0] for i in a if 'wifi' in i] + if len(all_adps) <= 1: + return all_adps[0].strip() + all_adps_bytes = "\n".join(all_adps).encode() + sel = Popen(dmenu_cmd(len(all_adps), "CHOOSE ADAPTER:"), + stdin=PIPE, + stdout=PIPE).communicate(input=all_adps_bytes)[0].decode() + if not sel.strip(): + sys.exit() + return sel.strip() + + +def current_conns(): + """Get list of current NetworkManager connections (ssid:security) + + Returns: list of strings: ['firecat4153:WPA2', 'firecat4153x:WEP'...] + + """ + conns = ["nmcli", "-t", "-f", "name,type", "connection"] + return Popen(conns, stdout=PIPE).communicate()[0].decode().split('\n') + + +def current_ssids(adapter): + """Get list of current SSIDs seen by NetworkManager and order by signal + strength + + Returns: list - + ["firecat4153:WPA2","firecat4153-guest:", "firecat4153x:WPA2"] + + """ + scan = ["nmcli", "-t", "-f", "ssid,security,signal", + "device", "wifi", "list", "ifname", adapter] + res = Popen(scan, stdout=PIPE).communicate()[0].decode().split("\n") + del res[-1] + res = [i.rsplit(':', 1) for i in res] + res = sorted(res, key=lambda x: x[1], reverse=True) + res = unique_ssid(res) + return [i[0].replace("'", "") for i in res] + + +def unique_ssid(conns): + """Filters the list of ids, so that duplicate ids will only show the one + with the greatest strength. The list of ssids is already sorted by strength + so this just deletes any duplicates after the first item. + + """ + ssids = [] + for conn in conns: + if conn[0] in ssids: + del conns[conns.index(conn)] + else: + ssids.append(conn[0]) + return conns + + +def vpn_connections(conns): + """Parse list of current connections for VPNs + + Args: conns - ['ssid:security', 'firecat4153:WPA2', ...] + Returns: list of VPN connection names ['pia_us_west',...] + + """ + conns = [i.split(':') for i in conns if i] + return [i[0] for i in conns if i and 'vpn' in i[1]] + + +def get_network_status(): + """Get current status of networking + + Returns: string 'Enable' or 'Disable', + + """ + stat = ["nmcli", "networking"] + res = Popen(stat, stdout=PIPE).communicate()[0] + if 'enabled' in res.decode(): + return 'Disable' + else: + return 'Enable' + + +def get_active_connections(): + """Get currently active connections + + Returns: list of strings + + """ + status = ["nmcli", "-t", "-f", "name", "connection", + "show", "--active"] + active = Popen(status, stdout=PIPE).communicate()[0] + active = active.decode().split('\n') + del active[-1] + return active + + +def mark_active(conns, active): + """Given a list of connections, mark currently active connections + + Args: conns - list of strings + Returns: list of strings (active prepended with a '**') + + """ + conn_t = [i.rsplit(":", 1)[0] for i in conns] + act = [i for i in conn_t if i and i in active] + for i, conn in enumerate(conn_t): + if conn in act: + conns[i] = "**{}".format(conns[i]) + return conns + + +def other_actions(): + """Return list of other actions that can be taken + + """ + return ["{} Networking".format(get_network_status()), + "Launch Connection Manager"] + + +def get_selection(ssids, vpns, other): + """Combine the arg lists and send to dmenu for selection. + + Args: args - ssids: list of strings + vpns: list of strings + other: list of strings + Returns: selection (string) + + """ + active = get_active_connections() + vpns = ["{}:VPN".format(i) for i in vpns] + inp = mark_active(ssids, active) + [""] + \ + mark_active(vpns, active) + [""] + other + inp_bytes = "\n".join(inp).encode() + sel = Popen(dmenu_cmd(len(inp)), + stdin=PIPE, + stdout=PIPE).communicate(input=inp_bytes)[0].decode() + if not sel.strip(): + sys.exit() + return sel.strip() + + +def toggle_existing(conn): + """Get conn status, then toggle connection up or down if it's not + 'activated' + + Args: conn - string + + """ + conn_status = ["nmcli", "-t", "-f", "GENERAL", "connection", "show", conn] + res = Popen(conn_status, stdout=PIPE).communicate()[0] + if 'activated' not in res.decode(): + updown = 'up' + else: + updown = 'down' + conn_string = ["nmcli", "connection", updown, "id", conn] + Popen(conn_string, stdout=PIPE).communicate() + + +def toggle_networking(sel): + """Enable/disable networking + + Args: sel - string ('Enable Networking' or 'Disable Networking') + + """ + if sel.startswith('Enable'): + updown = 'on' + else: + updown = 'off' + net = ["nmcli", "networking", updown] + Popen(net, stdout=PIPE).communicate() + + +def launch_connection_editor(): + """Launch nmtui or the gui nm-connection-editor + + """ + conf = configparser.ConfigParser() + terminal = "xterm" + gui_if_available = "True" + conf.read(expanduser("~/.config/networkmanager-dmenu/config.ini")) + try: + editor = conf.items("editor") + except configparser.NoSectionError: + conf = False + if conf: + opts = {str(k): str(v) for (k, v) in editor} + if "terminal" in opts: + terminal = opts["terminal"] + if "gui_if_available" in opts: + gui_if_available = opts["gui_if_available"] + if gui_if_available == "True": + try: + Popen(["nm-connection-editor"]).communicate() + except OSError: + Popen([terminal, "-e", "nmtui"]).communicate() + else: + Popen([terminal, "-e", "nmtui"]).communicate() + + +def get_passphrase(): + """Get a password + + Returns: string + + """ + return Popen(dmenu_cmd(0, "Passphrase"), + stdin=PIPE, stdout=PIPE).communicate()[0].decode() + + +def set_new_connection(ssid, pw): + """Setup a new NetworkManager connection + + Args: ssid - string + pw - string + + """ + pw = str(pw).strip() + new_conn = ["nmcli", "device", "wifi", "connect", ssid, "password", pw] + res = Popen(new_conn, stdout=PIPE).communicate() + # Delete connection if it fails somehow. + # With nmcli 0.9.10, you occasionally get an error message: + # "Error: Failed to add/activate new connection: Unknown error", which + # doesn't always mean the connection failed, so test for 'activated' or + # 'activating' in the connection status as well + status = ["nmcli", "-t", "-f", "GENERAL", "connection", "show", ssid] + active = Popen(status, stdout=PIPE).communicate()[0] + # Delete connections with errors + if "Error" in res and \ + ('activating' not in active or 'activated' not in active): + delete = ["nmcli", "connection", "delete", ssid] + Popen(delete, stdout=PIPE).communicate() + + +def run(): + adapter = choose_adapter() + conns = current_conns() + vpns = vpn_connections(conns) + ssids = current_ssids(adapter) + other = other_actions() + sel = get_selection(ssids, vpns, other) + if sel in other: + # Parse other actions + if 'Networking' in sel: + toggle_networking(sel) + elif 'Launch' in sel: + launch_connection_editor() + sys.exit() + elif sel in ssids: + # Set ssid, security if selection is an SSID + ssid, security = sel.split(":") + ssid = ssid.strip("'").strip().replace("**", "") + security = security.strip() + elif sel.replace(":VPN", "").replace("**", "") in vpns: + # Select VPN connection (sel="pia_us_west:VPN") + ssid = sel.replace(":VPN", "").replace("**", "") + else: + sys.exit() + # Decide if selection is existing connection or new + if ssid in [i.split(':')[0] for i in conns if i]: + toggle_existing(ssid) + else: + if security: + pw = get_passphrase() + else: + pw = "" + set_new_connection(ssid, pw) + + +if __name__ == '__main__': + run() diff --git a/framework/sources.json b/framework/sources.json new file mode 100644 index 0000000..1012668 --- /dev/null +++ b/framework/sources.json @@ -0,0 +1,27 @@ +{ + "lanzaboote": { + "branch": "master", + "description": "Secure Boot for NixOS [maintainers=@blitz @raitobezarius @nikstur]", + "homepage": "", + "owner": "nix-community", + "repo": "lanzaboote", + "rev": "v0.2.0", + "sha256": "1wny47cxjq4nin26xx0rrgfa9a6r1g6i6f974z30rr458fqd6y9w", + "type": "tarball", + "url": "https://github.com/nix-community/lanzaboote/archive/v0.2.0.tar.gz", + "url_template": "https://github.com///archive/.tar.gz", + "version": "0.2.0" + }, + "nixpkgs": { + "branch": "master", + "description": "Nix Packages collection", + "homepage": "", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "73909f4f263cf74a557612770a239f6a425ebbed", + "sha256": "1hnfwrpk4xs5js9w7pi4lz5si6rdvz3pljkg2abkrw9ziz1a385s", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/73909f4f263cf74a557612770a239f6a425ebbed.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + } +} diff --git a/framework/sources.nix b/framework/sources.nix new file mode 100644 index 0000000..9a01c8a --- /dev/null +++ b/framework/sources.nix @@ -0,0 +1,194 @@ +# This file has been generated by Niv. + +let + + # + # The fetchers. fetch_ fetches specs of type . + # + + fetch_file = pkgs: name: spec: + let + name' = sanitizeName name + "-src"; + in + if spec.builtin or true then + builtins_fetchurl { inherit (spec) url sha256; name = name'; } + else + pkgs.fetchurl { inherit (spec) url sha256; name = name'; }; + + fetch_tarball = pkgs: name: spec: + let + name' = sanitizeName name + "-src"; + in + if spec.builtin or true then + builtins_fetchTarball { name = name'; inherit (spec) url sha256; } + else + pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; + + fetch_git = name: spec: + let + ref = + if spec ? ref then spec.ref else + if spec ? branch then "refs/heads/${spec.branch}" else + if spec ? tag then "refs/tags/${spec.tag}" else + abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!"; + submodules = if spec ? submodules then spec.submodules else false; + submoduleArg = + let + nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0; + emptyArgWithWarning = + if submodules == true + then + builtins.trace + ( + "The niv input \"${name}\" uses submodules " + + "but your nix's (${builtins.nixVersion}) builtins.fetchGit " + + "does not support them" + ) + {} + else {}; + in + if nixSupportsSubmodules + then { inherit submodules; } + else emptyArgWithWarning; + in + builtins.fetchGit + ({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg); + + fetch_local = spec: spec.path; + + fetch_builtin-tarball = name: throw + ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`. + $ niv modify ${name} -a type=tarball -a builtin=true''; + + fetch_builtin-url = name: throw + ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`. + $ niv modify ${name} -a type=file -a builtin=true''; + + # + # Various helpers + # + + # https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695 + sanitizeName = name: + ( + concatMapStrings (s: if builtins.isList s then "-" else s) + ( + builtins.split "[^[:alnum:]+._?=-]+" + ((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name) + ) + ); + + # The set of packages used when specs are fetched using non-builtins. + mkPkgs = sources: system: + let + sourcesNixpkgs = + import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; }; + hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; + hasThisAsNixpkgsPath = == ./.; + in + if builtins.hasAttr "nixpkgs" sources + then sourcesNixpkgs + else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then + import {} + else + abort + '' + Please specify either (through -I or NIX_PATH=nixpkgs=...) or + add a package called "nixpkgs" to your sources.json. + ''; + + # The actual fetching function. + fetch = pkgs: name: spec: + + if ! builtins.hasAttr "type" spec then + abort "ERROR: niv spec ${name} does not have a 'type' attribute" + else if spec.type == "file" then fetch_file pkgs name spec + else if spec.type == "tarball" then fetch_tarball pkgs name spec + else if spec.type == "git" then fetch_git name spec + else if spec.type == "local" then fetch_local spec + else if spec.type == "builtin-tarball" then fetch_builtin-tarball name + else if spec.type == "builtin-url" then fetch_builtin-url name + else + abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; + + # If the environment variable NIV_OVERRIDE_${name} is set, then use + # the path directly as opposed to the fetched source. + replace = name: drv: + let + saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name; + ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; + in + if ersatz == "" then drv else + # this turns the string into an actual Nix path (for both absolute and + # relative paths) + if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}"; + + # Ports of functions for older nix versions + + # a Nix version of mapAttrs if the built-in doesn't exist + mapAttrs = builtins.mapAttrs or ( + f: set: with builtins; + listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) + ); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 + range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 + stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269 + stringAsChars = f: s: concatStrings (map f (stringToCharacters s)); + concatMapStrings = f: list: concatStrings (map f list); + concatStrings = builtins.concatStringsSep ""; + + # https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331 + optionalAttrs = cond: as: if cond then as else {}; + + # fetchTarball version that is compatible between all the versions of Nix + builtins_fetchTarball = { url, name ? null, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchTarball; + in + if lessThan nixVersion "1.12" then + fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) + else + fetchTarball attrs; + + # fetchurl version that is compatible between all the versions of Nix + builtins_fetchurl = { url, name ? null, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchurl; + in + if lessThan nixVersion "1.12" then + fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) + else + fetchurl attrs; + + # Create the final "sources" from the config + mkSources = config: + mapAttrs ( + name: spec: + if builtins.hasAttr "outPath" spec + then abort + "The values in sources.json should not have an 'outPath' attribute" + else + spec // { outPath = replace name (fetch config.pkgs name spec); } + ) config.sources; + + # The "config" used by the fetchers + mkConfig = + { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null + , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile) + , system ? builtins.currentSystem + , pkgs ? mkPkgs sources system + }: rec { + # The sources, i.e. the attribute set of spec name to spec + inherit sources; + + # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers + inherit pkgs; + }; + +in +mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }