diff options
114 files changed, 1950 insertions, 2903 deletions
diff --git a/.dir-locals.el b/.dir-locals.el index 5535ffa9..d9b7c0ae 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -1,4 +1,22 @@ ;;; Directory Local Variables ;;; For more information see (info "(emacs) Directory Variables") -((nil . ((compile-command . "home-manager switch")))) +((nil . ((compile-command . "./bin/home-manager switch"))) + ("system/nanopi.nix" . + ((nil . ((ssh-deploy-root-local . "/home/alan/projects/alanpearce.eu/nixfiles/") + (ssh-deploy-root-remote . "/sshx:nanopi:projects/alanpearce.eu/nixfiles/") + (ssh-deploy-on-explicit-save . 1))))) + ("user/nanopi.nix" . + ((nil . ((ssh-deploy-root-local . "/home/alan/projects/alanpearce.eu/nixfiles/") + (ssh-deploy-root-remote . "/sshx:nanopi:projects/alanpearce.eu/nixfiles/") + (ssh-deploy-on-explicit-save . 1))))) + ("system/linde.nix" . + ((nil . ((ssh-deploy-root-local . "/home/alan/projects/alanpearce.eu/nixfiles/") + (ssh-deploy-root-remote . "/sshx:linde:projects/alanpearce.eu/nixfiles/") + (ssh-deploy-on-explicit-save . 1) + (ssh-deploy-async . 1))))) + ("system/linde-hardware.nix" . + ((nil . ((ssh-deploy-root-local . "/home/alan/projects/alanpearce.eu/nixfiles/") + (ssh-deploy-root-remote . "/sshx:linde:projects/alanpearce.eu/nixfiles/") + (ssh-deploy-on-explicit-save . 1) + (ssh-deploy-async . 1)))))) diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..78030d65 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,2 @@ +[nix/sources.json] +indent_size = 4 diff --git a/.envrc b/.envrc index fa82cfc4..e7aaa238 100644 --- a/.envrc +++ b/.envrc @@ -1,7 +1,8 @@ if type -P lorri &>/dev/null; then - eval "$(lorri direnv)" + eval "$(lorri direnv)" else - echo 'while direnv evaluated .envrc, could not find the command "lorri" [https://github.com/nix-community/lorri]' - use flake + echo 'while direnv evaluated .envrc, could not find the command "lorri" [https://github.com/nix-community/lorri]' + use nix fi +PATH_add bin FLAKE=$PWD diff --git a/.gitignore b/.gitignore index eaa6f762..c4a847d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ /result -/override.nix diff --git a/.gitmodules b/.gitmodules index cd7b321f..e6975e13 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "private"] path = private url = ssh://alanpearce.eu/nixfiles-private +[submodule "packages"] + path = packages + url = ssh://git.alanpearce.eu/nix-packages diff --git a/bin/darwin-rebuild b/bin/darwin-rebuild new file mode 120000 index 00000000..2eaccdef --- /dev/null +++ b/bin/darwin-rebuild @@ -0,0 +1 @@ +home-manager \ No newline at end of file diff --git a/bin/home-manager b/bin/home-manager new file mode 100755 index 00000000..cf434738 --- /dev/null +++ b/bin/home-manager @@ -0,0 +1,152 @@ +#!/usr/bin/env fish + +if not set --query HOME + echo "error: no HOME" + exit 1 +end + +set --query XDG_STATE_HOME || set --function XDG_STATE_HOME $HOME/.local/state +set --function nix_state_home $XDG_STATE_HOME/nix +set --function channel_root $nix_state_home/channels +set --function user_nixpkgs $HOME/.config/nixpkgs +set --function nixfiles (path resolve (status dirname)/..) + +if set --query XDG_CONFIG_HOME + set --function hm_config_dir $XDG_CONFIG_HOME/home-manager +else + set --function hm_config_dir $HOME/.config/home-manager +end + +for i in 1 + if test ! -d $user_nixpkgs + if test ! -e $user_nixpkgs && test -L $user_nixpkgs + echo "~/.config/nixpkgs is a broken symlink, deleting it" + rm $channel_root + end + echo "user nixpkgs folder $user_nixpkgs does not exist, creating it" + mkdir -p $user_nixpkgs + end + if test -L $hm_config_dir -a (path resolve $hm_config_dir) = (path resolve (status basename)) + if test y = (read --nchars=1 --prompt-str="$hm_config_dir already exists as a symlink to the current directory. Remove it [yN]? ") + unlink $hm_config_dir + end + end + if test ! -d $hm_config_dir + echo "user home-manager configuration folder $hm_config_dir does not exist, creating it" + mkdir -p $hm_config_dir + end + if test ! -e $channel_root + if test -L $channel_root + # broken symlink + rm $channel_root + end + echo "channel root $channel_root does not exist, creating it" + mkdir -p $channel_root + else + if test ! -d $channel_root + echo "error: $channel_root is not a directory" + else if test -L $channel_root + echo "error: $channel_root is a symlink, please remove it" + else if path is --invert --perm write $channel_root + echo "error: $channel_root is not writable; might be a symlink" + else if path is --invert --type link $channel_root/* + for p in (path filter --invert --type link $channel_root/*) + # might be a broken symlink + if test -L $p -a ! -e $p + rm $p + else + echo "error: channel $p is not a broken symlink, don't know what to do with it" + end + end + # check again and fail if there are still unknown files + if path is --invert --type link $channel_root/* + echo "error: non-link(s) in $channel_root" + path filter --invert --type link $channel_root/* + else + continue + end + else + continue # with script + end + exit 1 + end +end + +set --function current_script_name (status basename) +switch $current_script_name + case darwin-rebuild + set --local darwin_config_source $nixfiles/system/$hostname.nix + set --local darwin_config_target $user_nixpkgs/darwin-configuration.nix + if test ! -e $darwin_config_target + ln -s $darwin_config_source $darwin_config_target + end + set --append argv -I darwin-config=$darwin_config_source + case nixos-rebuild + set --local nixos_config_source $nixfiles/system/$hostname.nix + set --local nixos_config_target $user_nixpkgs/configuration.nix + if test ! -e $nixos_config_target + ln -s $nixos_config_source $nixos_config_target + end + if ! fish_is_root_user + set --append argv --use-remote-sudo + end + set --append argv -I nixos-config=$nixos_config_source + case home-manager + set --local hm_config_source $nixfiles/user/$hostname.nix + set --local hm_config_target $hm_config_dir/home.nix + if test ! -e $hm_config_target + ln -s $hm_config_source $hm_config_target + end + set --export HOME_MANAGER_CONFIG $hm_config_source +end + +set --function old_channels (path basename $channel_root/*) + +function update_link --argument-names new_src target + set --function current_src (path resolve $target) + if test -e $current_src + if test $current_src = $new_src + # no need to re-link it + return + else + unlink $target + end + end + ln -s $new_src $target +end + +for np in $NIX_PATH + if string match --quiet --entire "=" $np + echo $np | read --function --delimiter "=" channel new_src_rel + set --local new_src (path resolve $new_src_rel) + + if test $channel = darwin-config + continue + end + if set --local i (contains --index $channel $old_channels) + set --erase old_channels[$i] + end + + update_link $new_src $channel_root/$channel + end +end + +for old in $channel_root/$old_channels + rm $old +end + +if set --function i (contains --index (status dirname) $PATH) && test -n $i + set --erase PATH[$i] +end + +set --function cmd $current_script_name $argv + +if contains -- -n $argv + set --prepend cmd echo +end + +if set --query IN_NIX_SHELL + eval $cmd +else + nix-shell --run "$cmd" +end diff --git a/bin/nixos-rebuild b/bin/nixos-rebuild new file mode 120000 index 00000000..2eaccdef --- /dev/null +++ b/bin/nixos-rebuild @@ -0,0 +1 @@ +home-manager \ No newline at end of file diff --git a/flake.lock b/flake.lock deleted file mode 100644 index e968f6f6..00000000 --- a/flake.lock +++ /dev/null @@ -1,619 +0,0 @@ -{ - "nodes": { - "agenix": { - "inputs": { - "darwin": "darwin", - "home-manager": "home-manager", - "nixpkgs": [ - "nixpkgs" - ], - "systems": "systems" - }, - "locked": { - "lastModified": 1715290355, - "narHash": "sha256-2T7CHTqBXJJ3ZC6R/4TXTcKoXWHcvubKNj9SfomURnw=", - "owner": "ryantm", - "repo": "agenix", - "rev": "8d37c5bdeade12b6479c85acd133063ab53187a0", - "type": "github" - }, - "original": { - "owner": "ryantm", - "repo": "agenix", - "type": "github" - } - }, - "darwin": { - "inputs": { - "nixpkgs": [ - "agenix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1700795494, - "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", - "owner": "lnl7", - "repo": "nix-darwin", - "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", - "type": "github" - }, - "original": { - "owner": "lnl7", - "ref": "master", - "repo": "nix-darwin", - "type": "github" - } - }, - "darwin_2": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1713946171, - "narHash": "sha256-lc75rgRQLdp4Dzogv5cfqOg6qYc5Rp83oedF2t0kDp8=", - "owner": "lnl7", - "repo": "nix-darwin", - "rev": "230a197063de9287128e2c68a7a4b0cd7d0b50a7", - "type": "github" - }, - "original": { - "owner": "lnl7", - "ref": "master", - "repo": "nix-darwin", - "type": "github" - } - }, - "deploy-rs": { - "inputs": { - "flake-compat": "flake-compat", - "nixpkgs": "nixpkgs", - "utils": "utils" - }, - "locked": { - "lastModified": 1711973905, - "narHash": "sha256-UFKME/N1pbUtn+2Aqnk+agUt8CekbpuqwzljivfIme8=", - "owner": "serokell", - "repo": "deploy-rs", - "rev": "88b3059b020da69cbe16526b8d639bd5e0b51c8b", - "type": "github" - }, - "original": { - "owner": "serokell", - "repo": "deploy-rs", - "type": "github" - } - }, - "emacs-overlay": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": [ - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" - }, - "locked": { - "lastModified": 1715418343, - "narHash": "sha256-DieMydUZ8oZkH2jdjPv02FXTujJoJ8u0cLXQIYApX5o=", - "owner": "nix-community", - "repo": "emacs-overlay", - "rev": "e41288bc8adbd180681d12eb4b9274a7bae7f974", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "emacs-overlay", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_2": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems_3" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_2": { - "inputs": { - "systems": "systems_4" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "searchix", - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "gomod2nix": { - "inputs": { - "flake-utils": [ - "searchix", - "flake-utils" - ], - "nixpkgs": [ - "searchix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1710154385, - "narHash": "sha256-4c3zQ2YY4BZOufaBJB4v9VBBeN2dH7iVdoJw8SDNCfI=", - "owner": "nix-community", - "repo": "gomod2nix", - "rev": "872b63ddd28f318489c929d25f1f0a3c6039c971", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "gomod2nix", - "type": "github" - } - }, - "home-manager": { - "inputs": { - "nixpkgs": [ - "agenix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1703113217, - "narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=", - "owner": "nix-community", - "repo": "home-manager", - "rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "home-manager", - "type": "github" - } - }, - "home-manager_2": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1715380449, - "narHash": "sha256-716+f9Rj3wjSyD1xitCv2FcYbgPz1WIVDj+ZBclH99Y=", - "owner": "nix-community", - "repo": "home-manager", - "rev": "d7682620185f213df384c363288093b486b2883f", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "home-manager", - "type": "github" - } - }, - "nix-index-database": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1714878592, - "narHash": "sha256-E68C03sYRsYFsK7wiGHUIJm8IsyPRALOrFoTL0glXnI=", - "owner": "Mic92", - "repo": "nix-index-database", - "rev": "a362555e9dbd4ecff3bb98969bbdb8f79fe87f10", - "type": "github" - }, - "original": { - "owner": "Mic92", - "repo": "nix-index-database", - "type": "github" - } - }, - "nixos-hardware": { - "locked": { - "lastModified": 1715148395, - "narHash": "sha256-lRxjTxY3103LGMjWdVqntKZHhlmMX12QUjeFrQMmGaE=", - "owner": "NixOS", - "repo": "nixos-hardware", - "rev": "a4e2b7909fc1bdf30c30ef21d388fde0b5cdde4a", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixos-hardware", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1702272962, - "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-small": { - "locked": { - "lastModified": 1715910673, - "narHash": "sha256-D7gtcOKMK0PFLrQHCndErNi2m5n6ddgtJdbQukL1QZE=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "22b25d36f84f5449e2799af1def209278ef75147", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable-small", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-stable": { - "locked": { - "lastModified": 1715218190, - "narHash": "sha256-R98WOBHkk8wIi103JUVQF3ei3oui4HvoZcz9tYOAwlk=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "9a9960b98418f8c385f52de3b09a63f9c561427a", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-stable_2": { - "locked": { - "lastModified": 1710695816, - "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "614b4613980a522ba49f0d194531beddbb7220d3", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1715266358, - "narHash": "sha256-doPgfj+7FFe9rfzWo1siAV2mVCasW+Bh8I1cToAXEE4=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "f1010e0469db743d14519a1efd37e23f8513d714", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1715447595, - "narHash": "sha256-VsVAUQOj/cS1LCOmMjAGeRksXIAdPnFIjCQ0XLkCsT0=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "062ca2a9370a27a35c524dc82d540e6e9824b652", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1710765496, - "narHash": "sha256-p7ryWEeQfMwTB6E0wIUd5V2cFTgq+DRRBz2hYGnJZyA=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "e367f7a1fb93137af22a3908f00b9a35e2d286a7", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "pre-commit-hooks": { - "inputs": { - "flake-compat": "flake-compat_2", - "flake-utils": [ - "searchix", - "flake-utils" - ], - "gitignore": "gitignore", - "nixpkgs": "nixpkgs_4", - "nixpkgs-stable": "nixpkgs-stable_2" - }, - "locked": { - "lastModified": 1714478972, - "narHash": "sha256-q//cgb52vv81uOuwz1LaXElp3XAe1TqrABXODAEF6Sk=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "2849da033884f54822af194400f8dff435ada242", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, - "root": { - "inputs": { - "agenix": "agenix", - "darwin": "darwin_2", - "deploy-rs": "deploy-rs", - "emacs-overlay": "emacs-overlay", - "home-manager": "home-manager_2", - "nix-index-database": "nix-index-database", - "nixos-hardware": "nixos-hardware", - "nixpkgs": "nixpkgs_2", - "nixpkgs-small": "nixpkgs-small", - "searchix": "searchix", - "secrets": "secrets", - "utils": "utils_2" - } - }, - "searchix": { - "inputs": { - "flake-utils": "flake-utils_2", - "gomod2nix": "gomod2nix", - "nixpkgs": "nixpkgs_3", - "pre-commit-hooks": "pre-commit-hooks", - "simple-css": "simple-css" - }, - "locked": { - "lastModified": 1715960277, - "narHash": "sha256-b/iq6O1Y4DkiPBWjiu+20lGzDVGYKVpx7SL85UKm3Fw=", - "ref": "refs/heads/main", - "rev": "8df293c0ad8b8be9f43f2d5dc1334b8546d6f470", - "revCount": 168, - "type": "git", - "url": "https://git.alanpearce.eu/searchix" - }, - "original": { - "type": "git", - "url": "https://git.alanpearce.eu/searchix" - } - }, - "secrets": { - "flake": false, - "locked": { - "lastModified": 1712637001, - "narHash": "sha256-0JUbvcWQRAZKubLIn0TTA83v1g/QyjxUiTckVdU189k=", - "ref": "refs/heads/main", - "rev": "5264068d4f5b85bc3b08e4b86ca46e49d8a411eb", - "revCount": 62, - "type": "git", - "url": "file:///home/alan/projects/alanpearce.eu/nixfiles/private" - }, - "original": { - "id": "secrets", - "type": "indirect" - } - }, - "simple-css": { - "flake": false, - "locked": { - "narHash": "sha256-AAA6fucfxB8R7z66UjOps79XMxbK/gZAB+JDEpZeXGo=", - "type": "file", - "url": "https://raw.githubusercontent.com/kevquirk/simple.css/v2.3.0/simple.css" - }, - "original": { - "type": "file", - "url": "https://raw.githubusercontent.com/kevquirk/simple.css/v2.3.0/simple.css" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_3": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_4": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_5": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "utils": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "utils_2": { - "inputs": { - "systems": "systems_5" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 459d2202..00000000 --- a/flake.nix +++ /dev/null @@ -1,186 +0,0 @@ -{ - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - nixpkgs-small.url = "github:NixOS/nixpkgs/nixos-unstable-small"; - nixos-hardware.url = "github:NixOS/nixos-hardware"; - nix-index-database.url = "github:Mic92/nix-index-database"; - nix-index-database.inputs.nixpkgs.follows = "nixpkgs"; - darwin.url = "github:lnl7/nix-darwin/master"; - darwin.inputs.nixpkgs.follows = "nixpkgs"; - home-manager.url = "github:nix-community/home-manager"; - home-manager.inputs.nixpkgs.follows = "nixpkgs"; - emacs-overlay.url = "github:nix-community/emacs-overlay"; - emacs-overlay.inputs.nixpkgs.follows = "nixpkgs"; - secrets = { - flake = false; - }; - utils.url = "github:numtide/flake-utils"; - agenix.url = "github:ryantm/agenix"; - agenix.inputs.nixpkgs.follows = "nixpkgs"; - deploy-rs.url = "github:serokell/deploy-rs"; - searchix.url = "git+https://git.alanpearce.eu/searchix"; - }; - - outputs = - inputs@ - { self - , utils - , nixpkgs - , nixpkgs-small - , nixos-hardware - , home-manager - , darwin - , nix-index-database - , secrets - , emacs-overlay - , agenix - , deploy-rs - , searchix - , ... - }: - let - readOverlays = path: - let content = builtins.readDir path; in - map (n: import (path + ("/" + n))) - (builtins.filter - (n: - (builtins.match ".*\\.nix" n != null && - # ignore Emacs lock files (.#foo.nix) - builtins.match "\\.#.*" n == null) || - builtins.pathExists (path + ("/" + n + "/default.nix"))) - (builtins.attrNames content)); - - mkHomeConfiguration = { modules, system }: home-manager.lib.homeManagerConfiguration { - pkgs = import nixpkgs { - inherit system; - overlays = readOverlays (toString ./overlays) ++ [ emacs-overlay.overlay ]; - }; - - inherit modules; - extraSpecialArgs = { - inherit inputs system; - }; - }; - in - { - nixosConfigurations.prefect = nixpkgs.lib.nixosSystem { - system = utils.lib.system.x86_64-linux; - specialArgs = { inherit inputs; }; - modules = [ - ./system/prefect.nix - ] ++ (with nixos-hardware.nixosModules; [ - common-cpu-amd - common-cpu-amd-pstate - common-pc-ssd - common-pc - common-gpu-nvidia-nonprime - ]); - }; - nixosConfigurations.nanopi = nixpkgs-small.lib.nixosSystem { - system = utils.lib.system.aarch64-linux; - specialArgs = { inherit inputs; }; - modules = [ - agenix.nixosModules.default - ./system/nanopi.nix - ]; - }; - nixosConfigurations.linde = nixpkgs-small.lib.nixosSystem { - system = utils.lib.system.aarch64-linux; - specialArgs = { inherit inputs; }; - modules = [ - agenix.nixosModules.default - searchix.nixosModules.default - ./system/linde.nix - ]; - }; - darwinConfigurations.mba = darwin.lib.darwinSystem { - system = utils.lib.system.aarch64-darwin; - specialArgs = { inherit inputs; }; - modules = [ ./system/mba.nix ]; - }; - homeConfigurations."alan@mba" = mkHomeConfiguration { - system = utils.lib.system.aarch64-darwin; - modules = [ - ./user/mba.nix - nix-index-database.hmModules.nix-index - (secrets + "/default.nix") - (secrets + "/ssh.nix") - ]; - }; - homeConfigurations."alan@prefect" = mkHomeConfiguration { - system = utils.lib.system.x86_64-linux; - modules = [ - ./user/prefect.nix - nix-index-database.hmModules.nix-index - (secrets + "/default.nix") - (secrets + "/ssh.nix") - ]; - }; - homeConfigurations."alan@nanopi" = mkHomeConfiguration { - system = utils.lib.system.aarch64-linux; - modules = [ - ./user/nanopi.nix - nix-index-database.hmModules.nix-index - (secrets + "/default.nix") - ]; - }; - homeConfigurations."alan@linde" = mkHomeConfiguration { - system = utils.lib.system.aarch64-linux; - modules = [ - ./user/server.nix - nix-index-database.hmModules.nix-index - (secrets + "/default.nix") - ]; - }; - - checks = builtins.mapAttrs - (system: deployLib: - deployLib.deployChecks self.deploy) - deploy-rs.lib; - - deploy = { - remoteBuild = true; - nodes.linde = { - hostname = "linde"; - profiles.system = { - user = "root"; - interactiveSudo = true; - path = deploy-rs.lib.${utils.lib.system.aarch64-linux}.activate.nixos - self.nixosConfigurations.linde; - }; - profiles.alan = { - user = "alan"; - path = deploy-rs.lib.${utils.lib.system.aarch64-linux}.activate.home-manager - self.homeConfigurations."alan@linde"; - }; - }; - nodes.nanopi = { - hostname = "nanopi"; - profiles.system = { - user = "root"; - interactiveSudo = true; - path = deploy-rs.lib.${utils.lib.system.aarch64-linux}.activate.nixos - self.nixosConfigurations.nanopi; - }; - profiles.alan = { - user = "alan"; - path = deploy-rs.lib.${utils.lib.system.aarch64-linux}.activate.home-manager - self.homeConfigurations."alan@nanopi"; - }; - }; - }; - } // utils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { inherit system; }; - in - { - devShells = { - default = pkgs.mkShell { - packages = [ - deploy-rs.packages.${system}.default - agenix.packages.${system}.default - ]; - }; - }; - }); -} diff --git a/lib/caddy.nix b/lib/caddy.nix new file mode 100644 index 00000000..42777eeb --- /dev/null +++ b/lib/caddy.nix @@ -0,0 +1,47 @@ +{ lib +, ... +}: +rec { + subValue = v: + if builtins.isList v + then + builtins.concatStringsSep " " + (builtins.map + (v: + (if lib.strings.hasPrefix "http" v + then v + else "'${v}'")) + v) + else toString v; + + headerValue = sep: val: + if builtins.isAttrs val + then + builtins.concatStringsSep "; " + (lib.attrsets.mapAttrsToList + (k: v: + if builtins.isBool v then k else + "${k}${sep}${subValue v}" + ) + val) + else toString val; + genHeader = header: + let + sep = if header == "content-security-policy" then " " else "="; + in + value: "${header} \"${headerValue sep value}\""; + + headers = matcher: headers: '' + header ${matcher} { + ${builtins.concatStringsSep "\n" + (lib.attrsets.mapAttrsToList genHeader headers)} + } + ''; + security-headers = { matcher ? "", overrides ? { } }: headers matcher ({ + strict-transport-security = { + max-age = 2 * 365 * 24 * 60 * 60; + }; + x-content-type-options = "nosniff"; + x-frame-options = "DENY"; + } // overrides); +} diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 00000000..2cbaf55c --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,25 @@ +{ pkgs }: +with builtins; +let + inherit (pkgs) lib; +in +rec { + importPathStore = p: "${append ../. "/${p}"}"; + + mkPathable = s: toString ( + if lib.path.subpath.isValid s + then (lib.path.append ../. s) + else s + ); + + kvPath = k: v: "${k}=${v}"; + + fromSources = sources: + lib.attrsets.mapAttrs + (k: v: v.outPath) + sources; + + mkNixPath = sources: lib.attrsets.mapAttrsToList + (k: v: kvPath k (mkPathable v)) + sources; +} diff --git a/npins/default.nix b/npins/default.nix new file mode 100644 index 00000000..5e7d086e --- /dev/null +++ b/npins/default.nix @@ -0,0 +1,80 @@ +# Generated by npins. Do not modify; will be overwritten regularly +let + data = builtins.fromJSON (builtins.readFile ./sources.json); + version = data.version; + + mkSource = + spec: + assert spec ? type; + let + path = + if spec.type == "Git" then + mkGitSource spec + else if spec.type == "GitRelease" then + mkGitSource spec + else if spec.type == "PyPi" then + mkPyPiSource spec + else if spec.type == "Channel" then + mkChannelSource spec + else + builtins.throw "Unknown source type ${spec.type}"; + in + spec // { outPath = path; }; + + mkGitSource = + { + repository, + revision, + url ? null, + hash, + branch ? null, + ... + }: + assert repository ? type; + # At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository + # In the latter case, there we will always be an url to the tarball + if url != null then + (builtins.fetchTarball { + inherit url; + sha256 = hash; # FIXME: check nix version & use SRI hashes + }) + else + assert repository.type == "Git"; + let + urlToName = + url: rev: + let + matched = builtins.match "^.*/([^/]*)(\\.git)?$" repository.url; + + short = builtins.substring 0 7 rev; + + appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else ""; + in + "${if matched == null then "source" else builtins.head matched}${appendShort}"; + name = urlToName repository.url revision; + in + builtins.fetchGit { + url = repository.url; + rev = revision; + inherit name; + # hash = hash; + }; + + mkPyPiSource = + { url, hash, ... }: + builtins.fetchurl { + inherit url; + sha256 = hash; + }; + + mkChannelSource = + { url, hash, ... }: + builtins.fetchTarball { + inherit url; + sha256 = hash; + }; +in +if version == 3 then + builtins.mapAttrs (_: mkSource) data.pins +else + throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`" diff --git a/npins/sources.json b/npins/sources.json new file mode 100644 index 00000000..d7b43684 --- /dev/null +++ b/npins/sources.json @@ -0,0 +1,95 @@ +{ + "pins": { + "agenix": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "ryantm", + "repo": "agenix" + }, + "branch": "main", + "revision": "3a56735779db467538fb2e577eda28a9daacaca6", + "url": "https://github.com/ryantm/agenix/archive/3a56735779db467538fb2e577eda28a9daacaca6.tar.gz", + "hash": "1h66zapc6im07k3kcgvhy3lhzahb70vd6m2ijhz4i0v6mn5l3fk9" + }, + "darwin": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "lnl7", + "repo": "nix-darwin" + }, + "branch": "master", + "revision": "50581970f37f06a4719001735828519925ef8310", + "url": "https://github.com/lnl7/nix-darwin/archive/50581970f37f06a4719001735828519925ef8310.tar.gz", + "hash": "1c2zihl124j7xz5fyhkjvcpabyrvs1qgix1fzr0fc002mnkcrf13" + }, + "emacs-overlay": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "nix-community", + "repo": "emacs-overlay" + }, + "branch": "master", + "revision": "dc376600483aae0272de58ea9b2d06c9f4e132eb", + "url": "https://github.com/nix-community/emacs-overlay/archive/dc376600483aae0272de58ea9b2d06c9f4e132eb.tar.gz", + "hash": "15b1w9vg1g7zih56lh198yi8si6m7b4yxxfsn4dxffdzal415vbl" + }, + "home-manager": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "nix-community", + "repo": "home-manager" + }, + "branch": "master", + "revision": "cd886711998fe5d9ff7979fdd4b4cbd17b1f1511", + "url": "https://github.com/nix-community/home-manager/archive/cd886711998fe5d9ff7979fdd4b4cbd17b1f1511.tar.gz", + "hash": "1kvww9d28nlz2gawbrasvgpk172vzxlxdbhh1b8c41m1x7rrvqk8" + }, + "nix-index-database": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "Mic92", + "repo": "nix-index-database" + }, + "branch": "main", + "revision": "afc8f5a6a2c00a89a6d6bdcaf4157797960f10f7", + "url": "https://github.com/Mic92/nix-index-database/archive/afc8f5a6a2c00a89a6d6bdcaf4157797960f10f7.tar.gz", + "hash": "0kh8nyxp44wv5i37jwylf6vvjcwnr6zfqavxajb3zglhkrdfija6" + }, + "nixos-hardware": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "NixOS", + "repo": "nixos-hardware" + }, + "branch": "master", + "revision": "e8232c132a95ddc62df9d404120ad4ff53862910", + "url": "https://github.com/NixOS/nixos-hardware/archive/e8232c132a95ddc62df9d404120ad4ff53862910.tar.gz", + "hash": "0w6d2nk498i0hqiimfxhxj7i9zhija9sybnhbyknwl7pkc4b7lkp" + }, + "nixpkgs": { + "type": "Channel", + "name": "nixos-unstable", + "url": "https://releases.nixos.org/nixos/unstable/nixos-24.11pre642660.a71e967ef369/nixexprs.tar.xz", + "hash": "0km1smh73aqa9syc3pd6f8l8rz6jb87x8a4qx7d6x1b8932z3is2" + }, + "nur": { + "type": "Git", + "repository": { + "type": "GitHub", + "owner": "nix-community", + "repo": "NUR" + }, + "branch": "master", + "revision": "88407857c90e39f2654a0ef347c2c920c25f453c", + "url": "https://github.com/nix-community/NUR/archive/88407857c90e39f2654a0ef347c2c920c25f453c.tar.gz", + "hash": "1gn8lbgrcqx4i13p2jjqqp3n2pkrmxn8rliz53x0vdmlg4vvzrjk" + } + }, + "version": 3 +} \ No newline at end of file diff --git a/overlays/emacs.nix b/overlays/emacs.nix new file mode 100644 index 00000000..ded36707 --- /dev/null +++ b/overlays/emacs.nix @@ -0,0 +1 @@ +import <emacs-overlay> diff --git a/overlays/extra-packages.nix b/overlays/extra-packages.nix index 0e0451d0..6c64c24b 100644 --- a/overlays/extra-packages.nix +++ b/overlays/extra-packages.nix @@ -13,14 +13,4 @@ self: super: { ''; }; }); - enchant = super.enchant.overrideAttrs (old: { - configureFlags = old.configureFlags ++ [ "--without-hspell" ] - # builtins.filter (c: c != "--with-hspell") old.configureFlags - ++ self.lib.optional super.stdenv.isDarwin "--with-applespell" - ; - buildInputs = - builtins.filter (c: c.name != "hspell") old.buildInputs - ++ self.lib.optionals super.stdenv.isDarwin (with super.darwin.apple_sdk.frameworks; [ Cocoa ]); - propagatedBuildInputs = builtins.filter (c: c.name != "hspell") old.propagatedBuildInputs; - }); } diff --git a/overlays/htmlformat/default.nix b/overlays/htmlformat/default.nix deleted file mode 100644 index 93292c76..00000000 --- a/overlays/htmlformat/default.nix +++ /dev/null @@ -1,3 +0,0 @@ -self: super: { - htmlformat = super.callPackage ./htmlformat.nix { }; -} diff --git a/overlays/htmlformat/htmlformat.nix b/overlays/htmlformat/htmlformat.nix deleted file mode 100644 index aa124ee5..00000000 --- a/overlays/htmlformat/htmlformat.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ lib -, buildGoModule -, fetchFromGitHub -}: - -buildGoModule rec { - pname = "htmlformat"; - version = "unstable-2023-11-08"; - - src = fetchFromGitHub { - owner = "a-h"; - repo = "htmlformat"; - rev = "5bd994fe268e4d505a9793143fa85414c7d50887"; - hash = "sha256-YSl9GsXhc0L2oKGZLwwjUtpe5W6ra6kk74zvQdsDCMU="; - }; - - vendorHash = "sha256-uVfh1pPhfj6AyQDqFd1EDWshuyDRvbMDZj3SN5tCS2w="; - - ldflags = [ "-s" "-w" ]; - - meta = with lib; { - description = "Htmlformat"; - homepage = "https://github.com/a-h/htmlformat"; - license = licenses.mit; - maintainers = with maintainers; [ alanpearce ]; - mainProgram = "htmlformat"; - }; -} diff --git a/overlays/node-packages/default.nix b/overlays/node-packages/default.nix index b89a10a3..9c8720ff 100644 --- a/overlays/node-packages/default.nix +++ b/overlays/node-packages/default.nix @@ -1,8 +1,4 @@ self: super: { - nodePackages = super.nodePackages.extend - (final: prev: - super.callPackage ./prettier-plugin-go-template { } // { } - ); prettierd = super.prettierd.overrideAttrs (old: { patches = [ ./prettierd.patch ]; }); diff --git a/overlays/node-packages/prettier-plugin-go-template/default.nix b/overlays/node-packages/prettier-plugin-go-template/default.nix deleted file mode 100644 index d9c0daef..00000000 --- a/overlays/node-packages/prettier-plugin-go-template/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -# This file has been generated by node2nix 1.11.1. Do not edit! - -{pkgs ? import <nixpkgs> { - inherit system; - }, system ? builtins.currentSystem, nodejs ? pkgs."nodejs_18"}: - -let - nodeEnv = import ./node-env.nix { - inherit (pkgs) stdenv lib python2 runCommand writeTextFile writeShellScript; - inherit pkgs nodejs; - libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null; - }; -in -import ./node-packages.nix { - inherit (pkgs) fetchurl nix-gitignore stdenv lib fetchgit; - inherit nodeEnv; -} diff --git a/overlays/node-packages/prettier-plugin-go-template/node-env.nix b/overlays/node-packages/prettier-plugin-go-template/node-env.nix deleted file mode 100644 index bc1e3662..00000000 --- a/overlays/node-packages/prettier-plugin-go-template/node-env.nix +++ /dev/null @@ -1,689 +0,0 @@ -# This file originates from node2nix - -{lib, stdenv, nodejs, python2, pkgs, libtool, runCommand, writeTextFile, writeShellScript}: - -let - # Workaround to cope with utillinux in Nixpkgs 20.09 and util-linux in Nixpkgs master - utillinux = if pkgs ? utillinux then pkgs.utillinux else pkgs.util-linux; - - python = if nodejs ? python then nodejs.python else python2; - - # Create a tar wrapper that filters all the 'Ignoring unknown extended header keyword' noise - tarWrapper = runCommand "tarWrapper" {} '' - mkdir -p $out/bin - - cat > $out/bin/tar <<EOF - #! ${stdenv.shell} -e - $(type -p tar) "\$@" --warning=no-unknown-keyword --delay-directory-restore - EOF - - chmod +x $out/bin/tar - ''; - - # Function that generates a TGZ file from a NPM project - buildNodeSourceDist = - { name, version, src, ... }: - - stdenv.mkDerivation { - name = "node-tarball-${name}-${version}"; - inherit src; - buildInputs = [ nodejs ]; - buildPhase = '' - export HOME=$TMPDIR - tgzFile=$(npm pack | tail -n 1) # Hooks to the pack command will add output (https://docs.npmjs.com/misc/scripts) - ''; - installPhase = '' - mkdir -p $out/tarballs - mv $tgzFile $out/tarballs - mkdir -p $out/nix-support - echo "file source-dist $out/tarballs/$tgzFile" >> $out/nix-support/hydra-build-products - ''; - }; - - # Common shell logic - installPackage = writeShellScript "install-package" '' - installPackage() { - local packageName=$1 src=$2 - - local strippedName - - local DIR=$PWD - cd $TMPDIR - - unpackFile $src - - # Make the base dir in which the target dependency resides first - mkdir -p "$(dirname "$DIR/$packageName")" - - if [ -f "$src" ] - then - # Figure out what directory has been unpacked - packageDir="$(find . -maxdepth 1 -type d | tail -1)" - - # Restore write permissions to make building work - find "$packageDir" -type d -exec chmod u+x {} \; - chmod -R u+w "$packageDir" - - # Move the extracted tarball into the output folder - mv "$packageDir" "$DIR/$packageName" - elif [ -d "$src" ] - then - # Get a stripped name (without hash) of the source directory. - # On old nixpkgs it's already set internally. - if [ -z "$strippedName" ] - then - strippedName="$(stripHash $src)" - fi - - # Restore write permissions to make building work - chmod -R u+w "$strippedName" - - # Move the extracted directory into the output folder - mv "$strippedName" "$DIR/$packageName" - fi - - # Change to the package directory to install dependencies - cd "$DIR/$packageName" - } - ''; - - # Bundle the dependencies of the package - # - # Only include dependencies if they don't exist. They may also be bundled in the package. - includeDependencies = {dependencies}: - lib.optionalString (dependencies != []) ( - '' - mkdir -p node_modules - cd node_modules - '' - + (lib.concatMapStrings (dependency: - '' - if [ ! -e "${dependency.packageName}" ]; then - ${composePackage dependency} - fi - '' - ) dependencies) - + '' - cd .. - '' - ); - - # Recursively composes the dependencies of a package - composePackage = { name, packageName, src, dependencies ? [], ... }@args: - builtins.addErrorContext "while evaluating node package '${packageName}'" '' - installPackage "${packageName}" "${src}" - ${includeDependencies { inherit dependencies; }} - cd .. - ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."} - ''; - - pinpointDependencies = {dependencies, production}: - let - pinpointDependenciesFromPackageJSON = writeTextFile { - name = "pinpointDependencies.js"; - text = '' - var fs = require('fs'); - var path = require('path'); - - function resolveDependencyVersion(location, name) { - if(location == process.env['NIX_STORE']) { - return null; - } else { - var dependencyPackageJSON = path.join(location, "node_modules", name, "package.json"); - - if(fs.existsSync(dependencyPackageJSON)) { - var dependencyPackageObj = JSON.parse(fs.readFileSync(dependencyPackageJSON)); - - if(dependencyPackageObj.name == name) { - return dependencyPackageObj.version; - } - } else { - return resolveDependencyVersion(path.resolve(location, ".."), name); - } - } - } - - function replaceDependencies(dependencies) { - if(typeof dependencies == "object" && dependencies !== null) { - for(var dependency in dependencies) { - var resolvedVersion = resolveDependencyVersion(process.cwd(), dependency); - - if(resolvedVersion === null) { - process.stderr.write("WARNING: cannot pinpoint dependency: "+dependency+", context: "+process.cwd()+"\n"); - } else { - dependencies[dependency] = resolvedVersion; - } - } - } - } - - /* Read the package.json configuration */ - var packageObj = JSON.parse(fs.readFileSync('./package.json')); - - /* Pinpoint all dependencies */ - replaceDependencies(packageObj.dependencies); - if(process.argv[2] == "development") { - replaceDependencies(packageObj.devDependencies); - } - else { - packageObj.devDependencies = {}; - } - replaceDependencies(packageObj.optionalDependencies); - replaceDependencies(packageObj.peerDependencies); - - /* Write the fixed package.json file */ - fs.writeFileSync("package.json", JSON.stringify(packageObj, null, 2)); - ''; - }; - in - '' - node ${pinpointDependenciesFromPackageJSON} ${if production then "production" else "development"} - - ${lib.optionalString (dependencies != []) - '' - if [ -d node_modules ] - then - cd node_modules - ${lib.concatMapStrings (dependency: pinpointDependenciesOfPackage dependency) dependencies} - cd .. - fi - ''} - ''; - - # Recursively traverses all dependencies of a package and pinpoints all - # dependencies in the package.json file to the versions that are actually - # being used. - - pinpointDependenciesOfPackage = { packageName, dependencies ? [], production ? true, ... }@args: - '' - if [ -d "${packageName}" ] - then - cd "${packageName}" - ${pinpointDependencies { inherit dependencies production; }} - cd .. - ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."} - fi - ''; - - # Extract the Node.js source code which is used to compile packages with - # native bindings - nodeSources = runCommand "node-sources" {} '' - tar --no-same-owner --no-same-permissions -xf ${nodejs.src} - mv node-* $out - ''; - - # Script that adds _integrity fields to all package.json files to prevent NPM from consulting the cache (that is empty) - addIntegrityFieldsScript = writeTextFile { - name = "addintegrityfields.js"; - text = '' - var fs = require('fs'); - var path = require('path'); - - function augmentDependencies(baseDir, dependencies) { - for(var dependencyName in dependencies) { - var dependency = dependencies[dependencyName]; - - // Open package.json and augment metadata fields - var packageJSONDir = path.join(baseDir, "node_modules", dependencyName); - var packageJSONPath = path.join(packageJSONDir, "package.json"); - - if(fs.existsSync(packageJSONPath)) { // Only augment packages that exist. Sometimes we may have production installs in which development dependencies can be ignored - console.log("Adding metadata fields to: "+packageJSONPath); - var packageObj = JSON.parse(fs.readFileSync(packageJSONPath)); - - if(dependency.integrity) { - packageObj["_integrity"] = dependency.integrity; - } else { - packageObj["_integrity"] = "sha1-000000000000000000000000000="; // When no _integrity string has been provided (e.g. by Git dependencies), add a dummy one. It does not seem to harm and it bypasses downloads. - } - - if(dependency.resolved) { - packageObj["_resolved"] = dependency.resolved; // Adopt the resolved property if one has been provided - } else { - packageObj["_resolved"] = dependency.version; // Set the resolved version to the version identifier. This prevents NPM from cloning Git repositories. - } - - if(dependency.from !== undefined) { // Adopt from property if one has been provided - packageObj["_from"] = dependency.from; - } - - fs.writeFileSync(packageJSONPath, JSON.stringify(packageObj, null, 2)); - } - - // Augment transitive dependencies - if(dependency.dependencies !== undefined) { - augmentDependencies(packageJSONDir, dependency.dependencies); - } - } - } - - if(fs.existsSync("./package-lock.json")) { - var packageLock = JSON.parse(fs.readFileSync("./package-lock.json")); - - if(![1, 2].includes(packageLock.lockfileVersion)) { - process.stderr.write("Sorry, I only understand lock file versions 1 and 2!\n"); - process.exit(1); - } - - if(packageLock.dependencies !== undefined) { - augmentDependencies(".", packageLock.dependencies); - } - } - ''; - }; - - # Reconstructs a package-lock file from the node_modules/ folder structure and package.json files with dummy sha1 hashes - reconstructPackageLock = writeTextFile { - name = "reconstructpackagelock.js"; - text = '' - var fs = require('fs'); - var path = require('path'); - - var packageObj = JSON.parse(fs.readFileSync("package.json")); - - var lockObj = { - name: packageObj.name, - version: packageObj.version, - lockfileVersion: 2, - requires: true, - packages: { - "": { - name: packageObj.name, - version: packageObj.version, - license: packageObj.license, - bin: packageObj.bin, - dependencies: packageObj.dependencies, - engines: packageObj.engines, - optionalDependencies: packageObj.optionalDependencies - } - }, - dependencies: {} - }; - - function augmentPackageJSON(filePath, packages, dependencies) { - var packageJSON = path.join(filePath, "package.json"); - if(fs.existsSync(packageJSON)) { - var packageObj = JSON.parse(fs.readFileSync(packageJSON)); - packages[filePath] = { - version: packageObj.version, - integrity: "sha1-000000000000000000000000000=", - dependencies: packageObj.dependencies, - engines: packageObj.engines, - optionalDependencies: packageObj.optionalDependencies - }; - dependencies[packageObj.name] = { - version: packageObj.version, - integrity: "sha1-000000000000000000000000000=", - dependencies: {} - }; - processDependencies(path.join(filePath, "node_modules"), packages, dependencies[packageObj.name].dependencies); - } - } - - function processDependencies(dir, packages, dependencies) { - if(fs.existsSync(dir)) { - var files = fs.readdirSync(dir); - - files.forEach(function(entry) { - var filePath = path.join(dir, entry); - var stats = fs.statSync(filePath); - - if(stats.isDirectory()) { - if(entry.substr(0, 1) == "@") { - // When we encounter a namespace folder, augment all packages belonging to the scope - var pkgFiles = fs.readdirSync(filePath); - - pkgFiles.forEach(function(entry) { - if(stats.isDirectory()) { - var pkgFilePath = path.join(filePath, entry); - augmentPackageJSON(pkgFilePath, packages, dependencies); - } - }); - } else { - augmentPackageJSON(filePath, packages, dependencies); - } - } - }); - } - } - - processDependencies("node_modules", lockObj.packages, lockObj.dependencies); - - fs.writeFileSync("package-lock.json", JSON.stringify(lockObj, null, 2)); - ''; - }; - - # Script that links bins defined in package.json to the node_modules bin directory - # NPM does not do this for top-level packages itself anymore as of v7 - linkBinsScript = writeTextFile { - name = "linkbins.js"; - text = '' - var fs = require('fs'); - var path = require('path'); - - var packageObj = JSON.parse(fs.readFileSync("package.json")); - - var nodeModules = Array(packageObj.name.split("/").length).fill("..").join(path.sep); - - if(packageObj.bin !== undefined) { - fs.mkdirSync(path.join(nodeModules, ".bin")) - - if(typeof packageObj.bin == "object") { - Object.keys(packageObj.bin).forEach(function(exe) { - if(fs.existsSync(packageObj.bin[exe])) { - console.log("linking bin '" + exe + "'"); - fs.symlinkSync( - path.join("..", packageObj.name, packageObj.bin[exe]), - path.join(nodeModules, ".bin", exe) - ); - } - else { - console.log("skipping non-existent bin '" + exe + "'"); - } - }) - } - else { - if(fs.existsSync(packageObj.bin)) { - console.log("linking bin '" + packageObj.bin + "'"); - fs.symlinkSync( - path.join("..", packageObj.name, packageObj.bin), - path.join(nodeModules, ".bin", packageObj.name.split("/").pop()) - ); - } - else { - console.log("skipping non-existent bin '" + packageObj.bin + "'"); - } - } - } - else if(packageObj.directories !== undefined && packageObj.directories.bin !== undefined) { - fs.mkdirSync(path.join(nodeModules, ".bin")) - - fs.readdirSync(packageObj.directories.bin).forEach(function(exe) { - if(fs.existsSync(path.join(packageObj.directories.bin, exe))) { - console.log("linking bin '" + exe + "'"); - fs.symlinkSync( - path.join("..", packageObj.name, packageObj.directories.bin, exe), - path.join(nodeModules, ".bin", exe) - ); - } - else { - console.log("skipping non-existent bin '" + exe + "'"); - } - }) - } - ''; - }; - - prepareAndInvokeNPM = {packageName, bypassCache, reconstructLock, npmFlags, production}: - let - forceOfflineFlag = if bypassCache then "--offline" else "--registry http://www.example.com"; - in - '' - # Pinpoint the versions of all dependencies to the ones that are actually being used - echo "pinpointing versions of dependencies..." - source $pinpointDependenciesScriptPath - - # Patch the shebangs of the bundled modules to prevent them from - # calling executables outside the Nix store as much as possible - patchShebangs . - - # Deploy the Node.js package by running npm install. Since the - # dependencies have been provided already by ourselves, it should not - # attempt to install them again, which is good, because we want to make - # it Nix's responsibility. If it needs to install any dependencies - # anyway (e.g. because the dependency parameters are - # incomplete/incorrect), it fails. - # - # The other responsibilities of NPM are kept -- version checks, build - # steps, postprocessing etc. - - export HOME=$TMPDIR - cd "${packageName}" - runHook preRebuild - - ${lib.optionalString bypassCache '' - ${lib.optionalString reconstructLock '' - if [ -f package-lock.json ] - then - echo "WARNING: Reconstruct lock option enabled, but a lock file already exists!" - echo "This will most likely result in version mismatches! We will remove the lock file and regenerate it!" - rm package-lock.json - else - echo "No package-lock.json file found, reconstructing..." - fi - - node ${reconstructPackageLock} - ''} - - node ${addIntegrityFieldsScript} - ''} - - npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${lib.optionalString production "--production"} rebuild - - runHook postRebuild - - if [ "''${dontNpmInstall-}" != "1" ] - then - # NPM tries to download packages even when they already exist if npm-shrinkwrap is used. - rm -f npm-shrinkwrap.json - - npm ${forceOfflineFlag} --nodedir=${nodeSources} --no-bin-links --ignore-scripts ${npmFlags} ${lib.optionalString production "--production"} install - fi - - # Link executables defined in package.json - node ${linkBinsScript} - ''; - - # Builds and composes an NPM package including all its dependencies - buildNodePackage = - { name - , packageName - , version ? null - , dependencies ? [] - , buildInputs ? [] - , production ? true - , npmFlags ? "" - , dontNpmInstall ? false - , bypassCache ? false - , reconstructLock ? false - , preRebuild ? "" - , dontStrip ? true - , unpackPhase ? "true" - , buildPhase ? "true" - , meta ? {} - , ... }@args: - - let - extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" "dontStrip" "dontNpmInstall" "preRebuild" "unpackPhase" "buildPhase" "meta" ]; - in - stdenv.mkDerivation ({ - name = "${name}${if version == null then "" else "-${version}"}"; - buildInputs = [ tarWrapper python nodejs ] - ++ lib.optional (stdenv.isLinux) utillinux - ++ lib.optional (stdenv.isDarwin) libtool - ++ buildInputs; - - inherit nodejs; - - inherit dontStrip; # Stripping may fail a build for some package deployments - inherit dontNpmInstall preRebuild unpackPhase buildPhase; - - compositionScript = composePackage args; - pinpointDependenciesScript = pinpointDependenciesOfPackage args; - - passAsFile = [ "compositionScript" "pinpointDependenciesScript" ]; - - installPhase = '' - source ${installPackage} - - # Create and enter a root node_modules/ folder - mkdir -p $out/lib/node_modules - cd $out/lib/node_modules - - # Compose the package and all its dependencies - source $compositionScriptPath - - ${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }} - - # Create symlink to the deployed executable folder, if applicable - if [ -d "$out/lib/node_modules/.bin" ] - then - ln -s $out/lib/node_modules/.bin $out/bin - - # Fixup all executables - ls $out/bin/* | while read i - do - file="$(readlink -f "$i")" - chmod u+rwx "$file" - if isScript "$file" - then - sed -i 's/\r$//' "$file" # convert crlf to lf - fi - done - fi - - # Create symlinks to the deployed manual page folders, if applicable - if [ -d "$out/lib/node_modules/${packageName}/man" ] - then - mkdir -p $out/share - for dir in "$out/lib/node_modules/${packageName}/man/"* - do - mkdir -p $out/share/man/$(basename "$dir") - for page in "$dir"/* - do - ln -s $page $out/share/man/$(basename "$dir") - done - done - fi - - # Run post install hook, if provided - runHook postInstall - ''; - - meta = { - # default to Node.js' platforms - platforms = nodejs.meta.platforms; - } // meta; - } // extraArgs); - - # Builds a node environment (a node_modules folder and a set of binaries) - buildNodeDependencies = - { name - , packageName - , version ? null - , src - , dependencies ? [] - , buildInputs ? [] - , production ? true - , npmFlags ? "" - , dontNpmInstall ? false - , bypassCache ? false - , reconstructLock ? false - , dontStrip ? true - , unpackPhase ? "true" - , buildPhase ? "true" - , ... }@args: - - let - extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" ]; - in - stdenv.mkDerivation ({ - name = "node-dependencies-${name}${if version == null then "" else "-${version}"}"; - - buildInputs = [ tarWrapper python nodejs ] - ++ lib.optional (stdenv.isLinux) utillinux - ++ lib.optional (stdenv.isDarwin) libtool - ++ buildInputs; - - inherit dontStrip; # Stripping may fail a build for some package deployments - inherit dontNpmInstall unpackPhase buildPhase; - - includeScript = includeDependencies { inherit dependencies; }; - pinpointDependenciesScript = pinpointDependenciesOfPackage args; - - passAsFile = [ "includeScript" "pinpointDependenciesScript" ]; - - installPhase = '' - source ${installPackage} - - mkdir -p $out/${packageName} - cd $out/${packageName} - - source $includeScriptPath - - # Create fake package.json to make the npm commands work properly - cp ${src}/package.json . - chmod 644 package.json - ${lib.optionalString bypassCache '' - if [ -f ${src}/package-lock.json ] - then - cp ${src}/package-lock.json . - chmod 644 package-lock.json - fi - ''} - - # Go to the parent folder to make sure that all packages are pinpointed - cd .. - ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."} - - ${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }} - - # Expose the executables that were installed - cd .. - ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."} - - mv ${packageName} lib - ln -s $out/lib/node_modules/.bin $out/bin - ''; - } // extraArgs); - - # Builds a development shell - buildNodeShell = - { name - , packageName - , version ? null - , src - , dependencies ? [] - , buildInputs ? [] - , production ? true - , npmFlags ? "" - , dontNpmInstall ? false - , bypassCache ? false - , reconstructLock ? false - , dontStrip ? true - , unpackPhase ? "true" - , buildPhase ? "true" - , ... }@args: - - let - nodeDependencies = buildNodeDependencies args; - extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" "dontStrip" "dontNpmInstall" "unpackPhase" "buildPhase" ]; - in - stdenv.mkDerivation ({ - name = "node-shell-${name}${if version == null then "" else "-${version}"}"; - - buildInputs = [ python nodejs ] ++ lib.optional (stdenv.isLinux) utillinux ++ buildInputs; - buildCommand = '' - mkdir -p $out/bin - cat > $out/bin/shell <<EOF - #! ${stdenv.shell} -e - $shellHook - exec ${stdenv.shell} - EOF - chmod +x $out/bin/shell - ''; - - # Provide the dependencies in a development shell through the NODE_PATH environment variable - inherit nodeDependencies; - shellHook = lib.optionalString (dependencies != []) '' - export NODE_PATH=${nodeDependencies}/lib/node_modules - export PATH="${nodeDependencies}/bin:$PATH" - ''; - } // extraArgs); -in -{ - buildNodeSourceDist = lib.makeOverridable buildNodeSourceDist; - buildNodePackage = lib.makeOverridable buildNodePackage; - buildNodeDependencies = lib.makeOverridable buildNodeDependencies; - buildNodeShell = lib.makeOverridable buildNodeShell; -} diff --git a/overlays/node-packages/prettier-plugin-go-template/node-packages.json b/overlays/node-packages/prettier-plugin-go-template/node-packages.json deleted file mode 100644 index 64857b1e..00000000 --- a/overlays/node-packages/prettier-plugin-go-template/node-packages.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "prettier-plugin-go-template" -] diff --git a/overlays/node-packages/prettier-plugin-go-template/node-packages.nix b/overlays/node-packages/prettier-plugin-go-template/node-packages.nix deleted file mode 100644 index 449c93c8..00000000 --- a/overlays/node-packages/prettier-plugin-go-template/node-packages.nix +++ /dev/null @@ -1,50 +0,0 @@ -# This file has been generated by node2nix 1.11.1. Do not edit! - -{nodeEnv, fetchurl, fetchgit, nix-gitignore, stdenv, lib, globalBuildInputs ? []}: - -let - sources = { - "prettier-3.2.5" = { - name = "prettier"; - packageName = "prettier"; - version = "3.2.5"; - src = fetchurl { - url = "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz"; - sha512 = "3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A=="; - }; - }; - "ulid-2.3.0" = { - name = "ulid"; - packageName = "ulid"; - version = "2.3.0"; - src = fetchurl { - url = "https://registry.npmjs.org/ulid/-/ulid-2.3.0.tgz"; - sha512 = "keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw=="; - }; - }; - }; -in -{ - prettier-plugin-go-template = nodeEnv.buildNodePackage { - name = "prettier-plugin-go-template"; - packageName = "prettier-plugin-go-template"; - version = "0.0.15"; - src = fetchurl { - url = "https://registry.npmjs.org/prettier-plugin-go-template/-/prettier-plugin-go-template-0.0.15.tgz"; - sha512 = "WqU92E1NokWYNZ9mLE6ijoRg6LtIGdLMePt2C7UBDjXeDH9okcRI3zRqtnWR4s5AloiqyvZ66jNBAa9tmRY5EQ=="; - }; - dependencies = [ - sources."prettier-3.2.5" - sources."ulid-2.3.0" - ]; - buildInputs = globalBuildInputs; - meta = { - description = "Prettier plugin for formatting Go & GoHugo templates."; - homepage = "https://github.com/NiklasPor/prettier-plugin-go-template#readme"; - license = "MIT"; - }; - production = true; - bypassCache = true; - reconstructLock = true; - }; -} diff --git a/overlays/nur.nix b/overlays/nur.nix new file mode 100644 index 00000000..6f34f2aa --- /dev/null +++ b/overlays/nur.nix @@ -0,0 +1,3 @@ +self: super: { + nur = import <nur> { pkgs = self; }; +} diff --git a/overlays/personal.nix b/overlays/personal.nix new file mode 100644 index 00000000..9eae64c4 --- /dev/null +++ b/overlays/personal.nix @@ -0,0 +1,13 @@ +self: super: +let + personal = import <personal> { + pkgs = self; + }; +in +{ + inherit personal; + enchant = personal.enchant-configurable.override { + withHspell = false; + withAspell = false; + }; +} diff --git a/packages b/packages new file mode 160000 +Subproject 1155711309d6e54ec6d6cfdbaee2160bab94000 diff --git a/pin.nix b/pin.nix deleted file mode 100644 index ab7c8b3e..00000000 --- a/pin.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ inputs, ... }: -let - inherit (inputs) nixpkgs; -in -{ - nix = { - registry = { - nixpkgs.flake = nixpkgs; - }; - }; -} diff --git a/private b/private -Subproject 5264068d4f5b85bc3b08e4b86ca46e49d8a411e +Subproject 442aa5d4590153b95817b1f102510e87639d60a diff --git a/secrets/dex.age b/secrets/dex.age new file mode 100644 index 00000000..99d463b4 --- /dev/null +++ b/secrets/dex.age Binary files differdiff --git a/secrets/golink.age b/secrets/golink.age new file mode 100644 index 00000000..c7039771 --- /dev/null +++ b/secrets/golink.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> ssh-ed25519 cvV2sw Afv1D+MaopWkuWEKI0t0zp4qlcam7bBUtWHq7CwABg8 +T49GUjm0yIB8L93giMNNQm56goIlyUKw81Awem7LGBE +-> piv-p256 u9NeZg Aym6b0XVHJFxEaH1bi82HjDGpbId6LjDzeANPlP1q75N +euudxSXIVs2mTeP8DKe6+8ixQb5doTwp3HR7eyfCsCk +--- c0wvkDM428LPfxbK7xL22xMmUh9OaEXM+gEImi6FVJg + ¢ +h׃Uß…?•“Í/3 ;!Ç»¤îP‰Ù'.‚¾ÕrÄÁætæ±\Üì‹©:¤ ¶uèƒÌ9ùY‚y˜_xº€9 Œ.ÇO˜£#פö=%#ìû£,MP?®Ù£ \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 86d1062c..75c174d1 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -16,6 +16,8 @@ let binarycache = [ linde ]; paperless = [ linde ]; powerdns = [ linde ]; + dex = [ linde ]; + golink = [ linde ]; dyndns = [ nanopi ]; syncthing = [ nanopi ]; diff --git a/shell.nix b/shell.nix index d2c4c458..b7d05d66 100644 --- a/shell.nix +++ b/shell.nix @@ -1,3 +1,20 @@ -{ system ? builtins.currentSystem }: +let + inherit (import ./sources.nix) nixPath sources; -(builtins.getFlake (toString ./.)).devShells.${system}.default + pkgs = import sources.nixpkgs { }; +in +pkgs.mkShell +{ + + name = "nixfiles-shell"; + + buildInputs = with pkgs; [ + npins + (pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { }) + (import sources.home-manager { inherit pkgs; }).home-manager + ]; + + shellHook = '' + export NIX_PATH="${builtins.concatStringsSep ":" nixPath}"; + ''; +} diff --git a/sources.nix b/sources.nix new file mode 100644 index 00000000..8bcc5a4f --- /dev/null +++ b/sources.nix @@ -0,0 +1,15 @@ +let + sources = import ./npins; + pkgs = import sources.nixpkgs { }; + inherit (import ./lib { inherit pkgs; }) mkNixPath fromSources; + + allSources = { + personal = ./packages; + nixpkgs-overlays = ./overlays; + private = ./private; + } // (fromSources sources); +in +{ + sources = allSources; + nixPath = mkNixPath allSources; +} diff --git a/system/.gitignore b/system/.gitignore deleted file mode 100644 index 9e7db1a3..00000000 --- a/system/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -/private/ -/hardware-configuration.nix -/configuration.nix -/darwin-configuration.nix -/cachix -/result diff --git a/system/autorandr/docked-close/block b/system/autorandr/docked-close/block deleted file mode 100755 index 782c3a74..00000000 --- a/system/autorandr/docked-close/block +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -exec grep -vq close /proc/acpi/button/lid/LID/state \ No newline at end of file diff --git a/system/autorandr/docked-close/config b/system/autorandr/docked-close/config deleted file mode 100644 index d8ce5031..00000000 --- a/system/autorandr/docked-close/config +++ /dev/null @@ -1,23 +0,0 @@ -output DP1 -off -output DP2 -off -output DP2-3 -off -output HDMI1 -off -output HDMI2 -off -output VIRTUAL1 -off -output eDP1 -off -output DP2-1 -mode 2560x1440 -pos 0x0 -primary -rate 59.95 -output DP2-2 -mode 2560x1440 -pos 2560x0 -rate 59.95 diff --git a/system/autorandr/docked-close/setup b/system/autorandr/docked-close/setup deleted file mode 100644 index 607eacbc..00000000 --- a/system/autorandr/docked-close/setup +++ /dev/null @@ -1,3 +0,0 @@ -DP2-1 00ffffffffffff0030aeaf61010101011c1c0104a53c22783e9325a9544d9e250c5054a1080081809500b300d1c0d100a9c001010101565e00a0a0a029503020350055502100001a023a801871382d40582c450055502100001e000000fd00324c1e7822000a202020202020000000fc004c454e20503237682d31300a20010d02031df14a01020304051413901f12230907078301000065030c001000011d007251d01e206e28550055502100001e8c0ad08a20e02d10103e96005550210000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd -DP2-2 00ffffffffffff0030aeaf61010101010a1c0104a53c22783e9325a9544d9e250c5054a1080081809500b300d1c0d100a9c001010101565e00a0a0a029503020350055502100001a023a801871382d40582c450055502100001e000000fd00324c1e7822000a202020202020000000fc004c454e20503237682d31300a20011f02031df14a01020304051413901f12230907078301000065030c001000011d007251d01e206e28550055502100001e8c0ad08a20e02d10103e96005550210000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd -eDP1 00ffffffffffff0006af3d2400000000001a0104951f117802a2b591575894281c505400000001010101010101010101010101010101843a8034713828403064310035ad10000018d02e8034713828403064310035ad10000018000000fe0041554f0a202020202020202020000000fe004231343048414e30322e34200a00e4 diff --git a/system/autorandr/docked-open/block b/system/autorandr/docked-open/block deleted file mode 100755 index 4c82692a..00000000 --- a/system/autorandr/docked-open/block +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -exec grep -vq open /proc/acpi/button/lid/LID/state \ No newline at end of file diff --git a/system/autorandr/docked-open/config b/system/autorandr/docked-open/config deleted file mode 100644 index 231a3942..00000000 --- a/system/autorandr/docked-open/config +++ /dev/null @@ -1,25 +0,0 @@ -output DP1 -off -output DP2 -off -output DP2-3 -off -output HDMI1 -off -output HDMI2 -off -output VIRTUAL1 -off -output eDP1 -mode 1920x1080 -pos 1600x1440 -rate 60.03 -output DP2-1 -mode 2560x1440 -pos 0x0 -primary -rate 59.95 -output DP2-2 -mode 2560x1440 -pos 2560x0 -rate 59.95 diff --git a/system/autorandr/docked-open/setup b/system/autorandr/docked-open/setup deleted file mode 100644 index 607eacbc..00000000 --- a/system/autorandr/docked-open/setup +++ /dev/null @@ -1,3 +0,0 @@ -DP2-1 00ffffffffffff0030aeaf61010101011c1c0104a53c22783e9325a9544d9e250c5054a1080081809500b300d1c0d100a9c001010101565e00a0a0a029503020350055502100001a023a801871382d40582c450055502100001e000000fd00324c1e7822000a202020202020000000fc004c454e20503237682d31300a20010d02031df14a01020304051413901f12230907078301000065030c001000011d007251d01e206e28550055502100001e8c0ad08a20e02d10103e96005550210000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd -DP2-2 00ffffffffffff0030aeaf61010101010a1c0104a53c22783e9325a9544d9e250c5054a1080081809500b300d1c0d100a9c001010101565e00a0a0a029503020350055502100001a023a801871382d40582c450055502100001e000000fd00324c1e7822000a202020202020000000fc004c454e20503237682d31300a20011f02031df14a01020304051413901f12230907078301000065030c001000011d007251d01e206e28550055502100001e8c0ad08a20e02d10103e96005550210000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd -eDP1 00ffffffffffff0006af3d2400000000001a0104951f117802a2b591575894281c505400000001010101010101010101010101010101843a8034713828403064310035ad10000018d02e8034713828403064310035ad10000018000000fe0041554f0a202020202020202020000000fe004231343048414e30322e34200a00e4 diff --git a/system/autorandr/laptop/config b/system/autorandr/laptop/config deleted file mode 100644 index 94f4e43d..00000000 --- a/system/autorandr/laptop/config +++ /dev/null @@ -1,19 +0,0 @@ -output DP1 -off -output HDMI1 -off -output DP2 -off -output HDMI2 -off -output DP2-1 -off -output DP2-2 -off -output DP2-3 -off -output eDP1 -mode 1920x1080 -pos 0x0 -primary -rate 60.03 diff --git a/system/autorandr/laptop/setup b/system/autorandr/laptop/setup deleted file mode 100644 index dc17ff13..00000000 --- a/system/autorandr/laptop/setup +++ /dev/null @@ -1 +0,0 @@ -eDP1 00ffffffffffff0006af3d2400000000001a0104951f117802a2b591575894281c505400000001010101010101010101010101010101843a8034713828403064310035ad10000018d02e8034713828403064310035ad10000018000000fe0041554f0a202020202020202020000000fe004231343048414e30322e34200a00e4 diff --git a/system/autorandr/postswitch b/system/autorandr/postswitch deleted file mode 100755 index 25b068d2..00000000 --- a/system/autorandr/postswitch +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -notify-send --expire-time=5000 "Display profile: '$AUTORANDR_CURRENT_PROFILE'" diff --git a/system/autorandr/work-1/config b/system/autorandr/work-1/config deleted file mode 100644 index 34fda0db..00000000 --- a/system/autorandr/work-1/config +++ /dev/null @@ -1,21 +0,0 @@ -output DP1 -off -output HDMI1 -off -output DP2 -off -output HDMI2 -mode 1920x1200 -pos 0x0 -primary -rate 59.95 -output DP2-1 -off -output DP2-2 -off -output DP2-3 -off -output eDP1 -mode 1920x1080 -pos 1920x0 -rate 60.03 diff --git a/system/autorandr/work-1/setup b/system/autorandr/work-1/setup deleted file mode 100644 index 12a4c698..00000000 --- a/system/autorandr/work-1/setup +++ /dev/null @@ -1,2 +0,0 @@ -HDMI2 00ffffffffffff0015c33425b1a21403041b010380342178ea0495a9554d9d26105054a10800a9408180b300a9c081c0810001010101283c80a070b023403020360007442100001a023a801871382d40582c450007442100001e000000fd00313d0f4c11000a202020202020000000fc004556323435350a202020202020011e020325f14e901f051404130312021107160615230907078301000066030c00100080e2007b011d8018711c1620582c250007442100009e011d80d0721c1620102c258007442100009e8c0ad08a20e02d10103e96000744210000188c0ad090204031200c4055000744210000180000000000000000000000000000000000008e -eDP1 00ffffffffffff0006af3d2400000000001a0104951f117802a2b591575894281c505400000001010101010101010101010101010101843a8034713828403064310035ad10000018d02e8034713828403064310035ad10000018000000fe0041554f0a202020202020202020000000fe004231343048414e30322e34200a00e4 diff --git a/system/linde.nix b/system/linde.nix index 91fc0c3a..067d4dad 100644 --- a/system/linde.nix +++ b/system/linde.nix @@ -15,12 +15,22 @@ let net-rdnsip = "2a01:4f8:c012:23a4::53"; net-mask6 = "64"; net-gw6 = "fe80::1"; + ts-domain = "hydra-pinecone.ts.net"; + golink = (builtins.getFlake (toString <golink>)).nixosModules.default; in { imports = [ + <personal/modules/laminar.nix> + <home-manager/nixos> + <agenix/modules/age.nix> + <searchix/nix/modules> + golink # Include the results of the hardware scan. ./linde-hardware.nix + + ./settings/pin.nix + ./settings/services/git-server.nix ]; age.secrets = { paperless = @@ -36,7 +46,16 @@ in }; acme.file = ../secrets/acme.age; binarycache.file = ../secrets/binarycache.age; + dex.file = ../secrets/dex.age; powerdns.file = ../secrets/powerdns.age; + golink = let golink = config.services.golink; in { + # hope this doesn't collide... + path = "${golink.dataDir}/.config/tsnet-golink/auth.key"; + owner = golink.user; + mode = "400"; + symlink = false; + file = ../secrets/golink.age; + }; }; # Use the systemd-boot EFI boot loader. @@ -54,7 +73,6 @@ in environment.systemPackages = with pkgs; [ htop lsof - gitMinimal powerdns sqlite-interactive knot-dns @@ -63,51 +81,6 @@ in nix-output-monitor ]; - programs.ssh = with pkgs; { - knownHostsFiles = [ - (writeText "github.keys" '' - # github.com:22 SSH-2.0-babeld-05989c77 - # github.com:22 SSH-2.0-babeld-05989c77 - # github.com:22 SSH-2.0-babeld-05989c77 - # github.com:22 SSH-2.0-babeld-05989c77 - # github.com:22 SSH-2.0-babeld-05989c77 - github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= - github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= - github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl - '') - (writeText "gitlab.keys" '' - # gitlab.com:22 SSH-2.0-GitLab-SSHD - # gitlab.com:22 SSH-2.0-GitLab-SSHD - # gitlab.com:22 SSH-2.0-GitLab-SSHD - # gitlab.com:22 SSH-2.0-GitLab-SSHD - # gitlab.com:22 SSH-2.0-GitLab-SSHD - gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 - gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= - gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf - '') - (writeText "codeberg.keys" '' - # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 - # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 - # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 - # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 - # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 - codeberg.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8hZi7K1/2E2uBX8gwPRJAHvRAob+3Sn+y2hxiEhN0buv1igjYFTgFO2qQD8vLfU/HT/P/rqvEeTvaDfY1y/vcvQ8+YuUYyTwE2UaVU5aJv89y6PEZBYycaJCPdGIfZlLMmjilh/Sk8IWSEK6dQr+g686lu5cSWrFW60ixWpHpEVB26eRWin3lKYWSQGMwwKv4LwmW3ouqqs4Z4vsqRFqXJ/eCi3yhpT+nOjljXvZKiYTpYajqUC48IHAxTWugrKe1vXWOPxVXXMQEPsaIRc2hpK+v1LmfB7GnEGvF1UAKnEZbUuiD9PBEeD5a1MZQIzcoPWCrTxipEpuXQ5Tni4mN - codeberg.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL2pDxWr18SoiDJCGZ5LmxPygTlPu+cCKSkpqkvCyQzl5xmIMeKNdfdBpfbCGDPoZQghePzFZkKJNR/v9Win3Sc= - codeberg.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIVIC02vnjFyL+I4RHfvIGNtOgJMe769VTF1VR4EB3ZB - '') - (writeText "sr.ht.keys" '' - # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 - # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 - # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 - # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 - # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 - git.sr.ht ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZ+l/lvYmaeOAPeijHL8d4794Am0MOvmXPyvHTtrqvgmvCJB8pen/qkQX2S1fgl9VkMGSNxbp7NF7HmKgs5ajTGV9mB5A5zq+161lcp5+f1qmn3Dp1MWKp/AzejWXKW+dwPBd3kkudDBA1fa3uK6g1gK5nLw3qcuv/V4emX9zv3P2ZNlq9XRvBxGY2KzaCyCXVkL48RVTTJJnYbVdRuq8/jQkDRA8lHvGvKI+jqnljmZi2aIrK9OGT2gkCtfyTw2GvNDV6aZ0bEza7nDLU/I+xmByAOO79R1Uk4EYCvSc1WXDZqhiuO2sZRmVxa0pQSBDn1DB3rpvqPYW+UvKB3SOz - git.sr.ht ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCj6y+cJlqK3BHZRLZuM+KP2zGPrh4H66DacfliU1E2DHAd1GGwF4g1jwu3L8gOZUTIvUptqWTkmglpYhFp4Iy4= - git.sr.ht ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60 - '') - ]; - }; - # Initial empty root password for easy login: users.users.root.initialHashedPassword = ""; services.openssh = { @@ -125,18 +98,18 @@ in programs.mosh.enable = true; system.autoUpgrade = { - enable = true; + enable = false; dates = "02:10"; randomizedDelaySec = "59 min"; allowReboot = true; flake = "git+file://${config.services.gitolite.dataDir}/repositories/nixfiles.git"; flags = [ "--no-write-lock-file" + "--impure" "--update-input" "nixpkgs-small" "--update-input" "searchix" - "git+https://git.alanpearce.eu/searchix" ]; }; @@ -169,6 +142,7 @@ in services.nix-serve = { enable = true; + package = pkgs.nix-serve-ng; secretKeyFile = config.age.secrets.binarycache.path; }; @@ -210,51 +184,111 @@ in ]; allowedUDPPorts = [ 53 + 443 # HTTP/3 (QUIC) 3478 6885 # DHT 6922 ]; + trustedInterfaces = [ "tailscale0" ]; }; resolvconf = { - enable = true; + enable = false; useLocalResolver = false; }; }; - services.resolved.enable = false; + services.resolved = { + enable = true; + llmnr = "false"; + dnssec = "true"; + }; systemd.network = { enable = true; networks.${netif} = { name = netif; - gateway = [ net-gw ]; - routes = [{ - routeConfig = { + routes = [ + { Gateway = net-gw6; PreferredSource = net-ip6; - }; - }]; + QuickAck = true; + InitialCongestionWindow = 30; + InitialAdvertisedReceiveWindow = 30; + } + { + Gateway = net-gw; + QuickAck = true; + InitialCongestionWindow = 30; + InitialAdvertisedReceiveWindow = 30; + } + ]; address = [ "${net-ip6}/${net-mask6}" "${net-rdnsip}/${net-mask6}" ]; addresses = [{ - addressConfig = { - Address = "${net-ip4}/${net-mask4}"; - Peer = "${net-gw}/32"; - }; + Address = "${net-ip4}/${net-mask4}"; + Peer = "${net-gw}/32"; }]; }; + wait-online = { + extraArgs = [ "--interface=${netif}" ]; + }; + }; + + services.tailscale = { + enable = true; + extraUpFlags = [ "--accept-routes" ]; + useRoutingFeatures = "client"; + }; + services.golink = { + enable = true; + tailscaleAuthKeyFile = config.age.secrets.golink.path; }; services.journald.extraConfig = '' MaxRetentionSec=1 month ''; - boot.kernel.sysctl = { - "net.ipv4.tcp_allowed_congestion_control" = "bbr illinois reno"; - "net.ipv4.tcp_congestion_control" = "bbr"; - "net.core.default_qdisc" = "fq"; - }; + zramSwap = { + enable = true; + algorithm = "zstd"; + }; + + boot.kernel.sysctl = + let + buffer_size = 16 * 1024 * 1024; + server_count = 2; + max_clients = 100; + page_size = 4096; + # This server might have 100 clients simultaneously, so: + # max(tcp_wmem) * 2 * 100 / 4096 + mem = toString (buffer_size * server_count * max_clients / page_size); + in + { + "net.ipv4.tcp_allowed_congestion_control" = "bbr illinois reno"; + "net.ipv4.tcp_congestion_control" = "bbr"; + "net.core.default_qdisc" = "fq"; + + # Provide adequate buffer memory. + # rmem_max and wmem_max are TCP max buffer size + # settable with setsockopt(), in bytes + # tcp_rmem and tcp_wmem are per socket in bytes. + # tcp_mem is for all TCP streams, in 4096-byte pages. + # The following are suggested on IBM's + # High Performance Computing page + "net.core.rmem_max" = buffer_size; + "net.core.wmem_max" = buffer_size; + "net.core.rmem_default" = buffer_size; + "net.core.wmem_default" = buffer_size; + "net.ipv4.tcp_rmem" = "4096 87380 ${toString buffer_size}"; + "net.ipv4.tcp_wmem" = "4096 87380 ${toString buffer_size}"; + "net.ipv4.tcp_mem" = "${mem} ${mem} ${mem}"; + + "net.ipv4.tcp_sack" = false; + "net.ipv4.tcp_dsack" = false; + + "net.ipv4.tcp_slow_start_after_idle" = false; + }; security.sudo.execWheelOnly = true; security.sudo.extraConfig = '' @@ -275,7 +309,7 @@ in users.users.root.shell = "${pkgs.fish}/bin/fish"; users.users.alan = { shell = "${pkgs.fish}/bin/fish"; - extraGroups = [ "wheel" "caddy" "docker" ]; + extraGroups = [ "wheel" "caddy" "docker" "laminar" ]; isNormalUser = true; home = "/home/alan"; createHome = true; @@ -284,6 +318,9 @@ in "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII8VIII+598QOBxi/52O1Kb19RdUdX0aZmS1/dNoyqc5 alan@hetzner.strongbox" ]; }; + home-manager = { + users.alan = import ../user/server.nix; + }; users.users.nixremote = { shell = "/bin/sh"; @@ -295,6 +332,7 @@ in "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBmDSZnUzIPQowLrKSa24eSb1WFQe7yPjTcDPPe3UY0Q nix@mba" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE9of82WBHK8nr8L9RGeieLMfcAWaFCeCkmvYHM9LCuT nanopi" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIy9jFioBvV0JA0lc+De2N+vDOABGHgCECW6vkD33CE4 sourcehut" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIII7sWEwsm8JZiJ0LUnjSt0Kg1RXypG6p5AzP/R2n5ca actions@github.com" ]; }; @@ -306,40 +344,53 @@ in # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). system.stateVersion = "23.05"; # Did you read the comment? - services.powerdns = { - enable = true; - secretFile = config.age.secrets.powerdns.path; - extraConfig = '' - launch=gsqlite3 - dnsupdate=yes - allow-dnsupdate-from=0.0.0.0/0,::/0 - only-notify= - also-notify=216.218.130.2 - allow-axfr-ips=216.218.133.2,2001:470:600::2 - outgoing-axfr-expand-alias=yes - expand-alias=yes - resolver=1.1.1.1 - local-address=${net-ip4} ${net-ip6} - reuseport=yes - log-dns-details=no - log-dns-queries=no - loglevel=5 - primary=yes - secondary=yes - send-signed-notify=no - prevent-self-notification=no - - default-soa-edit=inception-increment - - api=yes - # replaced by secretFile/envsubst - api-key=$API_KEY - - gsqlite3-database=/var/db/pdns/zones.db - gsqlite3-pragma-foreign-keys=yes - gsqlite3-dnssec=yes - ''; - }; + services.powerdns = + let + inherit (lib.lists) flatten; + inherit (lib.strings) concatStringsSep; + he = { + notify = "216.218.130.2"; + axfr = [ + "216.218.133.2" + "2001:470:600::2" + ]; + }; + iplist = ips: concatStringsSep "," (flatten ips); + in + { + enable = true; + secretFile = config.age.secrets.powerdns.path; + extraConfig = '' + launch=gsqlite3 + dnsupdate=yes + allow-dnsupdate-from=0.0.0.0/0,::/0 + only-notify= + also-notify=${iplist [ he.notify ]} + allow-axfr-ips=${iplist [ he.axfr ]} + outgoing-axfr-expand-alias=yes + expand-alias=yes + resolver=1.1.1.1 + local-address=${net-ip4} ${net-ip6} + reuseport=yes + log-dns-details=no + log-dns-queries=no + loglevel=5 + primary=yes + secondary=yes + send-signed-notify=no + prevent-self-notification=no + + default-soa-edit=inception-increment + + api=yes + # replaced by secretFile/envsubst + api-key=$API_KEY + + gsqlite3-database=/var/db/pdns/zones.db + gsqlite3-pragma-foreign-keys=yes + gsqlite3-dnssec=yes + ''; + }; systemd.services.hagezi-blocklist-update = { enable = true; @@ -498,21 +549,6 @@ in }; }; - systemd.services.backup-etc-nixos = { - startAt = "04:30"; - path = with pkgs; [ - rdiff-backup - openssh - ]; - script = '' - rdiff-backup --api-version 201 backup /etc/nixos ${hostname}@home.alanpearce.eu::nixos - rdiff-backup --api-version 201 remove increments --older-than 3M ${hostname}@home.alanpearce.eu::nixos - ''; - serviceConfig = { - Type = "oneshot"; - }; - }; - systemd.services.backup-gitolite = { startAt = "daily"; path = with pkgs; [ @@ -555,7 +591,7 @@ in }; acceptTerms = true; certs."alanpearce.eu" = { - extraDomainNames = [ "*.alanpearce.eu" ]; + extraDomainNames = [ "*.alanpearce.eu" "*.linde.alanpearce.eu" ]; }; certs."dns.alanpearce.eu" = { reloadServices = map (x: "kresd@${toString x}") (range 1 config.services.kresd.instances); @@ -573,259 +609,296 @@ in auto_https disable_certs default_bind ${net-ip6} ${net-ip4} ''; - virtualHosts = { - "http://" = { - # Needed for HTTP->HTTPS servers - }; - "${hostname}.alanpearce.eu" = { - serverAliases = [ "https://" ]; - useACMEHost = "alanpearce.eu"; - extraConfig = '' - respond * 204 - ''; - }; - "pdns.alanpearce.eu" = { - useACMEHost = "alanpearce.eu"; - extraConfig = '' - log { - output discard - } - reverse_proxy 127.0.0.1:8081 - ''; - }; - "dns.alanpearce.eu" = { - useACMEHost = "alanpearce.eu"; - extraConfig = '' - log { - output discard - } - reverse_proxy localhost:443 { - transport http { - tls_server_name dns.alanpearce.eu - } - } - ''; - }; - "files.alanpearce.eu" = { - useACMEHost = "alanpearce.eu"; - extraConfig = '' - encode zstd gzip - root * /srv/http/files - file_server browse - ''; - }; - "git.alanpearce.eu" = - let - fcgi = config.services.fcgiwrap; - fcgisocket = "${fcgi.socketType}/${fcgi.socketAddress}"; - in - { + virtualHosts = + let + inherit (import ../lib/caddy.nix { inherit lib; }) security-headers; + in + { + "http://" = { + # Needed for HTTP->HTTPS servers + }; + "alanpearce.eu" = { + serverAliases = [ "www.alanpearce.eu" "test.alanpearce.eu" ]; useACMEHost = "alanpearce.eu"; extraConfig = '' - root * ${pkgs.cgit-pink}/cgit/ encode zstd gzip - handle_path /custom/* { - file_server { - root /srv/http/cgit/ - } + root * /srv/http/website/public + file_server + ${security-headers {}} + handle_errors { + rewrite * /404.html + file_server } - rewrite /robots.txt /assets/robots.txt - handle_path /assets/* { - file_server { - hide cgit.cgi - } + ''; + }; + "${hostname}.alanpearce.eu" = { + serverAliases = [ "https://" ]; + useACMEHost = "alanpearce.eu"; + extraConfig = '' + respond * 204 + ${security-headers {}} + ''; + }; + "pdns.alanpearce.eu" = { + useACMEHost = "alanpearce.eu"; + extraConfig = '' + log { + output discard } - @git_http_backend path_regexp "^/.+/(info/refs|git-upload-pack)$" - handle @git_http_backend { - reverse_proxy ${fcgisocket} { - transport fastcgi { - env SCRIPT_FILENAME ${pkgs.git}/libexec/git-core/git-http-backend - env GIT_PROJECT_ROOT ${config.services.gitolite.dataDir}/repositories - } - } + reverse_proxy 127.0.0.1:8081 + ''; + }; + "id.alanpearce.eu" = { + useACMEHost = "alanpearce.eu"; + extraConfig = '' + encode zstd gzip + ${security-headers {}} + reverse_proxy http://${config.services.dex.settings.web.http} + ''; + }; + "dns.alanpearce.eu" = { + useACMEHost = "alanpearce.eu"; + extraConfig = '' + log { + output discard } - handle { - reverse_proxy ${fcgisocket} { - transport fastcgi { - env SCRIPT_FILENAME {http.vars.root}/cgit.cgi - env CGIT_CONFIG ${pkgs.writeText "cgitrc" '' - head-include=/srv/http/cgit/responsive-cgit-css-master/head.html - css=/custom/responsive-cgit-css-master/cgit.css - virtual-root=/ - logo= - readme=:README.md - source-filter=${pkgs.cgit-pink}/lib/cgit/filters/syntax-highlighting.py - about-filter=${pkgs.cgit-pink}/lib/cgit/filters/about-formatting.sh - enable-git-config=1 - enable-index-owner=0 - enable-index-links=1 - enable-follow-links=0 - enable-log-linecount=1 - max-stats=year - snapshots=tar.lz tar.zst zip - cache-size=10240 - enable-http-clone=1 - enable-commit-graph=1 - mimetype-file=${pkgs.nginx}/conf/mime.types - section-from-path=1 - noplainemail=1 - repository-sort=age - root-title=my personal projects - clone-url=git://git.alanpearce.eu/$CGIT_REPO_URL https://git.alanpearce.eu/$CGIT_REPO_URL - remove-suffix=1 - strict-export=git-daemon-export-ok - scan-path=${config.services.gitolite.dataDir}/repositories/ - ''} - } - } + encode zstd gzip + reverse_proxy localhost:443 { + transport http { + tls_server_name dns.alanpearce.eu + } } ''; }; - "ntfy.alanpearce.eu" = { - useACMEHost = "alanpearce.eu"; - extraConfig = '' - encode zstd gzip - reverse_proxy localhost${config.services.ntfy-sh.settings.listen-http} - ''; - }; - "searchix.alanpearce.eu" = { - useACMEHost = "alanpearce.eu"; - extraConfig = '' - reverse_proxy localhost:${toString config.services.searchix.settings.web.port} { - health_uri /health - health_status 2xx - } - encode zstd gzip { - match { - header Content-Type text/* - header Content-Type application/json* - header Content-Type application/javascript* - header Content-Type application/opensearchdescription+xml - header Content-Type application/atom+xml* - header Content-Type application/rss+xml* - header Content-Type image/svg+xml* - } - } - ''; - }; - "legit.alanpearce.eu" = - let - server = config.services.legit.settings.server; - in - { + "files.alanpearce.eu" = { useACMEHost = "alanpearce.eu"; extraConfig = '' encode zstd gzip - handle_path /static/* { - root * /srv/http/legit/src/static - file_server + ${security-headers {}} + root * /srv/http/files + file_server browse + ''; + }; + "ntfy.alanpearce.eu" = { + useACMEHost = "alanpearce.eu"; + extraConfig = '' + encode zstd gzip + ${security-headers {}} + reverse_proxy localhost${config.services.ntfy-sh.settings.listen-http} { + health_uri /v1/health + health_body `"healthy":true` } - reverse_proxy ${server.host}:${toString server.port} ''; }; - "papers.alanpearce.eu" = { - extraConfig = '' - encode zstd gzip - handle_path /static/* { - root * ${config.services.paperless.package}/lib/paperless-ngx/static - file_server - } - reverse_proxy localhost:${toString config.services.paperless.port} - - ''; - }; - "binarycache.alanpearce.eu" = - let - ns = config.services.nix-serve; - in - { + "searchix.alanpearce.eu" = { + useACMEHost = "alanpearce.eu"; + serverAliases = [ "searchix.linde.alanpearce.eu" ]; extraConfig = '' - reverse_proxy ${ns.bindAddress}:${toString ns.port} + reverse_proxy localhost:${toString config.services.searchix.settings.web.port} { + health_uri /health + health_status 2xx + } + encode zstd gzip { + match { + header Content-Type text/* + header Content-Type application/json* + header Content-Type application/javascript* + header Content-Type application/opensearchdescription+xml + header Content-Type application/atom+xml* + header Content-Type application/rss+xml* + header Content-Type image/svg+xml* + } + } ''; }; - }; + "binarycache.alanpearce.eu" = + let + ns = config.services.nix-serve; + in + { + extraConfig = '' + reverse_proxy ${ns.bindAddress}:${toString ns.port} + ''; + }; + "ci.alanpearce.eu" = + let + srv = config.services.laminar; + in + { + extraConfig = '' + reverse_proxy ${srv.settings.bindHTTP} + ''; + }; + }; }; systemd.services.caddy.serviceConfig = { UMask = "007"; }; - services.fcgiwrap = { + networking.nat = { enable = true; - group = "gitolite"; - preforkProcesses = 2; - socketType = "tcp6"; - socketAddress = "[::1]:9000"; + internalInterfaces = [ "ve-+" ]; + externalInterface = netif; + enableIPv6 = true; }; - services.gitolite = { - enable = true; - adminPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII8VIII+598QOBxi/52O1Kb19RdUdX0aZmS1/dNoyqc5 alan@hetzner.strongbox"; - extraGitoliteRc = '' - $RC{UMASK} = 0027; - $RC{LOG_EXTRA} = 0; - $RC{HOSTNAME} = "${config.networking.hostName}"; - $RC{LOCAL_CODE} = "$rc{GL_ADMIN_BASE}/local"; - push( @{$RC{ENABLE}}, 'D' ); - push( @{$RC{ENABLE}}, 'Shell alan' ); - push( @{$RC{ENABLE}}, 'cgit' ); - push( @{$RC{ENABLE}}, 'repo-specific-hooks' ); - ''; + + users.users.paperless = { + group = "paperless"; + uid = config.ids.uids.paperless; + home = "/srv/paperless"; }; - services.legit = { - enable = true; - group = "gitolite"; - settings = { - server.name = "legit.alanpearce.eu"; - dirs = { - templates = "/srv/http/legit/src/templates"; + users.groups.paperless.members = [ "alan" "syncthing" ]; + containers.papers = + let + hostDataDir = config.users.users.paperless.home; + localAddress6 = "fc00::2"; + tsHostname = "papers.${ts-domain}"; + tsPort = 41642; + in + { + # or maybe socket activated? + autoStart = true; + # does TS need this? + enableTun = true; + privateNetwork = true; + hostAddress6 = "fc00::1"; + inherit localAddress6; + forwardPorts = [{ + hostPort = tsPort; + }]; + bindMounts = { + ${config.services.paperless.dataDir} = { + hostPath = hostDataDir; + isReadOnly = false; + }; }; - repo = { - scanPath = "/srv/http/legit/repos"; - readme = [ - "readme" - "readme.md" - "README.md" + config = { + environment.systemPackages = with pkgs; [ + lsof ]; + networking = { + useHostResolvConf = false; + resolvconf.enable = false; + firewall.trustedInterfaces = [ "tailscale0" ]; + firewall.rejectPackets = true; + nameservers = config.networking.nameservers; + }; + services.resolved = { + enable = true; + llmnr = "false"; + }; + services.tailscale = { + enable = true; + openFirewall = true; + permitCertUid = "caddy"; + port = tsPort; + }; + services.caddy = { + enable = true; + email = "caddy@alanpearce.eu"; + virtualHosts = { + "http://" = { + # avoid logging to an awkward file name based on the attribute name i.e. http:// + hostName = "papers"; + extraConfig = '' + redir ${tsHostname}{uri} + ''; + }; + ${tsHostname} = { + extraConfig = '' + encode zstd gzip + tls { + get_certificate tailscale + } + handle_path /static/* { + root * ${config.services.paperless.package}/lib/paperless-ngx/static + file_server + } + reverse_proxy [::1]:${toString config.services.paperless.port} + ''; + }; + }; + }; + services.paperless = { + enable = true; + address = "[::1]"; + settings = { + PAPERLESS_DBENGINE = "sqlite"; + PAPERLESS_TIME_ZONE = "Europe/Berlin"; + + PAPERLESS_URL = "https://${tsHostname}"; + PAPERLESS_TRUSTED_PROXIES = "[::1]"; + PAPERLESS_USE_X_FORWARD_HOST = true; + PAPERLESS_USE_X_FORWARD_PORT = true; + PAPERLESS_PROXY_SSL_HEADER = [ "HTTP_X_FORWARDED_PROTO" "https" ]; + PAPERLESS_ENABLE_COMPRESSION = false; # let caddy do it + + PAPERLESS_OCR_SKIP_ARCHIVE_FILE = "with_text"; + PAPERLESS_OCR_LANGUAGE = "deu+eng"; + PAPERLESS_IGNORE_DATES = "09.08.90"; + + PAPERLESS_TASK_WORKERS = 2; + PAPERLESS_THREADS_PER_WORKER = 1; + PAPERLESS_NUMBER_OF_SUGGESTED_DATES = 4; + + PAPERLESS_CONSUMER_IGNORE_PATTERN = [ ".DS_STORE/*" "desktop.ini" ".stfolder/*" ".stversions/*" ]; + + PAPERLESS_FILENAME_FORMAT = "{correspondent}/{created} {title} {asn}"; + PAPERLESS_FILENAME_FORMAT_REMOVE_NONE = true; + }; + }; + system.stateVersion = "24.11"; }; }; - }; - users.groups.git.gid = config.ids.gids.git; - services.gitDaemon = { - enable = true; - user = "git"; - group = "gitolite"; - basePath = "${config.services.gitolite.dataDir}/repositories/"; - }; - users.groups.paperless.members = [ "alan" "syncthing" ]; - services.paperless = { + services.etcd = { enable = true; - package = pkgs.paperless-ngx; - dataDir = "/srv/paperless"; - settings = { - PAPERLESS_DBENGINE = "sqlite"; - PAPERLESS_TIME_ZONE = "Europe/Berlin"; - - PAPERLESS_URL = "https://papers.alanpearce.eu"; - PAPERLESS_TRUSTED_PROXIES = "127.0.0.1"; - PAPERLESS_USE_X_FORWARD_HOST = true; - PAPERLESS_USE_X_FORWARD_PORT = true; - PAPERLESS_PROXY_SSL_HEADER = [ "HTTP_X_FORWARDED_PROTO" "https" ]; - PAPERLESS_ENABLE_COMPRESSION = false; # let caddy do it - - PAPERLESS_OCR_SKIP_ARCHIVE_FILE = "with_text"; - PAPERLESS_OCR_LANGUAGE = "deu+eng"; - PAPERLESS_IGNORE_DATES = "09.08.90"; - - PAPERLESS_TASK_WORKERS = 2; - PAPERLESS_THREADS_PER_WORKER = 1; - PAPERLESS_NUMBER_OF_SUGGESTED_DATES = 4; - - PAPERLESS_CONSUMER_IGNORE_PATTERN = [ ".DS_STORE/*" "desktop.ini" ".stfolder/*" ".stversions/*" ]; + initialClusterState = "existing"; + dataDir = "/var/lib/etcd"; # TODO backup + }; - PAPERLESS_FILENAME_FORMAT = "{correspondent}/{created} {title} {asn}"; - PAPERLESS_FILENAME_FORMAT_REMOVE_NONE = true; + services.dex = + let + issuer = "https://id.alanpearce.eu/"; + in + { + enable = true; + environmentFile = config.age.secrets.dex.path; + settings = { + inherit issuer; + storage = { + type = "etcd"; + config = { + endpoints = config.services.etcd.listenClientUrls; + namespace = "dex/"; + }; + }; + web.http = "127.0.0.1:5556"; + connectors = [{ + type = "github"; + id = "github"; + name = "GitHub"; + config = { + clientID = "$GITHUB_CLIENT_ID"; + clientSecret = "$GITHUB_CLIENT_SECRET"; + redirectURI = "${issuer}callback"; + orgs = [{ + name = "alan-pearce"; + }]; + teamNameField = "slug"; + useLoginAsID = true; + }; + }]; + staticClients = [ + { + name = "Tailscale"; + id = "oCaiv7aije1thaep0eib"; + secretEnv = "TAILSCALE_CLIENT_SECRET"; + redirectURIs = [ "https://login.tailscale.com/a/oauth_response" ]; + } + ]; + }; }; - }; services.syncthing = { enable = true; @@ -839,46 +912,112 @@ in services.searchix = { enable = true; settings = { - web = { - baseURL = "https://searchix.alanpearce.eu"; - sentryDSN = "https://26d4cd8d20157ae2f6b4726ceae1a563@o4507187730120704.ingest.de.sentry.io/4507187734970448"; - contentSecurityPolicy = { - script-src = [ - "'self'" - "https://gc.zgo.at" - "https://js-de.sentry-cdn.com" - "https://browser.sentry-cdn.com" - ]; - img-src = [ - "'self'" - "https://gc.zgo.at" - ]; - connect-src = [ - "'self'" - "https://searchix.goatcounter.com/count" - "*.sentry.io" - ]; - worker-src = [ - "blob:" - ]; + web = + let + baseURL = "https://searchix.alanpearce.eu"; + in + { + inherit baseURL; + sentryDSN = "https://26d4cd8d20157ae2f6b4726ceae1a563@o4507187730120704.ingest.de.sentry.io/4507187734970448"; + contentSecurityPolicy = + let + self = "'self'"; + in + { + script-src = [ + (baseURL + "/static/") + "https://gc.zgo.at" + "https://js-de.sentry-cdn.com" + "https://browser.sentry-cdn.com" + ]; + img-src = [ + self + "https://gc.zgo.at" + ]; + connect-src = [ + self + "https://searchix.goatcounter.com/count" + "*.sentry.io" + ]; + worker-src = [ + "blob:" + ]; + }; + extraHeadHTML = '' + <script async + src="https://js-de.sentry-cdn.com/d735e99613a86e1625fb85d0e8e762de.min.js" + crossorigin="anonymous"></script> + <script data-goatcounter="https://searchix.goatcounter.com/count" + async src="//gc.zgo.at/count.v4.js" + crossorigin="anonymous" + integrity="sha384-nRw6qfbWyJha9LhsOtSb2YJDyZdKvvCFh0fJYlkquSFjUxp9FVNugbfy8q1jdxI+"></script> + ''; }; - extraHeadHTML = '' - <script async - src="https://js-de.sentry-cdn.com/d735e99613a86e1625fb85d0e8e762de.min.js" - crossorigin="anonymous"></script> - <script data-goatcounter="https://searchix.goatcounter.com/count" - async src="//gc.zgo.at/count.js"></script> - ''; - }; importer.sources = { darwin = { enable = true; fetcher = "download"; - url = "https://alanpearce.github.io/nix-darwin-options"; + url = "https://alanpearce.github.io/nix-options/darwin"; + }; + home-manager = { + enable = true; + fetcher = "download"; + url = "https://alanpearce.github.io/nix-options/home-manager"; + }; + nixpkgs = { + enable = true; + fetcher = "channel-nixpkgs"; + channel = "nixos-unstable"; }; - home-manager.enable = true; + nixos = { + enable = true; + fetcher = "channel-nixpkgs"; + channel = "nixos-unstable"; + }; + }; + }; + }; + + programs.git = { + enable = true; + package = pkgs.gitMinimal; + config = { + advice = { + detachedHead = false; + mergeConflict = false; }; }; }; + + systemd.services.laminar.environment = { + NIX_PATH = "nixpkgs=${<nixpkgs>}"; + }; + services.laminar = { + enable = true; + path = with pkgs; [ + bash + stdenv + git + cached-nix-shell + nix + config.programs.ssh.package + flock + just + ]; + settings = { + bindHTTP = "[::1]:8002"; + keepRundirs = 1; + }; + }; + users.users.laminar = { + homeMode = "770"; + }; + + virtualisation.containers = { + enable = true; + policy = { + default = [{ type = "insecureAcceptAnything"; }]; + }; + }; } diff --git a/system/mba.nix b/system/mba.nix index c39862cf..abed520b 100644 --- a/system/mba.nix +++ b/system/mba.nix @@ -8,6 +8,7 @@ networking = { hostName = "mba"; }; + services.tailscale.enable = true; services.activate-system.enable = true; diff --git a/system/nanopi.nix b/system/nanopi.nix index 45eae872..5083f9e7 100755 --- a/system/nanopi.nix +++ b/system/nanopi.nix @@ -1,16 +1,19 @@ { config , pkgs , lib -, inputs , ... }: let fsTypes = [ "f2fs" "ext" "exfat" "vfat" ]; + domain = "home.arpa"; + ts_domain = "hydra-pinecone.ts.net"; in { imports = [ ./nanopi-hardware.nix - (inputs.nixos-hardware + "/friendlyarm/nanopi-r5s") + <agenix/modules/age.nix> + <nixos-hardware/friendlyarm/nanopi-r5s> + <home-manager/nixos> ]; age.secrets = { @@ -68,6 +71,26 @@ in }; }; + systemd.services.backup-golink = { + enable = true; + startAt = "daily"; + description = "Export short links from golink"; + path = with pkgs; [ curl gitMinimal ]; + script = '' + [ -d golink ] || git init --quiet golink --initial-branch=main --shared=world + git config --global user.email linde@alanpearce.eu + cd golink + curl https://go.${ts_domain}/.export > links.json + git add links.json + git commit -m $(date +%F) + ''; + serviceConfig = { + Type = "oneshot"; + User = "linde"; + WorkingDirectory = config.users.users.linde.home; + }; + }; + services.journald.extraConfig = '' MaxRetentionSec=1 month ''; @@ -85,61 +108,33 @@ in systemd.network.config.networkConfig = { SpeedMeter = true; }; + networking = { hostName = "nanopi"; - domain = "lan"; + domain = domain; + search = [ domain ]; + hosts = { + "fd7a:115c:a1e0::53" = [ "tailscale" "ts" ]; + "192.168.100.1" = [ "modem" "pyur" ]; + "192.168.4.1" = [ "lte" ]; + }; useDHCP = false; useNetworkd = true; - nameservers = [ - "176.9.93.198" - "176.9.1.117" - "2a01:4f8:151:34aa::198" - "2a01:4f8:141:316d::117" - ]; + nat = { + enable = true; + internalInterfaces = [ "bridge0" "lan1" "lan2" ]; + externalInterface = "wan0"; + }; firewall = { enable = true; rejectPackets = true; logRefusedConnections = false; pingLimit = "5/second"; filterForward = true; # we are a router - allowedUDPPorts = [ - 53 - 123 - ]; - allowedTCPPorts = [ - 53 - 123 - 80 - 443 + trustedInterfaces = [ + "bridge0" + "tailscale0" ]; - interfaces.bridge0 = { - allowedTCPPorts = [ - 53 - 67 - 139 - 445 - 1883 - 3000 - 3689 - 5357 - 5533 # SmartDNS - 8096 - 9091 # Transmission - ]; - allowedUDPPorts = [ - 53 - 67 - 69 - 137 - 4011 # PXE - 5533 # SmartDNS - 5353 - 5355 # LLMNR - 3702 # Samba WSDD - 41641 - 51827 - ]; - }; interfaces.wan0 = { allowedTCPPorts = [ 6980 # aria2c @@ -151,8 +146,10 @@ in ]; }; extraForwardRules = '' - iifname { "wan0", "wlan0", "wwan0" } oifname { "lan1", "lan2", "bridge0" } icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, mld-listener-query, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept - iifname { "lan1", "lan2", "bridge0" } oifname { "wan0", "wlan0", "wwan0" } accept + iifname { "wlan0", "lte0" } oifname { "lan1", "lan2", "bridge0" } icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, mld-listener-query, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept + iifname { "lan1", "lan2", "bridge0" } oifname { "wlan0", "lte0" } accept + iifname "tailscale0" oifname "bridge0" accept + iifname "bridge0" oifname "tailscale0" accept ''; }; nftables = { @@ -163,7 +160,7 @@ in content = '' chain postrouting { type nat hook postrouting priority srcnat; policy accept; - oifname { "wan0", "wlan0", "wwan0" } masquerade + oifname { "wlan0", "lte0" } masquerade } chain prerouting { type nat hook prerouting priority dstnat; @@ -185,7 +182,57 @@ in # }; }; }; - services.resolved.enable = false; + + networking = { + resolvconf = { + # having this enabled (the default) is pointless + # a) this device has fixed upstream nameservers + enable = false; + # b) it makes tailscale think it should change the search domains for MagicDNS + # ... due to this: + # useLocalResolver = false; + # which is set by kresd?! + # https://github.com/NixOS/nixpkgs/blob/7780e5160e011b39019797a4c4b1a4babc80d1bf/nixos/modules/services/networking/kresd.nix#L113 + }; + nameservers = lib.optionals config.services.dnsmasq.enable [ + "::1" + "127.0.0.1" + ]; + }; + services.resolved = { + # this allows link-specific DNS configuration, which is useful. + enable = true; + # why use simple boolean when string do trick? + llmnr = "false"; + dnssec = "true"; + fallbackDns = [ + "9.9.9.9" + "149.112.112.112" + "2620::fe:fe" + "2620::fe:9" + "116.203.248.56" + "2a01:4f8:c012:23a4::1" + ]; + }; + + # leaving this here just in case I ever think about disabling both `resolvconf` and `resolved` + # I thought that there would have been a fallback that does this anyway, but apparently not. + environment.etc."resolv.conf".text = lib.mkDefault (lib.optionalString + ( + !config.networking.resolvconf.enable + && + !config.services.resolved.enable + ) '' + search ${domain} ${ts_domain} + nameserver ::1 + nameserver 127.0.0.1 + options edns0 + ''); + + services.tailscale = { + enable = true; + extraUpFlags = [ "--accept-dns=false" "--advertise-routes=10.0.0.0/20,fd12:d04f:65d:42::/56" ]; + }; programs.command-not-found.enable = false; @@ -193,6 +240,10 @@ in enable = true; openFirewall = true; startWhenNeeded = false; + settings = { + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + }; }; programs.mosh.enable = true; services.sshguard = { @@ -203,7 +254,7 @@ in systemd.network = { enable = true; wait-online = { - ignoredInterfaces = [ "wan0" "wlan0" "wwan0" ]; + extraArgs = [ "--interface" "bridge0" ]; }; links = { "10-name-lan1" = { @@ -233,10 +284,10 @@ in Name = "wlan0"; }; }; - "10-name-wwan0" = { + "10-name-lte0" = { matchConfig.MACAddress = "34:4b:50:00:00:00"; linkConfig = { - Name = "wwan0"; + Name = "lte0"; }; }; }; @@ -254,7 +305,6 @@ in bridge = [ "bridge0" ]; linkConfig = { MACAddress = "82:E0:06:9C:8E:7C"; - RequiredForOnline = "no"; }; networkConfig.LinkLocalAddressing = "no"; }; @@ -265,11 +315,20 @@ in "10.0.0.1/20" "fd12:d04f:65d:42::1/56" ]; + addresses = [ + { + Address = "fe80::1/64"; + Scope = "link"; + } + ]; networkConfig = { IPv6AcceptRA = false; - IPv6SendRA = true; + IPv6SendRA = false; DHCPPrefixDelegation = true; ConfigureWithoutCarrier = true; + MulticastDNS = true; + BindCarrier = [ "lan0" "lan1" ]; + Domains = [ domain ]; }; dhcpPrefixDelegationConfig = { UplinkInterface = "wan0"; @@ -277,17 +336,9 @@ in Assign = true; Token = "::1"; }; - ipv6SendRAConfig = { - RouterLifetimeSec = 1800; - EmitDNS = true; - DNS = "fd12:d04f:65d:42::1"; - EmitDomains = true; - Domains = [ config.networking.domain ]; - }; }; - "50-wwan0" = { - matchConfig.Name = "wwan0"; - linkConfig.RequiredForOnline = false; + "50-lte0" = { + matchConfig.Name = "lte0"; networkConfig = { DHCP = "yes"; IPv6AcceptRA = true; @@ -296,17 +347,16 @@ in dhcpV4Config = { UseDNS = false; SendHostname = false; - RouteMetric = 2048; + UseRoutes = false; }; ipv6AcceptRAConfig.UseDNS = false; routes = [ { - routeConfig = { - Gateway = "_dhcp4"; - QuickAck = true; - InitialCongestionWindow = 30; - InitialAdvertisedReceiveWindow = 30; - }; + Gateway = "_dhcp4"; + Metric = 2048; + QuickAck = true; + InitialCongestionWindow = 30; + InitialAdvertisedReceiveWindow = 30; } ]; cakeConfig = { @@ -320,7 +370,6 @@ in }; "50-wan" = { matchConfig.Name = "wan0"; - linkConfig.RequiredForOnline = "no"; networkConfig = { DHCP = "yes"; IPv6AcceptRA = true; @@ -328,6 +377,7 @@ in }; dhcpV4Config = { UseDNS = false; + UseRoutes = false; SendHostname = false; SendRelease = false; UseHostname = false; @@ -343,15 +393,28 @@ in }; ipv6AcceptRAConfig = { UseDNS = false; + UseGateway = false; }; addresses = [ { - addressConfig = { - Address = "192.168.100.10/24"; - # Peer = "192.168.100.1/32"; - Label = "wan0:0"; - # Scope = "link"; - }; + Address = "192.168.100.10/24"; + # Peer = "192.168.100.1/32"; + Label = "wan0:0"; + # Scope = "link"; + } + ]; + routes = [ + { + Gateway = "_dhcp4"; + QuickAck = true; + InitialCongestionWindow = 30; + InitialAdvertisedReceiveWindow = 30; + } + { + Gateway = "_ipv6ra"; + QuickAck = true; + InitialCongestionWindow = 30; + InitialAdvertisedReceiveWindow = 30; } ]; cakeConfig = { @@ -365,7 +428,6 @@ in }; "60-wlan" = { matchConfig.MACAddress = "9c:53:22:33:bf:e9"; - linkConfig.RequiredForOnline = "no"; networkConfig = { DHCP = "yes"; IPForward = "yes"; @@ -380,13 +442,11 @@ in }; routes = [ { - routeConfig = { - Metric = 2048; - Gateway = "_dhcp4"; - QuickAck = true; - InitialCongestionWindow = 30; - InitialAdvertisedReceiveWindow = 30; - }; + Metric = 2048; + Gateway = "_dhcp4"; + QuickAck = true; + InitialCongestionWindow = 30; + InitialAdvertisedReceiveWindow = 30; } ]; cakeConfig = { @@ -415,12 +475,13 @@ in services.dnsmasq = { enable = true; - resolveLocalQueries = true; + # let systemd-resolved.do this + resolveLocalQueries = false; alwaysKeepRunning = true; settings = { local-ttl = 60; - domain = "lan"; - dhcp-fqdn = false; + domain = domain; + dhcp-fqdn = true; domain-needed = true; bogus-priv = true; no-resolv = true; @@ -434,34 +495,42 @@ in "2620::fe:9" "116.203.248.56" "2a01:4f8:c012:23a4::1" - # "127.0.0.1#5553" - # "::1#5553" - "127.0.0.1#5533" - "::1#5533" + # kresd + "127.0.0.1#5553" + "::1#5553" + # smartdns + # "127.0.0.1#5533" + # "::1#5533" + "/ts.net/tailscale" ]; localise-queries = true; cname = [ - "homeassistant,ha" + "ha,home-assistant" ]; interface-name = [ - "home.alanpearce.eu,wan0" - "nanopi.alanpearce.eu,wan0" - "nanopi.lan.alanpearce.eu,bridge0" - "syncthing.lan.alanpearce.eu,bridge0" - "wan,wan0" - "wlan,wlan0" - "wwan,wwan0" + "nanopi.${domain},bridge0" + "wan.${domain},wan0" + "wlan.${domain},wlan0" ]; interface = [ + "lo" "bridge0" ]; + no-dhcp-interface = [ + "tailscale0" + ]; # auth-zone = "lan,wan0"; # auth-server = [ # "nanopi.alanpearce.eu,wan0" # ]; - bind-interfaces = false; + bind-interfaces = true; - no-hosts = true; + # if this is false, a remote query for nanopi returns 127.0.0.2, because that's in /etc/hosts + no-hosts = false; + expand-hosts = true; + + dnssec = true; + trust-anchor = ".,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D"; enable-ra = true; dhcp-lease-max = 240; @@ -469,19 +538,18 @@ in dhcp-rapid-commit = true; dhcp-range = [ "10.0.1.0,10.0.1.250,12h" - "::, constructor:bridge0, ra-stateless, 48h" - "fd12:d04f:65d::, ra-stateless, ra-names, 48h" + "fd12:d04f:65d:42::,slaac,ra-names,48h" + "::,constructor:bridge0,ra-stateless,48h" ]; dhcp-host = [ "00:a0:de:b3:0c:01,10.0.0.50,wxa-50" "10:f0:68:12:b1:e0,10.0.0.11,Ruckus" "9c:93:4e:ad:05:c8,10.0.0.210,xerox-b210" "00:08:9b:f5:b8:25,10.0.0.42,dontpanic" - "d8:3a:dd:34:85:cc,d8:3a:dd:34:85:cd,10.0.0.81,ha" + "d8:3a:dd:34:85:cc,d8:3a:dd:34:85:cd,10.0.0.81,home-assistant" ]; dhcp-option = [ "option:ntp-server,0.0.0.0" - "option:dns-server,0.0.0.0,10.0.0.81" "option:tftp-server,0.0.0.0" "option:ip-forward-enable,0" # ip-forwarding "252,\"\\n\"" @@ -512,7 +580,7 @@ in services.networkd-dispatcher = { # broken? - enable = false; + enable = true; rules = { update-home-address = { onState = [ "configured" "configuring" ]; @@ -527,6 +595,18 @@ in exit 0 ''; }; + tailscale-subnet-router-optimisation = { + onState = [ "routable" ]; + script = '' + #!${pkgs.runtimeShell} + set -eu + + if [[ $IFACE == "wan0" && $OperationalState == "routable" ]] + then + ${pkgs.ethtool}/bin/ethtool -K $IFACE rx-udp-gro-forwarding on rx-gro-list off + fi + ''; + }; }; }; @@ -555,6 +635,7 @@ in "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMvcW4Z9VxOQgEJjsRC1uSMwEJ4vru9BwjT+Z50nawp4 lan" ]; }; + home-manager.users.alan = import ../user/nanopi.nix; users.groups = { linde.members = [ ]; @@ -566,6 +647,7 @@ in isSystemUser = true; shell = "/bin/sh"; home = "/srv/backup/linde"; + homeMode = "755"; createHome = true; packages = with pkgs; [ rdiff-backup ]; openssh.authorizedKeys.keys = [ @@ -614,7 +696,7 @@ in }; nixpkgs.config.allowUnfree = true; system.autoUpgrade = { - enable = false; + enable = true; dates = "04:15"; randomizedDelaySec = "59 min"; flake = "git+https://git.alanpearce.eu/nixfiles"; @@ -700,22 +782,6 @@ in ''; }; - services.avahi = { - enable = true; - nssmdns4 = true; - denyInterfaces = [ "wan0" "wwan0" "wlan0" ]; - browseDomains = [ - "alanpearce.eu" - ]; - publish = { - enable = true; - hinfo = true; - addresses = true; - userServices = true; - workstation = true; - }; - }; - services.samba = { enable = true; enableNmbd = false; @@ -786,7 +852,7 @@ in "10.0.0.1:53 -group lan -exclude-default-group" ]; nameserver = [ - "/lan/lan" + "/${domain}/${domain}" ]; dualstack-ip-selection = true; dualstack-ip-selection-threshold = 10; diff --git a/system/prefect.nix b/system/prefect.nix index 12f0dd56..801692e3 100644 --- a/system/prefect.nix +++ b/system/prefect.nix @@ -10,23 +10,47 @@ ./settings/configuration/user.nix ./settings/hardware/audio.nix ./settings/hardware/bare-metal.nix - ./settings/hardware/personal-computer.nix ./settings/hardware/mouse.nix ./settings/hardware/systemd-boot.nix ./settings/hardware/nvidia-gpu.nix ./settings/hardware/keyboard.nix ./settings/hardware/keyboard-lofree.nix + ./settings/hardware/trezor.nix ./settings/services/syncthing.nix - ./settings/services/zeroconf.nix + ./settings/services/virtualisation.nix ./settings/user-interface.nix ./settings/programs/base.nix - ./settings/programs/gnupg.nix ./settings/programs/kde.nix ./settings/programs/shell.nix ./settings/programs/docker.nix ./settings/gaming.nix + <nixos-hardware/common/cpu/amd> + <nixos-hardware/common/cpu/amd/pstate.nix> + <nixos-hardware/common/pc/ssd> + <nixos-hardware/common/pc> + <nixos-hardware/common/gpu/nvidia> ]; + virtualisation.vmVariant = { + disabledModules = [ + ./settings/hardware/nvidia-gpu.nix + ./settings/hardware/bare-metal.nix + ./settings/gaming.nix + ./settings/user-interface.nix + ./settings/programs/kde.nix + <nixos-hardware/common/cpu/amd> + <nixos-hardware/common/cpu/amd/pstate.nix> + <nixos-hardware/common/pc/ssd> + <nixos-hardware/common/pc> + <nixos-hardware/common/gpu/nvidia> + ]; + services.qemuGuest.enable = true; + virtualisation = { + memorySize = 4096; + cores = 4; + }; + }; + nixpkgs.hostPlatform = "x86_64-linux"; services.xserver.screenSection = '' @@ -40,9 +64,6 @@ user = "alan"; enable = true; }; - services.displayManager.sddm = { - enableHidpi = false; - }; boot.kernelPackages = pkgs.linuxPackages_xanmod; boot.extraModulePackages = with config.boot.kernelPackages; [ @@ -102,36 +123,57 @@ }; systemd.network = { - enable = true; networks."40-enp7s0" = { + matchConfig = { + Name = "enp7s0"; + }; dhcpV4Config = { - UseDNS = true; + UseDomains = true; + }; + dhcpV6Config = { + UseDomains = true; }; ipv6AcceptRAConfig = { - UseDNS = true; + UseDomains = true; + }; + networkConfig = { + MulticastDNS = true; }; }; }; networking = { + hostName = "prefect"; useDHCP = false; useNetworkd = true; interfaces.enp7s0 = { useDHCP = true; }; + hosts = { + "fd7a:115c:a1e0::53" = [ "tailscale" "ts" ]; + }; + + nftables = { + enable = true; + }; + firewall = { + extraInputRules = '' + ip saddr 10.0.0.0/8 accept + ip6 saddr { fd00::/8, fe80::/10 } accept + ''; + }; }; - networking.nftables = { - enable = true; - }; - networking.firewall = { - allowedTCPPorts = [ 80 443 139 445 1024 ]; - extraInputRules = '' - ip saddr 10.0.0.0/8 accept - ip6 saddr { fd00::/8, fe80::/10 } accept - ''; + + services.resolved = { + llmnr = "false"; + dnssec = "true"; }; - networking = { - hostName = "prefect"; + services.tailscale = { + enable = true; + extraUpFlags = [ + "--accept-dns=true" + "--accept-routes=false" + ]; }; system.stateVersion = "23.05"; diff --git a/system/settings/base.nix b/system/settings/base.nix index 5eee9088..81dab9a1 100644 --- a/system/settings/base.nix +++ b/system/settings/base.nix @@ -1,14 +1,9 @@ { config , pkgs , lib -, inputs , ... }: -let - inherit (inputs) self; -in { boot.loader.timeout = lib.mkDefault 1; services.irqbalance.enable = true; - system.configurationRevision = toString (self.rev or self.dirtyRev or self.lastModified or "unknown"); } diff --git a/system/settings/configuration/networking.nix b/system/settings/configuration/networking.nix deleted file mode 100644 index ad4200b1..00000000 --- a/system/settings/configuration/networking.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ config -, pkgs -, ... -}: { - environment.systemPackages = with pkgs; [ lxqt.lxqt-policykit ]; # provides a default authentification client for policykit - services.gvfs.enable = true; # enables gvfs - - imports = [ - ../services/zeroconf.nix - ]; -} diff --git a/system/settings/configuration/nix-linux.nix b/system/settings/configuration/nix-linux.nix index 3ee9f420..e11b0389 100644 --- a/system/settings/configuration/nix-linux.nix +++ b/system/settings/configuration/nix-linux.nix @@ -20,7 +20,6 @@ system.autoUpgrade = { enable = true; flags = [ "--max-jobs" "2" ]; - flake = "/home/alan/projects/alanpearce/nixfiles"; }; systemd.services.nixos-upgrade = { script = pkgs.lib.mkForce '' diff --git a/system/settings/configuration/nix.nix b/system/settings/configuration/nix.nix index c8db7836..b28fde18 100644 --- a/system/settings/configuration/nix.nix +++ b/system/settings/configuration/nix.nix @@ -3,9 +3,7 @@ , pkgs , ... }: { - imports = [ - ../../../pin.nix - ]; + imports = [ ../pin.nix ]; nix = { settings = { cores = lib.mkDefault 0; @@ -14,6 +12,15 @@ keep-derivations = true; experimental-features = "nix-command flakes"; warn-dirty = false; + substituters = [ + "https://nix-community.cachix.org" + "https://binarycache.alanpearce.eu" + ]; + + trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "binarycache.alanpearce.eu:ZwqO3XMuajPictjwih8OY2+RXnOKpjZEZFHJjGSxAI4=" + ]; }; gc = { diff --git a/system/settings/configuration/user.nix b/system/settings/configuration/user.nix index 3a7f9620..9d6fed69 100644 --- a/system/settings/configuration/user.nix +++ b/system/settings/configuration/user.nix @@ -15,6 +15,7 @@ "dialout" "pipewire" "networkmanager" + "libvirtd" "video" ]; initialPassword = "password"; diff --git a/system/settings/darwin.nix b/system/settings/darwin.nix index aa55cce5..6d5b357d 100644 --- a/system/settings/darwin.nix +++ b/system/settings/darwin.nix @@ -16,6 +16,7 @@ [ "/run/current-system/sw" "/nix/var/nix/profiles/default" ] ]; + environment.darwinConfig = "$HOME/.config/nixpkgs/darwin-configuration.nix"; nix = { daemonIOLowPriority = true; gc = { @@ -24,7 +25,6 @@ }; settings.extra-platforms = "aarch64-darwin x86_64-darwin"; - linux-builder.enable = true; settings.trusted-users = [ "@admin" ]; }; @@ -32,7 +32,13 @@ allowUnfree = true; }; - launchd.user.agents.lorri = lib.mkIf config.services.lorri.enable { + # needed so that nix-darwin can activate the system as root + security.sudo.extraConfig = '' + Defaults env_keep += "NIX_PATH" + ''; + + services.lorri.enable = true; + launchd.user.agents.lorri = { serviceConfig = { RunAtLoad = lib.mkForce false; Sockets = { diff --git a/system/settings/gaming.nix b/system/settings/gaming.nix index 17f25065..d11d5a3c 100644 --- a/system/settings/gaming.nix +++ b/system/settings/gaming.nix @@ -19,9 +19,9 @@ }; fonts.fontconfig.cache32Bit = true; hardware.steam-hardware.enable = true; - hardware.opengl = { + hardware.graphics = { enable = true; - driSupport32Bit = true; + enable32Bit = true; }; hardware.pulseaudio.support32Bit = true; services.pipewire.alsa.support32Bit = true; diff --git a/system/settings/hardware/intel-gpu.nix b/system/settings/hardware/intel-gpu.nix deleted file mode 100644 index 494cb86e..00000000 --- a/system/settings/hardware/intel-gpu.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ config -, pkgs -, ... -}: { - # https://wiki.gentoo.org/wiki/Intel#Feature_support - services.xserver = { - useGlamor = true; - deviceSection = '' - Option "DRI" "3" - ''; - videoDrivers = [ "intel" ]; - }; - - boot.kernelParams = [ - "i915.enable_guc=2" - "i915.fastboot=1" - ]; -} diff --git a/system/settings/hardware/laptop.nix b/system/settings/hardware/laptop.nix deleted file mode 100644 index bd66fb8f..00000000 --- a/system/settings/hardware/laptop.nix +++ /dev/null @@ -1,79 +0,0 @@ -{ config -, pkgs -, lib -, ... -}: { - imports = [ - ./bluetooth.nix - ./bluetooth-audio.nix - ./connman.nix - ./iwd.nix - ./personal-computer.nix - ../user-interface.nix - ]; - - boot.kernelModules = [ "coretemp" ]; - - environment.systemPackages = with pkgs; [ - powerstat - powertop - - arandr - autorandr - ]; - - programs.light.enable = true; - - services.autorandr = { - enable = true; - defaultTarget = "common"; - }; - systemd.services.autorandr.wantedBy = [ "graphical.target" ]; - - environment.etc.autorandr = { - enable = true; - source = ../../autorandr; - target = "xdg/autorandr"; - }; - - services.logind = { - lidSwitch = "suspend"; - lidSwitchExternalPower = "ignore"; - extraConfig = '' - IdleAction=suspend - IdleActionSec=600 - ''; - }; - - services.acpid = { - enable = true; - lidEventCommands = '' - ${pkgs.autorandr}/bin/autorandr --batch --change - ''; - }; - - services.tlp = { - extraConfig = '' - CPU_SCALING_GOVERNOR_ON_BAT=powersave - ENERGY_PERF_POLICY_ON_BAT="balance_power" - - SOUND_POWER_SAVE_ON_AC=60 - DEVICES_TO_DISABLE_ON_BAT_NOT_IN_USE="bluetooth wwan" - ''; - }; - - services.xserver = { - libinput = { - enable = lib.mkDefault true; - naturalScrolling = true; - disableWhileTyping = true; - }; - displayManager.sessionCommands = '' - ${pkgs.autorandr}/bin/autorandr --change --force - ''; - }; - - systemd.services.nixos-upgrade.unitConfig.ConditionACPower = true; - systemd.services.nix-gc.unitConfig.ConditionACPower = true; - systemd.services.docker-prune.unitConfig.ConditionACPower = true; -} diff --git a/system/settings/hardware/mouse.nix b/system/settings/hardware/mouse.nix index b74d17aa..d4a232af 100644 --- a/system/settings/hardware/mouse.nix +++ b/system/settings/hardware/mouse.nix @@ -2,7 +2,7 @@ , pkgs , ... }: { - services.xserver.libinput = { + services.libinput = { enable = true; mouse = { accelProfile = "flat"; diff --git a/system/settings/hardware/network-manager.nix b/system/settings/hardware/network-manager.nix deleted file mode 100644 index a27ca892..00000000 --- a/system/settings/hardware/network-manager.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ config -, lib -, pkgs -, ... -}: { - networking = { - networkmanager = { - enable = true; - }; - }; - - environment.systemPackages = with pkgs; [ - networkmanagerapplet - networkmanager_dmenu - ]; -} diff --git a/system/settings/hardware/personal-computer.nix b/system/settings/hardware/personal-computer.nix deleted file mode 100644 index 35824136..00000000 --- a/system/settings/hardware/personal-computer.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ config -, pkgs -, lib -, ... -}: { - boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_zen; - powerManagement.cpuFreqGovernor = "schedutil"; -} diff --git a/system/settings/hardware/thinkpad.nix b/system/settings/hardware/thinkpad.nix deleted file mode 100644 index 649f626a..00000000 --- a/system/settings/hardware/thinkpad.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ config -, pkgs -, ... -}: { - boot.kernelModules = [ ]; - boot.blacklistedKernelModules = [ "thinkpad_ec" ]; - boot.extraModulePackages = with config.boot.kernelPackages; [ - acpi_call - ]; - - services.fwupd = { - enable = true; - }; - - services.thinkfan = { - enable = true; - }; - - imports = [ - ./bare-metal.nix - ./laptop.nix - ]; -} diff --git a/system/settings/hardware/trackball.nix b/system/settings/hardware/trackball.nix deleted file mode 100644 index c2f7e68c..00000000 --- a/system/settings/hardware/trackball.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ config -, pkgs -, ... -}: { - services.xserver.config = '' - Section "InputClass" - Identifier "Trackball (No Acceleration)" - MatchIsPointer "yes" - MatchIsTouchpad "no" - MatchProduct "Trackball" - Option "AccelerationProfile" "-1" - Option "AccelerationScheme" "none" - EndSection - ''; -} diff --git a/system/settings/hardware/trezor.nix b/system/settings/hardware/trezor.nix index 1004833a..3883d76f 100644 --- a/system/settings/hardware/trezor.nix +++ b/system/settings/hardware/trezor.nix @@ -5,13 +5,7 @@ }: { services.trezord.enable = true; environment.systemPackages = with pkgs; [ - gnupg - pinentry (python3.withPackages (ps: with ps; [ trezor_agent wheel ])) trezor-suite ]; - programs.gnupg.agent = { - enable = lib.mkForce false; - enableSSHSupport = lib.mkForce false; - }; } diff --git a/system/settings/machines/t470s.nix b/system/settings/machines/t470s.nix deleted file mode 100644 index 5f1f4a1c..00000000 --- a/system/settings/machines/t470s.nix +++ /dev/null @@ -1,57 +0,0 @@ -{ config -, pkgs -, ... -}: { - hardware.usbWwan.enable = false; # unused - systemd.services.ModemManager.enable = false; - - hardware.enableRedistributableFirmware = true; - - boot.extraModprobeConfig = '' - options thinkpad_acpi fan_control=1 - ''; - - services.thinkfan.sensors = '' - hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon0/temp3_input - hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon0/temp1_input - hwmon /sys/devices/platform/coretemp.0/hwmon/hwmon0/temp2_input - ''; - services.thinkfan.levels = '' - (0, 0, 48) - (1, 45, 52) - (2, 50, 57) - (3, 55, 63) - (6, 60, 65) - (7, 60, 85) - (127, 80, 32767) - ''; - - boot.postBootCommands = '' - echo bfq > /sys/block/nvme0n1/queue/scheduler - ''; - - hardware.pulseaudio.extraConfig = '' - load-module module-alsa-sink device=hw:0,7 - ''; - - services.tlp.extraConfig = '' - DISK_DEVICES="nvme0n1" - DISK_IOSCHED="keep" - ''; - - services.xserver = { - dpi = 109; - monitorSection = '' - DisplaySize 310 176 - ''; - }; - - environment.systemPackages = with pkgs; [ - nvme-cli - ]; - - imports = [ - ../hardware/intel-gpu.nix - ../hardware/thinkpad.nix - ]; -} diff --git a/system/settings/pin.nix b/system/settings/pin.nix new file mode 100644 index 00000000..533149fe --- /dev/null +++ b/system/settings/pin.nix @@ -0,0 +1,12 @@ +let + inherit (import ../../sources.nix) nixPath sources; +in +{ + nix = { + inherit nixPath; + registry.nixpkgs.to = { + type = "path"; + path = sources.nixpkgs; + }; + }; +} diff --git a/system/settings/programs/barrier.nix b/system/settings/programs/barrier.nix deleted file mode 100644 index 76e1b06b..00000000 --- a/system/settings/programs/barrier.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ config -, pkgs -, ... -}: { - environment.systemPackages = with pkgs; [ - barrier - ]; - - networking.firewall.allowedTCPPorts = [ 24800 ]; -} diff --git a/system/settings/programs/base.nix b/system/settings/programs/base.nix index bfc81312..47ed4c07 100644 --- a/system/settings/programs/base.nix +++ b/system/settings/programs/base.nix @@ -1,26 +1,11 @@ { pkgs, ... }: { - services.lorri.enable = true; environment.systemPackages = with pkgs; [ home-manager + brotli lzma lzop zstd ] ++ (lib.optionals (stdenv.isLinux) [ psmisc ]); - nix.settings = { - substituters = [ - "https://nix-community.cachix.org" - "https://deploy-rs.cachix.org" - "https://binarycache.alanpearce.eu" - "https://deploy-rs.cachix.org" - ]; - - trusted-public-keys = [ - "deploy-rs.cachix.org-1:xfNobmiwF/vzvK1gpfediPwpdIP0rpDV2rYqx40zdSI=" - "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - "deploy-rs.cachix.org-1:xfNobmiwF/vzvK1gpfediPwpdIP0rpDV2rYqx40zdSI=" - "binarycache.alanpearce.eu:ZwqO3XMuajPictjwih8OY2+RXnOKpjZEZFHJjGSxAI4=" - ]; - }; } diff --git a/system/settings/programs/gnome.nix b/system/settings/programs/gnome.nix deleted file mode 100644 index f9618009..00000000 --- a/system/settings/programs/gnome.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ config -, lib -, pkgs -, ... -}: -with lib; { - services = { - gnome3 = { - gnome-documents.enable = false; - gnome-user-share.enable = false; - gnome-online-accounts.enable = false; - tracker.enable = false; - }; - telepathy.enable = false; - - xserver = { - desktopManager.gnome3 = { - enable = true; - extraGSettingsOverrides = '' - [org.gnome.desktop.input-sources] - sources=[('xkb','${config.services.xserver.layout + (optionalString (config.services.xserver.xkbVariant != "") ("+" + config.services.xserver.xkbVariant))}')] - ''; - }; - }; - }; -} diff --git a/system/settings/programs/gnupg.nix b/system/settings/programs/gnupg.nix deleted file mode 100644 index f17263c9..00000000 --- a/system/settings/programs/gnupg.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ config -, pkgs -, lib -, ... -}: { - environment.systemPackages = with pkgs; [ - gnupg - pinentry - (python3.withPackages (ps: with ps; [ trezor_agent wheel ])) - ]; - environment.variables.GNUPGHOME = "$HOME/.gnupg/trezor/"; -} diff --git a/system/settings/programs/kde.nix b/system/settings/programs/kde.nix index 1a753cf2..1cf3c917 100644 --- a/system/settings/programs/kde.nix +++ b/system/settings/programs/kde.nix @@ -3,13 +3,16 @@ , pkgs , ... }: -with lib; { +{ services = { desktopManager = { plasma6.enable = true; }; displayManager = { - sddm.enable = true; + sddm = { + enable = true; + enableHidpi = lib.mkDefault false; + }; }; physlock.enable = lib.mkForce false; diff --git a/system/settings/programs/shell.nix b/system/settings/programs/shell.nix index 87372033..680985cd 100644 --- a/system/settings/programs/shell.nix +++ b/system/settings/programs/shell.nix @@ -4,6 +4,7 @@ }: { programs.fish = { enable = true; + useBabelfish = true; }; users.users.alan.shell = pkgs.fish; } diff --git a/system/settings/programs/tor.nix b/system/settings/programs/tor.nix deleted file mode 100644 index 31521857..00000000 --- a/system/settings/programs/tor.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ config -, pkgs -, lib -, ... -}: { - services.tor = { - enable = true; - client = { - enable = true; - socksListenAddress = { - IPv6Traffic = true; - port = 9050; - }; - }; - torsocks = { - enable = true; - }; - }; - systemd.services.tor.wantedBy = lib.mkForce [ ]; - systemd.timers.tor = { - description = "Delayed startup of Tor"; - wantedBy = [ "timers.target" ]; - timerConfig = { - OnActiveSec = "1 min"; - }; - }; -} diff --git a/system/settings/programs/window-manager.nix b/system/settings/programs/window-manager.nix deleted file mode 100644 index bbe4c638..00000000 --- a/system/settings/programs/window-manager.nix +++ /dev/null @@ -1,57 +0,0 @@ -{ config -, pkgs -, lib -, ... -}: { - services.xserver = { - desktopManager.xterm.enable = false; - - displayManager = { - autoLogin = { - user = "alan"; - enable = false; - }; - lightdm = { - enable = true; - greeter.enable = true; - greeters.mini = { - enable = false; - user = "alan"; - }; - }; - sessionCommands = '' - ${pkgs.xorg.xrdb}/bin/xrdb -merge $HOME/.xresources/main - ${pkgs.xorg.xsetroot}/bin/xsetroot -cursor_name left_ptr -solid '#4d4d4c' - '' ++ (lib.optionalString config.networking.networkmanager.enable '' - ${pkgs.networkmanagerapplet}/bin/nm-applet & - ''); - }; - xautolock = { - enable = true; - locker = "${pkgs.i3lock}/bin/i3lock -n"; - enableNotifier = true; - notifier = "${pkgs.libnotify}/bin/notify-send \"Locking in 10 seconds\""; - time = 5; - }; - }; - - services.xserver.displayManager.setupCommands = '' - ${pkgs.redshift}/bin/redshift \ - -l ${toString config.location.latitude}:${toString config.location.longitude} \ - -t ${toString config.services.redshift.temperature.day}:${toString config.services.redshift.temperature.night} \ - -b 1:1 \ - -o \ - -r - ''; - - environment.systemPackages = with pkgs; [ - dmenu - libnotify # for notify-send - xterm - rofi - sxhkd - maim - - perlPackages.FileMimeInfo # xdg-utils uses this when no DE - ]; -} diff --git a/system/settings/programs/xfce.nix b/system/settings/programs/xfce.nix deleted file mode 100644 index a896810a..00000000 --- a/system/settings/programs/xfce.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ pkgs, ... }: { - services.xserver.desktopManager.xfce = { - enable = true; - }; - environment.systemPackages = with pkgs; [ - xfce.xfce4-panel-profiles - ]; -} diff --git a/system/settings/services/git-server.nix b/system/settings/services/git-server.nix new file mode 100644 index 00000000..54e8560c --- /dev/null +++ b/system/settings/services/git-server.nix @@ -0,0 +1,279 @@ +{ config +, lib +, pkgs +, ... +}: +let + inherit (lib) pipe flatten concatMapAttrs mergeAttrsList mapAttrsToList; + inherit (import ../../../lib/caddy.nix { inherit lib; }) security-headers; + repos = "${config.services.gitolite.dataDir}/repositories"; + + mirrors = { + sourcehut = { + hostname = "git.sr.ht"; + username = "~alanpearce"; + }; + codeberg = { + hostname = "codeberg.org"; + username = "alanpearce"; + }; + github = { + hostname = "github.com"; + username = "alanpearce"; + }; + }; + + repoMirrors = { + nixfiles = [ "sourcehut" ]; + searchix = [ "sourcehut" ]; + website = [ "sourcehut" ]; + nix-packages = [ "sourcehut" "github" ]; + zola-bearblog = [ "sourcehut" "codeberg" ]; + }; + + createMirrorService = + name: { hostname, username }: + { + "mirror-to-${name}@" = { + path = with pkgs; [ gitMinimal openssh ]; + serviceConfig = { + Type = "oneshot"; + User = "gitolite"; + WorkingDirectory = "${repos}/%i.git"; + ExecStart = "${pkgs.gitMinimal}/bin/git push --mirror git@${hostname}:${username}/%i"; + }; + unitConfig = { + # only mirror public repositories + ConditionPathExists = "${repos}/%i.git/git-daemon-export-ok"; + }; + }; + }; + + createMirrorPath = name: { hostname, username }: + { + "mirror-to-${name}@" = { + pathConfig = { + PathChanged = "${repos}/%i.git/refs/heads"; + StartLimitIntervalSec = "1h"; + StartLimitBurst = 5; + }; + }; + }; + + + mkMirrorWants = repo: map (target: "mirror-to-${target}@${repo}.path"); +in +{ + services.fcgiwrap = { + enable = true; + user = "gitolite"; + group = "gitolite"; + preforkProcesses = 2; + socketType = "tcp6"; + socketAddress = "[::1]:9000"; + }; + services.gitolite = { + enable = true; + adminPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII8VIII+598QOBxi/52O1Kb19RdUdX0aZmS1/dNoyqc5 alan@hetzner.strongbox"; + extraGitoliteRc = '' + $RC{UMASK} = 0027; + $RC{LOG_EXTRA} = 0; + $RC{HOSTNAME} = "${config.networking.hostName}"; + $RC{LOCAL_CODE} = "$rc{GL_ADMIN_BASE}/local"; + push( @{$RC{ENABLE}}, 'D' ); + push( @{$RC{ENABLE}}, 'Shell alan' ); + push( @{$RC{ENABLE}}, 'cgit' ); + push( @{$RC{ENABLE}}, 'repo-specific-hooks' ); + ''; + }; + services.legit = { + enable = true; + group = "gitolite"; + settings = { + server.name = "legit.alanpearce.eu"; + dirs = { + templates = "/srv/http/legit/src/templates"; + }; + repo = { + scanPath = "/srv/http/legit/repos"; + readme = [ + "readme" + "readme.md" + "README.md" + ]; + }; + }; + }; + services.gitDaemon = { + enable = true; + user = "gitolite"; + group = "gitolite"; + basePath = repos; + }; + + services.caddy.virtualHosts = { + "git.alanpearce.eu" = + let + fcgi = config.services.fcgiwrap; + fcgisocket = "${fcgi.socketType}/${fcgi.socketAddress}"; + in + { + useACMEHost = "alanpearce.eu"; + extraConfig = '' + root * ${pkgs.cgit-pink}/cgit/ + encode zstd gzip + ${security-headers { + overrides.content-security-policy = { + default-src = [ "none" ]; + base-uri = [ "none" ]; + style-src = [ "self" "unsafe-inline" ]; + script-src = [ "self" "unsafe-inline" ]; + form-action = [ "self" ]; + connect-src = [ "self" ]; + img-src = [ "https" ]; + object-src = [ "none" ]; + }; + }} + handle_path /custom/* { + file_server { + root /srv/http/cgit/ + } + } + rewrite /robots.txt /assets/robots.txt + handle_path /assets/* { + file_server { + hide cgit.cgi + } + } + @git_http_backend path_regexp "^.*/(HEAD|info/refs|objects/info/[^/]+|git-upload-pack)$" + handle @git_http_backend { + reverse_proxy ${fcgisocket} { + transport fastcgi { + env SCRIPT_FILENAME ${pkgs.git}/libexec/git-core/git-http-backend + env GIT_PROJECT_ROOT ${repos} + } + } + } + handle { + reverse_proxy ${fcgisocket} { + transport fastcgi { + env SCRIPT_FILENAME {http.vars.root}/cgit.cgi + env CGIT_CONFIG ${pkgs.writeText "cgitrc" '' + head-include=/srv/http/cgit/responsive-cgit-css-master/head.html + css=/custom/responsive-cgit-css-master/cgit.css + virtual-root=/ + logo= + readme=:README.md + source-filter=${pkgs.cgit-pink}/lib/cgit/filters/syntax-highlighting.py + about-filter=${pkgs.cgit-pink}/lib/cgit/filters/about-formatting.sh + enable-git-config=1 + enable-index-owner=0 + enable-index-links=1 + enable-follow-links=0 + enable-log-linecount=1 + max-stats=year + snapshots=tar.lz tar.zst zip + cache-size=10240 + enable-http-clone=1 + enable-commit-graph=1 + mimetype-file=${pkgs.nginx}/conf/mime.types + section-from-path=1 + noplainemail=1 + repository-sort=age + root-title=my personal projects + clone-url=git://git.alanpearce.eu/$CGIT_REPO_URL https://git.alanpearce.eu/$CGIT_REPO_URL + remove-suffix=1 + strict-export=git-daemon-export-ok + scan-path=${repos} + ''} + } + } + } + ''; + }; + + "legit.alanpearce.eu" = + let + server = config.services.legit.settings.server; + in + { + useACMEHost = "alanpearce.eu"; + extraConfig = '' + encode zstd gzip + handle_path /static/* { + root * /srv/http/legit/src/static + file_server + } + ${security-headers { + overrides.content-security-policy = { + default-src = [ "none" ]; + base-uri = [ "none" ]; + style-src = [ "self" ]; + script-src = [ "none" ]; + form-action = [ "self" ]; + connect-src = [ "self" ]; + img-src = [ "https" ]; + object-src = [ "none" ]; + }; + }} + reverse_proxy ${server.host}:${toString server.port} + ''; + }; + }; + + programs.ssh = with pkgs; { + knownHostsFiles = [ + (writeText "github.keys" '' + # github.com:22 SSH-2.0-babeld-05989c77 + # github.com:22 SSH-2.0-babeld-05989c77 + # github.com:22 SSH-2.0-babeld-05989c77 + # github.com:22 SSH-2.0-babeld-05989c77 + # github.com:22 SSH-2.0-babeld-05989c77 + github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= + github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + '') + (writeText "gitlab.keys" '' + # gitlab.com:22 SSH-2.0-GitLab-SSHD + # gitlab.com:22 SSH-2.0-GitLab-SSHD + # gitlab.com:22 SSH-2.0-GitLab-SSHD + # gitlab.com:22 SSH-2.0-GitLab-SSHD + # gitlab.com:22 SSH-2.0-GitLab-SSHD + gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 + gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= + gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf + '') + (writeText "codeberg.keys" '' + # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 + # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 + # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 + # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 + # codeberg.org:22 SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2 + codeberg.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8hZi7K1/2E2uBX8gwPRJAHvRAob+3Sn+y2hxiEhN0buv1igjYFTgFO2qQD8vLfU/HT/P/rqvEeTvaDfY1y/vcvQ8+YuUYyTwE2UaVU5aJv89y6PEZBYycaJCPdGIfZlLMmjilh/Sk8IWSEK6dQr+g686lu5cSWrFW60ixWpHpEVB26eRWin3lKYWSQGMwwKv4LwmW3ouqqs4Z4vsqRFqXJ/eCi3yhpT+nOjljXvZKiYTpYajqUC48IHAxTWugrKe1vXWOPxVXXMQEPsaIRc2hpK+v1LmfB7GnEGvF1UAKnEZbUuiD9PBEeD5a1MZQIzcoPWCrTxipEpuXQ5Tni4mN + codeberg.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL2pDxWr18SoiDJCGZ5LmxPygTlPu+cCKSkpqkvCyQzl5xmIMeKNdfdBpfbCGDPoZQghePzFZkKJNR/v9Win3Sc= + codeberg.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIVIC02vnjFyL+I4RHfvIGNtOgJMe769VTF1VR4EB3ZB + '') + (writeText "sr.ht.keys" '' + # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 + # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 + # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 + # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 + # git.sr.ht:22 SSH-2.0-OpenSSH_9.6 + git.sr.ht ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZ+l/lvYmaeOAPeijHL8d4794Am0MOvmXPyvHTtrqvgmvCJB8pen/qkQX2S1fgl9VkMGSNxbp7NF7HmKgs5ajTGV9mB5A5zq+161lcp5+f1qmn3Dp1MWKp/AzejWXKW+dwPBd3kkudDBA1fa3uK6g1gK5nLw3qcuv/V4emX9zv3P2ZNlq9XRvBxGY2KzaCyCXVkL48RVTTJJnYbVdRuq8/jQkDRA8lHvGvKI+jqnljmZi2aIrK9OGT2gkCtfyTw2GvNDV6aZ0bEza7nDLU/I+xmByAOO79R1Uk4EYCvSc1WXDZqhiuO2sZRmVxa0pQSBDn1DB3rpvqPYW+UvKB3SOz + git.sr.ht ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCj6y+cJlqK3BHZRLZuM+KP2zGPrh4H66DacfliU1E2DHAd1GGwF4g1jwu3L8gOZUTIvUptqWTkmglpYhFp4Iy4= + git.sr.ht ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60 + '') + ]; + }; + + systemd.services = concatMapAttrs createMirrorService mirrors; + systemd.paths = concatMapAttrs createMirrorPath mirrors; + systemd.targets.git-mirroring = { + wantedBy = [ "multi-user.target" ]; + wants = pipe + repoMirrors [ + (mapAttrsToList mkMirrorWants) + flatten + ]; + }; +} diff --git a/system/settings/services/virtualisation.nix b/system/settings/services/virtualisation.nix index dbe041c7..172dfcec 100644 --- a/system/settings/services/virtualisation.nix +++ b/system/settings/services/virtualisation.nix @@ -12,9 +12,11 @@ runAsRoot = false; }; }; + programs.virt-manager = { + enable = true; + }; environment.systemPackages = with pkgs; [ - virt-manager OVMF ]; } diff --git a/system/settings/services/xserver.nix b/system/settings/services/xserver.nix index c5a82d48..29f181ee 100644 --- a/system/settings/services/xserver.nix +++ b/system/settings/services/xserver.nix @@ -20,12 +20,6 @@ with lib; { xorg.xdpyinfo xclip xfontsel - - arc-theme - arc-icon-theme - - gtk-engine-murrine - gtk_engines ]; fonts = { @@ -57,24 +51,15 @@ with lib; { }; packages = with pkgs; [ - gohufont - dina-font - terminus_font - corefonts - xorg.fontmiscmisc xorg.fontcursormisc ] ++ lib.optionals config.fonts.fontconfig.antialias [ cantarell-fonts - fira - fira-code - fira-mono ibm-plex - oxygenfonts noto-fonts-color-emoji office-code-pro diff --git a/system/settings/user-interface.nix b/system/settings/user-interface.nix index 20cac135..d9d3297f 100644 --- a/system/settings/user-interface.nix +++ b/system/settings/user-interface.nix @@ -4,23 +4,14 @@ , ... }: { documentation.info.enable = true; - nixpkgs.config.firefox.enableOfficialBranding = true; environment.systemPackages = with pkgs; [ - aria2 - pcmanfm - epdfview - geeqie lxappearance lxrandr lxtask - mpv - - cifs-utils - trash-cli ]; @@ -59,11 +50,9 @@ }; }; - programs.dconf.enable = true; - programs.nh = { enable = true; - flake = "/home/alan/projects/alanpearce.eu/nixfiles"; + flake = builtins.toString ../..; clean = { enable = true; extraArgs = "--keep-since 14d"; diff --git a/user/.gitignore b/user/.gitignore deleted file mode 100644 index d7bc17e5..00000000 --- a/user/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -home.nix -result \ No newline at end of file diff --git a/user/config.nix b/user/config.nix index c12a0bb1..5a420d7b 100644 --- a/user/config.nix +++ b/user/config.nix @@ -1,5 +1,16 @@ -{ pkgs }: { - allowUnfree = true; - allowUnfreePredicate = pkg: true; +{ pkgs }: +let + inherit (pkgs) lib; +in +{ + allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ + "beeper" + "discord" + "input-fonts" + "tabnine" + ]; input-fonts.acceptLicense = true; + permittedInsecurePackages = [ + "electron-28.3.3" # for logseq 0.10.9 + ]; } diff --git a/user/emacs/early-init.el b/user/emacs/early-init.el index 29dadb92..d24c661d 100644 --- a/user/emacs/early-init.el +++ b/user/emacs/early-init.el @@ -4,9 +4,16 @@ frame-inhibit-implied-resize t byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local cl-functions)) +(require 'xdg) +(startup-redirect-eln-cache + (expand-file-name "emacs/native-compile" + (xdg-cache-home))) + ;; Disable all the bars, unless on macOS, in which case, keep the menu bar. (unless (eq window-system 'ns) (menu-bar-mode -1)) (scroll-bar-mode -1) (tool-bar-mode -1) (set-fringe-mode '(4 . 4)) + +(setenv "LSP_USE_PLISTS" "true") ; must match with lsp-mode override diff --git a/user/emacs/init.el b/user/emacs/init.el index dddd0ec0..b666e033 100644 --- a/user/emacs/init.el +++ b/user/emacs/init.el @@ -90,6 +90,10 @@ original-stimmung-themes-string)) (load-theme current-theme :noconfirm))))))) +(global-set-key (kbd "<pinch>") 'ignore) +(global-set-key (kbd "<C-wheel-up>") 'ignore) +(global-set-key (kbd "<C-wheel-down>") 'ignore) + (setq font-lock-maximum-decoration '((t . 1)) jit-lock-stealth-time 1.25 jit-lock-stealth-nice 0.5 @@ -133,7 +137,11 @@ (setq-default display-line-numbers 'relative display-line-numbers-widen t display-line-numbers-width 4) -(setq frame-resize-pixelwise t) +(setq frame-resize-pixelwise t + window-resize-pixelwise t + display-buffer-alist `(("\\*\\(?:shell\\|compilation\\)\\*" display-buffer-in-side-window + (side . bottom) (slot . 0) (preserve-size . (nil . t)) + (no-other-window . t) (no-delete-other-windows . t)))) (defun noct-relative () "Show relative line numbers." @@ -478,6 +486,12 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve :defer 2 :config (evil-commentary-mode +1)) +(use-package evil-lion + :after evil + :defer 10 + :config (progn + (evil-lion-mode +1))) + (use-package evil-matchit :after evil :defer 2 @@ -568,7 +582,7 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (setq kind-icon-default-face 'corfu-default) (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))) -(use-package tabnine +(use-package tabnine-core :config (progn (setq tabnine-binaries-folder "~/.local/tabnine") (with-demoted-errors "TabNine error: %s" @@ -635,11 +649,10 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve ;;;; Auto-reloading (use-package autorevert - :defer 1 :config (progn (setq auto-revert-verbose nil auto-revert-use-notify t) - (global-auto-revert-mode t))) + (global-auto-revert-mode 1))) (setq delete-by-moving-to-trash t) @@ -666,11 +679,18 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (add-to-list 'tramp-default-proxies-alist `(,(regexp-quote (system-name)) nil nil)))) +(use-package ssh-deploy + :config (progn + (ssh-deploy-line-mode +1) + (ssh-deploy-add-find-file-hook) + (ssh-deploy-add-after-save-hook))) + ;;; Directories (setq dired-dwim-target t dired-recursive-copies 'top dired-listing-switches "-alh --group-directories-first" + dired-kill-when-opening-new-dired-buffer t dired-recursive-deletes (if delete-by-moving-to-trash 'always 'top)) @@ -707,7 +727,9 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (use-package eshell-toggle :commands (eshell-toggle) - :general ("C-`" #'eshell-toggle)) + :general ("C-`" #'eshell-toggle) + :config (progn + (setq eshell-toggle-find-project-root-package 'project))) (declare-function eshell-push-command "esh-buf-stack" (CMD)) (defun my-bind-esh-push () @@ -777,6 +799,13 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (with-eval-after-load 'project (add-to-list 'project-vc-extra-root-markers "go.mod")) +(setq-default go-ts-mode-indent-offset 2) +(use-package templ-ts-mode + :gfhook #'eglot-format-before-save-mode + :defer t + :config (progn + (setq-default go-ts-mode-indent-offset 2))) + ;;;; nim (use-package nim-mode :defer t @@ -786,6 +815,7 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve ;;;; js (setq js-enabled-frameworks '(javascript)) +(add-to-list 'auto-mode-alist '("\\.[cm]js\\'" . js-ts-mode)) ;;;; typescript @@ -798,7 +828,7 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (add-hook 'compilation-filter-hook #'colourise-compilation-buffer) ;;;; shell -(general-add-hook 'sh-mode-hook +(general-add-hook '(sh-mode-hook bash-ts-mode-hook fish-mode-hook) (lambda () (general-add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p :append :local))) @@ -806,8 +836,6 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (add-to-list 'auto-mode-alist '("\\.env\\'" . conf-unix-mode)) (add-to-list 'auto-mode-alist '("\\.zsh\\'" . shell-script-mode)) (add-to-list 'auto-mode-alist '("zshenv\\'" . shell-script-mode)) -(add-to-list 'auto-mode-alist '("zshrc\\'" . shell-script-mode)) -(setq sh-shell-file "/usr/bin/env zsh") (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on) @@ -882,14 +910,16 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (use-package web-mode :mode (("\\.html?.erb\\'" . web-mode) + ("\\.gotmpl\\'" . web-mode) ("\\.tmpl\\'" . web-mode)) :config (setq web-mode-enable-auto-pairing nil web-mode-style-padding 2 web-mode-script-padding 2 - web-mode-engines-alist '(("go" . "\\.tmpl\\'")))) + web-mode-engines-alist '(("go" . "\\.tmpl\\'") + ("go" . "\\.gotmpl\\'")))) (use-package emmet-mode - :ghook '(web-mode-hook sgml-mode-hook)) + :ghook '(web-mode-hook sgml-mode-hook templ-ts-mode-hook)) ;;; IDE features @@ -941,6 +971,32 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (evil-ex-define-cmd "pb" #'project-switch-to-buffer) (evil-ex-define-cmd "psw[itch]" #'project-switch-project)))) +(use-package treemacs + :general (:keymaps 'treemacs-mode-map + [mouse-1] #'treemacs-single-click-expand-action) + :config (progn + (treemacs-project-follow-mode t) + (setq treemacs-is-never-other-window t + treemacs-select-when-already-in-treemacs 'move-back + treemacs-eldoc-display nil + treemacs-indentation '(8 px) + treemacs-show-hidden-files nil + treemacs-recenter-after-project-jump 'on-distance + treemacs-missing-project-action 'remove))) + +(use-package treemacs-evil + :after treemacs) + +(use-package treemacs-magit + :after treemacs) + +(use-package treemacs-nerd-icons + :after treemacs + :init (progn + (setq treemacs-nerd-icons-tab " ")) + :config (progn + (treemacs-load-theme "simple"))) + (use-package consult-ghq :defer 5 :general (:keymaps 'project-prefix-map @@ -961,12 +1017,15 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve :general ([remap project-vc-dir] #'magit-project-status) (:keymaps 'project-prefix-map "m" #'magit-project-status) :init (progn - (with-eval-after-load 'project - (add-to-list 'project-switch-commands '(magit-project-status "Magit") t))) + (defvar magit-auto-revert-mode nil) + (setq magit-auto-revert-mode nil) + (require 'project) + (add-to-list 'project-switch-commands '(magit-project-status "Magit") t)) :config (progn (setq magit-section-visibility-indicator nil magit-diff-refine-hunk t - magit-auto-revert-immediately t + magit-auto-revert-mode nil + magit-auto-revert-immediately nil ; unnecessary when global-auto-revert-mode is enabled magit-display-buffer-function #'magit-display-buffer-fullcolumn-most-v1) (remove-hook 'magit-status-sections-hook 'magit-insert-tags-header) (remove-hook 'magit-section-highlight-hook 'magit-section-highlight) @@ -974,6 +1033,11 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (remove-hook 'magit-section-highlight-hook 'magit-diff-highlight) (require 'magit-extras))) +(use-package magit-todos + :after magit + :config (progn + (magit-todos-mode +1))) + (use-package git-gutter-fringe :defer 5 :config (progn @@ -1001,7 +1065,9 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve :defer 2 :config (progn (editorconfig-mode +1) - (setq editorconfig-lisp-use-default-indent t))) + (setq editorconfig-lisp-use-default-indent t) + (setf (alist-get 'templ-ts-mode editorconfig-indentation-alist) + 'go-ts-mode-indent-offset))) (setq-default ispell-dictionary "en_GB-ise-w_accents") (setq ispell-extra-args '("--sug-mode=ultra" "--camel-case")) @@ -1034,11 +1100,22 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (defvaralias 'nix-ts-mode-hook 'nix-mode-hook) +(use-package consult-lsp + :commands (consult-lsp-symbols + consult-lsp-diagnostics)) + +(define-minor-mode eglot-format-before-save-mode + "Whether to ask the LSP to format the buffer before saving" + :init-val nil + (if eglot-format-before-save-mode + (add-hook 'before-save-hook #'eglot-format-buffer nil 'local) + (remove-hook 'before-save-hook #'eglot-format-buffer 'local))) + (use-package eglot :defer 3 :general (:states 'normal :keymaps 'eglot-mode-map "gr" #'xref-find-references - "C-t" #'xref-pop-marker-stack) + "C-t" #'xref-go-back) :ghook ('(typescript-mode-hook dockerfile-mode-hook yaml-mode-hook @@ -1048,6 +1125,7 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve nim-mode-hook html-mode-hook nix-mode-hook + templ-ts-mode-hook toml-ts-mode-hook haskell-mode-hook) #'eglot-ensure) @@ -1055,14 +1133,14 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (when (assoc 'nix-mode eglot-server-programs) (setf (car (assoc 'nix-mode eglot-server-programs)) '(nix-mode nix-ts-mode))) (nconc eglot-server-programs '((toml-ts-mode "taplo" "lsp" "stdio"))) - (advice-add 'eglot--message :before-while (lambda (formatstring &rest rest) + (advice-add 'eglot--message :before-until (lambda (formatstring &rest rest) (s-starts-with-p "Connected!" formatstring))) (defun my/setup-eglot-eldoc () (push 'flymake-eldoc-function eldoc-documentation-functions)) (add-hook 'eglot-managed-mode-hook 'my/setup-eglot-eldoc) (setq-default eglot-workspace-configuration '( :yaml (:keyOrdering nil) - :nix (:autoArchive t) + :nil (:nix (:flake (:autoArchive t))) :gopls ( :staticcheck t :usePlaceholders t))) (defun my/eglot-capf () @@ -1090,12 +1168,13 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve ('lsp-completion-mode-hook #'my/lsp-mode-setup-completion) :general (:states 'normal :keymaps 'lsp-mode-map "gr" #'xref-find-references - "C-t" #'xref-pop-marker-stack) + "C-t" #'xref-go-back) :config (progn (setq lsp-auto-guess-root t lsp-auto-execute-action nil lsp-headerline-breadcrumb-enable nil lsp-enable-suggest-server-download nil + lsp-modeline-diagnostics-enable nil lsp-completion-provider :none ; value `:capf' is actually for company :( lsp-diagnostics-provider t ; this means prefer flymake over flycheck, why‽ ) @@ -1131,16 +1210,18 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (call-interactively #'lsp-rename) (call-interactively #'eglot-rename))) -;; Inside a javascript project, it's common to install tools locally to -;; the project. This will allows emacs to find their executables. +(defun my/ls-consult-symbol () + (interactive) + (if lsp-mode + (call-interactively #'consult-lsp-symbols) + (call-interactively #'consult-eglot-symbols))) -(use-package add-node-modules-path - :config (setq add-node-modules-max-depth 6) - :ghook ('(feature-mode-hook - js-base-mode-hook - json-ts-mode-hook - typescript-ts-mode-hook) - #'add-node-modules-path)) +(defun my/ls-code-actions () + (interactive) + (call-interactively + (if lsp-mode + #'lsp-execute-code-action + #'eglot-code-actions))) ;;;; Reformat on save @@ -1166,15 +1247,13 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve (setq apheleia-formatters (append apheleia-formatters '((nixpkgs-fmt "nixpkgs-fmt") (golines "golines") + (taplo "taplo" "format" "-") (prettier-gotmpl "prettier" "--stdin-filepath" filepath "--parser=go-template" (apheleia-formatters-indent "--use-tabs" "--tab-width"))))) - (setf (alist-get 'go-ts-mode apheleia-mode-alist) - '(golines) - (alist-get 'web-mode apheleia-mode-alist) - '(prettier-gotmpl)) (setq apheleia-mode-alist (append apheleia-mode-alist '((nix-ts-mode . nixpkgs-fmt) - (nix-mode . nixpkgs-fmt)))) + (nix-mode . nixpkgs-fmt) + (toml-ts-mode . taplo)))) (add-hook 'apheleia-mode-hook #'turn-off-format-all-mode)) :init (progn (apheleia-global-mode +1))) @@ -1188,14 +1267,16 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve "w" '(:keymap evil-window-map :package evil) "x" '(:keymap ctl-x-map) "c" (general-simulate-key "C-c") - "j" #'consult-eglot-symbols + "j" #'my/ls-consult-symbol "r" #'my/ls-rename "q" #'evil-delete-buffer "p" '(:keymap project-prefix-map :package project) "v" #'split-window-right "o" #'other-window + "s" #'treemacs-select-window "u" #'universal-argument ";" #'execute-extended-command + "a" #'my/ls-code-actions "bb" #'consult-buffer "bx" #'kill-this-buffer "br" #'revert-buffer @@ -1222,7 +1303,8 @@ _C-k_: prev _u_pper _=_: upper/lower _s_mart resolve "iu" #'insert-char "xe" #'eval-last-sexp "xx" #'eval-defun - "xi" #'consult-imenu) + "xi" #'consult-imenu + "z" '(:keymap ssh-deploy-prefix-map :package ssh-deploy)) (let ((mail-config (expand-file-name "mail.el" user-emacs-directory))) (if (file-readable-p mail-config) diff --git a/user/gnupg/dirmngr.conf b/user/gnupg/dirmngr.conf deleted file mode 100644 index f69421d7..00000000 --- a/user/gnupg/dirmngr.conf +++ /dev/null @@ -1,3 +0,0 @@ -keyserver hkps://keys.openpgp.org -# keyserver hkp://zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad.onion -# use-tor diff --git a/user/gnupg/gpa.conf b/user/gnupg/gpa.conf deleted file mode 100644 index 2e33e80b..00000000 --- a/user/gnupg/gpa.conf +++ /dev/null @@ -1,2 +0,0 @@ -default-key 5FA779613E2AB0EEFC6DD3056A56F2A314E23293 -detailed-view diff --git a/user/gnupg/gpg-agent.conf b/user/gnupg/gpg-agent.conf deleted file mode 100644 index 52eb1dca..00000000 --- a/user/gnupg/gpg-agent.conf +++ /dev/null @@ -1,3 +0,0 @@ -enable-ssh-support -default-cache-ttl 600 -max-cache-ttl 7200 diff --git a/user/gnupg/gpg.conf b/user/gnupg/gpg.conf deleted file mode 100644 index 61df93cf..00000000 --- a/user/gnupg/gpg.conf +++ /dev/null @@ -1,83 +0,0 @@ -# -# This is an implementation of the Riseup OpenPGP Best Practices -# https://help.riseup.net/en/security/message-security/openpgp/best-practices -# - -#----------------------------- -# default key -#----------------------------- - -# The default key to sign with. If this option is not used, the default key is -# the first key found in the secret keyring - -# default-key - -#----------------------------- -# behavior -#----------------------------- - -# Disable inclusion of the version string in ASCII armored output -no-emit-version - -# Disable comment string in clear text signatures and ASCII armored messages -no-comments - -# Display long key IDs -keyid-format 0xlong - -# List all keys (or the specified ones) along with their fingerprints -with-fingerprint - -# Display the calculated validity of user IDs during key listings -list-options show-uid-validity -verify-options show-uid-validity - -# Try to use the GnuPG-Agent. With this option, GnuPG first tries to connect to -# the agent before it asks for a passphrase. -use-agent - -#----------------------------- -# keyserver -#----------------------------- - -# This is the server that --recv-keys, --send-keys, and --search-keys will -# communicate with to receive keys from, send keys to, and search for keys on -keyserver hkps://keys.openpgp.org - -# Provide a certificate store to override the system default -# Get this from https://sks-keyservers.net/sks-keyservers.netCA.pem -# keyserver-options ca-cert-file=.gnupg/sks-keyservers.netCA.pem - -# Set the proxy to use for HTTP and HKP keyservers - default to the standard -# local Tor socks proxy -# It is encouraged to use Tor for improved anonymity. Preferrably use either a -# dedicated SOCKSPort for GnuPG and/or enable IsolateDestPort and -# IsolateDestAddr -# keyserver-options http-proxy=socks5-hostname://127.0.0.1:9050 - -# When using --refresh-keys, if the key in question has a preferred keyserver -# URL, then disable use of that preferred keyserver to refresh the key from -keyserver-options no-honor-keyserver-url -# When searching for a key with --search-keys, include keys that are marked on -# the keyserver as revoked -keyserver-options include-revoked - - -#----------------------------- -# algorithm and ciphers -#----------------------------- - -# list of personal digest preferences. When multiple digests are supported by -# all recipients, choose the strongest one -personal-cipher-preferences AES256 AES192 AES CAST5 - -# list of personal digest preferences. When multiple ciphers are supported by -# all recipients, choose the strongest one -personal-digest-preferences SHA512 SHA384 SHA256 SHA224 - -# message digest algorithm used when signing a key -cert-digest-algo SHA512 - -# This preference list is used for new keys and becomes the default for -# "setpref" in the edit menu -default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed \ No newline at end of file diff --git a/user/gnupg/trezor/dirmngr.conf b/user/gnupg/trezor/dirmngr.conf deleted file mode 100644 index 17612d46..00000000 --- a/user/gnupg/trezor/dirmngr.conf +++ /dev/null @@ -1 +0,0 @@ -keyserver hkps://keys.openpgp.org \ No newline at end of file diff --git a/user/mba.nix b/user/mba.nix index a205fea4..ca7b0706 100644 --- a/user/mba.nix +++ b/user/mba.nix @@ -4,7 +4,6 @@ ./settings/development/base.nix ./settings/development/javascript.nix ./settings/development/golang.nix - ./settings/development/lisp.nix ./settings/development/web.nix ./settings/darwin.nix ./settings/emacs.nix @@ -15,10 +14,12 @@ ./settings/ssh.nix ./settings/tabnine.nix ./settings/user-interface.nix + <private> + <private/ssh.nix> ]; home.username = "alan"; - home.homeDirectory = "/home/alan"; + home.homeDirectory = "/Users/alan"; home.stateVersion = "22.11"; launchd.agents.colima = { diff --git a/user/nanopi.nix b/user/nanopi.nix index 44561eda..f2dfceac 100644 --- a/user/nanopi.nix +++ b/user/nanopi.nix @@ -7,7 +7,6 @@ ./settings/git.nix ./settings/nix.nix ./settings/nixos.nix - ./settings/music-management.nix ./settings/ssh.nix ]; home = { diff --git a/user/nvim/init.lua b/user/nvim/init.lua index f7bb020a..f9162167 100644 --- a/user/nvim/init.lua +++ b/user/nvim/init.lua @@ -2,6 +2,7 @@ vim.opt.autoindent = true vim.opt.background = "light" vim.opt.number = true +vim.opt.clipboard = "unnamed" vim.g.mapleader = "," diff --git a/user/prefect.nix b/user/prefect.nix index b5c4789e..6cf31cbc 100644 --- a/user/prefect.nix +++ b/user/prefect.nix @@ -7,24 +7,21 @@ ./settings/dunst.nix ./settings/emacs.nix ./settings/development/base.nix - ./settings/development/lisp.nix ./settings/development/golang.nix ./settings/development/javascript.nix ./settings/development/web.nix ./settings/fish.nix ./settings/git.nix ./settings/gnupg.nix - ./settings/i3.nix ./settings/music.nix ./settings/nixos.nix - ./settings/rofi.nix ./settings/passwords.nix ./settings/ssh.nix - ./settings/sxhkd.nix ./settings/tabnine.nix - ./settings/trezor.nix ./settings/user-interface.nix ./settings/xresources.nix + <private> + <private/ssh.nix> ]; home.username = "alan"; @@ -33,8 +30,7 @@ transgui ]; - xsession.windowManager.i3.config.startup = [ - ]; + xsession.enable = true; home.stateVersion = "22.11"; } diff --git a/user/server.nix b/user/server.nix index 235e6908..9b3db3fc 100644 --- a/user/server.nix +++ b/user/server.nix @@ -9,6 +9,7 @@ ./settings/nix.nix ./settings/nixos.nix ./settings/development/base.nix + <private> ]; home = { username = "alan"; diff --git a/user/settings/base.nix b/user/settings/base.nix index 6725b6db..52cb14ac 100644 --- a/user/settings/base.nix +++ b/user/settings/base.nix @@ -1,4 +1,4 @@ -{ config +args@{ config , lib , pkgs , ... @@ -6,7 +6,10 @@ imports = [ ./neovim.nix ./shell.nix + (import <nix-index-database/home-manager-module.nix> + (args // { databases = import <nix-index-database/packages.nix>; })) ]; + # Let Home Manager install and manage itself. programs.home-manager.enable = true; manual = { @@ -22,11 +25,8 @@ in { EMAIL = "alan@alanpearce.eu"; - MANPAGER = "bat -l man -p"; ABDUCO_SOCKET_DIR = "${state}/abduco"; - GNUPGHOME = "${data}/gnupg"; SOLARGRAPH_CACHE = "${cache}/solargraph"; - ASPELL_CONF = "per-conf ${conf}/aspell/aspell.conf; personal ${conf}/aspell/en.pws; repl ${conf}/aspell/en.prepl; dict-dir ${config.home.profileDirectory}/lib/aspell"; ELECTRUMDIR = "${data}/electrum"; DOCKER_CONFIG = "${conf}/docker"; npm_config_userconfig = "${conf}/npm/config"; @@ -72,7 +72,7 @@ ]; config = { theme = "ansi"; - style = "header-filename,header-filesize,grid,rule"; + style = "header-filename,header-filesize,rule"; }; }; programs.nix-index-database.comma.enable = true; @@ -99,9 +99,11 @@ abduco dvtm walk - (aspellWithDicts (d: [ d.en d.en-computers d.en-science d.de ])) - ] - ++ ( + nuspell + ] ++ (with pkgs.hunspellDicts; [ + en-gb-large + de-de + ]) ++ ( if !stdenv.isDarwin then [ file diff --git a/user/settings/development/base.nix b/user/settings/development/base.nix index b1c636ad..5bf54172 100644 --- a/user/settings/development/base.nix +++ b/user/settings/development/base.nix @@ -1,5 +1,4 @@ { config -, lib , pkgs , ... }: @@ -20,6 +19,7 @@ mosh + curlHTTP3 xh htmlq jq @@ -27,7 +27,6 @@ miller watchexec entr - httping diffoscopeMinimal @@ -39,11 +38,12 @@ colima docker-client ] else [ - zeal + httping ]); home.sessionVariables = { FLY_NO_UPDATE_CHECK = "1"; + MOSH_TITLE_NOPREFIX = "1"; LIMA_INSTANCE = "nixos"; }; @@ -57,7 +57,10 @@ insert_final_newline = true; indent_style = "space"; indent_size = 2; - tab_width = 4; + tab_width = 2; + }; + "*.fish" = { + indent_size = 4; }; justfile = { indent_style = "tab"; @@ -75,6 +78,7 @@ ea = "direnv allow"; ex = "direnv exec"; es = "direnv status"; + curl3 = "${pkgs.curlHTTP3}/bin/curl --http3"; }; programs.direnv = { enable = true; @@ -84,6 +88,7 @@ config = { global = { disable_stdin = true; + load_dotenv = true; strict_env = true; hide_env_diff = true; }; @@ -104,4 +109,7 @@ } ''; }; + services.lorri = { + enable = pkgs.stdenv.isLinux; + }; } diff --git a/user/settings/development/golang.nix b/user/settings/development/golang.nix index 6373a1c4..a9293a31 100644 --- a/user/settings/development/golang.nix +++ b/user/settings/development/golang.nix @@ -6,12 +6,16 @@ gogetdoc gotools golines + impl + gomodifytags golangci-lint golangci-lint-langserver - nodePackages.prettier-plugin-go-template + personal.prettier-plugin-go-template ]; programs.emacs.extraPackages = epkgs: (with epkgs; [ go-eldoc + go-tag + templ-ts-mode ]); programs.neovim.plugins = with pkgs.vimPlugins; [ coc-go diff --git a/user/settings/development/javascript.nix b/user/settings/development/javascript.nix index 4d196cb4..fa418cc1 100644 --- a/user/settings/development/javascript.nix +++ b/user/settings/development/javascript.nix @@ -23,10 +23,6 @@ }; }; - programs.emacs.extraPackages = epkgs: (with epkgs; [ - add-node-modules-path - ]); - home.shellAliases = { bn = "bun"; bni = "bun install"; diff --git a/user/settings/development/web.nix b/user/settings/development/web.nix index 4d26416c..77b3e01d 100644 --- a/user/settings/development/web.nix +++ b/user/settings/development/web.nix @@ -1,5 +1,6 @@ { config , pkgs +, lib , ... }: { home.packages = with pkgs.nodePackages; [ @@ -10,12 +11,90 @@ ] ++ (with pkgs; [ flyctl prettierd - htmlformat + personal.htmlformat + nodePackages.vercel ]); home.shellAliases = { # 0.2.25 current completion command only affects `flyctl`, although `fly` is a link to `flyctl` fly = "flyctl"; }; + programs.chromium = lib.mkIf pkgs.stdenv.isLinux { + enable = true; + package = pkgs.ungoogled-chromium; + extensions = [ + # # uBlock origin + { id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } + { + id = "ocaahdebbfolfmndjeplogmgcagdmblk"; + updateUrl = "https://raw.githubusercontent.com/NeverDecaf/chromium-web-store/master/updates.xml"; + } + ]; + dictionaries = with pkgs.hunspellDictsChromium; [ + en-gb + de-de + ]; + }; + programs.firefox = { + enable = pkgs.stdenv.isLinux; + package = pkgs.firefox-devedition; + profiles.dev-edition-default = { + search.default = "DuckDuckGo"; + extensions = with pkgs.nur.repos.rycee.firefox-addons; [ + a11ycss + disable-javascript + laboratory-by-mozilla + side-view + ublock-origin + ]; + settings = { + "browser.aboutConfig.showWarning" = false; + "browser.theme.content-theme" = 1; + "browser.theme.toolbar-theme" = 1; + "browser.tabs.firefox-view" = false; + "extensions.activeThemeID" = "firefox-compact-light@mozilla.org"; + }; + }; + policies = { + AutoFillCreditCardEnabled = false; + CaptivePortal = false; + Cookies = { + Behavior = "reject-foreign"; + }; + SanitizeOnShutdown = { + Cache = true; + Cookies = true; + FormData = true; + }; + DisableFirefoxAccounts = true; + DisableFirefoxScreenShots = true; + DisableFirefoxStudies = true; + DisableMasterPasswordCreation = true; + DisablePasswordReveal = true; + DisablePocket = true; + DisableTelemetry = true; + DNSOverHTTPS.Enabled = false; + DontCheckDefaultBrowser = true; + EnableTrackingProtection = true; + GoToIntranetSiteForSingleWordEntryInAddressBar = true; + Homepage.URL = "http://localhost:7331"; + NewTabPage = false; + NoDefaultBookmarks = true; + OfferToSaveLogins = false; + OverrideFirstRunPage = ""; + OverridePostUpdatePage = ""; + PasswordManagerEnabled = false; + PrintingEnabled = false; + SearchBar = "separate"; + ShowHomeButton = true; + UserMessaging = { + ExtensionRecommendations = false; + FeatureRecommendations = false; + UrlbarInterventions = false; + SkipOnboarding = true; + MoreFromMozilla = false; + }; + }; + }; programs.emacs.extraPackages = epkgs: (with epkgs; [ caddyfile-mode emmet-mode diff --git a/user/settings/emacs.nix b/user/settings/emacs.nix index a65f8d8c..cc9deab6 100644 --- a/user/settings/emacs.nix +++ b/user/settings/emacs.nix @@ -6,13 +6,6 @@ let inherit (pkgs) stdenv; - nativeCompileDirectory = "${config.xdg.cacheHome}/emacs/native-compile/"; - - darwinPath = pkgs.runCommandLocal "path_helper " { } '' - eval $(/usr/libexec/path_helper) - echo -n $PATH > $out - ''; - editorScript = pkgs.writeScriptBin "edit" '' #!${pkgs.runtimeShell} if [ -z "$1" ]; then @@ -34,6 +27,11 @@ in xfuncname = "^(((;;;+ )|\\(|([ \t]+\\(((cl-|el-patch-)?def(un|var|macro|method|custom)|gb/))).*)$"; }; + services.emacs = lib.mkIf stdenv.isLinux { + enable = true; + package = config.programs.emacs.finalPackage; + client.enable = true; + }; programs.emacs = { enable = true; package = lib.mkDefault (pkgs.emacs29.override { withGTK3 = true; }); @@ -65,6 +63,7 @@ in cdg = "cd (project-root)"; }; }; + extraPackages = epkgs: (with epkgs; [ ace-link @@ -80,6 +79,7 @@ in consult-dir consult-ghq consult-eglot + consult-lsp crux dired-git-info docker-compose-mode @@ -100,6 +100,7 @@ in evil-commentary evil-embrace evil-exchange + evil-lion evil-matchit evil-mu4e evil-numbers @@ -130,6 +131,7 @@ in lsp-mode lispyville magit + magit-todos markdown-mode marginalia nerd-icons @@ -142,11 +144,16 @@ in quickrun rainbow-mode rainbow-delimiters + ssh-deploy stimmung-themes systemd tempel tempel-collection eglot-tempel + treemacs + treemacs-evil + treemacs-magit + treemacs-nerd-icons treesit-grammars.with-all-grammars treesit-auto vc-msg @@ -166,23 +173,36 @@ in --replace-fail '"prettier"' '"prettierd"' ''; }); + just-mode = self.melpaPackages.just-mode.overrideAttrs (old: { + src = pkgs.fetchFromGitHub { + owner = "alanpearce"; + repo = "just-mode.el"; + rev = "08eb25e0641b4b6d79aa39182c70b9d40c56fc02"; + sha256 = "13ccphbd95bn79pqbw6ycnfy1z8yd32swrhd1ljl7gwbhi7q6s0p"; + # date = "2024-05-01T22:22:02+02:00"; + }; + }); + treemacs-nerd-icons = self.melpaPackages.treemacs-nerd-icons.overrideAttrs (old: { + src = pkgs.fetchFromGitHub { + owner = "aaronmiller"; + repo = "treemacs-nerd-icons"; + sha256 = "171pdi5y9zym26iqi02c5p7zw9i7xxhv4csnjb7qlkkczha17jgp"; + rev = "90b4f0868eea1ea923dee97d2c5457c21a61f37a"; + # date = "2023-11-02T13:42:55-04:00"; + }; + }); lsp-mode = self.melpaPackages.lsp-mode.overrideAttrs { - LSP_USE_PLISTS = "true"; # sync with below + LSP_USE_PLISTS = "true"; # must be set in early-init }; }; extraConfig = '' - (setenv "LSP_USE_PLISTS" "true") ; sync with above (with-eval-after-load 'editorconfig - (setq editorconfig-exec-path "${pkgs.editorconfig-core-c}/bin/editorconfig")) - (when (featurep 'native-compile) - (setq native-compile-target-directory "${nativeCompileDirectory}") - (add-to-list 'native-comp-eln-load-path "${nativeCompileDirectory}" :append)) + (defvar editorconfig-exec-path "${pkgs.editorconfig-core-c}/bin/editorconfig")) '' + lib.optionalString stdenv.isDarwin '' (with-eval-after-load 'files - (setq insert-directory-program "${pkgs.coreutils-prefixed}/bin/gls")) + (defvar insert-directory-program "${pkgs.coreutils-prefixed}/bin/gls")) (with-eval-after-load 'dired - (setq dired-use-ls-dired t)) - (setq exec-path (parse-colon-path (setenv "PATH" "${pkgs.lib.readFile darwinPath}"))) + (defvar dired-use-ls-dired t)) ''; }; home.packages = with pkgs; [ diff --git a/user/settings/fish/functions/dired.fish b/user/settings/fish/functions/dired.fish index 97174b35..a59ffac2 100644 --- a/user/settings/fish/functions/dired.fish +++ b/user/settings/fish/functions/dired.fish @@ -4,5 +4,5 @@ function dired else set --function repo $pwd end - emacsclient -e "(magit-status \"$argv[1]\")" + emacsclient --suppress-output --eval "(dired \"$argv[1]\")" end diff --git a/user/settings/fish/functions/magit.fish b/user/settings/fish/functions/magit.fish index 048fd42f..96c90096 100644 --- a/user/settings/fish/functions/magit.fish +++ b/user/settings/fish/functions/magit.fish @@ -4,5 +4,5 @@ function magit else set --function repo $pwd end - emacsclient -e "(magit-status \"$argv[1]\")" + emacsclient --suppress-output --eval "(magit-status \"$argv[1]\")" end diff --git a/user/settings/fish/functions/newest.fish b/user/settings/fish/functions/newest.fish index 73e26dcc..3f2fa66f 100644 --- a/user/settings/fish/functions/newest.fish +++ b/user/settings/fish/functions/newest.fish @@ -4,9 +4,11 @@ function newest return 1 end for arg in $argv - fd --hidden --print0 --max-depth 1 . $arg | - bfs -files0-from - \( -name .git -prune \) -o \( -printf '%TY%Tm%Td%TR %TF %h/%f\n' \) | - sort --reverse --key 1n,1 | head --lines 1 | - cut -d ' ' -f 2,3 + if test -d $arg + fd --hidden --print0 --max-depth 1 . $arg | + bfs -files0-from - \( -name .git -prune \) -o \( -printf '%TY%Tm%Td%TH%TM %TF %h/%f\n' \) | + sort --key 1nr,1 | head --lines 1 | + cut -d ' ' -f 2,3 + end end end diff --git a/user/settings/fish/functions/oldest.fish b/user/settings/fish/functions/oldest.fish index 66aad720..140d74cc 100644 --- a/user/settings/fish/functions/oldest.fish +++ b/user/settings/fish/functions/oldest.fish @@ -4,9 +4,11 @@ function oldest return 1 end for arg in $argv - fd --hidden --print0 --max-depth 1 . $arg | - bfs -files0-from - \( -name .git -prune \) -o \( -printf '%TY%Tm%Td%TR %TF %h/%f\n' \) | - sort --key 1n,1 | head --lines 1 | - cut -d ' ' -f 2,3 + if test -d $arg + fd --hidden --print0 --max-depth 1 . $arg | + bfs -files0-from - \( -name .git -prune \) -o \( -printf '%TY%Tm%Td%TH%TM %TF %h/%f\n' \) | + sort --key 1n,1 | head --lines 1 | + cut -d ' ' -f 2,3 + end end end diff --git a/user/settings/git.nix b/user/settings/git.nix index 18368864..769b3728 100644 --- a/user/settings/git.nix +++ b/user/settings/git.nix @@ -17,6 +17,11 @@ init = { defaultBranch = "main"; }; + advice = { + addEmptyPathspec = false; + detachedHead = false; + mergeConflict = false; + }; ghq = { root = "${config.home.homeDirectory}/projects"; user = "alanpearce"; diff --git a/user/settings/gnupg.nix b/user/settings/gnupg.nix index 913b5d27..d719b618 100644 --- a/user/settings/gnupg.nix +++ b/user/settings/gnupg.nix @@ -2,8 +2,18 @@ , pkgs , ... }: { - home.file.".gnupg" = { - recursive = true; - source = ../gnupg; + programs.gpg = { + enable = true; + homedir = "${config.xdg.dataHome}/gnupg"; + settings = { + keyserver = "hkps://keys.openpgp.org"; + }; + }; + services.gpg-agent = { + enable = true; + pinentryPackage = with pkgs; + if stdenv.isDarwin + then pinentry_mac + else pinentry-qt; }; } diff --git a/user/settings/i3.nix b/user/settings/i3.nix index 79a7811d..e8951062 100644 --- a/user/settings/i3.nix +++ b/user/settings/i3.nix @@ -7,6 +7,9 @@ recursive = true; source = ../i3/i3status; }; + home.sessionVariables = { + TERMINAL = "xterm"; + }; xsession.windowManager.i3 = let mod = "Mod4"; diff --git a/user/settings/neovim.nix b/user/settings/neovim.nix index 315a309b..dcee5fde 100644 --- a/user/settings/neovim.nix +++ b/user/settings/neovim.nix @@ -31,16 +31,22 @@ enable = true; settings = { "json.enable" = true; - "suggest.enablePreview" = true; - "coc.preferences.formatOnSaveFiletypes" = [ "nix" ]; - "nil.formatting.command" = "nixpkgs-fmt"; - semantictokens = { - filetypes = [ "nix" ]; - }; languageserver = { nix = { command = "${pkgs.nil}/bin/nil"; filetypes = [ "nix" ]; + rootPatterns = [ "flake.nix" ]; + settings = { + coc.preferences.formatOnSaveFiletypes = [ "nix" ]; + links.tooltip = true; + semanticTokens = { + filetypes = [ "nix" ]; + }; + nil = { + formatting.command = [ "nixpkgs-fmt" ]; + nix.flake.autoArchive = true; + }; + }; }; lua = { command = "${pkgs.lua-language-server}/bin/lua-language-server"; diff --git a/user/settings/nix.nix b/user/settings/nix.nix index e0fb3d3e..66c00daf 100644 --- a/user/settings/nix.nix +++ b/user/settings/nix.nix @@ -1,25 +1,26 @@ { config , pkgs +, lib , ... }: let toml = pkgs.formats.toml { }; in { - imports = [ - ../../pin.nix - ]; nixpkgs.config = import ../config.nix; nix = { enable = true; - package = pkgs.nix; + # needed for "standalone" home-manager, conflicts with module + package = lib.mkDefault pkgs.nix; settings = { use-xdg-base-directories = true; }; }; home.packages = with pkgs; [ + cached-nix-shell nil + npins nix-prefetch-scripts nix-init nix-update @@ -29,11 +30,10 @@ in nixpkgs-lint nixpkgs-review nix-output-monitor - cachix ]; xdg.configFile."nix-init/config.toml".source = toml.generate "config.toml" { maintainers = [ "alanpearce" ]; - nixpkgs = "builtins.getFlake \"nixpkgs\""; + nixpkgs = "<nixpkgs>"; }; programs.emacs.extraPackages = epkgs: (with epkgs; [ nix-mode diff --git a/user/settings/nixos.nix b/user/settings/nixos.nix index 05b87333..85ea7f72 100644 --- a/user/settings/nixos.nix +++ b/user/settings/nixos.nix @@ -6,8 +6,8 @@ home.shellAliases = { srb = "nixos-rebuild"; - rbs = "nixos-rebuild switch"; - rbb = "nixos-rebuild boot"; + rbs = "nixos-rebuild switch --fast"; + rbb = "nixos-rebuild boot --fast"; rbr = "nixos-rebuild switch --rollback"; }; } diff --git a/user/settings/shell.nix b/user/settings/shell.nix index 5358f618..fe2b4690 100644 --- a/user/settings/shell.nix +++ b/user/settings/shell.nix @@ -30,7 +30,7 @@ in llr = "ll -t"; c = "lk"; - "c," = "cd $(ghq list -p nixfiles)"; + "c," = "cd ${config.home.homeDirectory + "/projects/alanpearce.eu/nixfiles"}"; cg = "cd $(git root)"; cdg = "cd $(git root)"; @@ -125,7 +125,11 @@ in hol = "home-manager generations"; hox = "home-manager expire-generations '-30 days'"; - nsh = "nix shell"; + lw = "lorri watch"; + lw1 = "lorri watch --once"; + lwo = "lorri watch --once"; + + nsh = "nix-shell"; nb = "nix build"; nl = "nix log"; # shadows `coreutils.nl`, but I've never used that yet nr = "nix run"; @@ -135,6 +139,8 @@ in nfp = "nix flake prefetch"; nfu = "nix flake update"; nfl = "nix flake lock"; + nfsh = "nix shell"; + ndev = "nix develop"; nlg = "nix-env --list-generations"; snlg = "sudo nix-env --list-generations --profile /nix/var/nix/profiles/system"; ngc = "nix-collect-garbage --delete-older-than 30d"; @@ -142,6 +148,7 @@ in }; }; home.packages = with pkgs; [ + babashka fzf up ]; diff --git a/user/settings/ssh.nix b/user/settings/ssh.nix index f5073c8d..b7c46bba 100644 --- a/user/settings/ssh.nix +++ b/user/settings/ssh.nix @@ -12,6 +12,10 @@ serverAliveInterval = 15; extraConfig = '' VerifyHostKeyDNS ask + CanonicalizeHostname yes + CanonicalizeFallbackLocal no + CanonicalizeMaxDots 0 + CanonicalDomains home.arpa hydra-pinecone.ts.net ''; includes = [ "local.ssh_config" diff --git a/user/settings/tabnine.nix b/user/settings/tabnine.nix index 377b8217..9502c68d 100644 --- a/user/settings/tabnine.nix +++ b/user/settings/tabnine.nix @@ -21,18 +21,28 @@ disable_local_when_using_battery = false; enable_power_saving_mode = false; enable_telemetry = false; + exclude_file_masks = true; force_local_hub = true; generation = 0; + guuid = null; + gusr.gcgdc = "0000000000000000000000000000000000000000000000000000000000000000"; + has_git_repos = null; + heartbeat_interval_seconds = null; hide_deep_information_message = false; hide_promotional_message = true; hosted_deep_completions_enabled = "Disabled"; ignore_all_lsp = false; inline_suggestions_mode = true; + inline_suggestions_mode_clients = null; + last_service_level = null; line_suggestions = true; local_enabled = "Yes"; local_indexing = null; local_model_size = null; + manually_selected_model = null; + model_hash_override = null; num_of_suggestions = 5; + omit_prefix_suggestions = null; onboarding = { model_type = null; skipped_login = true; @@ -40,6 +50,7 @@ }; rate_limit_amount = null; rate_limit_interval_seconds = null; + rlhf = null; semantic_status = { css = "Enabled"; dockerfile = "Enabled"; @@ -57,7 +68,9 @@ tabnine_cloud_certificate_domain = null; tabnine_cloud_host = null; tabnine_cloud_port = null; + tabnine_hub_port = null; use_specialized_model_if_available = true; + user_understands_that_enabling_tabnine_cloud_sends_code_to_tabnine_servers = false; }; lspConfig.language = { typescript = { diff --git a/user/settings/trezor.nix b/user/settings/trezor.nix deleted file mode 100644 index 6996d9b0..00000000 --- a/user/settings/trezor.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ config -, pkgs -, ... -}: { - home.file.".ssh/agent.config" = { - text = '' - ecdsa-curve-name = ed25519 - ''; - }; -} diff --git a/user/settings/user-interface.nix b/user/settings/user-interface.nix index 6adf57ff..29de4439 100644 --- a/user/settings/user-interface.nix +++ b/user/settings/user-interface.nix @@ -9,9 +9,6 @@ in imports = [ ./kitty.nix ]; - home.sessionVariables = { - TERMINAL = "xterm"; - }; services.ssh-agent = { enable = stdenv.hostPlatform.isLinux; @@ -47,11 +44,15 @@ in }) ] ++ lib.optionals (!stdenv.isDarwin) (with pkgs; [ - logseq + logseq # 0.10.9 is insecure, see ../config.nix (discord.override { withOpenASAR = true; }) + zeal falkon - mu beeper + kdePackages.neochat + kdePackages.kleopatra ]); + services.lorri.enableNotifications = true; + services.emacs.startWithUserSession = "graphical"; } |