summaryrefslogtreecommitdiff
path: root/Omni/Deploy/Systemd.hs
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-12-26 10:57:03 -0500
committerBen Sima <ben@bensima.com>2025-12-26 10:57:03 -0500
commit0e7cc8d0970c24cf24c0e3be221427981a799efb (patch)
tree43f46aa1fb4dbe076bbdcddceef871b695d08b0a /Omni/Deploy/Systemd.hs
parent7c63dca29cfe6c2e402d917efedfb426fb3b8fe6 (diff)
fix UTF-8 encoding in deployed services
- Systemd.hs: add LANG and LC_ALL defaults (en_US.utf8) to all generated unit files to ensure proper UTF-8 handling - Systemd.hs: add generateUnitWithLocale that reads LOCALE_ARCHIVE from the deployer's environment and injects it into generated units - Telegram.hs: add safePutText wrapper that catches encoding errors in logging to prevent them from killing message sends The root cause was NixOS systemd services not inheriting locale settings from the system, causing emoji characters to fail encoding. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'Omni/Deploy/Systemd.hs')
-rw-r--r--Omni/Deploy/Systemd.hs23
1 files changed, 21 insertions, 2 deletions
diff --git a/Omni/Deploy/Systemd.hs b/Omni/Deploy/Systemd.hs
index 8c6d416..99d4820 100644
--- a/Omni/Deploy/Systemd.hs
+++ b/Omni/Deploy/Systemd.hs
@@ -8,6 +8,7 @@
-- : dep directory
module Omni.Deploy.Systemd
( generateUnit,
+ generateUnitWithLocale,
writeUnit,
createSymlink,
reloadAndRestart,
@@ -27,12 +28,24 @@ import qualified Data.Text.IO as Text.IO
import Omni.Deploy.Manifest (Artifact (..), Exec (..), Hardening (..), Service (..), Systemd (..))
import qualified Omni.Test as Test
import qualified System.Directory as Dir
+import System.Environment (lookupEnv)
import System.FilePath ((</>))
import qualified System.Process as Process
servicesDir :: FilePath
servicesDir = "/var/lib/deployer/services"
+-- | Generate unit with locale settings from the current environment.
+-- This reads LOCALE_ARCHIVE at generation time and injects it into the unit.
+generateUnitWithLocale :: Service -> IO Text
+generateUnitWithLocale svc = do
+ maybeLocaleArchive <- lookupEnv "LOCALE_ARCHIVE"
+ let localeEnv = case maybeLocaleArchive of
+ Just path -> Map.singleton "LOCALE_ARCHIVE" (Text.pack path)
+ Nothing -> mempty
+ svcWithLocale = svc {serviceEnv = Map.union (serviceEnv svc) localeEnv}
+ pure (generateUnit svcWithLocale)
+
generateUnit :: Service -> Text
generateUnit Service {..} =
Text.unlines <| unitSection ++ serviceSection ++ hardeningSection ++ installSection
@@ -69,9 +82,15 @@ generateUnit Service {..} =
Just dir -> ["WorkingDirectory=" <> dir]
envLines =
- Map.toList serviceEnv
+ Map.toList envWithLocale
|> map (\(k, v) -> "Environment=\"" <> k <> "=" <> v <> "\"")
+ -- Add locale settings for NixOS if not already set
+ envWithLocale =
+ Map.insertWith (\_ old -> old) "LANG" "en_US.utf8"
+ <| Map.insertWith (\_ old -> old) "LC_ALL" "en_US.utf8"
+ <| serviceEnv
+
envFileLine = case serviceEnvFile of
Nothing -> []
Just path -> ["EnvironmentFile=" <> path]
@@ -104,7 +123,7 @@ writeUnit :: FilePath -> Service -> IO FilePath
writeUnit baseDir svc = do
Dir.createDirectoryIfMissing True baseDir
let path = baseDir </> Text.unpack (serviceName svc) <> ".service"
- content = generateUnit svc
+ content <- generateUnitWithLocale svc
Text.IO.writeFile path content
pure path