network-link-*.service: Set stopIfChanged = false

This reduces the time window during which IP addresses are gone during
switch-to-configuration. A complication is that with stopIfChanged =
true, preStop would try to delete the *new* IP addresses rather than
the old one (since the preStop script now runs after the switch to the
new configuration). So we now record the actually configured addresses
in /run/nixos/network/addresses/<interface>. This is more robust in
any case.

Issue https://github.com/NixOS/nixops/issues/640.

+20 -13
+1 -1
nixos/modules/security/polkit.nix
··· 64 systemd.packages = [ pkgs.polkit.out ]; 65 66 systemd.services.polkit.restartTriggers = [ config.system.path ]; 67 - systemd.services.polkit.unitConfig.X-StopIfChanged = false; 68 69 # The polkit daemon reads action/rule files 70 environment.pathsToLink = [ "/share/polkit-1" ];
··· 64 systemd.packages = [ pkgs.polkit.out ]; 65 66 systemd.services.polkit.restartTriggers = [ config.system.path ]; 67 + systemd.services.polkit.stopIfChanged = false; 68 69 # The polkit daemon reads action/rule files 70 environment.pathsToLink = [ "/share/polkit-1" ];
+19 -12
nixos/modules/tasks/network-interfaces-scripted.nix
··· 159 after = [ "network-pre.target" ] ++ (deviceDependency i.name); 160 serviceConfig.Type = "oneshot"; 161 serviceConfig.RemainAfterExit = true; 162 path = [ pkgs.iproute ]; 163 script = 164 '' 165 echo "bringing up interface..." 166 ip link set "${i.name}" up 167 168 - restart_network_interfaces=false 169 '' + flip concatMapStrings (ips) (ip: 170 let 171 address = "${ip.address}/${toString ip.prefixLength}"; 172 in 173 '' 174 - echo "checking ip ${address}..." 175 if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then 176 - echo "added ip ${address}..." 177 elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then 178 echo "failed to add ${address}" 179 exit 1 180 fi 181 ''); 182 - preStop = flip concatMapStrings (ips) (ip: 183 - let 184 - address = "${ip.address}/${toString ip.prefixLength}"; 185 - in 186 - '' 187 - echo -n "deleting ${address}..." 188 - ip addr del "${address}" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed" 189 - echo "" 190 - ''); 191 }; 192 193 createTunDevice = i: nameValuePair "${i.name}-netdev"
··· 159 after = [ "network-pre.target" ] ++ (deviceDependency i.name); 160 serviceConfig.Type = "oneshot"; 161 serviceConfig.RemainAfterExit = true; 162 + # Restart rather than stop+start this unit to prevent the 163 + # network from dying during switch-to-configuration. 164 + stopIfChanged = false; 165 path = [ pkgs.iproute ]; 166 script = 167 '' 168 + # FIXME: shouldn't this be done in network-link? 169 echo "bringing up interface..." 170 ip link set "${i.name}" up 171 172 + state="/run/nixos/network/addresses/${i.name}" 173 + 174 + mkdir -p $(dirname "$state") 175 + 176 '' + flip concatMapStrings (ips) (ip: 177 let 178 address = "${ip.address}/${toString ip.prefixLength}"; 179 in 180 '' 181 + echo "${address}" >> $state 182 if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then 183 + echo "added ip ${address}" 184 elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then 185 echo "failed to add ${address}" 186 exit 1 187 fi 188 ''); 189 + preStop = '' 190 + state="/run/nixos/network/addresses/${i.name}" 191 + while read address; do 192 + echo -n "deleting $address..." 193 + ip addr del "$address" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed" 194 + echo "" 195 + done < "$state" 196 + rm -f "$state" 197 + ''; 198 }; 199 200 createTunDevice = i: nameValuePair "${i.name}-netdev"