summaryrefslogtreecommitdiffstats
path: root/modules.d/slx-network/hooks/s3-parse-network-kcl.sh
blob: 37dc78142833c28d0e3453e638ec6ac4255807bd (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/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