diff options
author | Jonathan Bauer | 2019-08-08 13:53:37 +0200 |
---|---|---|
committer | Jonathan Bauer | 2019-08-08 13:53:37 +0200 |
commit | bec14f4e1ac4d1b4a7a782d6c3c54cd5ebe5208b (patch) | |
tree | b0b9d81568f2d732988c54d432fcb5c35ccf39f9 /builder | |
parent | [busybox] install busybox into stage4 (diff) | |
download | systemd-init-bec14f4e1ac4d1b4a7a782d6c3c54cd5ebe5208b.tar.gz systemd-init-bec14f4e1ac4d1b4a7a782d6c3c54cd5ebe5208b.tar.xz systemd-init-bec14f4e1ac4d1b4a7a782d6c3c54cd5ebe5208b.zip |
[slx-network] support for dhcp in stage4
Diffstat (limited to 'builder')
-rw-r--r-- | builder/modules.d/slx-network/hooks/activate-bootif-dhcp.sh | 22 | ||||
-rw-r--r-- | builder/modules.d/slx-network/hooks/parse-ipxe-network-kcl.sh | 2 | ||||
-rwxr-xr-x | builder/modules.d/slx-network/module-setup.sh | 17 | ||||
-rwxr-xr-x | builder/modules.d/slx-network/scripts/setup-bootif-network.stage4 | 52 | ||||
-rwxr-xr-x | builder/modules.d/slx-network/scripts/udhcpc-trigger.stage3 (renamed from builder/modules.d/slx-network/scripts/udhcpc-trigger-stage3) | 0 | ||||
-rwxr-xr-x | builder/modules.d/slx-network/scripts/udhcpc-trigger.stage4 | 225 | ||||
-rw-r--r-- | builder/modules.d/slx-network/services/udhcpc@.service | 12 |
7 files changed, 325 insertions, 5 deletions
diff --git a/builder/modules.d/slx-network/hooks/activate-bootif-dhcp.sh b/builder/modules.d/slx-network/hooks/activate-bootif-dhcp.sh new file mode 100644 index 00000000..93ca850d --- /dev/null +++ b/builder/modules.d/slx-network/hooks/activate-bootif-dhcp.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +. /run/openslx/network.conf + +for script in setup-bootif-network udhcpc-trigger; do + if [ -e "${NEWROOT}/opt/openslx/scripts/${script}" ]; then + mv "${NEWROOT}/opt/openslx/scripts/${script}"{,.stage4} + fi + cp -f "/opt/openslx/scripts/${script}.stage4" \ + "${NEWROOT}/opt/openslx/scripts/${script}" +done + +# copy udhcpc@ systemd service, backup existing ones for debugging +mkdir -p "${NEWROOT}/etc/systemd/system" +if [ -e "${NEWROOT}/etc/systemd/system/udhcpc@.service" ]; then + mv "${NEWROOT}/etc/systemd/system/udhcpc@.service"{,.stage4} +fi +cp -f "/opt/openslx/services/udhcpc@.service" "${NEWROOT}/etc/systemd/system" + +# activate it for the bridge or the physical interface if not bridged +systemctl --root "$NEWROOT" enable "udhcpc@${SLX_BRIDGE:-${SLX_PXE_NETIF}}" + diff --git a/builder/modules.d/slx-network/hooks/parse-ipxe-network-kcl.sh b/builder/modules.d/slx-network/hooks/parse-ipxe-network-kcl.sh index 472437fd..0811d370 100644 --- a/builder/modules.d/slx-network/hooks/parse-ipxe-network-kcl.sh +++ b/builder/modules.d/slx-network/hooks/parse-ipxe-network-kcl.sh @@ -99,5 +99,5 @@ NETIF= [ -n "${BRIDGED}" ] && [ -n "${BRIDGE_NAME}" ] && NETIF="${BRIDGE_NAME}" [ -n "${VLAN}" ] && NETIF="${BOOTIF_NAME}.${VLAN}" -/sbin/initqueue --settled /usr/local/bin/setup-network +/sbin/initqueue --settled /usr/local/bin/setup-bootif-network /sbin/initqueue --finished [ -e "/.network" ] diff --git a/builder/modules.d/slx-network/module-setup.sh b/builder/modules.d/slx-network/module-setup.sh index e9278474..560b3e5c 100755 --- a/builder/modules.d/slx-network/module-setup.sh +++ b/builder/modules.d/slx-network/module-setup.sh @@ -23,9 +23,18 @@ install() { _arch=$(uname -m) inst_libdir_file {"tls/$_arch/",tls/,"$_arch/",}"libnss_dns.so.*" - inst "$moddir/scripts/setup-network" "/usr/local/bin/setup-network" - inst "$moddir/scripts/udhcpc-trigger" "/usr/local/bin/udhcpc-trigger" - inst_hook cmdline 10 "$moddir/hooks/parse-ipxe-network-kcl.sh" - inst_hook pre-pivot 50 "$moddir/hooks/copy-network-config.sh" + # stage3 network scripts + inst "${moddir}/scripts/setup-bootif-network.stage3" "/usr/local/bin/setup-bootif-network" + inst "${moddir}/scripts/udhcpc-trigger.stage3" "/usr/local/bin/udhcpc-trigger" + + # files for stage4, park them in /opt/openslx + inst "${moddir}/scripts/setup-bootif-network.stage4" "/opt/openslx/scripts/setup-bootif-network.stage4" + inst "${moddir}/scripts/udhcpc-trigger.stage4" "/opt/openslx/scripts/udhcpc-trigger.stage4" + inst "${moddir}/services/udhcpc@service" "/opt/openslx/services/udhcpc@service" + + # hooks + inst_hook cmdline 10 "${moddir}/hooks/parse-ipxe-network-kcl.sh" + inst_hook pre-pivot 50 "${moddir}/hooks/copy-network-config.sh" + inst_hook pre-pivot 60 "${moddir}/hooks/activate-bootif-dhcp.sh" } diff --git a/builder/modules.d/slx-network/scripts/setup-bootif-network.stage4 b/builder/modules.d/slx-network/scripts/setup-bootif-network.stage4 new file mode 100755 index 00000000..7ccb94e6 --- /dev/null +++ b/builder/modules.d/slx-network/scripts/setup-bootif-network.stage4 @@ -0,0 +1,52 @@ +#!/bin/bash +# For arrays + +export PATH=$PATH:/opt/openslx/sbin:/opt/openslx/bin + +. /run/openslx/network.conf + +net_if="$1" +net_ip="$(ip addr show dev "${net_if}" | grep -m1 '^\s*inet ' | \ + awk -F " " '{print $2}' | awk -F "/" '{print $1}')" + +# set default options +declare -a udhcpc_opts +udhcpc_opts+=("-t" "8") +udhcpc_opts+=("-O" "domain") +udhcpc_opts+=("-O" "nissrv") +udhcpc_opts+=("-O" "nisdomain") +udhcpc_opts+=("-O" "wpad") +udhcpc_opts+=("-O" "search") +udhcpc_opts+=("-O" "wins") + +# need to renew? +if [ -n "$net_ip" ]; then + udhcpc_opts+=( "-r" "$net_ip" ) +fi + +primary="br0" +[ -n "$SLX_BRIDGE" ] && primary="$SLX_BRIDGE" + +# send machine uuid during DHCP if acting on primary interface +if [ "$primary" = "$net_if" ] && [ "$SLX_NET_DHCP_UUID" = "yes" ]; then + uid=$(dmidecode -s system-uuid | \ + sed -r 's/^(..)(..)(..)(..)-(..)(..)-(..)(..)-(....)-/00\4\3\2\1\6\5\8\7\9/') + if [ "${#uid}" = 34 ]; then + echo "Using SMBIOS uid for DHCP" + udhcpc_opts+=( "-x" "0x3d:$uid" ) + fi +fi + +mkdir -p /run/udhcpc || echo "Could not create '/run/udhcpc'." + +udhcpc "${udhcpc_opts[@]}" -i "${net_if}" \ + -s /opt/openslx/scripts/udhcpc-trigger \ + -p "/run/udhcpc/udhcpc.${net_if}.pid" +ret=$? + +if [ "${ret}" != 0 ]; then + echo "udhcpc" "Could not run 'udhcpc ${udhcpc_opts[*]}' on ${net_if}." +fi + +exit "${ret}" + diff --git a/builder/modules.d/slx-network/scripts/udhcpc-trigger-stage3 b/builder/modules.d/slx-network/scripts/udhcpc-trigger.stage3 index 8bed11c7..8bed11c7 100755 --- a/builder/modules.d/slx-network/scripts/udhcpc-trigger-stage3 +++ b/builder/modules.d/slx-network/scripts/udhcpc-trigger.stage3 diff --git a/builder/modules.d/slx-network/scripts/udhcpc-trigger.stage4 b/builder/modules.d/slx-network/scripts/udhcpc-trigger.stage4 new file mode 100755 index 00000000..92aa9596 --- /dev/null +++ b/builder/modules.d/slx-network/scripts/udhcpc-trigger.stage4 @@ -0,0 +1,225 @@ +#!/bin/bash +# Needs bash for printf -v VARNAME +# ----------------------------------------------------------------------------- +# +# Copyright (c) 2011..2018 bwLehrpool-Projektteam +# +# This program/file is free software distributed under the GPL version 2. +# See https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html +# +# If you have any feedback please consult https://bwlehrpool.de and +# send your feedback to bwlehrpool@hs-offenburg.de. +# +# General information about bwLehrpool can be found at https://bwlehrpool.de +# +# ----------------------------------------------------------------------------- +# +# Mini-Linux Toolkit +# +# ----------------------------------------------------------------------------- + +export PATH=$PATH:/opt/openslx/sbin:/opt/openslx/bin + +. /opt/openslx/config + +primary="br0" +[ -n "$SLX_BRIDGE" ] && primary="$SLX_BRIDGE" + +RESOLV_CONF="/opt/openslx/resolv.conf" +THIS_RESOLV="/run/network/${interface}.resolv" + +rebuild_resolv_conf () { + # Don't do anything if the active resolv.conf is not ours + # Also this will not run resolvconf update.d... No idea if we should still do so... + [ -L "/etc/resolv.conf" ] || return 0 + [ "x$(readlink "/etc/resolv.conf")" == "x${RESOLV_CONF}" ] || return 0 + # Maybe make this smarter some time, if anyone is using clients that are on multiple networks at once etc... + # This is a little braindead but should work most of the time + sort -u /run/network/*.resolv > "$RESOLV_CONF" 2> /dev/null + + # add support for resolv.conf update scripts // see man(8) resolvconf + for s in /etc/resolvconf/update.d/*.sh; do + [ -f "$s" ] && [ -x "$s" ] && "$s" + done +} + +escape_search() { + echo "$@" | sed -e 's/[]\/()$*.^|[]/\\&/g' +} + +escape_replace() { + echo "$@" | sed -e 's/[\/&]/\\&/g' +} + +check_env() { + if [ -z "$ip" ] || [ -z "$subnet" ] || [ -z "$interface" ]; then + echo "$1 event with missing data" >&2 + echo "ip = '$ip'" >&2 + echo "subnet = '$subnet'" >&2 + echo "interface = '$interface'" >&2 + exit 1 + fi +} + +if [ ! -d /run ]; then + echo -n "Waiting for /run." >&2 + while [ ! -d /run ]; do + echo -n "." >&2 + usleep 500000 + done + echo "" >&2 +fi + +mkdir -p "/run/network" + +case "$1" in + bound|renew) + check_env "$1" + mkdir -p "/run/dhcpc" + # Set address on interface + ip addr add "$ip/$(ipcalc -s -p "$ip" "$subnet" | sed s/.*=//)" dev "$interface" + # Set default route, if given + if [ -n "$router" ]; then + ip route replace default via "$router" + fi + + # get domain, hostname and thus fqdn from DNS + dns_fqdn=$(busybox timeout -t 3 rdns "$ip") + dns_short="${dns_fqdn%%.*}" + # check if it is fqdn + if [ "$dns_fqdn" == "$dns_short" ]; then + unset dns_fqdn dns_short + fi + + # Update resolver configuration file + conf_file="$(mktemp)" + # Own domain suffix + if [ -n "$domain" ]; then + : + elif [ -n "$dns_fqdn" ]; then + domain="${dns_fqdn#*.}" + + elif [ -n "$SLX_NET_DOMAIN" ]; then + domain="$SLX_NET_DOMAIN" + fi + if [ -n "$domain" ]; then + echo "domain ${domain%% *}" >> "${conf_file}" + fi + # Add domain to list of search domains if not in there yet + if [ -n "$domain" ] && [ -n "$search" ]; then + FOUND=no + for sd in $search; do + [ "x$sd" = "x$domain" ] && FOUND=yes + done + [ "$FOUND" = "no" ] && search="$domain $search" + elif [ -n "$domain" ]; then + search="$domain" + fi + # Search domains + if [ -n "$search" ]; then + echo "search $search" >> "${conf_file}" + elif [ -n "$SLX_NET_SEARCH" ]; then + echo "search $SLX_NET_SEARCH" >> "${conf_file}" + elif [ -n "$SLX_NET_DOMAIN" ]; then + echo "search $SLX_NET_DOMAIN" >> "${conf_file}" + fi + for i in $dns; do + echo "$0: Adding DNS $i" + echo "nameserver $i" >> "${conf_file}" + done + + if [ -x "/sbin/resolvconf" ] && [ -L "/etc/resolv.conf" ] && [ -d "/etc/resolvconf/update.d" ]; then + # Automatic handling :-) + resolvconf --create-runtime-directories + resolvconf --enable-updates + < "$conf_file" resolvconf -a "${interface}.udhcpc" + rm -- "$conf_file" + else + # Manual handling required :-( + mv -f "$conf_file" "$THIS_RESOLV" + rebuild_resolv_conf + fi + + + # Things that should only happen for the main interface that was used for booting + if [ "$interface" = "$primary" ]; then + # Update IP, TODO: check if we really want/need to overwrite the PXE_IP, + # it might be better/clearer to change the SLX_DHCP_CLIENT_IP... + sed -i "s/^\(SLX_PXE_CLIENT_IP=\).*$/\1'$ip'/" /opt/openslx/config + # Write DOMAIN and SEARCH to /opt/openslx/config if empty + if [ -z "$SLX_NET_DOMAIN" ] && [ -n "$domain" ]; then + sed -i "/^SLX_NET_DOMAIN=/d" /opt/openslx/config + echo "SLX_NET_DOMAIN='$domain'" >> /opt/openslx/config + fi + if [ -z "$SLX_NET_SEARCH" ] && [ -n "$search" ]; then + sed -i "/^SLX_NET_SEARCH=/d" /opt/openslx/config + echo "SLX_NET_SEARCH='$search'" >> /opt/openslx/config + fi + # Same for WINS servers + if [ -z "$SLX_NET_WINS" ] && [ -n "$wins" ]; then + sed -i "/^SLX_NET_WINS=/d" /opt/openslx/config + echo "SLX_NET_WINS='$wins'" >> /opt/openslx/config + fi + + # Update /etc/issue for proper spacing + [ -x "/opt/openslx/scripts/openslx-create_issue" ] && /opt/openslx/scripts/openslx-create_issue + + # Remove any stray addresses; we expect the primary interface to only have one + # address supplied via DHCP. We do this after adding the new one, obviously. + rem_list=$( ip -o addr show "$interface" | awk '{ for (i=1;i<NF;++i) if ($i == "inet") print $(i+1) }' | grep -v "^${ip}/" ) + if [ -n "$rem_list" ]; then + echo "PRIMARY: Removing $rem_list since we just got assigned $ip" + echo 1 > "/proc/sys/net/ipv4/conf/$interface/promote_secondaries" + for addr in $rem_list; do + ip addr del "$addr" dev "$interface" + sed -i "/^$(escape_search "${addr%/*}")(\s|$)/d" /etc/hosts + done + fi + fi # end "primary only" + + # Write to openslx-config + echo "# Config written by openslx-dhcp-script (2)" >> /opt/openslx/config + sed -i "/^SLX_DNS=/d" /opt/openslx/config + echo "SLX_DNS='$dns'" >> /opt/openslx/config + ;; + + deconfig) + check_env "$1" + if [ "$interface" = "$primary" ]; then + echo "Ignoring deconfig for primary interface" + else + echo 1 > "/proc/sys/net/ipv4/conf/$interface/promote_secondaries" + clientip=${ip%%:*} + ip addr del "$clientip/$(ipcalc -s -p "$clientip" "$subnet" | sed s/.*=//)" dev "$interface" + sed -i "/^$(escape_search "$ip")(\s|$)/d" /etc/hosts + fi + + if [ -x /sbin/resolvconf ] && [ -L /etc/resolv.conf ] && [ -d /etc/resolvconf/update.d ]; then + # Automatic handling :-) + resolvconf -d "${interface}.udhcpc" + else + # Manual handling required :-( + rm -f -- "$THIS_RESOLV" + rebuild_resolv_conf + fi + ;; + + leasefail) + echo "$0: Lease failed: $message" >&2 + + ;; + + nak) + echo "$0: Received a NAK: $message" >&2 + + ;; + + *) + echo "$0: Unknown udhcpc command: $1" >&2 + exit 1 + + ;; +esac + +exit 0 + diff --git a/builder/modules.d/slx-network/services/udhcpc@.service b/builder/modules.d/slx-network/services/udhcpc@.service new file mode 100644 index 00000000..f2bcb840 --- /dev/null +++ b/builder/modules.d/slx-network/services/udhcpc@.service @@ -0,0 +1,12 @@ +[Unit] +Description=DHCP Client for %i +Before=network.target + +[Service] +Type=forking +PIDFile=/run/udhcpc/udhcpc.%i.pid +ExecStart=/opt/openslx/scripts/setup-bootif-network-stage4 %i +ExecStopPost=/opt/openslx/bin/rm /run/udhcpc/udhcpc.%i.pid + +[Install] +WantedBy=network.target |