Skip to content

Commit 9a031b7

Browse files
authored
Merge pull request #583 from hercules-ci/add-config-nixSettings
hercules-ci-agent: Add nixSettings config item
2 parents c3841d8 + d096081 commit 9a031b7

9 files changed

Lines changed: 94 additions & 12 deletions

File tree

docs/modules/ROOT/pages/agent-config.adoc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,23 @@ Optional. Control the importance threshold for messages are logged to the system
185185

186186
Defaults to `"InfoS"`. More verbose: `"DebugS"`, less verbose: `"WarningS"`, `"ErrorS"`.
187187

188+
[[nixSettings]]
189+
== nixSettings
190+
191+
Since hercules-ci-agent 0.10.2
192+
193+
Optional. A key-value map of Nix settings.
194+
195+
Nix interprets keys that start with `extra-` as additions to the existing (e.g. system) value. However, `nixSettings` is unordered, so make sure to use `extra-${x}` or plain `${x}`, but not both.
196+
197+
Example, to ignore other system caches:
198+
199+
```json
200+
"nixSettings": {
201+
"substituters": "https://cache.nixos.org"
202+
}
203+
```
204+
188205
[[nixVerbosity]]
189206
== nixVerbosity
190207

hercules-ci-agent/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## Unreleased
9+
10+
### Added
11+
12+
- Add `nixSettings` configuration item, to more easily configure Nix settings such as `substituters`, overriding the system Nix settings.
13+
814
## [0.10.1] - 2024-02-12
915

1016
### Changed

hercules-ci-agent/hercules-ci-agent/Hercules/Agent/Config.hs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import Data.Aeson.Types qualified as A
2525
import Data.Profunctor (Star (Star))
2626
import GHC.Conc (getNumProcessors)
2727
import Hercules.Agent.Config.Combined
28-
import Hercules.Agent.Config.Json as Json
28+
import Hercules.Agent.Config.Json (GCodec (GCodec), (.=.))
29+
import Hercules.Agent.Config.Json qualified as Json
2930
import Hercules.Agent.Config.Toml qualified as Toml
3031
import Hercules.CNix.Verbosity (Verbosity (..))
3132
import Hercules.Formats.Mountable (Mountable (Mountable))
@@ -72,7 +73,8 @@ data Config purpose = Config
7273
labels :: Item purpose 'Required (Map Text A.Value),
7374
allowInsecureBuiltinFetchers :: Item purpose 'Required Bool,
7475
remotePlatformsWithSameFeatures :: Item purpose 'Optional [Text],
75-
effectMountables :: Map Text Mountable
76+
effectMountables :: Map Text Mountable,
77+
nixSettings :: Map Text Text
7678
}
7779
deriving (Generic)
7880

@@ -120,6 +122,9 @@ combiCodec =
120122
(Json.tableMap' (forJson mountableCodec) "effectMountables")
121123
)
122124
.=. effectMountables
125+
<*> optEmpty
126+
(tableMap textAtKey "nixSettings")
127+
.=. nixSettings
123128

124129
mountableCodec :: Combi' Mountable
125130
mountableCodec =
@@ -233,5 +238,6 @@ finalizeConfig loc input = do
233238
labels = fromMaybe mempty $ labels input,
234239
allowInsecureBuiltinFetchers = fromMaybe False $ allowInsecureBuiltinFetchers input,
235240
remotePlatformsWithSameFeatures = remotePlatformsWithSameFeatures input,
236-
effectMountables = effectMountables input
241+
effectMountables = effectMountables input,
242+
nixSettings = nixSettings input
237243
}

hercules-ci-agent/hercules-ci-agent/Hercules/Agent/Config/Combined.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ optEmpty c = dimap Just (fromMaybe mempty) (opt c)
4646

4747
enumBoundedAtKey :: (Bounded a, Enum a, Show a) => Key -> Combi' a
4848
enumBoundedAtKey k = Combi (Data.Bifunctor.Product.Pair (Toml.enumBounded k) (Json.enumBounded k))
49+
50+
tableMap :: (Key -> Combi' a) -> Key -> Combi' (Map Text a)
51+
tableMap c k = Combi $ Pair (Toml.tableMap Toml._KeyText (forToml . c) k) (Json.tableMap (forJson . c) k)

hercules-ci-agent/hercules-ci-agent/Hercules/Agent/Config/Json.hs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import Toml hiding
3939
dimap,
4040
first,
4141
match,
42+
tableMap,
4243
_EnumBounded,
4344
_Text,
4445
_TextBy,
@@ -250,12 +251,30 @@ tableMap' ::
250251
Key ->
251252
JsonCodec' (Map Text v)
252253
tableMap' valCodec key =
254+
tableMap
255+
( \k ->
256+
GCodec
257+
{ gRead =
258+
local
259+
(\v -> fromMaybe (panic "tableMap': key disappeared") (v ^? at' k))
260+
(gRead valCodec),
261+
gWrite = do
262+
panic "tableMap': write not implemented"
263+
}
264+
)
265+
key
266+
267+
tableMap ::
268+
(Key -> JsonCodec' v) ->
269+
Key ->
270+
JsonCodec' (Map Text v)
271+
tableMap valCodec key =
253272
let c = match (prismWithError "JSON Object expected" (Aeson.Lens._Object . aesonMap)) key
254273
in GCodec
255274
{ gRead = do
256275
x <- gRead c
257-
fmap M.fromList $ for (M.toList x) $ \(k, v) -> do
258-
v' <- local (const v) $ gRead valCodec
276+
fmap M.fromList $ for (M.toList x) $ \(k, _v) -> do
277+
v' <- gRead (valCodec (key <> (Key $ Piece k :| [])))
259278
pure (k, v'),
260279
gWrite = do
261280
panic "tableMap': write not implemented"

hercules-ci-agent/hercules-ci-agent/Hercules/Agent/Init.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ withEnv config logEnv f = do
4040
concPushes <- newMemo
4141
concQueries <- newMemo
4242
withLogging $ Hercules.Agent.Cachix.Init.withEnv config (BC.cachixCaches bcs) \cachix -> liftIO do
43-
nix <- Hercules.Agent.Nix.Init.newEnv
43+
nix <- Hercules.Agent.Nix.Init.newEnv config
4444
serviceInfo <- ServiceInfo.newEnv clientEnv
4545
let env =
4646
Env

hercules-ci-agent/hercules-ci-agent/Hercules/Agent/Nix/Init.hs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1+
{-# LANGUAGE DataKinds #-}
2+
13
module Hercules.Agent.Nix.Init where
24

5+
import Data.Map qualified as M
6+
import Hercules.Agent.Config (Config, Purpose (Final))
7+
import Hercules.Agent.Config qualified
38
import Hercules.Agent.EnvironmentInfo qualified as EnvironmentInfo
49
import Hercules.Agent.Nix.Env
10+
import Hercules.CNix qualified as CNix
511
import Protolude
612

7-
newEnv :: IO Env
8-
newEnv = do
13+
newEnv :: Config 'Final -> IO Env
14+
newEnv config = do
15+
for_ (M.toList config.nixSettings) $ \(k, v) -> do
16+
CNix.setGlobalOption k v
917
nixInfo <- EnvironmentInfo.getNixInfo
1018
when (EnvironmentInfo.nixNarinfoCacheNegativeTTL nixInfo /= 0) $ do
1119
putErrText
@@ -33,5 +41,5 @@ newEnv = do
3341
-- extraOptions here.
3442
pure
3543
Env
36-
{ extraOptions = []
44+
{ extraOptions = M.toList config.nixSettings
3745
}

hercules-ci-agent/test/Hercules/Agent/ConfigSpec.hs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ spec =
4545
"workDirectory = \"/var/lib/hercules-ci-agent/work\"",
4646
"remotePlatformsWithSameFeatures = [\"aarch64-darwin\"]",
4747
"nixVerbosity = \"vomit\"",
48+
"[nixSettings]",
49+
" substituters = \"https://example.com\"",
4850
-- This line should not be needed!
4951
"[effectMountables]",
5052
"[effectMountables.hosts]",
@@ -91,7 +93,8 @@ spec =
9193
condition = Hercules.Formats.Secret.Const True
9294
}
9395
)
94-
]
96+
],
97+
nixSettings = M.singleton "substituters" "https://example.com"
9598
}
9699
)
97100
it "parses empty config" $ do
@@ -119,6 +122,7 @@ spec =
119122
"\"secretsJsonPath\": \"/var/lib/hercules-ci-agent/secrets/secrets.json\",",
120123
"\"logLevel\": \"DebugS\",",
121124
"\"nixVerbosity\": \"Vomit\",",
125+
"\"nixSettings\": { \"substituters\": \"https://example.com\" },",
122126
"\"remotePlatformsWithSameFeatures\": [\"aarch64-darwin\"],",
123127
"\"labels\": {",
124128
" \"agent\": {\"source\": \"flake\"},",
@@ -169,7 +173,8 @@ spec =
169173
condition = Hercules.Formats.Secret.Const True
170174
}
171175
)
172-
]
176+
],
177+
nixSettings = M.singleton "substituters" "https://example.com"
173178
}
174179

175180
it "handles empty config" $ do
@@ -232,5 +237,6 @@ emptyConfig =
232237
labels = Nothing,
233238
allowInsecureBuiltinFetchers = Nothing,
234239
remotePlatformsWithSameFeatures = Nothing,
235-
effectMountables = mempty
240+
effectMountables = mempty,
241+
nixSettings = mempty
236242
}

internal/nix/settings.nix

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,23 @@ let
119119
internal = true;
120120
default = "Talkative";
121121
};
122+
nixSettings = mkOption {
123+
description = mdDoc ''
124+
Since hercules-ci-agent 0.10.2.
125+
126+
A key-value map of Nix settings.
127+
128+
Nix interprets keys that start with `extra-` as additions to the existing (e.g. system) value. However, `nixSettings` is unordered, so make sure to use `extra-''${x}` or plain `''${x}`, but not both.
129+
'';
130+
type = types.lazyAttrsOf types.str;
131+
default = { };
132+
example = lib.literalExpression ''
133+
{
134+
# ignore other system substituters
135+
substituters = "https://cache.nixos.org";
136+
};
137+
'';
138+
};
122139
remotePlatformsWithSameFeatures = mkOption {
123140
internal = true;
124141
default = [ ];

0 commit comments

Comments
 (0)