summaryrefslogtreecommitdiffstats
path: root/modules.d/slx-network/hooks/parse-ipxe-network-kcl.sh
blob: fec160a80bce50729ee31a4962c71e4e1f116809 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/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
		echo "Getting $param..."
		local current="$(getarg ipv4.${param}=)"
		[ -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
}

# 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

# set hostname asap
[ -n "$hostname" ] && echo "$hostname" > /proc/sys/kernel/hostname

# Save network config for later use
save_network_config &

# Create the udev rule to rename the boot interface to the declared BOOTIF_NAME
create_udev_bootif_name_rule &

wait

# TODO handle case where the MAC address of the boot interface was not found
/sbin/initqueue --settled /usr/local/bin/setup-bootif-network
/sbin/initqueue --finished [ -e "/.network" ]