diff options
Diffstat (limited to 'nix')
| -rw-r--r-- | nix/common.nix | 78 | ||||
| -rw-r--r-- | nix/host.nix | 9 | ||||
| -rw-r--r-- | nix/vm.nix | 63 |
3 files changed, 68 insertions, 82 deletions
diff --git a/nix/common.nix b/nix/common.nix index a34dfba..fb04dc7 100644 --- a/nix/common.nix +++ b/nix/common.nix @@ -1,13 +1,12 @@ { config, pkgs, lib, dotfilesRoot, ... }: -# Shared Home-Manager module: the leaf-CLI subset, editor/AI-agent -# runtimes, and the shared dotfiles symlinks used by **both** the Arch -# host and the Ubuntu remote-dev VM. Profile-specific extras live in -# `host.nix` and `vm.nix`. -# -# The path to the runtime dotfiles checkout (where symlinks point) is -# read from `config.my.dotfilesPath`; the per-profile module sets it -# (host: ~/dotfiles, vm: ~/.local/share/dotfiles). +# Shared Home-Manager module: ONLY package installation. Config-file +# deployment is *not* handled here — on the Arch host, chezmoi owns +# every dotfile under $HOME; on the remote-dev VM, `vm.nix` carries +# its own `xdg.configFile`/`home.activation` block since chezmoi isn't +# installed there. Keeping this module deployment-agnostic prevents +# home-manager from conflicting with chezmoi on the host (which would +# otherwise materialize as `.backup` files on every `nix-switch`). # # Policy: this profile carries leaf CLI tools, editor/AI-agent runtimes # (node, uv), and build *orchestrators* (cmake, ninja, ccache, sccache). @@ -30,22 +29,7 @@ # — manages its own python interpreters under XDG, doesn't install a # system python3). -let - dotfiles = config.my.dotfilesPath; - link = path: config.lib.file.mkOutOfStoreSymlink "${dotfiles}/${path}"; -in { - options.my.dotfilesPath = lib.mkOption { - type = lib.types.str; - description = '' - Absolute path to the runtime dotfiles checkout that the - mkOutOfStoreSymlink-based home.file entries point at. The host - profile sets this to "$HOME/dotfiles"; the vm profile sets it - to "$HOME/.local/share/dotfiles". - ''; - }; - - config = { home.stateVersion = "25.05"; # ── Packages ──────────────────────────────────────────────────────────────── @@ -213,57 +197,9 @@ in enableZshIntegration = false; # zshrc already calls `eval "$(direnv hook zsh)"` }; - # ── Shared config symlinks ────────────────────────────────────────────────── - # Live symlinks back into the cloned working tree so `git pull` is enough - # to update configs — no `home-manager switch` required after every edit. - xdg.configFile = { - "nvim".source = link "dot_config/nvim"; - "zellij".source = link "dot_config/zellij"; - "zsh/.zshrc".source = link "dot_config/zsh/dot_zshrc"; - "zsh/.zprofile".source = link "dot_config/zsh/dot_zprofile"; - "ghostty".source = link "dot_config/ghostty"; # for terminfo refs only - "direnv/direnvrc".source = link "dot_config/direnv/direnvrc"; - "git/config".source = link "dot_config/git/config"; - "git/attributes".source = link "dot_config/git/attributes"; - "git/ignore".source = link "dot_config/git/ignore"; - # Git hooks: source filenames carry the chezmoi `executable_` attribute - # prefix which only chezmoi strips. In nix-managed setups we use raw - # symlinks, so map each hook to its stripped name explicitly. The - # executable bit comes from the working-tree file mode (git resolves - # the symlink). - "git/hooks/pre-push".source = link "dot_config/git/hooks/executable_pre-push"; - "git/hooks/pre-commit".source = link "dot_config/git/hooks/executable_pre-commit"; - "git/hooks/commit-msg".source = link "dot_config/git/hooks/executable_commit-msg"; - "git/hooks/post-commit".source = link "dot_config/git/hooks/executable_post-commit"; - "git/hooks/_dispatch.sh".source = link "dot_config/git/hooks/_dispatch.sh"; - }; - - # ~/.ssh/config from the dotfiles tree (read-only); keys + known_hosts - # stay machine-local. We can't symlink via home.file because - # mkOutOfStoreSymlink exposes the working-tree perms (0664 under a - # default umask 002) and OpenSSH refuses any group-writable ssh_config. - # Materialize a real 0600 file via activation instead. - home.activation.sshConfig = lib.hm.dag.entryAfter [ "writeBoundary" ] '' - run install -D -m 600 \ - "${dotfiles}/private_dot_ssh/config" "$HOME/.ssh/config" - ''; - - # ZDOTDIR redirect so login shells find ~/.config/zsh/.zprofile etc. - # Also source HM's session-vars — HM normally drops these into - # ~/.profile, but zsh login shells don't read .profile, and we don't - # use programs.zsh.enable. - home.file.".zshenv".text = '' - if [ -r "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" ]; then - . "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" - fi - export ZDOTDIR="$HOME/.config/zsh" - [[ -r "$ZDOTDIR/.zshenv" ]] && source "$ZDOTDIR/.zshenv" - ''; - # ── XDG base dirs ────────────────────────────────────────────────────────── xdg.enable = true; # ── Enable HM-managed activation messages ────────────────────────────────── programs.home-manager.enable = true; - }; } diff --git a/nix/host.nix b/nix/host.nix index d589002..eac2a20 100644 --- a/nix/host.nix +++ b/nix/host.nix @@ -2,6 +2,10 @@ # Arch host Home-Manager profile. Layered on top of `common.nix`; adds # only host-specific concerns that don't make sense on the VM. +# +# Dotfile deployment on the host is owned entirely by **chezmoi** (run +# via `just apply` / `just sync`). Home-Manager here only installs +# binaries and writes the host-only smartcard config below. { imports = [ ./common.nix ]; @@ -9,11 +13,6 @@ home.username = builtins.getEnv "USER"; home.homeDirectory = builtins.getEnv "HOME"; - # The Arch host keeps its chezmoi source state at ~/dotfiles (the - # canonical clone location for the dotfiles repo). The VM convention - # of ~/.local/share/dotfiles doesn't apply here. - my.dotfilesPath = "${builtins.getEnv "HOME"}/dotfiles"; - # ── Smartcard (Yubikey) ──────────────────────────────────────────────────── # Nix's gnupg ships its own scdaemon. Delegate to the system pcscd # service instead of letting nix's scdaemon open the USB device @@ -1,18 +1,20 @@ { config, pkgs, lib, dotfilesRoot, ... }: -# VM-only Home-Manager profile (Ubuntu 22.04 remote-dev box). Adds -# Mason-related runtime carve-outs and the rootless podman stack on -# top of `common.nix`. +# VM-only Home-Manager profile (Ubuntu 22.04 remote-dev box). Adds the +# rootless podman stack, the editor/zellij/zsh/git config symlinks +# back into the cloned dotfiles tree, and a minimal ~/.zshenv shim — +# all of which the Arch host gets from chezmoi instead. +let + dotfiles = "${builtins.getEnv "HOME"}/.local/share/dotfiles"; + link = path: config.lib.file.mkOutOfStoreSymlink "${dotfiles}/${path}"; +in { imports = [ ./common.nix ]; home.username = builtins.getEnv "USER"; home.homeDirectory = builtins.getEnv "HOME"; - # Remote-dev VM clones the dotfiles tree under XDG_DATA_HOME. - my.dotfilesPath = "${builtins.getEnv "HOME"}/.local/share/dotfiles"; - home.sessionVariables = { # Ubuntu 20.04-derived hosts still default to cgroups v1; podman 5 # warns on every invocation. Flipping to v2 is a host-level reboot @@ -34,6 +36,55 @@ passt # pasta backend (slirp4netns successor; podman picks it up) ]; + # ── Shared config symlinks ────────────────────────────────────────────────── + # Live symlinks back into the cloned working tree so `git pull` is enough + # to update configs — no `home-manager switch` required after every edit. + # On the Arch host the same files are deployed by chezmoi; this block + # exists because the VM doesn't run chezmoi. + xdg.configFile = { + "nvim".source = link "dot_config/nvim"; + "zellij".source = link "dot_config/zellij"; + "zsh/.zshrc".source = link "dot_config/zsh/dot_zshrc"; + "zsh/.zprofile".source = link "dot_config/zsh/dot_zprofile"; + "ghostty".source = link "dot_config/ghostty"; # for terminfo refs only + "direnv/direnvrc".source = link "dot_config/direnv/direnvrc"; + "git/config".source = link "dot_config/git/config"; + "git/attributes".source = link "dot_config/git/attributes"; + "git/ignore".source = link "dot_config/git/ignore"; + # Git hooks: source filenames carry the chezmoi `executable_` attribute + # prefix which only chezmoi strips. In nix-managed setups we use raw + # symlinks, so map each hook to its stripped name explicitly. The + # executable bit comes from the working-tree file mode (git resolves + # the symlink). + "git/hooks/pre-push".source = link "dot_config/git/hooks/executable_pre-push"; + "git/hooks/pre-commit".source = link "dot_config/git/hooks/executable_pre-commit"; + "git/hooks/commit-msg".source = link "dot_config/git/hooks/executable_commit-msg"; + "git/hooks/post-commit".source = link "dot_config/git/hooks/executable_post-commit"; + "git/hooks/_dispatch.sh".source = link "dot_config/git/hooks/_dispatch.sh"; + }; + + # ~/.ssh/config from the dotfiles tree (read-only); keys + known_hosts + # stay machine-local. We can't symlink via home.file because + # mkOutOfStoreSymlink exposes the working-tree perms (0664 under a + # default umask 002) and OpenSSH refuses any group-writable ssh_config. + # Materialize a real 0600 file via activation instead. + home.activation.sshConfig = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + run install -D -m 600 \ + "${dotfiles}/private_dot_ssh/config" "$HOME/.ssh/config" + ''; + + # ZDOTDIR redirect so login shells find ~/.config/zsh/.zprofile etc. + # Also source HM's session-vars — HM normally drops these into + # ~/.profile, but zsh login shells don't read .profile, and we don't + # use programs.zsh.enable. + home.file.".zshenv".text = '' + if [ -r "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" ]; then + . "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" + fi + export ZDOTDIR="$HOME/.config/zsh" + [[ -r "$ZDOTDIR/.zshenv" ]] && source "$ZDOTDIR/.zshenv" + ''; + # ── Rootless podman config ────────────────────────────────────────────────── # Kept inline (not in the chezmoi tree) because Arch's system-wide # /etc/containers defaults already work there; these files exist only |
