diff options
Diffstat (limited to 'modules.d/slx-network/hooks/s3-parse-network-kcl.sh')
-rwxr-xr-x | modules.d/slx-network/hooks/s3-parse-network-kcl.sh | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/modules.d/slx-network/hooks/s3-parse-network-kcl.sh b/modules.d/slx-network/hooks/s3-parse-network-kcl.sh new file mode 100755 index 00000000..daf2e9b7 --- /dev/null +++ b/modules.d/slx-network/hooks/s3-parse-network-kcl.sh @@ -0,0 +1,119 @@ +#!/bin/bash +# +# Script parsing the kernel command line to get the IP configuration from +# (i)PXE. Supports either the older +# ip=<CLIENT_IP>:<PXE_SERVER_IP>:<GATEWAY>:<NETMASK> format or our new format +# consisting of 'ipv4.<attr>' key/value pairs. Valid attributes are: ip, router, +# dns, hostname, domain, search, if, ntpsrv, subnet. + +command -v getarg >/dev/null || . /lib/dracut-lib.sh + +# static names for the boot interface and its bridge +declare -rg bootif_name="boot0" +declare -rg bridge_name="br0" + +# parse old syslinux style 'ip=...' and 'BOOTIF=...' parameters +parse_kcl_ip() { + declare -g if="$(getarg BOOTIF=)" + if [ -n "$if" ] && [ ${#if} -eq 20 ]; then + if="${if#???}" + if="${if//-/:}" + fi + local ip_line="$(getarg ip=)" + [ -z "$ip_line" ] && return 0 + read -r ip bootsrv router subnet \ + <<< $( awk -F: '{print $1" "$2" "$3" "$4}' <<< "${ip_line}" ) + declare -g ip bootsrv router subnet +} + +# parse new style 'ipv4.*=...' parameters +parse_kcl_ipv4() { + for param in "ip" "router" "dns" "hostname" "domain" "search" "if" "ntpsrv" "subnet"; do + local current="$(getarg ipv4.${param}=)" + echo "KCL '$param'='$current'" + [ -z "$current" ] && continue + declare -g "${param}=${current}" + done +} + +parse_kcl() { + # we assume (and we should) that both variants contain the + # same information if they are present simultaneously. + parse_kcl_ip + parse_kcl_ipv4 + + # if not boot server was given, use slxsrv + if [ -z "$bootsrv" ]; then + kclsrv="$(getarg slxsrv=)" + if [ -n "$kclsrv" ]; then + declare -g bootsrv="$kclsrv" + fi + fi + + # calculate network mask + declare -g mask="$(ipcalc -s -p "$ip" "$subnet" | sed 's/.*=//')" + + # vlan specified? + declare -g vlan="$(getarg vlan=)" + + # Bridged the boot interface? + grep -wqE 'bridged' /proc/cmdline && declare -g bridged="y" + + # backwards compat for old style hostname/dns/domain + for conf in hostname dns domain; do + conf_value="$(getarg ${conf}=)" + if [ -n "$conf_value" ]; then + declare -g "${conf}=${conf_value}" + fi + done +} + +save_network_config() { + declare -rg network_conf="/run/openslx/network.conf" + mkdir -p "${network_conf%/*}" + cat <<-EOF > "$network_conf" + SLX_PXE_CLIENT_IP='$ip' + SLX_PXE_SERVER_IP='$bootsrv' + SLX_PXE_GATEWAY='$router' + SLX_PXE_NETMASK='$mask' + SLX_PXE_SUBNET='$subnet' + SLX_PXE_MAC='$if' + SLX_PXE_NETIF='$bootif_name' + SLX_PXE_DNS='${dns//,/ }' + SLX_PXE_HOSTNAME='$hostname' + SLX_PXE_DOMAIN='${search//,/ }' + SLX_PXE_NTP='${ntpsrv//,/ }' + SLX_BRIDGE='${bridged:+${bridge_name}}' + SLX_VLAN_ID='$vlan' + EOF + echo "network.conf written." +} + +# Create udev rule to rename the PXE boot interface to BOOTIF_NAME +create_udev_bootif_name_rule() { + if [ -z "$if" ]; then + echo "MAC address of boot interface not set!" + return 1 + fi + # priority 70 < 80-net-name-slot.rules. + echo 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="'$if'", NAME="'$bootif_name'"' > /etc/udev/rules.d/70-pxe-boot-interface.rules +} + +## MAIN ## +parse_kcl + +if [ -z "$if" ]; then + emergency_shell "MAC address of primary interface not given on command line" + exit 1 +fi + +# Create the udev rule to rename the boot interface to the declared BOOTIF_NAME +create_udev_bootif_name_rule & + +# Save network config for later use +save_network_config & + +# set hostname asap +[ -n "$hostname" ] && echo "$hostname" > /proc/sys/kernel/hostname + +wait |