diff --git a/assets/black.png b/assets/black.png new file mode 100644 index 0000000..b87512f Binary files /dev/null and b/assets/black.png differ diff --git a/components/hm/alacritty.nix b/components/hm/alacritty.nix new file mode 100644 index 0000000..075d3bc --- /dev/null +++ b/components/hm/alacritty.nix @@ -0,0 +1,49 @@ +{ ... }: +{ + # More of an experiment to try out since wezterm is being weird on wayland... + programs.alacritty = { + enable = true; + settings = { + window = { + # TODO revisit, I still want some border shadow but no top bar but that is not an option + # decorations = "None"; + dynamic_title = false; + }; + colors = { + primary = { + foreground = "#e0e0e0"; + background = "#262626"; + }; + normal = { + # Catppuccin Coal + black = "#1f1f1f"; + red = "#f38ba8"; + green = "#a6e3a1"; + yellow = "#f9e2af"; + blue = "#89b4fa"; + magenta = "#cba6f7"; + cyan = "#89dceb"; + white = "#e0e0e0"; + }; + }; + font = { + normal = { family = "JetBrainsMonoNL Nerd Font"; style = "Regular"; }; + size = 12.0; + ## TODO use 16 on macos ... + }; + # TODO revisit... none of this is working. + # NOTE: I probably wont need these anymore, I've since entirely remade and relearned my tmux shortcuts to not be based on these + keyboard.bindings = [ + # { key = "m"; mods = "Command"; chars = "test"; } + # { key = "t"; mods = "Control"; action = { SendString = "\\x01t"; }; } + # { key = "w"; mods = "Control"; action = { SendString = "\\x01w"; }; } + # { key = "o"; mods = "Control"; action = { SendString = "testing123"; }; } + # { key = "w"; mods = "Control"; chars = "\\\\x01w"; } + # { key = "o"; mods = "Control"; chars = "\\\\x01o"; } + # { key = "1"; mods = "Control"; chars = "\\\\x011"; } + # { key = "2"; mods = "Control"; chars = "\\\\x012"; } + ]; + }; + }; +} + diff --git a/components/hm/atuin.nix b/components/hm/atuin.nix new file mode 100644 index 0000000..6270354 --- /dev/null +++ b/components/hm/atuin.nix @@ -0,0 +1,16 @@ +{ ... }: +{ + programs.atuin = { + enable = true; + enableZshIntegration = true; + flags = [ "--disable-up-arrow" ]; + settings = { + workspaces = true; + exit-mode = "return-query"; + enter_accept = true; + sync_address = "http://10.12.14.2:8888"; + sync = { records = true; }; + }; + }; +} + diff --git a/components/hm/direnv.nix b/components/hm/direnv.nix new file mode 100644 index 0000000..008f82a --- /dev/null +++ b/components/hm/direnv.nix @@ -0,0 +1,18 @@ +{ ... }: +{ + programs.direnv = { + enable = true; + enableZshIntegration = true; + config = { + nix-direnv = true; + global = { + strict_env = true; + load_dotenv = true; + hide_env_diff = true; + }; + whitelist = { + prefix = [ "~/projects" ]; + }; + }; + }; +} diff --git a/components/hm/git.nix b/components/hm/git.nix new file mode 100644 index 0000000..df11fc9 --- /dev/null +++ b/components/hm/git.nix @@ -0,0 +1,61 @@ +{ ... }: +{ + programs.git = { + enable = true; + # TODO make configurable + userEmail = "ringofstorms@gmail.com"; + userName = "RingOfStorms (Joshua Bell)"; + + extraConfig = { + core.pager = "cat"; + core.editor = "nvim"; + + pull.rebase = false; + + init.defaultBranch = "main"; + }; + + difftastic = { + enable = true; + background = "dark"; + }; + + ignores = [ + # -------------- + # Intellij + # -------------- + "*.iml" + # -------------- + # MAC OS + # -------------- + ".DS_Store" + ".AppleDouble" + ".LSOverride" + # Icon must end with two \r + "Icon" + # Thumbnails + "._*" + # Files that might appear in the root of a volume + ".DocumentRevisions-V100" + ".fseventsd" + ".Spotlight-V100" + ".TemporaryItems" + ".Trashes" + ".VolumeIcon.icns" + ".com.apple.timemachine.donotpresent" + + # Directories potentially created on remote AFP share + ".AppleDB" + ".AppleDesktop" + "Network Trash Folder" + "Temporary Items" + ".apdisk" + + # direnv things + "/.direnv" + + # local only files + "*.local" + ]; + }; +} diff --git a/components/hm/launcher_rofi.nix b/components/hm/launcher_rofi.nix new file mode 100644 index 0000000..353b29e --- /dev/null +++ b/components/hm/launcher_rofi.nix @@ -0,0 +1,18 @@ +{ + pkgs, + ... +}: +{ + programs.rofi = { + enable = true; + plugins = with pkgs; [ rofi-calc ]; + extraConfig = { + modi = "drun,run,ssh,window,calc"; + terminal = "alacritty"; + }; + theme = "glue_pro_blue"; + }; + programs.wofi = { + enable = true; + }; +} diff --git a/components/hm/nix_deprecations.nix b/components/hm/nix_deprecations.nix new file mode 100644 index 0000000..d281d87 --- /dev/null +++ b/components/hm/nix_deprecations.nix @@ -0,0 +1,18 @@ +{ ... }: +{ + programs.zsh.shellAliases = { + # Nix deprecations + nix-hash = "echo 'The functionality of nix-hash may be covered by various subcommands or options in the new `nix` command.'"; + nix-build = "echo 'Use `nix build` instead.'"; + nix-info = "echo 'Use `nix flake info` or other `nix` subcommands to obtain system and Nix information.'"; + nix-channel = "echo 'Channels are being phased out in favor of flakes. Use `nix flake` subcommands.'"; + nix-instantiate = "echo 'Use `nix eval` or `nix-instantiate` with flakes.'"; + nix-collect-garbage = "echo 'Use `nix store gc` instead.'"; + nix-prefetch-url = "echo 'Use `nix-prefetch` or fetchers in Nix expressions.'"; + nix-copy-closure = "echo 'Use `nix copy` instead.'"; + nix-shell = "echo 'Use `nix shell` instead.'"; + # nix-daemon # No direct replacement: The Nix daemon is still in use and managed by the system service manager. + nix-store = "echo 'Use `nix store` subcommands for store operations.'"; + nix-env = "echo 'Use `nix profile` instead'"; + }; +} diff --git a/components/hm/postgres.nix b/components/hm/postgres.nix new file mode 100644 index 0000000..053099b --- /dev/null +++ b/components/hm/postgres.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + home.file.".psqlrc".text = '' + \pset pager off + ''; +} + diff --git a/components/hm/ssh.nix b/components/hm/ssh.nix new file mode 100644 index 0000000..22eb107 --- /dev/null +++ b/components/hm/ssh.nix @@ -0,0 +1,137 @@ +{ nixConfig, ... }: +let + inherit (nixConfig) age; +in +{ + # TODO can I put all IP's in the flake.nix top level settings and pull them in here instead? + programs.ssh = { + enable = true; + matchBlocks = { + # EXTERNAL + "github.com" = { + identityFile = age.secrets.nix2github.path; + }; + "bitbucket.org" = { + identityFile = age.secrets.nix2bitbucket.path; + }; + "git.joshuabell.xyz" = { + identityFile = age.secrets.nix2gitjosh.path; + port = 3032; + }; + # PERSONAL DEVICES + "lio" = { + identityFile = age.secrets.nix2lio.path; + hostname = "10.20.40.104"; + user = "josh"; + }; + "lio_" = { + identityFile = age.secrets.nix2lio.path; + hostname = "10.12.14.116"; + user = "josh"; + }; + "oren" = { + identityFile = age.secrets.nix2oren.path; + hostname = "10.20.40.105"; + user = "josh"; + }; + "joe" = { + identityFile = age.secrets.nix2joe.path; + hostname = "10.20.40.102"; + user = "josh"; + }; + "gpdPocket3" = { + identityFile = age.secrets.nix2gpdPocket3.path; + hostname = "10.20.40.103"; + user = "josh"; + }; + "t" = { + identityFile = age.secrets.nix2t.path; + hostname = "10.20.40.180"; + user = "joshua.bell"; + localForwards = [ + # { + # bind.port = 3000; + # host.port = 3000; + # host.address = "localhost"; + # } + { + bind.port = 3002; + host.port = 3002; + host.address = "localhost"; + } + ]; + setEnv = { + TERM = "vt100"; + }; + }; + "mbptv" = { + identityFile = age.secrets.nix2gpdPocket3.path; + hostname = "10.20.40.109"; + user = "waka"; + setEnv = { + TERM = "vt100"; + }; + }; + "mbptv_" = { + identityFile = age.secrets.nix2gpdPocket3.path; + hostname = "10.12.14.101"; + user = "waka"; + setEnv = { + TERM = "vt100"; + }; + }; + "nothing1" = { + identityFile = age.secrets.nix2gpdPocket3.path; + hostname = "10.20.40.124"; + user = "TODO"; + }; + "ipad1" = { + identityFile = age.secrets.nix2gpdPocket3.path; + hostname = "10.20.40.125"; + user = "TODO"; + }; + "tab1" = { + identityFile = age.secrets.nix2gpdPocket3.path; + hostname = "10.20.40.120"; + user = "TODO"; + }; + "pixel6" = { + identityFile = age.secrets.nix2gpdPocket3.path; + hostname = "10.20.40.126"; # TODO ON BOARD + user = "TODO"; + }; + # HOME SERVERS + "h001" = { + identityFile = age.secrets.nix2h001.path; + hostname = "10.20.40.190"; + user = "root"; + }; + "h001_" = { + identityFile = age.secrets.nix2h001.path; + hostname = "10.12.14.2"; + user = "root"; + }; + "h002" = { + identityFile = age.secrets.nix2h002.path; + hostname = "10.20.40.191"; + user = "luser"; + }; + # LINODE SERVERS + "l001" = { + identityFile = age.secrets.nix2l001.path; + hostname = "172.105.22.34"; # TODO REMOVE - OFF BOARD + user = "root"; + }; + "l002_" = { + identityFile = age.secrets.nix2l002.path; + hostname = "172.232.4.54"; + user = "luser"; + }; + "l002" = { + identityFile = age.secrets.nix2l002.path; + hostname = "10.20.40.1"; + user = "luser"; + }; + }; + }; +} diff --git a/components/hm/starship.nix b/components/hm/starship.nix new file mode 100644 index 0000000..7d74a3f --- /dev/null +++ b/components/hm/starship.nix @@ -0,0 +1,52 @@ +{ ... }: +{ + programs.starship = { + enable = true; + enableZshIntegration = true; + settings = { + add_newline = false; + palette = "catppuccin_coal"; + palettes.catppuccin_coal = { + # Same as catppuccin mocha for these + rosewater = "#f5e0dc"; + flamingo = "#f2cdcd"; + pink = "#f5c2e7"; + mauve = "#cba6f7"; + red = "#f38ba8"; + maroon = "#eba0ac"; + peach = "#fab387"; + yellow = "#f9e2af"; + green = "#a6e3a1"; + teal = "#94e2d5"; + sky = "#89dceb"; + sapphire = "#74c7ec"; + blue = "#89b4fa"; + lavender = "#b4befe"; + # Coal variant: https://gist.joshuabell.xyz/ringofstorms/catppucin-coal + text = "#e0e0e0"; + subtext1 = "#cccccc"; + subtext0 = "#b8b8b8"; + overlay2 = "#a3a3a3"; + overlay1 = "#8c8c8c"; + overlay0 = "#787878"; + surface2 = "#636363"; + surface1 = "#4f4f4f"; + surface0 = "#3b3b3b"; + base = "#262626"; + mantle = "#1f1f1f"; + crust = "#171717"; + }; + nix_shell = { + heuristic = true; + impure_msg = "不純 \\(ふじゅん\\)"; + pure_msg = " 純粋 \\(じゅんすい\\)"; + }; + git_branch = { + format = "オン [$symbol$branch(:$remote_branch)]($style) "; + }; + cmd_duration = { + format = "掛かった [$duration]($style) "; + }; + }; + }; +} diff --git a/components/hm/tmux/tmux-reset.conf b/components/hm/tmux/tmux-reset.conf new file mode 100644 index 0000000..258c1d4 --- /dev/null +++ b/components/hm/tmux/tmux-reset.conf @@ -0,0 +1,64 @@ +# Reset everything then add what we want exactly +unbind-key -a +bind C-Space send-prefix + +# Windows +# bind -r p previous-window +# bind -r n next-window +bind -r & kill-window +bind c new-window -c "#{pane_current_path}" +bind ',' command-prompt "rename-window %%" +bind "\|" split-window -h -c "#{pane_current_path}" +bind "\\" split-window -v -c "#{pane_current_path}" +bind w choose-tree -Zw +bind 1 select-window -t:1 +bind 2 select-window -t:2 +bind 3 select-window -t:3 +bind 4 select-window -t:4 +bind 5 select-window -t:5 +bind 6 select-window -t:6 +bind 7 select-window -t:7 +bind 8 select-window -t:8 +bind 9 select-window -t:9 +# custom +bind m command-prompt -p "Swap with window index:" "swap-window -t '%%'" +bind -r [ swap-window -t -1 \; previous-window +bind -r ] swap-window -t +1 \; next-window + + +# Panes +bind ! break-pane +bind -r left select-pane -L +bind -r down select-pane -D +bind -r up select-pane -U +bind -r right select-pane -R +bind x kill-pane +bind -r space resize-pane -Z +bind S select-layout tiled +bind -r h select-pane -L +bind -r j select-pane -D +bind -r k select-pane -U +bind -r l select-pane -R + + +# Sessions +bind $ command-prompt "rename-session %%" +bind -r ) switch-client -n +bind -r ( switch-client -p +# custom +bind C command-prompt -p "session name:" "new-session -s '%%'" + +# Tmux util +bind : command-prompt +bind C-d detach + +# ========== +# My options +set-option -g terminal-overrides ',xterm-256color:RGB' +set-option -sa terminal-features ',alacritty:LRGB' +set -g detach-on-destroy off +set -g renumber-windows on +set -g status-position top +set -sg escape-time 0 + +set-option -g focus-events on diff --git a/components/hm/tmux/tmux.nix b/components/hm/tmux/tmux.nix new file mode 100644 index 0000000..566b10c --- /dev/null +++ b/components/hm/tmux/tmux.nix @@ -0,0 +1,76 @@ +{ lib, pkgs, ... }: +{ + # home manager doesn't give us an option to add tmux extra config at the top so we do it ourselves here. + xdg.configFile."tmux/tmux.conf".text = lib.mkBefore (builtins.readFile ./tmux-reset.conf); + + programs.tmux = { + enable = true; + + # Revisit this later, permission denied to make anything in `/run` as my user... + secureSocket = false; + + # default is B switch to space for easier dual hand use + shortcut = "Space"; + prefix = "C-Space"; + baseIndex = 1; + mouse = true; + keyMode = "vi"; + shell = "${pkgs.zsh}/bin/zsh"; + terminal = "screen-256color"; + aggressiveResize = true; + sensibleOnTop = false; + + plugins = with pkgs.tmuxPlugins; [ + { + plugin = catppuccin.overrideAttrs (_: { + src = pkgs.fetchgit { + url = "https://git.joshuabell.xyz/tmux-catppuccin-coal.git"; + rev = "d078123cd81c0dbb3f780e8575a9d38fe2023e1b"; + sha256 = "sha256-qPY/dovDyut5WoUkZ26F2w3fJVmw4gcC+6l2ugsA65Y="; + }; + }); + extraConfig = '' + set -g @catppuccin_flavour 'mocha' + set -g @catppuccin_window_left_separator "" + set -g @catppuccin_window_right_separator " " + set -g @catppuccin_window_middle_separator " █" + set -g @catppuccin_window_number_position "right" + set -g @catppuccin_window_default_fill "number" + set -g @catppuccin_window_default_text "#W" + set -g @catppuccin_window_current_fill "number" + set -g @catppuccin_window_current_text "#W#{?window_zoomed_flag,(),}" + set -g @catppuccin_status_modules_right "directory application date_time" + set -g @catppuccin_status_modules_left "session" + set -g @catppuccin_status_left_separator " " + set -g @catppuccin_status_right_separator " " + set -g @catppuccin_status_right_separator_inverse "no" + set -g @catppuccin_status_fill "icon" + set -g @catppuccin_status_connect_separator "no" + set -g @catppuccin_directory_text "#{b:pane_current_path}" + set -g @catppuccin_date_time_text "%H:%M" + ''; + } + { + plugin = resurrect; + extraConfig = '' + set -g @resurrect-strategy-nvim 'session' + set -g @resurrect-capture-pane-contents 'on' + # Hook to save tmux-resurrect state when a pane is closed + set-hook -g pane-died "run-shell 'tmux-resurrect save'" + ''; + } + { + plugin = continuum; + extraConfig = '' + set -g @continuum-restore 'on' + set -g @continuum-save-interval '5' # minutes + ''; + } + ]; + }; + + home.shellAliases = { + t = "tmux"; + tat = "tmux ls 2>/dev/null && tmux attach-session -t \"$(tmux ls | head -n1 | cut -d: -f1)\" || tmux new-session"; + }; +} diff --git a/components/hm/zoxide.nix b/components/hm/zoxide.nix new file mode 100644 index 0000000..e298bcd --- /dev/null +++ b/components/hm/zoxide.nix @@ -0,0 +1,8 @@ +{ ... }: +{ + programs.zoxide = { + enable = true; + enableZshIntegration = true; + options = [ "--cmd cd" ]; + }; +} diff --git a/components/hm/zsh.nix b/components/hm/zsh.nix new file mode 100644 index 0000000..1fdc3bb --- /dev/null +++ b/components/hm/zsh.nix @@ -0,0 +1,41 @@ +{ ... }: +{ + programs.zsh = { + enable = true; + autosuggestion.enable = true; + + shellAliases = { }; + + defaultKeymap = "emacs"; + + initExtra = '' + # Set editor to neovim, TODO only do this if mod.neovim is enabled + export EDITOR=nvim + export VISUAL=nvim + + # Enable editing command in external editor + autoload -Uz edit-command-line + zle -N edit-command-line + # Try multiple bindings for edit-command-line + bindkey '^X^E' edit-command-line # Traditional Ctrl+X,Ctrl+E binding + bindkey '^[^M' edit-command-line # Alt+Enter + # Note: Ctrl+Enter might not be distinctly capturable in all terminals + + # Make home/end and ctrl + left/right nav how I expect them to like in bash + bindkey "\e[1~" beginning-of-line + bindkey "\e[4~" end-of-line + bindkey '^[[1;5D' emacs-backward-word + bindkey '^[[1;5C' emacs-forward-word + + # Auto completion/suggestions/and case insensitivity + autoload -Uz compinit && compinit + setopt correct + setopt extendedglob + setopt nocaseglob + zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # Case insensitive tab completion + zstyle ':completion:*' list-colors "''${(s.:.)LS_COLORS}" # Colored completion (different colors for dirs/files/etc) + zstyle ':completion:*' rehash true # automatically find new executables in path + ''; + }; +} + diff --git a/components/nix/lua.nix b/components/nix/lua.nix new file mode 100644 index 0000000..6809860 --- /dev/null +++ b/components/nix/lua.nix @@ -0,0 +1,5 @@ +{ pkgs, ... }: +{ + environment.systemPackages = with pkgs; [ lua ]; +} + diff --git a/components/nix/qdirstat.nix b/components/nix/qdirstat.nix new file mode 100644 index 0000000..e647d90 --- /dev/null +++ b/components/nix/qdirstat.nix @@ -0,0 +1,4 @@ +{ pkgs, ... }: +{ + environment.systemPackages = [ pkgs.qdirstat ]; +} diff --git a/components/nix/qflipper.nix b/components/nix/qflipper.nix new file mode 100644 index 0000000..9bcd907 --- /dev/null +++ b/components/nix/qflipper.nix @@ -0,0 +1,12 @@ +{ pkgs, ... }: +{ + hardware.flipperzero.enable = true; + environment.systemPackages = with pkgs; [ qFlipper ]; + + services.udev.extraRules = '' + #Flipper Zero serial port + SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ATTRS{manufacturer}=="Flipper Devices Inc.", GROUP="users", TAG+="uaccess" + #Flipper Zero DFU + SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", ATTRS{manufacturer}=="STMicroelectronics", GROUP="users", TAG+="uaccess" + ''; +} diff --git a/components/nix/rust-repl.nix b/components/nix/rust-repl.nix new file mode 100644 index 0000000..2f6078d --- /dev/null +++ b/components/nix/rust-repl.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: +{ + environment.systemPackages = with pkgs; [ evcxr rustc ]; + environment.shellAliases = { + rust = "evcxr"; + }; +} diff --git a/components/nix/uhk-agent.nix b/components/nix/uhk-agent.nix new file mode 100644 index 0000000..9166afc --- /dev/null +++ b/components/nix/uhk-agent.nix @@ -0,0 +1,6 @@ +{ pkgs, ... }: +{ + environment.systemPackages = with pkgs; [ uhk-agent uhk-udev-rules ]; + + services.udev.packages = [ pkgs.uhk-udev-rules ]; +} diff --git a/hosts/oren/flake.lock b/hosts/oren/flake.lock index dea29a9..9d9f334 100644 --- a/hosts/oren/flake.lock +++ b/hosts/oren/flake.lock @@ -3,7 +3,7 @@ "agenix": { "inputs": { "darwin": "darwin", - "home-manager": "home-manager_2", + "home-manager": "home-manager", "nixpkgs": [ "mods_common", "ragenix", @@ -126,27 +126,6 @@ } }, "home-manager": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1735344290, - "narHash": "sha256-oJDtWPH1oJT34RJK1FSWjwX4qcGOBRkcNQPD0EbSfNM=", - "owner": "nix-community", - "repo": "home-manager", - "rev": "613691f285dad87694c2ba1c9e6298d04736292d", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "release-24.11", - "repo": "home-manager", - "type": "github" - } - }, - "home-manager_2": { "inputs": { "nixpkgs": [ "mods_common", @@ -169,15 +148,37 @@ "type": "github" } }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "mods_home-manager", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1735344290, + "narHash": "sha256-oJDtWPH1oJT34RJK1FSWjwX4qcGOBRkcNQPD0EbSfNM=", + "owner": "rycee", + "repo": "home-manager", + "rev": "613691f285dad87694c2ba1c9e6298d04736292d", + "type": "github" + }, + "original": { + "owner": "rycee", + "ref": "release-24.11", + "repo": "home-manager", + "type": "github" + } + }, "mods_boot_systemd": { "locked": { "lastModified": 1, "narHash": "sha256-9Z/Z8Y4Q1q95zUeJWfUQFyeaAVkhb804kd3tiBpHfpI=", - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/boot_systemd", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/boot_systemd", "type": "path" }, "original": { - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/boot_systemd", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/boot_systemd", "type": "path" } }, @@ -190,12 +191,12 @@ }, "locked": { "lastModified": 1, - "narHash": "sha256-4fm0Y7ekxMI3Z93JkoPwpBInDDAa4HIcIp9JwXKWcys=", - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/common", + "narHash": "sha256-tSW1S2JPkgnJ563taboMx0RfcyCbcO4+zsaTjPYPRvI=", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/common", "type": "path" }, "original": { - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/common", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/common", "type": "path" } }, @@ -212,11 +213,41 @@ "locked": { "lastModified": 1, "narHash": "sha256-kTwFBa1QFUbcld1+ZUOK2M0OjOpg6rzVGrkuAB8CemA=", - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/de_cosmic", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/de_cosmic", "type": "path" }, "original": { - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/de_cosmic", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/de_cosmic", + "type": "path" + } + }, + "mods_home-manager": { + "inputs": { + "home-manager": "home-manager_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1, + "narHash": "sha256-9W9vNv25dFBOXVtiK8OeSrwU0epvI8y0dqdjfIEZhEc=", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/home_manager", + "type": "path" + }, + "original": { + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/home_manager", + "type": "path" + } + }, + "mods_nebula": { + "locked": { + "lastModified": 1, + "narHash": "sha256-WfYwWhjnePj5MYb9d84AAH7DT4W77eXV7DE1HV5nWbk=", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/nebula", + "type": "path" + }, + "original": { + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/nebula", "type": "path" } }, @@ -227,26 +258,26 @@ "locked": { "lastModified": 1, "narHash": "sha256-Do761YmlKOOr9+9vKUJnA2n5WQANXKPR2aesvsi/6VQ=", - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/neovim", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/neovim", "type": "path" }, "original": { - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/neovim", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/neovim", "type": "path" } }, - "mods_row_stormd": { + "mods_ros_stormd": { "inputs": { "ringofstorms-stormd": "ringofstorms-stormd" }, "locked": { "lastModified": 1, "narHash": "sha256-YjXJu/5Hcl7YpcpiHLd5wqCFUlJp39MM9CfQKhdpkk8=", - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/stormd", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/stormd", "type": "path" }, "original": { - "path": "/nix/store/9jx7g5wvvwsgbkkdqmn83k0fd8hh6ydq-source/modules/stormd", + "path": "/nix/store/sm477lnilan12wmmyd9s0dgphg6fqygf-source/modules/stormd", "type": "path" } }, @@ -1365,12 +1396,13 @@ }, "root": { "inputs": { - "home-manager": "home-manager", "mods_boot_systemd": "mods_boot_systemd", "mods_common": "mods_common", "mods_de_cosmic": "mods_de_cosmic", + "mods_home-manager": "mods_home-manager", + "mods_nebula": "mods_nebula", "mods_ros_neovim": "mods_ros_neovim", - "mods_row_stormd": "mods_row_stormd", + "mods_ros_stormd": "mods_ros_stormd", "nixpkgs": "nixpkgs_3" } }, @@ -1443,7 +1475,7 @@ "rust-overlay_4": { "inputs": { "nixpkgs": [ - "mods_row_stormd", + "mods_ros_stormd", "ringofstorms-stormd", "nixpkgs" ] diff --git a/hosts/oren/flake.nix b/hosts/oren/flake.nix index 1499646..b6bf154 100644 --- a/hosts/oren/flake.nix +++ b/hosts/oren/flake.nix @@ -3,10 +3,6 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; - home-manager = { - url = "github:nix-community/home-manager/release-24.11"; - inputs.nixpkgs.follows = "nixpkgs"; - }; mods_common.url = "../../modules/common"; mods_common.inputs.nixpkgs.follows = "nixpkgs"; @@ -15,15 +11,16 @@ mods_de_cosmic.inputs.nixpkgs-stable.follows = "nixpkgs"; mods_de_cosmic.inputs.nixpkgs.follows = "nixpkgs"; mods_ros_neovim.url = "../../modules/neovim"; - mods_row_stormd.url = "../../modules/stormd"; + mods_ros_stormd.url = "../../modules/stormd"; + mods_nebula.url = "../../modules/nebula"; + mods_home-manager.url = "../../modules/home_manager"; + mods_home-manager.inputs.home-manager.url = "github:rycee/home-manager/release-24.11"; + mods_home-manager.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { - self, nixpkgs, - home-manager, - mods_boot_systemd, ... }@inputs: let @@ -48,16 +45,80 @@ ./configuration.nix ./hardware-configuration.nix ( + { pkgs, ... }: { - ... - }: - { + imports = [ + ../../components/nix/lua.nix + ../../components/nix/rust-repl.nix + ../../components/nix/qflipper.nix + ../../components/nix/qdirstat.nix + ]; mods = { common = { systemName = configuration_name; allowUnfree = true; primaryUser = "josh"; docker = true; + zsh = true; + users = { + josh = { + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILMzgAe4od9K4EsvH2g7xjNU7hGoJiFJlYcvB0BoDCvn nix2oren" + ]; + initialPassword = "password1"; + isNormalUser = true; + extraGroups = [ + "wheel" + "networkmanager" + "video" + "input" + ]; + shell = pkgs.zsh; + packages = with pkgs; [ + # blender + google-chrome + # comma + discordo + discord + # nautilus qimgv # file browsing (not needed in cosmic) + firefox-esr + # freecad + # ladybird + # ollama + # vlc + ]; + }; + }; + }; + home_manager = { + users = { + josh = { + imports = [ + ../../components/hm/tmux/tmux.nix + ../../components/hm/alacritty.nix + ../../components/hm/atuin.nix + ../../components/hm/direnv.nix + ../../components/hm/git.nix + # ../../components/hm/launcher_rofi.nix # not needed in cosmic + ../../components/hm/nix_deprecations.nix + ../../components/hm/postgres.nix + ../../components/hm/ssh.nix + ../../components/hm/starship.nix + ../../components/hm/zoxide.nix + ../../components/hm/zsh.nix + ]; + }; + root = { + imports = [ + # ../../components/hm/atuin.nix + ../../components/hm/nix_deprecations.nix + ../../components/hm/postgres.nix + ../../components/hm/starship.nix + ../../components/hm/zoxide.nix + ../../components/hm/zsh.nix + ]; + }; + }; }; }; } diff --git a/hosts_old/oren/configuration.nix b/hosts_old/oren/configuration.nix index 94c64a3..f59ad62 100644 --- a/hosts_old/oren/configuration.nix +++ b/hosts_old/oren/configuration.nix @@ -18,8 +18,8 @@ tty_caps_esc.enable = true; # new docker.enable = true; # new fonts.enable = true; # new - stormd.enable = true; # - nebula.enable = true; + stormd.enable = true; # new + nebula.enable = true; # new ssh.enable = true; # new # rustdesk.enable = true; }; diff --git a/modules/common/flake.nix b/modules/common/flake.nix index 43f31df..c03e759 100644 --- a/modules/common/flake.nix +++ b/modules/common/flake.nix @@ -36,6 +36,11 @@ # default = "josh"; description = "The primary user of the system."; }; + primaryAuthorizedKeys = mkOption { + type = types.listOf types.str; + default = [ ]; + description = "The primary user's authorized keys."; + }; defaultLocal = mkOption { type = types.str; default = "en_US.UTF-8"; @@ -47,6 +52,12 @@ description = "Open the ssh port."; }; docker = mkEnableOption (lib.mdDoc "Enable docker"); + zsh = mkEnableOption (lib.mdDoc "Enable zsh"); + users = mkOption { + type = types.attrsOf types.attrs; + default = { }; + description = "Users to configure. Should match nix options of users.userser..*"; + }; }; imports = [ @@ -58,7 +69,9 @@ ./shell/common.nix ./tty_caps_esc.nix ./docker.nix + ./zsh.nix ./fonts.nix + ./users.nix ]; config = { _module.args = { @@ -169,7 +182,7 @@ ''; # Some basics - nixpkgs.config.allowUnfree = settings.allowUnfree; + nixpkgs.config.allowUnfree = cfg.allowUnfree; nixpkgs.config.allowUnfreePredicate = (pkg: true); }; }; diff --git a/modules/common/ssh.nix b/modules/common/ssh.nix index a1adbd1..86b372b 100644 --- a/modules/common/ssh.nix +++ b/modules/common/ssh.nix @@ -24,5 +24,33 @@ with lib; PermitRootLogin = "yes"; }; }; + + # Ensure SSH key pair generation for non-root users + systemd.services = mapAttrs' (name: _: { + name = "generate_ssh_key_${name}"; + value = { + description = "Generate SSH key pair for ${name}"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = name; + Type = "oneshot"; + }; + script = '' + #!/run/current-system/sw/bin/bash + if [ ! -f /home/${name}/.ssh/id_ed25519 ]; then + if [ -v DRY_RUN ]; then + echo "DRY_RUN is set. Would generate SSH key for ${name}."; + else + echo "Generating SSH key for ${name}."; + mkdir -p /home/${name}/.ssh; + chmod 700 /home/${name}/.ssh; + /run/current-system/sw/bin/ssh-keygen -t ed25519 -f /home/${name}/.ssh/id_ed25519 -N ""; + fi + else + echo "SSH key already exists for ${name}."; + fi + ''; + }; + }) config.mods.common.users; }; } diff --git a/modules/common/users.nix b/modules/common/users.nix new file mode 100644 index 0000000..316276a --- /dev/null +++ b/modules/common/users.nix @@ -0,0 +1,17 @@ +{ + lib, + config, + ... +}: +with lib; +{ + config = { + users.users = mapAttrs ( + name: config: + { + inherit name; + } + // config + ) config.mods.common.users; + }; +} diff --git a/modules/common/zsh.nix b/modules/common/zsh.nix new file mode 100644 index 0000000..49c6364 --- /dev/null +++ b/modules/common/zsh.nix @@ -0,0 +1,15 @@ +{ + config, + lib, + ... +}: +with lib; +let + cfg = config.mods.common; +in +{ + config = mkIf cfg.zsh { + programs.zsh.enable = true; + environment.pathsToLink = [ "/share/zsh" ]; + }; +} diff --git a/modules/home_manager/flake.nix b/modules/home_manager/flake.nix new file mode 100644 index 0000000..8df150b --- /dev/null +++ b/modules/home_manager/flake.nix @@ -0,0 +1,57 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + home-manager = { + url = "github:rycee/home-manager/release-24.11"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + { + home-manager, + ... + }: + { + nixosModules = { + default = + { + config, + pkgs, + lib, + ... + }: + with lib; + { + options.mods.home_manager = { + users = mkOption { + type = types.attrsOf types.attrs; + default = { }; + description = "Home manager users to configure. Should match nix options of home-manager.users..*"; + }; + }; + imports = [ home-manager.nixosModules.home-manager ]; + config = { + # Home manager options + security.polkit.enable = true; + home-manager.useUserPackages = true; + home-manager.useGlobalPkgs = true; + home-manager.extraSpecialArgs = { + nixConfig = config; + }; + + home-manager.users = mapAttrs' (name: user: { + inherit name; + value = user // { + # TODO does this need to be per user per machine and updated better? + home.stateVersion = "23.11"; + programs.home-manager.enable = true; + home.username = name; + home.homeDirectory = lib.mkForce "/home/${name}"; + }; + }) config.mods.home_manager.users; + }; + }; + }; + }; +} diff --git a/modules/nebula/flake.nix b/modules/nebula/flake.nix new file mode 100644 index 0000000..58e17d9 --- /dev/null +++ b/modules/nebula/flake.nix @@ -0,0 +1,73 @@ +{ + inputs = { + }; + + outputs = + { + ... + }: + { + nixosModules = { + default = + { + config, + pkgs, + lib, + ... + }: + with lib; + { + config = { + environment.systemPackages = with pkgs; [ + nebula + traceroute # for debugging + ]; + + networking.firewall.allowedUDPPorts = [ 4242 ]; + + systemd.services."nebula" = { + description = "Nebula VPN service"; + wants = [ "basic.target" ]; + after = [ + "basic.target" + "network.target" + ]; + before = [ "sshd.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "notify"; + Restart = "always"; + RestartSec = 1; + ExecStart = "${pkgs.nebula}/bin/nebula -config /etc/nebula/config.yml"; + UMask = "0027"; + CapabilityBoundingSet = "CAP_NET_ADMIN"; + AmbientCapabilities = "CAP_NET_ADMIN"; + LockPersonality = true; + NoNewPrivileges = true; + PrivateDevices = false; # needs access to /dev/net/tun (below) + DeviceAllow = "/dev/net/tun rw"; + DevicePolicy = "closed"; + PrivateTmp = true; + PrivateUsers = false; # CapabilityBoundingSet needs to apply to the host namespace + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictNamespaces = true; + RestrictSUIDSGID = true; + }; + unitConfig = { + StartLimitIntervalSec = 5; + StartLimitBurst = 3; + }; + }; + }; + }; + }; + }; +}