-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstandalone-wait-online.nix
147 lines (135 loc) · 4.53 KB
/
standalone-wait-online.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
{ config, options, lib, pkgs, utils, ... }:
let
inherit (builtins) toString map;
inherit (lib) types;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf;
inherit (lib.lists) optional;
opt = options.standalone-network-wait-online;
cfg = config.standalone-network-wait-online;
in
{
options.standalone-network-wait-online = {
enable = mkEnableOption "Enable the Standalone wait-online service";
pkg = mkOption {
type = types.package;
default = pkgs.wait-online;
description = lib.mDoc ''
wait-online package to use.
'';
};
requiredInterfaces = mkOption {
description = lib.mdDoc ''
Network interfaces to be required when deciding if the system is online.
Can't be combined with `ignoredInterfaces`.
'';
type = with types; listOf str;
default = [ ];
example = [ "enp2s0" ];
};
ignoredInterfaces = mkOption {
description = lib.mdDoc ''
Network interfaces to be ignored when deciding if the system is online.
Can't be combined with `requiredInterfaces`.
'';
type = with types; listOf str;
default = [ ];
example = [ "enp2s0" ];
};
requireIpv4 = mkOption {
description = lib.mdDoc ''
Whether to require an IPv4 address for an interface to be considered online.
'';
type = types.bool;
default = false;
};
requireIpv6 = mkOption {
description = lib.mdDoc ''
Whether to require an IPv4 address for an interface to be considered online.
'';
type = types.bool;
default = false;
};
anyInterface = mkOption {
description = lib.mdDoc ''
Whether to consider the network online when any interface is online, as opposed to all of them.
This is useful on portable machines with a wired and a wireless interface, for example.
'';
type = types.bool;
default = false;
};
timeout = mkOption {
description = lib.mdDoc ''
Time to wait for the network to come online, in seconds. Set to 0 to disable.
'';
type = types.ints.unsigned;
default = 120;
example = 0;
};
interval = mkOption {
description = lib.mdDoc ''
Time between checks to see if the network is online (in ms).
Must be between 10 and 10000.
'';
type = types.ints.unsigned;
example = 50;
};
extraArgs = mkOption {
description = lib.mdDoc ''
Extra command-line arguments to pass to standalone-network-wait-online.
'';
type = with types; listOf str;
default = [ ];
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = !config.systemd.network.wait-online.enable || !config.networking.networkmanager.enable;
message = ''
`standalone-network-wait-online` is not meant for use in combination with `systemd.network.wait-online` or `networking.networkmanager`
'';
}
{
assertion = !(cfg.requiredInterfaces != [ ] && cfg.ignoredInterfaces != [ ]);
message = ''
standalone-network-wait-online.ignoredInterfaces and standalone-network-wait-online.ignoredInterfaces
can't be used at the same time
'';
}
{
assertion = !opt.interval.isDefined || (10 <= cfg.interval && cfg.interval >= 10000);
message = ''
standalone-network-wait-online.interval must be between 10 and 10000 milliseconds
'';
}
];
standalone-network-wait-online.extraArgs = [ "--timeout=${toString cfg.timeout}" ]
++ optional opt.interval.isDefined "--interval=${toString cfg.interval}"
++ optional cfg.anyInterface "--any"
++ optional cfg.requireIpv6 "--ipv6"
++ optional cfg.requireIpv4 "--ipv4"
++ map (i: "--ignore=${i}") cfg.ignoredInterfaces
++ map (i: "--interface=${i}") cfg.requiredInterfaces;
systemd.services."network-standalone-wait-online" = {
enable = true;
# [Unit]
description = "Wait for Network to be Configured";
conflicts = [ "shutdown.target" ];
bindsTo = [ "network.target" ];
after = [ "network.target" ];
before = [ "network-online.target" "shutdown.target" ];
unitConfig = {
DefaultDependencies = "no";
};
# [Service]
serviceConfig = {
Type = "oneshot";
ExecStart = "${cfg.pkg}/bin/wait-online ${utils.escapeSystemdExecArgs cfg.extraArgs}";
RemainAfterExit = "yes";
};
# [Install]
wantedBy = [ "network-online.target" ];
};
};
}