kexec: restore static ips after kexec
This commit is contained in:
parent
65227bf951
commit
985547acc6
2 changed files with 103 additions and 0 deletions
|
@ -29,6 +29,11 @@
|
||||||
for p in /etc/ssh/ssh_host_*; do
|
for p in /etc/ssh/ssh_host_*; do
|
||||||
cp -a "$p" ssh
|
cp -a "$p" ssh
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# save the networking config for later use
|
||||||
|
ip --json addr > addrs.json
|
||||||
|
ip --json route > routes.json
|
||||||
|
|
||||||
find | cpio -o -H newc | gzip -9 > ../extra.gz
|
find | cpio -o -H newc | gzip -9 > ../extra.gz
|
||||||
popd
|
popd
|
||||||
cat "''${SCRIPT_DIR}/initrd" extra.gz > final-initrd
|
cat "''${SCRIPT_DIR}/initrd" extra.gz > final-initrd
|
||||||
|
@ -76,14 +81,29 @@
|
||||||
# for detection if we are on kexec
|
# for detection if we are on kexec
|
||||||
environment.etc.is_kexec.text = "true";
|
environment.etc.is_kexec.text = "true";
|
||||||
|
|
||||||
|
systemd.services.restoreNetwork = {
|
||||||
|
path = [
|
||||||
|
pkgs.iproute2
|
||||||
|
];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
serviceConfig.ExecStart = "/run/current-system/sw/bin/restore_network /root/network/addrs.json /root/network/routes.json";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
(pkgs.writers.writePython3Bin "restore_network" { flakeIgnore = ["E501"]; } ./restore_routes.py)
|
||||||
|
];
|
||||||
|
|
||||||
# Restore ssh host and user keys if they are available.
|
# Restore ssh host and user keys if they are available.
|
||||||
# This avoids warnings of unknown ssh keys.
|
# This avoids warnings of unknown ssh keys.
|
||||||
boot.initrd.postMountCommands = ''
|
boot.initrd.postMountCommands = ''
|
||||||
mkdir -m 700 -p /mnt-root/root/.ssh
|
mkdir -m 700 -p /mnt-root/root/.ssh
|
||||||
mkdir -m 755 -p /mnt-root/etc/ssh
|
mkdir -m 755 -p /mnt-root/etc/ssh
|
||||||
|
mkdir -m 755 -p /mnt-root/root/network
|
||||||
if [[ -f ssh/authorized_keys ]]; then
|
if [[ -f ssh/authorized_keys ]]; then
|
||||||
install -m 400 ssh/authorized_keys /mnt-root/root/.ssh
|
install -m 400 ssh/authorized_keys /mnt-root/root/.ssh
|
||||||
fi
|
fi
|
||||||
install -m 400 ssh/ssh_host_* /mnt-root/etc/ssh
|
install -m 400 ssh/ssh_host_* /mnt-root/etc/ssh
|
||||||
|
cp *.json /mnt-root/root/network/
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
83
nix/restore_routes.py
Normal file
83
nix/restore_routes.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def filter_interfaces(network):
|
||||||
|
output = []
|
||||||
|
for net in network:
|
||||||
|
if net["ifname"] == "lo":
|
||||||
|
continue
|
||||||
|
addr_info = []
|
||||||
|
for addr in net["addr_info"]:
|
||||||
|
if addr.get("dynamic", False):
|
||||||
|
pass
|
||||||
|
elif addr["local"].startswith("fe80"):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
addr_info.append(addr)
|
||||||
|
if addr_info != []:
|
||||||
|
net["addr_info"] = addr_info
|
||||||
|
output.append(net)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open(sys.argv[1]) as f:
|
||||||
|
addresses = json.load(f)
|
||||||
|
with open(sys.argv[2]) as f:
|
||||||
|
routes = json.load(f)
|
||||||
|
relevant_interfaces = filter_interfaces(addresses)
|
||||||
|
current_interfaces = json.loads(
|
||||||
|
subprocess.run(
|
||||||
|
["ip", "--json", "addr"],
|
||||||
|
capture_output=True,
|
||||||
|
).stdout
|
||||||
|
)
|
||||||
|
|
||||||
|
for interface in relevant_interfaces:
|
||||||
|
for current_interface in current_interfaces:
|
||||||
|
if "address" in interface and "address" in current_interface:
|
||||||
|
if interface["address"] == current_interface["address"]:
|
||||||
|
for addr in interface["addr_info"]:
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
"ip",
|
||||||
|
"addr",
|
||||||
|
"add",
|
||||||
|
"dev",
|
||||||
|
current_interface["ifname"],
|
||||||
|
f'{addr["local"]}/{addr["prefixlen"]}',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
for route in routes:
|
||||||
|
if route["dev"] == interface["ifname"]:
|
||||||
|
if route.get("gateway", False):
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
"ip",
|
||||||
|
"route",
|
||||||
|
"add",
|
||||||
|
route["dst"],
|
||||||
|
"via",
|
||||||
|
route["gateway"],
|
||||||
|
"dev",
|
||||||
|
current_interface["ifname"],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
subprocess.run(
|
||||||
|
[
|
||||||
|
"ip",
|
||||||
|
"route",
|
||||||
|
"add",
|
||||||
|
route["dst"],
|
||||||
|
"dev",
|
||||||
|
current_interface["ifname"],
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in a new issue