summaryrefslogtreecommitdiffstats
path: root/core/modules/networkd-dispatcher/data/etc/networkd-dispatcher/routable.d/00-fallback-dns-lookup.sh
blob: 40874b5664241431281f26b1634ddb34d28ee18a (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
#!/bin/bash
#
# This script is meant as a hook in /etc/networkd-dispatcher/routable.d
# It receives information on the state of the interface per environment,
# in particular:
# * $IFACE -> network interface that triggered this script
# * $ADDR  -> IP address configured on that interface

check_dns() {
	local fqdn host_out
	for timeout in 1 1 1 2 2 3 5 5 END; do
		if [ "$timeout" = "END" ]; then
			echo "Falling back to IP address if needed."
			fqdn=
			break
		fi
		host_out="$(host $ADDR)"
		if [ $? -ne 0 ]; then
			echo "Failed to retrieve FQDN through reverse lookup on '$ADDR'."
			sleep $timeout
		else
			local fqdn="$(<<< $host_out grep -E "$(awk -F. '{print $4"."$3"."$2"."$1}' <<< $ADDR )" | awk '{sub(".$",""); print $5}')"
			break
		fi
	done

	# check domain
	local domain="${fqdn#*.}"
	if [ -n "$domain" ] && ! grep -qE "^(search|domain).*$domain.*" /etc/resolv.conf; then
		echo "Adding DNS domain '$domain' to systemd-resolved configuration"
		mkdir -p /etc/systemd/resolved.conf.d 
		cat <<- EOF > /etc/systemd/resolved.conf.d/dns-domain.conf
			[Resolve]
			Domains=$domain
		EOF
		systemctl restart systemd-resolved
	fi
	# Check if we received a hostname from the DHCP
	local dhcp_hostname
	for lease in /run/systemd/netif/leases/*; do
		grep -qE "^ADDRESS=$ADDR" "$lease" || continue 
		dhcp_hostname="$(awk -F= '$1 = /HOSTNAME/ {print $2}' "$lease" )"
		break
	done
	if [ -n "$dhcp_hostname"  ]; then
		# Prefer DHCP hostname over anything else
		if [ "$dhcp_hostname" != "$(hostname)" ]; then
			echo "Current hostname differs from DHCP, forcing DHCP hostname: '$dhcp_hostname'"
			echo "systemd-networkd should have set it but did not. Check your configuration."
			set_hostname "$dhcp_hostname"
		fi
		return 0
	fi

	# No DHCP hostname, check DNS hostname
	local dns_hostname="${fqdn%%.*}"
	if [ -n "$dns_hostname" ]; then
		if [ "$dns_hostname" != "$(hostname)" ]; then
			echo "Current hostname differs from DNS, forcing DNS hostname: '$dns_hostname'"
			set_hostname "$dns_hostname"
		fi
	else
		echo "Neither DHCP nor DNS provided a hostname, use IP address as fallback."
		set_hostname "${ADDR//./-}"
	fi
	return 0
}

set_hostname() {
	hostnamectl set-hostname "$1"
}

if [ ! -e /opt/openslx/config ]; then
	echo "No OpenSLX configuration found - aborting."
	exit 1
fi

. /opt/openslx/config

if [ "$IFACE" != "${SLX_BRIDGE:-$SLX_PXE_NETIF}" ]; then
	echo "Ignoring $IFACE."
	exit 0
fi

# Wait until the interface is fully configured to make sure DNS lookups will work
# This works around the cases of a routable but configuring state which makes not sense at all...
for timeout in 1 1 1 2 2 3 5 5 END; do
	if [ "$timeout" = "END" ]; then
		echo "$IFACE did reach routable and configured state within 20sec, giving up..."
		exit 1
	fi
	if networkctl status "$IFACE" | grep -qE "^\s*State:\s*routable\s*\(configured\)"; then
		echo "$IFACE routable and configured, going on..."
		break
	fi
	sleep "$timeout"
done

sleep 1

check_dns