diff options
| author | 2026-05-20 13:56:11 +0100 | |
|---|---|---|
| committer | 2026-05-20 13:56:11 +0100 | |
| commit | 639f3cb82ef9f1e6dd0b47cf506ff3c09fd4a5a7 (patch) | |
| tree | a185181f6cc9d022fb7c966ec9805fedf3654485 /nix/vm.nix | |
| parent | 58f2d61be4c55c7cf7bdbb12f3fed6794e7481b5 (diff) | |
| download | dotfiles-639f3cb82ef9f1e6dd0b47cf506ff3c09fd4a5a7.tar.gz dotfiles-639f3cb82ef9f1e6dd0b47cf506ff3c09fd4a5a7.tar.bz2 dotfiles-639f3cb82ef9f1e6dd0b47cf506ff3c09fd4a5a7.zip | |
refactor(nix): deployment in vm.nix only; host uses chezmoi for dotfiles
Per user decision: on the Arch host, chezmoi remains the single deployer
of $HOME dotfiles. nix/common.nix's xdg.configFile + sshConfig
activation + .zshenv home.file block was causing home-manager to fight
chezmoi on every nix-switch, materializing .backup files for nvim,
zellij, zsh, git, ghostty, direnv.
Resolution:
- nix/common.nix: drop the entire deployment block, drop the
my.dotfilesPath option, drop the let..in dotfiles/link helpers.
Module is now deployment-agnostic: only installs packages.
- nix/host.nix: drop my.dotfilesPath; explicit comment that chezmoi
owns dotfile deployment on the host.
- nix/vm.nix: gains everything previously in common.nix's deployment
block — xdg.configFile (nvim/zellij/zsh/git/ghostty/direnv),
home.activation.sshConfig, home.file.".zshenv". The 'dotfiles'
let-binding (= $HOME/.local/share/dotfiles) and 'link' helper move
here too, since they're vm-only now.
Host runbook unchanged (`just sync`); first run after pulling will
just be a no-op nix-switch instead of a backup-file storm.
Diffstat (limited to 'nix/vm.nix')
| -rw-r--r-- | nix/vm.nix | 63 |
1 files changed, 57 insertions, 6 deletions
@@ -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 |
