summaryrefslogblamecommitdiffstats
path: root/modules.d/slx-network/hooks/s3-parse-network-kcl.sh
blob: 37dc78142833c28d0e3453e638ec6ac4255807bd (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11

           




                                                                                



                                                    








                                                               
          








                                                                             
                   
                                                                                                
                                                        
                                               





                                                








                                                            







                                                                  


                                                    

          








                                                                         






                                                            


                       











                                                            

                                               


                                                       
           
                                    



                                                                  

                                                             


                                         
                                                                                                                                                            


          

         






                                                                                    



                                   

                                                                  
 
    
      
#!/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