#!/bin/bash # # Script parsing the kernel command line to get the IP configuration from # (i)PXE. Supports either the older # ip=::: format or our new format # consisting of 'ipv4.' 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() { local param for param in "ip" "router" "dns" "hostname" "domain" "search" "if" "ntpsrv" "subnet"; do local current="$(getarg ipv4.${param}=)" echo "ipv4.'$param'='$current'" [ -z "$current" ] && continue declare -g "${param}=${current}" done } parse_kcl() { # backwards compat for old style hostname/dns/domain local conf for conf in hostname dns domain; do conf_value="$(getarg ${conf}=)" if [ -n "$conf_value" ]; then echo "legacy '$conf'='$conf_value'" declare -g "${conf}=${conf_value}" fi done # 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" # Sanitize if [[ $hostname = *.* ]]; then [ -z "$domain" ] && domain="${hostname#*.}" hostname="${hostname%%.*}" echo "Fixed up to '$hostname' and '$domain'" fi domain="${domain%% *}" } 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='${domain}' SLX_PXE_SEARCH='${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 exit 0