summaryrefslogtreecommitdiffstats
path: root/modules.d/slx-network/hooks/s3-parse-network-kcl.sh
diff options
context:
space:
mode:
Diffstat (limited to 'modules.d/slx-network/hooks/s3-parse-network-kcl.sh')
-rwxr-xr-xmodules.d/slx-network/hooks/s3-parse-network-kcl.sh119
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