Skip to content

Commit 18c5cff

Browse files
MartinNikovPetarKirov
authored andcommitted
config(modules/nimbus-eth2): Add argsFromFile option
1 parent 8c3a22b commit 18c5cff

File tree

3 files changed

+196
-142
lines changed

3 files changed

+196
-142
lines changed

modules/nimbus-eth2/default.nix

Lines changed: 29 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,18 @@
66
}: let
77
modulesLib = import ../lib.nix lib;
88

9-
inherit (lib.lists) findFirst sublist last;
10-
inherit (lib.strings) hasPrefix;
9+
serviceArgs =
10+
lib.mapAttrs (
11+
beaconName: let
12+
serviceName = "nimbus-eth2";
13+
in
14+
cfg: ((import ./service-args.nix {inherit lib pkgs;}).argsCreate serviceName cfg)
15+
)
16+
eachBeacon;
17+
1118
inherit (lib.attrsets) zipAttrsWith;
12-
inherit
13-
(lib)
14-
concatStringsSep
15-
filterAttrs
16-
flatten
17-
mapAttrs'
18-
mapAttrsToList
19-
mkIf
20-
mkMerge
21-
nameValuePair
22-
types
23-
;
24-
inherit (modulesLib) mkArgs baseServiceConfig defaultArgReducer;
19+
inherit (lib) filterAttrs flatten mapAttrs' mapAttrsToList mkIf mkMerge nameValuePair;
20+
inherit (modulesLib) baseServiceConfig;
2521

2622
eachBeacon = config.services.ethereum.nimbus-eth2;
2723
in {
@@ -57,139 +53,29 @@ in {
5753
in
5854
zipAttrsWith (_name: flatten) perService;
5955

56+
environment = lib.mapAttrs' (beaconName: cfg:
57+
lib.nameValuePair "etc" {
58+
"ethereum/nimbus-${beaconName}-args" = let
59+
argsFromFile = cfg.argsFromFile;
60+
in
61+
lib.mkIf argsFromFile.enable {
62+
source = builtins.toFile "nimbus-${beaconName}-args" ''
63+
ARGS="${serviceArgs.${beaconName}.beaconNodeArgs}"
64+
'';
65+
group = argsFromFile.group;
66+
mode = argsFromFile.mode;
67+
};
68+
})
69+
eachBeacon;
70+
6071
systemd.services =
6172
mapAttrs'
6273
(
6374
beaconName: let
6475
serviceName = "nimbus-eth2";
6576
in
6677
cfg: let
67-
network =
68-
if cfg.args.network != null
69-
then "--network=${cfg.args.network}"
70-
else "";
71-
72-
jwtSecret =
73-
if cfg.args.jwt-secret != null
74-
then ''--jwt-secret="%d/jwt-secret"''
75-
else "";
76-
77-
keymanagerTokenFile =
78-
if cfg.args.keymanager.token-file != null
79-
then ''--keymanager-token-file="%d/keymanager-token-file"''
80-
else "";
81-
82-
trustedNodeUrl =
83-
if cfg.args.trusted-node-url != null
84-
then ''--trusted-node-url="${cfg.args.trusted-node-url}"''
85-
else "";
86-
87-
backfilling =
88-
if cfg.args.trusted-node-url != null
89-
then ''--backfill=${lib.boolToString cfg.args.backfill}''
90-
else "";
91-
92-
web3Url =
93-
if cfg.args.web3-urls != null
94-
then ''--web3-url=${concatStringsSep " --web3-url=" cfg.args.web3-urls}''
95-
else "";
96-
97-
web3SignerUrls = lib.pipe cfg.args.web3-signer-url [
98-
(builtins.map (x: "--web3-signer-url=${x}"))
99-
(builtins.concatStringsSep " ")
100-
];
101-
102-
payloadBuilder =
103-
if cfg.args.payload-builder.enable
104-
then "--payload-builder=true --payload-builder-url=${cfg.args.payload-builder.url}"
105-
else "";
106-
107-
dataDirPath = "%S/${serviceName}";
108-
dataDir = ''--data-dir="${dataDirPath}"'';
109-
110-
beaconNodeArgs = let
111-
# generate args
112-
args = let
113-
opts = import ./args.nix lib;
114-
115-
pathReducer = path: let
116-
p =
117-
if (last path == "enable")
118-
then sublist 0 ((builtins.length path) - 1) path
119-
else path;
120-
in "--${concatStringsSep "-" p}";
121-
122-
argFormatter = {
123-
opt,
124-
path,
125-
value,
126-
argReducer ? defaultArgReducer,
127-
pathReducer ? defaultArgReducer,
128-
}: let
129-
arg = pathReducer path;
130-
in
131-
if (opt.type == types.bool)
132-
then
133-
(
134-
if value
135-
then "${arg}"
136-
else ""
137-
)
138-
else "${arg}=${argReducer value}";
139-
in
140-
mkArgs {
141-
inherit opts;
142-
inherit (cfg) args;
143-
inherit argFormatter;
144-
inherit pathReducer;
145-
};
146-
# filter out certain args which need to be treated differently
147-
specialArgs = ["--network" "--jwt-secret" "--web3-urls" "--web3-signer-url" "--trusted-node-url" "--backfill" "--payload-builder" "--keymanager-token-file"];
148-
isNormalArg = name: (findFirst (arg: hasPrefix arg name) null specialArgs) == null;
149-
filteredArgs = builtins.filter isNormalArg args;
150-
in ''
151-
${network} ${jwtSecret} \
152-
${web3Url} \
153-
${web3SignerUrls} \
154-
${dataDir} \
155-
${keymanagerTokenFile} \
156-
${payloadBuilder} \
157-
${concatStringsSep " \\\n" filteredArgs} \
158-
${lib.escapeShellArgs cfg.extraArgs}
159-
'';
160-
161-
nodeSyncArgs = ''
162-
${network} \
163-
${trustedNodeUrl} \
164-
${backfilling}'';
165-
166-
binaryName =
167-
if cfg.args.network == "gnosis" || cfg.args.network == "chiado"
168-
then "${cfg.package}/bin/nimbus_beacon_node_gnosis"
169-
else "${cfg.package}/bin/nimbus_beacon_node";
170-
171-
# When running trustedNodeSync after passing once, it gives an error
172-
# and doesn't continue to execute execStart. The problem occurs when
173-
# the service is restarted and execStartPre runs again. So we check
174-
# for the existence of a file in the folder, and that way we know if
175-
# Nimbus is running for the first time or not.
176-
trustedNodeSync =
177-
if cfg.args.trusted-node-url != null
178-
then let
179-
script = pkgs.writeShellScript "trustedNodeSync.sh" ''
180-
datadir="$1"
181-
shift
182-
if [ -f "$datadir/db/nbc.sqlite3" ]; then
183-
echo "skipping trustedNodeSync";
184-
exit 0
185-
else
186-
echo "starting trustedNodeSync";
187-
set -x
188-
${binaryName} trustedNodeSync "$@"
189-
fi
190-
'';
191-
in "${script} ${dataDirPath} ${dataDir} ${nodeSyncArgs}"
192-
else null;
78+
inherit (serviceArgs."${beaconName}") trustedNodeSync execStartCommand;
19379
in
19480
nameValuePair serviceName (mkIf cfg.enable {
19581
after = ["network.target"];
@@ -202,8 +88,9 @@ in {
20288
{
20389
User = serviceName;
20490
StateDirectory = serviceName;
91+
EnvironmentFile = lib.mkIf cfg.argsFromFile.enable "/etc/ethereum/nimbus-${beaconName}-args";
20592
ExecStartPre = trustedNodeSync;
206-
ExecStart = ''${binaryName} ${beaconNodeArgs}'';
93+
ExecStart = execStartCommand;
20794
MemoryDenyWriteExecute = "false"; # causes a library loading error
20895
}
20996
(mkIf (cfg.args.jwt-secret != null) {

modules/nimbus-eth2/options.nix

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,22 @@
3030
description = lib.mdDoc "Open ports in the firewall for any enabled networking services";
3131
};
3232

33+
argsFromFile = {
34+
enable = mkEnableOption (mdDoc "Create a file in the etc directory from which arguments can be modified");
35+
group = mkOption {
36+
type = types.str;
37+
default = "";
38+
example = "devops";
39+
description = lib.mdDoc "Group which can modify the arguments file";
40+
};
41+
mode = mkOption {
42+
type = types.str;
43+
default = "0664";
44+
example = "0060";
45+
description = lib.mdDoc "Arguments file mode";
46+
};
47+
};
48+
3349
# mixin backup options
3450
backup = let
3551
inherit (import ../backup/lib.nix lib) options;
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
{
2+
lib,
3+
pkgs,
4+
...
5+
}: let
6+
modulesLib = import ../lib.nix lib;
7+
8+
inherit (lib.lists) findFirst sublist last;
9+
inherit (lib.strings) hasPrefix;
10+
inherit (lib) concatStringsSep types;
11+
inherit (modulesLib) mkArgs defaultArgReducer;
12+
in {
13+
argsCreate = serviceName: cfg: let
14+
network =
15+
if cfg.args.network != null
16+
then "--network=${cfg.args.network}"
17+
else "";
18+
19+
jwtSecret =
20+
if cfg.args.jwt-secret != null
21+
then ''--jwt-secret="%d/jwt-secret"''
22+
else "";
23+
24+
keymanagerTokenFile =
25+
if cfg.args.keymanager.token-file != null
26+
then ''--keymanager-token-file="%d/keymanager-token-file"''
27+
else "";
28+
29+
trustedNodeUrl =
30+
if cfg.args.trusted-node-url != null
31+
then ''--trusted-node-url="${cfg.args.trusted-node-url}"''
32+
else "";
33+
34+
backfilling =
35+
if cfg.args.trusted-node-url != null
36+
then ''--backfill=${lib.boolToString cfg.args.backfill}''
37+
else "";
38+
39+
web3Url =
40+
if cfg.args.web3-urls != null
41+
then ''--web3-url=${concatStringsSep " --web3-url=" cfg.args.web3-urls}''
42+
else "";
43+
44+
web3SignerUrls = lib.pipe cfg.args.web3-signer-url [
45+
(builtins.map (x: "--web3-signer-url=${x}"))
46+
(builtins.concatStringsSep " ")
47+
];
48+
49+
payloadBuilder =
50+
if cfg.args.payload-builder.enable
51+
then "--payload-builder=true --payload-builder-url=${cfg.args.payload-builder.url}"
52+
else "";
53+
54+
dataDirPath = "%S/${serviceName}";
55+
dataDir = ''--data-dir="${dataDirPath}"'';
56+
in rec {
57+
beaconNodeArgs = let
58+
# generate args
59+
args = let
60+
opts = import ./args.nix lib;
61+
62+
pathReducer = path: let
63+
p =
64+
if (last path == "enable")
65+
then sublist 0 ((builtins.length path) - 1) path
66+
else path;
67+
in "--${concatStringsSep "-" p}";
68+
69+
argFormatter = {
70+
opt,
71+
path,
72+
value,
73+
argReducer ? defaultArgReducer,
74+
pathReducer ? defaultArgReducer,
75+
}: let
76+
arg = pathReducer path;
77+
in
78+
if (opt.type == types.bool)
79+
then
80+
(
81+
if value
82+
then "${arg}"
83+
else ""
84+
)
85+
else "${arg}=${argReducer value}";
86+
in
87+
mkArgs {
88+
inherit opts;
89+
inherit (cfg) args;
90+
inherit argFormatter;
91+
inherit pathReducer;
92+
};
93+
# filter out certain args which need to be treated differently
94+
specialArgs = ["--network" "--jwt-secret" "--web3-urls" "--web3-signer-url" "--trusted-node-url" "--backfill" "--payload-builder" "--keymanager-token-file"];
95+
isNormalArg = name: (findFirst (arg: hasPrefix arg name) null specialArgs) == null;
96+
filteredArgs = builtins.filter isNormalArg args;
97+
in ''
98+
${network} \
99+
${web3Url} \
100+
${web3SignerUrls} \
101+
${payloadBuilder} \
102+
${concatStringsSep " \\\n" filteredArgs} \
103+
${lib.escapeShellArgs cfg.extraArgs}
104+
'';
105+
106+
systemdPathsArgs = ''
107+
${jwtSecret} \
108+
${dataDir} \
109+
${keymanagerTokenFile} \
110+
'';
111+
112+
nodeSyncArgs = ''
113+
${network} \
114+
${trustedNodeUrl} \
115+
${backfilling}
116+
'';
117+
118+
binaryName =
119+
if cfg.args.network == "gnosis" || cfg.args.network == "chiado"
120+
then "${cfg.package}/bin/nimbus_beacon_node_gnosis"
121+
else "${cfg.package}/bin/nimbus_beacon_node";
122+
123+
# When running trustedNodeSync after passing once, it gives an error
124+
# and doesn't continue to execute execStart. The problem occurs when
125+
# the service is restarted and execStartPre runs again. So we check
126+
# for the existence of a file in the folder, and that way we know if
127+
# Nimbus is running for the first time or not.
128+
trustedNodeSync =
129+
if cfg.args.trusted-node-url != null
130+
then let
131+
script = pkgs.writeShellScript "trustedNodeSync.sh" ''
132+
datadir="$1"
133+
shift
134+
if [ -f "$datadir/db/nbc.sqlite3" ]; then
135+
echo "skipping trustedNodeSync";
136+
exit 0
137+
else
138+
echo "starting trustedNodeSync";
139+
set -x
140+
${binaryName} trustedNodeSync "$@"
141+
fi
142+
'';
143+
in "${script} ${dataDirPath} ${dataDir} ${nodeSyncArgs}"
144+
else null;
145+
146+
execStartCommand =
147+
if cfg.argsFromFile.enable
148+
then ''${binaryName} ${systemdPathsArgs} $ARGS''
149+
else ''${binaryName} ${systemdPathsArgs} ${beaconNodeArgs}'';
150+
};
151+
}

0 commit comments

Comments
 (0)