From 5e9cb8c4983f6cdd05568029e9c233202d01c9bf Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Thu, 25 Dec 2025 19:35:47 -0500 Subject: Omni/Deploy/Systemd: fix extractStorePath parsing bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function was incorrectly extracting store paths from ExecStart lines. For "ExecStart=/nix/store/xxx/bin/ava" it would return "/nix/store/nix" instead of "/nix/store/xxx". This caused the deployer to think services needed redeployment on every cycle, restarting them every 5 minutes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- Omni/Deploy/Systemd.hs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'Omni') diff --git a/Omni/Deploy/Systemd.hs b/Omni/Deploy/Systemd.hs index ee337bb..b47776a 100644 --- a/Omni/Deploy/Systemd.hs +++ b/Omni/Deploy/Systemd.hs @@ -158,16 +158,22 @@ getRunningStorePath serviceName' = do content <- Text.IO.readFile unitPath pure <| extractStorePath content where - -- Extract /nix/store/...-service-name from ExecStart=/nix/store/.../bin/... + -- Extract /nix/store/xxx-name from ExecStart=/nix/store/xxx-name/bin/... extractStorePath content = - content - |> Text.lines - |> find (Text.isPrefixOf "ExecStart=") - |> fmap (Text.drop (Text.length "ExecStart=")) - |> fmap (Text.dropWhile (/= '/')) - |> fmap (Text.drop 1) - |> fmap (Text.takeWhile (/= '/')) - |> fmap ("/nix/store/" <>) + case find (Text.isPrefixOf "ExecStart=") (Text.lines content) of + Nothing -> Nothing + Just line -> + let cmd = Text.drop (Text.length "ExecStart=") line + in extractNixStorePath cmd + + -- Extract store path up to /bin/ or end + extractNixStorePath :: Text -> Maybe Text + extractNixStorePath t + | "/nix/store/" `Text.isPrefixOf` t = + let afterStore = Text.drop 11 t -- drop "/nix/store/" + hashAndName = Text.takeWhile (/= '/') afterStore + in Just ("/nix/store/" <> hashAndName) + | otherwise = Nothing test :: Test.Tree test = -- cgit v1.2.3