Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions home-manager/programs/cass/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
...
}:
{
# Clean up the hydrate.sh output before linkGeneration so it doesn't
# block the next nix-switch.
home.activation.cassSourcesCleanup = config.lib.dag.entryBefore [ "linkGeneration" ] ''
$DRY_RUN_CMD ${pkgs.bash}/bin/bash -c '
if [ -f "${config.home.homeDirectory}/.config/cass/sources.toml" ]; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Darwin path missed. hydrate.sh:37-41 selects ~/Library/Application Support/cass/sources.toml on Darwin and ~/.config/cass/sources.toml elsewhere, and this module is imported unconditionally (home-manager/programs/default.nix:11). The cleanup hard-codes the Linux path, so on macOS it never fires. Today this is defensive-only (sources.toml isn't declared in home.file anywhere I could find), but it does mean the migration case the hydrate.sh comment calls out ("Older generations symlinked this file into the Nix store; replace it.") is only handled on Linux.

Consider selecting the path from Nix, e.g.:

let
  sourcesFile =
    if pkgs.stdenv.isDarwin then
      "${config.home.homeDirectory}/Library/Application Support/cass/sources.toml"
    else
      "${config.home.homeDirectory}/.config/cass/sources.toml";
in

rm -f "${config.home.homeDirectory}/.config/cass/sources.toml"
fi
'
'';

# sources.toml is hydrated at activation so each machine can drop itself from
# the peer list using its runtime hostname.
home.activation.hydrateCassSources = config.lib.dag.entryAfter [ "writeBoundary" ] ''
Expand Down
13 changes: 13 additions & 0 deletions home-manager/services/hermes/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ let
hermesNode = pkgs.nodejs_22;
in
lib.mkIf host.isKyber {
# Clean up writable copies that Hermes activate.sh creates (replacing Nix-managed
# symlinks) so they don't block the next nix-switch's linkGeneration.
home.activation.hermesCleanup = config.lib.dag.entryBefore [ "linkGeneration" ] ''

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleanup can be scheduled before writeBoundary/checkLinkTargets.

lib.hm.dag.entryBefore x is defined as entryBetween x [ ] (see modules/lib/dag.nix), so there is no constraint tying this entry to run after writeBoundary. Home-manager's own convention (home.activation docs) is: "If the script block produces any observable side effect … it must be placed after the special writeBoundary script block."

Why this matters here: checkLinkTargets runs entryBefore [ "writeBoundary" ] and only tolerates an existing non-symlink at a target path when cmp -s finds the content identical to the store version. activate.sh currently writes back the byte-identical content via printf '%s\n' "$content", so checkLinkTargets happens to pass today. The first time any of the three hermes units gets a Nix-side change (Environment=, ExecStart=, etc.), the writable copy on disk will differ from the new store version, checkLinkTargets will abort activation — and if the DAG has scheduled this cleanup after checkLinkTargets, the cleanup never runs and the switch is blocked exactly as this PR is trying to prevent.

Suggested fix (also applies to cassSourcesCleanup):

home.activation.hermesCleanup = config.lib.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
  ...
'';
Suggested change
home.activation.hermesCleanup = config.lib.dag.entryBefore [ "linkGeneration" ] ''
home.activation.hermesCleanup = config.lib.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''

$DRY_RUN_CMD ${pkgs.bash}/bin/bash -c '
for f in hermes-gateway.service hermes-dashboard.service hermes-dashboard-proxy.service; do
unit="${homeDir}/.config/systemd/user/$f"
if [ -f "$unit" ] && [ ! -L "$unit" ]; then
rm -f "$unit"
fi
done
'
'';

home.activation.hermesSetup = config.lib.dag.entryAfter [ "writeBoundary" ] ''
$DRY_RUN_CMD ${pkgs.bash}/bin/bash "${./activate.sh}" "${homeDir}" "${hermesNode}/bin/npm"
'';
Expand Down
Loading