blob: 37dc78142833c28d0e3453e638ec6ac4255807bd (
plain) (
tree)
|
|
#!/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() {
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
|