diff options
| author | Ben Sima <ben@bensima.com> | 2025-12-25 21:51:43 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-12-25 21:51:43 -0500 |
| commit | abdace209323b65f6c5db1bf553ede1f60da00cc (patch) | |
| tree | fd253f652d0e77838e9196ee9890cef94547bcdb /Omni/Deploy | |
| parent | 5e9cb8c4983f6cdd05568029e9c233202d01c9bf (diff) | |
Omni/Deploy: add WorkingDirectory support and rename to deployer
- Add execWorkingDirectory field to Exec type in Manifest.hs
- Generate WorkingDirectory= in systemd unit files
- Allow add-service to update existing services
- Rename biz-deployer to deployer throughout
- Fix Caddy.hs and Systemd.hs tests for new Exec constructor
This fixes subagent stalls caused by Coder running direnv from wrong directory.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'Omni/Deploy')
| -rw-r--r-- | Omni/Deploy/Caddy.hs | 2 | ||||
| -rw-r--r-- | Omni/Deploy/Deployer.hs | 16 | ||||
| -rw-r--r-- | Omni/Deploy/Deployer.nix | 6 | ||||
| -rw-r--r-- | Omni/Deploy/Manifest.hs | 15 | ||||
| -rw-r--r-- | Omni/Deploy/Systemd.hs | 11 |
5 files changed, 30 insertions, 20 deletions
diff --git a/Omni/Deploy/Caddy.hs b/Omni/Deploy/Caddy.hs index 6cedf92..72b1d43 100644 --- a/Omni/Deploy/Caddy.hs +++ b/Omni/Deploy/Caddy.hs @@ -194,7 +194,7 @@ mkTestService name path http = { serviceName = name, serviceArtifact = Artifact "nix-closure" path, serviceHosts = ["biz"], - serviceExec = Exec Nothing "root" "root", + serviceExec = Exec Nothing "root" "root" Nothing, serviceEnv = mempty, serviceEnvFile = Nothing, serviceHttp = http, diff --git a/Omni/Deploy/Deployer.hs b/Omni/Deploy/Deployer.hs index 7e57b34..bfeb1a9 100644 --- a/Omni/Deploy/Deployer.hs +++ b/Omni/Deploy/Deployer.hs @@ -12,7 +12,7 @@ -- Polls manifest from S3, compares to local state, pulls changed closures, -- generates systemd units, updates Caddy routes, and manages GC roots. -- --- : out biz-deployer +-- : out deployer -- : dep aeson -- : dep amazonka -- : dep amazonka-core @@ -61,7 +61,7 @@ import System.FilePath ((</>)) import qualified System.Process as Process stateDir :: FilePath -stateDir = "/var/lib/biz-deployer" +stateDir = "/var/lib/deployer" stateFile :: FilePath stateFile = stateDir </> "state.json" @@ -243,14 +243,14 @@ runDaemon intervalSeconds = do help :: Cli.Docopt help = [Cli.docopt| -biz-deployer - Mini-PaaS deployment agent +deployer - Mini-PaaS deployment agent Usage: - biz-deployer test - biz-deployer once - biz-deployer daemon [<interval>] - biz-deployer status - biz-deployer (-h | --help) + deployer test + deployer once + deployer daemon [<interval>] + deployer status + deployer (-h | --help) Commands: test Run tests diff --git a/Omni/Deploy/Deployer.nix b/Omni/Deploy/Deployer.nix index 54a8f6c..ed4241e 100644 --- a/Omni/Deploy/Deployer.nix +++ b/Omni/Deploy/Deployer.nix @@ -12,7 +12,7 @@ in { package = lib.mkOption { type = lib.types.package; - description = "The biz-deployer package to use"; + description = "The deployer package to use"; }; manifestPackage = lib.mkOption { @@ -28,7 +28,7 @@ in { stateDir = lib.mkOption { type = lib.types.path; - default = "/var/lib/biz-deployer"; + default = "/var/lib/deployer"; description = "Directory for deployer state and generated unit files"; }; @@ -69,7 +69,7 @@ in { serviceConfig = { Type = "oneshot"; - ExecStart = "${cfg.package}/bin/biz-deployer once"; + ExecStart = "${cfg.package}/bin/deployer once"; Environment = [ "HOME=/root" "AWS_SHARED_CREDENTIALS_FILE=/root/.aws/credentials" diff --git a/Omni/Deploy/Manifest.hs b/Omni/Deploy/Manifest.hs index e0d0b78..532ec4c 100644 --- a/Omni/Deploy/Manifest.hs +++ b/Omni/Deploy/Manifest.hs @@ -85,7 +85,8 @@ instance Aeson.ToJSON Artifact where data Exec = Exec { execCommand :: Maybe Text, execUser :: Text, - execGroup :: Text + execGroup :: Text, + execWorkingDirectory :: Maybe Text } deriving (Show, Eq, Generic) @@ -100,17 +101,19 @@ instance Aeson.FromJSON Exec where <*> o .:? "group" .!= "root" + <*> (o .:? "workingDirectory") instance Aeson.ToJSON Exec where toJSON Exec {..} = Aeson.object [ "command" .= execCommand, "user" .= execUser, - "group" .= execGroup + "group" .= execGroup, + "workingDirectory" .= execWorkingDirectory ] defaultExec :: Exec -defaultExec = Exec Nothing "root" "root" +defaultExec = Exec Nothing "root" "root" Nothing data Http = Http { httpDomain :: Text, @@ -507,8 +510,10 @@ move args m <- maybe createEmptyManifest pure manifest case findService (serviceName svc) m of Just _ -> do - Log.fail ["manifest", "service already exists:", serviceName svc] - Exit.exitWith (Exit.ExitFailure 1) + -- Replace existing service + let updated = m {manifestServices = map (\s -> if serviceName s == serviceName svc then svc else s) (manifestServices m)} + saveManifestToS3 updated + Log.good ["manifest", "updated service", serviceName svc] Nothing -> do let newManifest = m {manifestServices = manifestServices m ++ [svc]} saveManifestToS3 newManifest diff --git a/Omni/Deploy/Systemd.hs b/Omni/Deploy/Systemd.hs index b47776a..8c6d416 100644 --- a/Omni/Deploy/Systemd.hs +++ b/Omni/Deploy/Systemd.hs @@ -31,7 +31,7 @@ import System.FilePath ((</>)) import qualified System.Process as Process servicesDir :: FilePath -servicesDir = "/var/lib/biz-deployer/services" +servicesDir = "/var/lib/deployer/services" generateUnit :: Service -> Text generateUnit Service {..} = @@ -60,9 +60,14 @@ generateUnit Service {..} = "Restart=" <> systemdRestart serviceSystemd, "RestartSec=" <> tshow (systemdRestartSec serviceSystemd) ] + ++ workingDirLine ++ envLines ++ envFileLine + workingDirLine = case execWorkingDirectory serviceExec of + Nothing -> [] + Just dir -> ["WorkingDirectory=" <> dir] + envLines = Map.toList serviceEnv |> map (\(k, v) -> "Environment=\"" <> k <> "=" <> v <> "\"") @@ -193,7 +198,7 @@ mkTestService name path = { serviceName = name, serviceArtifact = Artifact "nix-closure" path, serviceHosts = ["biz"], - serviceExec = Exec Nothing "root" "root", + serviceExec = Exec Nothing "root" "root" Nothing, serviceEnv = mempty, serviceEnvFile = Nothing, serviceHttp = Nothing, @@ -230,7 +235,7 @@ test_generateUnitWithCustomExec = Test.unit "generates unit with custom exec" <| do let svc = (mkTestService "custom-exec" "/nix/store/abc") - { serviceExec = Exec (Just "my-binary") "www-data" "www-data" + { serviceExec = Exec (Just "my-binary") "www-data" "www-data" Nothing } unit = generateUnit svc Text.isInfixOf "ExecStart=/nix/store/abc/bin/my-binary" unit Test.@=? True |
