From 1efde7694d8562e62ca36e71fe15199fac9bfcd4 Mon Sep 17 00:00:00 2001 From: Jakob Lechner Date: Thu, 17 Jul 2025 00:45:59 +0200 Subject: [PATCH] initial commit --- .envrc | 1 + .gitignore | 9 ++ book.toml | 2 + docs/SUMMARY.md | 2 + flake.lock | 283 +++++++++++++++++++++++++++++++++ flake.nix | 218 +++++++++++++++++++++++++ justfile | 9 ++ modules/cli-tools.nix | 3 + modules/default.nix | 19 +++ modules/fish.nix | 3 + modules/impermanence.nix | 49 ++++++ modules/networking.nix | 3 + modules/nix.nix | 52 ++++++ modules/security.nix | 18 +++ modules/sshd.nix | 67 ++++++++ modules/zram.nix | 25 +++ pkgs/default.nix | 4 + users/jalr/default.nix | 41 +++++ users/jalr/modules/cli.nix | 12 ++ users/jalr/modules/default.nix | 9 ++ users/jalr/modules/fish.nix | 200 +++++++++++++++++++++++ users/jalr/modules/neovim.nix | 9 ++ 22 files changed, 1038 insertions(+) create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 book.toml create mode 100644 docs/SUMMARY.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 justfile create mode 100644 modules/cli-tools.nix create mode 100644 modules/default.nix create mode 100644 modules/fish.nix create mode 100644 modules/impermanence.nix create mode 100644 modules/networking.nix create mode 100644 modules/nix.nix create mode 100644 modules/security.nix create mode 100644 modules/sshd.nix create mode 100644 modules/zram.nix create mode 100644 pkgs/default.nix create mode 100644 users/jalr/default.nix create mode 100644 users/jalr/modules/cli.nix create mode 100644 users/jalr/modules/default.nix create mode 100644 users/jalr/modules/fish.nix create mode 100644 users/jalr/modules/neovim.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..537d029 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Nix +result* +.direnv + +# automatically generated +.pre-commit-config.yaml + +# mdBook +/book/* diff --git a/book.toml b/book.toml new file mode 100644 index 0000000..aac5ba1 --- /dev/null +++ b/book.toml @@ -0,0 +1,2 @@ +[book] +src = "docs" diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md new file mode 100644 index 0000000..c24460e --- /dev/null +++ b/docs/SUMMARY.md @@ -0,0 +1,2 @@ +# Weinturm Open Air Infrastructure + diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..44bf3fc --- /dev/null +++ b/flake.lock @@ -0,0 +1,283 @@ +{ + "nodes": { + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1752541678, + "narHash": "sha256-dyhGzkld6jPqnT/UfGV2oqe7tYn7hppAqFvF3GZTyXY=", + "owner": "nix-community", + "repo": "disko", + "rev": "2bf3421f7fed5c84d9392b62dcb9d76ef09796a7", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "fieldpoc": { + "inputs": { + "mitel-ommclient2": "mitel-ommclient2", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1711287766, + "narHash": "sha256-2roymGPfsQZC1Lg/i3iffBQ8c86DLEXmuoKQIlbOg5o=", + "ref": "refs/heads/main", + "rev": "f707f212378f9d8de103ac96abcd9d377a2605a8", + "revCount": 56, + "type": "git", + "url": "https://git.clerie.de/clerie/fieldpoc.git" + }, + "original": { + "type": "git", + "url": "https://git.clerie.de/clerie/fieldpoc.git" + } + }, + "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-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "nix-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" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1752544374, + "narHash": "sha256-ReX0NG6nIAEtQQjLqeu1vUU2jjZuMlpymNtb4VQYeus=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "2e00ed310c218127e02ffcf28ddd4e0f669fde3e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-25.05", + "repo": "home-manager", + "type": "github" + } + }, + "impermanence": { + "locked": { + "lastModified": 1737831083, + "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, + "krops": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1644957911, + "narHash": "sha256-ggie/j7pdBqzDs4W7OiPmhqH9IGbXAbJxGqBdVxA8jA=", + "owner": "Mic92", + "repo": "krops", + "rev": "86fb3d2ee94fd8306231853b323ed8804edf26ec", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "krops", + "type": "github" + } + }, + "mitel-ommclient2": { + "inputs": { + "nixpkgs": [ + "fieldpoc", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1687019250, + "narHash": "sha256-cN9ZuQ/1irnoYg013v1ZDn15MHcFXhxILGhRNDGd794=", + "ref": "refs/heads/main", + "rev": "a11629f543a8b43451cecc46600a78cbb6af015a", + "revCount": 70, + "type": "git", + "url": "https://git.clerie.de/clerie/mitel_ommclient2.git" + }, + "original": { + "type": "git", + "url": "https://git.clerie.de/clerie/mitel_ommclient2.git" + } + }, + "nix-pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1750779888, + "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "master", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1665732960, + "narHash": "sha256-WBZ+uSHKFyjvd0w4inbm0cNExYTn8lpYFcHEes8tmec=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4428e23312933a196724da2df7ab78eb5e67a88e", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1752620740, + "narHash": "sha256-f3pO+9lg66mV7IMmmIqG4PL3223TYMlnlw+pnpelbss=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "32a4e87942101f1c9f9865e04dc3ddb175f5f32e", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "disko": "disko", + "fieldpoc": "fieldpoc", + "flake-utils": "flake-utils", + "home-manager": "home-manager", + "impermanence": "impermanence", + "krops": "krops", + "nix-pre-commit-hooks": "nix-pre-commit-hooks", + "nixpkgs": "nixpkgs_2", + "sops-nix": "sops-nix" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1752544651, + "narHash": "sha256-GllP7cmQu7zLZTs9z0J2gIL42IZHa9CBEXwBY9szT0U=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "2c8def626f54708a9c38a5861866660395bb3461", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..73a27d9 --- /dev/null +++ b/flake.nix @@ -0,0 +1,218 @@ +{ + inputs = { + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + fieldpoc.url = "git+https://git.clerie.de/clerie/fieldpoc.git"; + + flake-utils.url = "github:numtide/flake-utils"; + + home-manager = { + url = "github:nix-community/home-manager/release-25.05"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + impermanence.url = "github:nix-community/impermanence"; + + krops = { + url = "github:Mic92/krops"; + inputs.flake-utils.follows = "flake-utils"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nix-pre-commit-hooks = { + url = "github:cachix/git-hooks.nix/master"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; + + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { + self, + flake-utils, + home-manager, + krops, + nix-pre-commit-hooks, + nixpkgs, + ... + } @ inputs: + flake-utils.lib.eachDefaultSystem + (system: let + pkgs = import nixpkgs {inherit system;}; + inherit (pkgs) lib; + in { + checks = { + pre-commit-check = nix-pre-commit-hooks.lib.${system}.run { + src = ./.; + excludes = [ + ".envrc" + ]; + hooks = { + alejandra.enable = true; + black.enable = true; + deadnix.enable = true; + markdownlint = { + enable = true; + settings.configuration = { + MD013.code_blocks = false; # Ignore line length in code blocks. + }; + }; + shellcheck.enable = true; + statix = { + enable = true; + settings.ignore = [".direnv"]; + }; + }; + }; + }; + + packages.docs = pkgs.stdenvNoCC.mkDerivation { + name = "infrastructure-documentation"; + src = builtins.path { + name = "docs-src"; + path = ./.; + filter = path: _type: let + relPath = lib.removePrefix (toString ./.) path; + in + lib.hasPrefix "/docs" relPath + || lib.hasPrefix "/assets" relPath + || relPath == "/book.toml"; + }; + nativeBuildInputs = with pkgs; [ + mdbook + ]; + buildPhase = "mdbook build -d $out"; + dontInstall = true; + }; + + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + alejandra + aws-vault + awscli2 + black + jq + just + markdownlint-cli2 + mdbook + opentofu + shellcheck + sops + ssh-to-age + ( + writeShellScriptBin "repl" '' + exec nix repl --expr " + let flake = builtins.getFlake \"$(git rev-parse --show-toplevel)\"; + in + flake // { + lib = flake.inputs.nixpkgs.lib; + pkgs = flake.inputs.nixpkgs.legacyPackages."\''${builtins.currentSystem}"; + } + " + '' + ) + ]; + + shellHook = '' + ${self.checks.${system}.pre-commit-check.shellHook} + ''; + }; + + apps = + lib.mapAttrs + (_name: program: { + type = "app"; + program = toString program; + }) + (flake-utils.lib.flattenTree { + deploy = lib.recurseIntoAttrs (lib.mapAttrs + ( + hostname: machine: let + inherit (krops.packages.${system}) writeCommand; + inherit (krops) lib; + in + writeCommand "deploy-${hostname}" { + target = + lib.mkTarget "root@${machine.config.deployment.targetHost}" + // { + extraOptions = [ + # force allocation of tty to allow aborting with ^C and to show build progress + "-t" + ]; + }; + source = lib.evalSource (lib.singleton { + config.file = { + path = toString ./.; + useChecksum = true; + }; + }); + command = targetPath: '' + nixos-rebuild switch --flake ${targetPath}/config -L --keep-going + ''; + force = true; + } + ) + self.nixosConfigurations); + }); + }) + // { + overlays.default = import ./pkgs inputs; + + nixosConfigurations = let + domain = "lan.weinturm-open-air.net"; + in + nixpkgs.lib.mapAttrs + (hostname: { + system, + extraModules ? [], + targetHost ? "${hostname}.${domain}", + }: + nixpkgs.lib.nixosSystem { + inherit system; + + modules = + [ + (./hosts + "/${hostname}/configuration.nix") + + ./modules + + { + _module.args = {inherit inputs domain;}; + } + + # deployment settings + ({lib, ...}: { + options.deployment = { + targetHost = lib.mkOption { + type = lib.types.str; + readOnly = true; + internal = true; + }; + }; + config.deployment = { + inherit targetHost; + }; + }) + ] + ++ [ + home-manager.nixosModules.home-manager + ] + ++ (with inputs; [ + disko.nixosModules.disko + fieldpoc.nixosModules.default + impermanence.nixosModules.impermanence + sops-nix.nixosModules.sops + ]) + ++ extraModules; + }) + (import ./hosts inputs); + }; +} diff --git a/justfile b/justfile new file mode 100644 index 0000000..684e369 --- /dev/null +++ b/justfile @@ -0,0 +1,9 @@ +repl: + nix repl --expr "\ + let \ + flake = builtins.getFlake \"$(git rev-parse --show-toplevel)\"; in \ + flake // (with flake; { \ + lib = inputs.nixpkgs.lib; \ + pkgs = inputs.nixpkgs.legacyPackages."\${builtins.currentSystem}".extend(import ./pkgs inputs); \ + }) \ + " diff --git a/modules/cli-tools.nix b/modules/cli-tools.nix new file mode 100644 index 0000000..962d000 --- /dev/null +++ b/modules/cli-tools.nix @@ -0,0 +1,3 @@ +{ + programs.tmux.enable = true; +} diff --git a/modules/default.nix b/modules/default.nix new file mode 100644 index 0000000..6497baa --- /dev/null +++ b/modules/default.nix @@ -0,0 +1,19 @@ +{domain, ...}: { + options.weinturm = { + }; + + imports = [ + ./cli-tools.nix + ./fish.nix + ./impermanence.nix + ./networking.nix + ./nix.nix + ./security.nix + ./sshd.nix + ./zram.nix + ]; + + config = { + networking.domain = domain; + }; +} diff --git a/modules/fish.nix b/modules/fish.nix new file mode 100644 index 0000000..958da57 --- /dev/null +++ b/modules/fish.nix @@ -0,0 +1,3 @@ +{ + programs.fish.enable = true; +} diff --git a/modules/impermanence.nix b/modules/impermanence.nix new file mode 100644 index 0000000..70f99bb --- /dev/null +++ b/modules/impermanence.nix @@ -0,0 +1,49 @@ +{ + config, + lib, + ... +}: { + options.weinturm = with lib; { + impermanence = { + enable = mkOption { + type = types.bool; + default = true; + description = "Whether to enable impermanence"; + }; + rootDevice = with types; + mkOption { + type = nullOr str; + default = null; + description = '' + The device which contains the btrfs root subvolume + ''; + }; + }; + }; + config = let + cfg = config.weinturm.impermanence; + in + lib.mkIf cfg.enable { + fileSystems."/persist".neededForBoot = true; + + environment.persistence."/persist".directories = [ + "/var/lib/nixos" + ]; + + boot.initrd.postDeviceCommands = let + rootDevice = + if cfg.rootDevice == null + then "" + else cfg.rootDevice; + in + lib.mkAfter '' + mkdir /mnt + mount -t btrfs "${rootDevice}" /mnt + btrfs subvolume list -o /mnt/root | cut -f9 -d' ' | while read subvolume; do + btrfs subvolume delete "/mnt/$subvolume" + done + btrfs subvolume delete /mnt/root + btrfs subvolume snapshot /mnt/root-blank /mnt/root + ''; + }; +} diff --git a/modules/networking.nix b/modules/networking.nix new file mode 100644 index 0000000..74ad318 --- /dev/null +++ b/modules/networking.nix @@ -0,0 +1,3 @@ +{ + networking.nftables.enable = true; +} diff --git a/modules/nix.nix b/modules/nix.nix new file mode 100644 index 0000000..352d31a --- /dev/null +++ b/modules/nix.nix @@ -0,0 +1,52 @@ +{ + lib, + pkgs, + inputs, + ... +}: { + nix = { + package = pkgs.nixVersions.stable; + extraOptions = '' + experimental-features = nix-command flakes + ''; + + daemonCPUSchedPolicy = "idle"; + daemonIOSchedClass = "idle"; + daemonIOSchedPriority = 7; + + nixPath = [ + "nixpkgs=${inputs.nixpkgs}" + ]; + + settings = { + trusted-users = ["@wheel"]; + auto-optimise-store = true; + allowed-users = ["@wheel"]; + + log-lines = lib.mkDefault 25; + + # Avoid disk full issues + max-free = lib.mkDefault (3000 * 1024 * 1024); + min-free = lib.mkDefault (512 * 1024 * 10); + + download-buffer-size = lib.mkDefault (512 * 1024 * 1024); + }; + + gc = { + automatic = true; + options = "--delete-older-than 30d"; + randomizedDelaySec = "60 min"; + }; + }; + + systemd.services.nix-daemon.serviceConfig.OOMScoreAdjust = 250; + + nixpkgs.overlays = with inputs; [ + self.overlays.default + ]; + + environment.systemPackages = with pkgs; [ + cached-nix-shell + git + ]; +} diff --git a/modules/security.nix b/modules/security.nix new file mode 100644 index 0000000..d0f84c1 --- /dev/null +++ b/modules/security.nix @@ -0,0 +1,18 @@ +{ + boot = { + tmp.cleanOnBoot = true; + kernel.sysctl = { + "kernel.kptr_restrict" = 1; + "kernel.yama.ptrace_scope" = 1; + "kernel.kexec_load_disabled" = 1; + }; + kernelParams = [ + "lockdown=integrity" + ]; + }; + + security = { + polkit.enable = true; + sudo.wheelNeedsPassword = false; + }; +} diff --git a/modules/sshd.nix b/modules/sshd.nix new file mode 100644 index 0000000..f90c296 --- /dev/null +++ b/modules/sshd.nix @@ -0,0 +1,67 @@ +{ + lib, + config, + ... +}: { + services.openssh = { + enable = true; + settings = { + KbdInteractiveAuthentication = false; + Ciphers = [ + "aes256-gcm@openssh.com" + ]; + # Use key exchange algorithms recommended by `nixpkgs#ssh-audit` + KexAlgorithms = [ + "curve25519-sha256" + "curve25519-sha256@libssh.org" + "diffie-hellman-group16-sha512" + "diffie-hellman-group18-sha512" + "sntrup761x25519-sha512@openssh.com" + ]; + PasswordAuthentication = false; + StreamLocalBindUnlink = true; # unbind gnupg sockets if they exists + UseDns = false; + X11Forwarding = false; + }; + hostKeys = + if config.weinturm.impermanence.enable + then [ + { + type = "ed25519"; + path = "/persist/etc/ssh/ssh_host_ed25519_key"; + } + ] + else [ + { + type = "ed25519"; + path = "/etc/ssh/ssh_host_ed25519_key"; + } + ]; + authorizedKeysFiles = lib.mkIf (!config.services.gitlab.enable) (lib.mkForce ["/etc/ssh/authorized_keys.d/%u"]); + }; + + networking.nftables.tables."nixos-fw".content = lib.mkOrder 20 '' + set ssh-ratelimit-v4 { + type ipv4_addr + timeout 60s + flags dynamic + } + + set ssh-ratelimit-v6 { + type ipv6_addr + timeout 60s + flags dynamic + } + ''; + + # Implement connection rate limit + services.openssh.openFirewall = false; + networking.firewall.extraInputRules = lib.mkOrder 5 ( + let + ports = builtins.concatStringsSep ", " (map builtins.toString config.services.openssh.ports); + in '' + tcp dport { ${ports} } update @ssh-ratelimit-v4 { ip saddr limit rate 1/second burst 10 packets } accept + tcp dport { ${ports} } update @ssh-ratelimit-v6 { ip6 saddr limit rate 1/second burst 10 packets } accept + '' + ); +} diff --git a/modules/zram.nix b/modules/zram.nix new file mode 100644 index 0000000..d6c5f70 --- /dev/null +++ b/modules/zram.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + ... +}: let + cfg = config.weinturm.zram; +in { + options.weinturm = with lib; { + zram = { + enable = mkOption { + type = types.bool; + default = true; + description = "Whether to enable zram swap"; + }; + }; + }; + config = { + zramSwap = { + inherit (cfg) enable; + algorithm = "zstd"; + memoryPercent = 60; + priority = 1; + }; + }; +} diff --git a/pkgs/default.nix b/pkgs/default.nix new file mode 100644 index 0000000..5c90043 --- /dev/null +++ b/pkgs/default.nix @@ -0,0 +1,4 @@ +inputs: _final: prev: let + inherit (prev) callPackage system; +in { +} diff --git a/users/jalr/default.nix b/users/jalr/default.nix new file mode 100644 index 0000000..c0b266b --- /dev/null +++ b/users/jalr/default.nix @@ -0,0 +1,41 @@ +{ + config, + pkgs, + ... +}: let + sshKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH3l+Yixrsjhze20CSjvUK4Qj/BNqbTNitgk20vuzPej cardno:25_750_479" + ]; +in { + users.users.jalr = { + isNormalUser = true; + extraGroups = [ + "adbusers" + "audio" + "dialout" + "libvirtd" + "lp" + "networkmanager" + "scanner" + "video" + "wheel" + "wireshark" + ]; + shell = pkgs.fish; + openssh.authorizedKeys.keys = sshKeys; + }; + + users.users.root.openssh.authorizedKeys.keys = sshKeys; + + home-manager = { + useUserPackages = true; + useGlobalPkgs = true; + + users.jalr = {...}: { + imports = [./modules]; + config = { + home.stateVersion = config.system.stateVersion; + }; + }; + }; +} diff --git a/users/jalr/modules/cli.nix b/users/jalr/modules/cli.nix new file mode 100644 index 0000000..43d6fa0 --- /dev/null +++ b/users/jalr/modules/cli.nix @@ -0,0 +1,12 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + cached-nix-shell + file + htop + inetutils + jq + lsof + ncdu + ripgrep + ]; +} diff --git a/users/jalr/modules/default.nix b/users/jalr/modules/default.nix new file mode 100644 index 0000000..dd2887b --- /dev/null +++ b/users/jalr/modules/default.nix @@ -0,0 +1,9 @@ +{...}: { + imports = [ + ./cli.nix + ./fish.nix + ./neovim.nix + ]; + + programs.nix-index.enable = true; +} diff --git a/users/jalr/modules/fish.nix b/users/jalr/modules/fish.nix new file mode 100644 index 0000000..d680907 --- /dev/null +++ b/users/jalr/modules/fish.nix @@ -0,0 +1,200 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + fzf + ]; + programs.fish = { + enable = true; + plugins = [ + { + name = "theme-agnoster"; + src = pkgs.fetchFromGitHub { + owner = "oh-my-fish"; + repo = "theme-agnoster"; + rev = "c142e802983bd1b34b4d91efac2126fc5913126d"; + sha256 = "0PLx626BWoBp/L6wgkB4o+53q8PymiEE/rTu2mfzHhg="; + fetchSubmodules = true; + }; + } + { + name = "fzf"; + src = pkgs.fetchFromGitHub { + owner = "jethrokuan"; + repo = "fzf"; + rev = "479fa67d7439b23095e01b64987ae79a91a4e283"; + sha256 = "0k6l21j192hrhy95092dm8029p52aakvzis7jiw48wnbckyidi6v"; + fetchSubmodules = true; + }; + } + ]; + shellAliases = { + ls = "ls --color=auto"; + crontab = "crontab -i"; + }; + + shellAbbrs = { + lessr = "less -R"; + jqc = "jq -C"; + }; + + #interactiveShellInit = '' + # echo "programs.fish.interactiveShellInit" + #''; + shellInit = '' + # key bindings + bind \cr '__fzf_reverse_isearch' + + # PATH + set -U fish_user_paths $HOME/.local/bin $HOME/.local/bin/pio + + # pass + #set -x PASSWORD_STORE_ENABLE_EXTENSIONS true + set -x AWS_VAULT_BACKEND pass + set -x AWS_VAULT_PASS_PREFIX aws + complete -c pw --no-files -a '(__fish_pass_print_entries)' + + # colors + set -x GCC_COLORS 'error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' + + abbr --add v vim + + #alias cal='ncal -b -M' + alias myip='dig +short myip.opendns.com @resolver1.opendns.com' + + function hm -d 'merge history and delete failed commands' + history --merge + + if test -z "$fish_private_mode" && test -e "$__fish_user_data_dir/successful_commands" && test -e "$__fish_user_data_dir/failed_commands" + while read line; + if ! grep -qFx $line "$__fish_user_data_dir/successful_commands" + set hist_command (echo $line | base64 -d) + echo "deleting command: $hist_command" + echo "." + history delete --exact --case-sensitive $hist_command + end + end < "$__fish_user_data_dir/failed_commands" + echo -n > "$__fish_user_data_dir/successful_commands" + echo -n > "$__fish_user_data_dir/failed_commands" + end + end + hm + + # fancy tools + if which eza > /dev/null 2>&1 + alias l=eza + alias ll='eza -l --time-style=long-iso --git' + alias la='eza -la --time-style=long-iso --git' + alias tree='eza --tree' + alias llt='eza -s modified -l' + else + alias l=ls + alias ll='ls -l' + alias la='ls -la' + alias llt='ls -trl' + end + + if which rg > /dev/null 2>&1 + alias g=rg + complete -c g -w rg + else if which ag > /dev/null 2>&1 + alias g=ag + complete -c g -w ag + else + alias g='grep --color=auto' + complete -c g -w grep + end + + function jqless -d 'jq -C [args] | less -R' + jq -C $argv | less -R + end + + # NixOS direnv + if which direnv > /dev/null + eval (direnv hook fish) + end + + function __cut_commandline -d 'cut commandline and paste it later' + set -g commandline_buffer (commandline) + commandline "" + end + + + + function __postexec --on-event fish_postexec + if test $status -ne 0 + if test -z "$hist_cmd" + if test -z "$fish_private_mode" + echo $argv[1] | base64 >> "$__fish_user_data_dir/failed_commands" + end + end + else + if test -z "$fish_private_mode" + echo $argv[1] | base64 >> "$__fish_user_data_dir/successful_commands" + end + commandline $commandline_buffer + set -e commandline_buffer + end + end + + function dirh-nocolor --description "Print the current directory history (the prev and next lists)" + set -l options h/help + argparse -n dirh --max-args=0 $options -- $argv + or return + + if set -q _flag_help + __fish_print_help dirh + return 0 + end + + set -l dirc (count $dirprev) + if test $dirc -gt 0 + set -l dirprev_rev $dirprev[-1..1] + # This can't be (seq $dirc -1 1) because of BSD. + set -l dirnum (seq 1 $dirc) + for i in $dirnum[-1..1] + printf '%s\n' $dirprev_rev[$i] + end + end + + echo $PWD + + set -l dirc (count $dirnext) + if test $dirc -gt 0 + set -l dirnext_rev $dirnext[-1..1] + for i in (seq $dirc) + printf '%s\n' $dirnext_rev[$i] + end + end + end + + function dirh-fzf -d 'directory history fuzzy finder' + builtin cd (dirh-nocolor | uniq | fzf) + end + + bind \ed 'dirh-fzf' + ''; + }; + + xdg.configFile."fish/completions/mycli.fish".text = '' + complete -e -c mycli + complete -c mycli -f -s h -l host -d "Host address of the database." + complete -c mycli -f -s P -l port -d "Port number to use for connection." + complete -c mycli -f -s u -l user -d "User name to connect to the database." + complete -c mycli -f -s S -l socket -d "The socket file to use for connection." + complete -c mycli -f -s p -l pass \ + -l password -d "Password to connect to the database." + complete -c mycli -f -s V -l version -d "Output mycli's version." + complete -c mycli -f -s v -l verbose -d "Verbose output." + complete -c mycli -f -s d -l dsn -d "Use DSN configured into the [alias_dsn] section of myclirc file." + complete -c mycli -f -l list-dsn -d "list of DSN configured into the [alias_dsn] section of myclirc file." + + complete -c mycli -f -s t -l table -d "Display batch output in table format." + complete -c mycli -f -l csv -d "Display batch output in CSV format." + complete -c mycli -f -l warn \ + -l no-warn -d "Warn before running a destructive query." + complete -c mycli -f -s e -l execute -d "Execute command and quit." + + + complete -c mycli -f -s h -l host -r -a '(__fish_print_hostnames)' + complete -c mycli -f -s d -l dsn -r -a '(mycli --list-dsn)' + ''; +} diff --git a/users/jalr/modules/neovim.nix b/users/jalr/modules/neovim.nix new file mode 100644 index 0000000..fd35985 --- /dev/null +++ b/users/jalr/modules/neovim.nix @@ -0,0 +1,9 @@ +{ + home.sessionVariables = { + EDITOR = "nvim"; + }; + programs.neovim = { + enable = true; + vimAlias = true; + }; +}