/modules-available/vmstore/

e='downloader-centos7'>downloader-centos7 Systemd init mit dracut (Masterprojekt)OpenSLX
summaryrefslogtreecommitdiffstats
path: root/builder/modules.d/systemd-networkd-ext/hooks
diff options
context:
space:
mode:
authorJonathan Bauer2017-09-22 11:00:34 +0200
committerJonathan Bauer2017-09-22 11:00:34 +0200
commitd7d92a6fbf097fb34075b3e1d57ef547a209e362 (patch)
treef4c26d6a9584fb110792588f9aebedd22658c83e /builder/modules.d/systemd-networkd-ext/hooks
parent[conf-tgz] add gzip (diff)
downloadsystemd-init-d7d92a6fbf097fb34075b3e1d57ef547a209e362.tar.gz
systemd-init-d7d92a6fbf097fb34075b3e1d57ef547a209e362.tar.xz
systemd-init-d7d92a6fbf097fb34075b3e1d57ef547a209e362.zip
reworked systemd-networkd module
* support new KCL arguments: domain, dns, hostname * fallback to DHCP configuration during stage3, if IP config is missing * copies the unit files to NEWROOT to ensure they present * configures boot interface to do DHCP within stage4 (this is to get proper nameservers and domain from the DHCP - currently bugged due to systemd version afaik)
Diffstat (limited to 'builder/modules.d/systemd-networkd-ext/hooks')
-rw-r--r--builder/modules.d/systemd-networkd-ext/hooks/configure-dhcp-for-newroot.sh27
-rw-r--r--builder/modules.d/systemd-networkd-ext/hooks/copy-networkd-files-to-newroot.sh28
-rw-r--r--builder/modules.d/systemd-networkd-ext/hooks/parse-kcl-for-networkd.sh188
3 files changed, 174 insertions, 69 deletions
diff --git a/builder/modules.d/systemd-networkd-ext/hooks/configure-dhcp-for-newroot.sh b/builder/modules.d/systemd-networkd-ext/hooks/configure-dhcp-for-newroot.sh
new file mode 100644
index 00000000..a0e876a4
--- /dev/null
+++ b/builder/modules.d/systemd-networkd-ext/hooks/configure-dhcp-for-newroot.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# This hook creates a networkd configuration for the NEWROOT
+# * DHCP configuration for the boot interface
+# * Set static hostname via /etc/hostname
+
+# This uses the configuration file generated by the parse-kcl-for-networkd.sh hook
+# Note: on systemd v219, UseDomains is bugged and does not seem to do anything
+# thus that option is complemented with the KCL's domain
+# to hopefully garantee one of these will take effect.
+mkdir -p "$NEWROOT/etc/systemd/network/"
+new_network_conf="$NEWROOT/etc/systemd/network/10-pxe-interface.network"
+echo '[Match]' > $new_network_conf
+grep "MACAddress=" /etc/systemd/network/*boot*.network >> $new_network_conf
+echo '' >> $new_network_conf
+echo '[Network]' >> $new_network_conf
+echo 'DHCP=ipv4' >> $new_network_conf
+grep "Domains=" /etc/systemd/network/*boot*.network >> $new_network_conf
+echo '' >> $new_network_conf
+echo '[DHCP]' >> $new_network_conf
+echo 'UseDNS=true' >> $new_network_conf
+echo 'UseDomains=true' >> $new_network_conf
+echo 'UseHostname=true' >> $new_network_conf
+echo 'CriticalConnection=true' >> $new_network_conf
+
+# Similarly, UseHostname seems to have no effect, so work around for now...
+cat /proc/sys/kernel/hostname > $NEWROOT/etc/hostname
diff --git a/builder/modules.d/systemd-networkd-ext/hooks/copy-networkd-files-to-newroot.sh b/builder/modules.d/systemd-networkd-ext/hooks/copy-networkd-files-to-newroot.sh
new file mode 100644
index 00000000..9510c8d3
--- /dev/null
+++ b/builder/modules.d/systemd-networkd-ext/hooks/copy-networkd-files-to-newroot.sh
@@ -0,0 +1,28 @@
+
+#!/bin/bash
+#
+# This hook copies the core systemd-networkd related service
+# to the NEWROOT and activated them in sysinit.target
+# to prevent systemd from killing these while pivot_root
+new_sysinit_wants="${NEWROOT}/usr/lib/systemd/system/sysinit.target.wants/"
+mkdir -p "${new_sysinit_wants}"
+
+for unit in \
+ systemd-networkd.socket \
+ systemd-networkd.service \
+ systemd-networkd-wait-online.service \
+ systemd-resolved.service
+do
+ service_path="$(systemctl show -p FragmentPath $unit | cut -c 14-)"
+ cp "${service_path}" "${NEWROOT}/${service_path}"
+ ln -sf "../${unit}" "${new_sysinit_wants}/${unit}"
+done
+
+# this drop-in is needed to prevent a pull-in loop sysinit.target <-> basic.target
+mkdir -p "${NEWROOT}/usr/lib/systemd/system/systemd-resolved.service.d/"
+echo '[Unit]' > "${NEWROOT}/usr/lib/systemd/system/systemd-resolved.service.d/00-no-default-deps.conf"
+echo 'DefaultDependencies=no' >> "${NEWROOT}/usr/lib/systemd/system/systemd-resolved.service.d/00-no-default-deps.conf"
+
+# finally make sure the NEWROOT resolv.conf links to the one managed by resolved.
+rm $NEWROOT/etc/resolv.conf
+ln -s /run/systemd/resolve/resolv.conf $NEWROOT/etc/resolv.conf
diff --git a/builder/modules.d/systemd-networkd-ext/hooks/parse-kcl-for-networkd.sh b/builder/modules.d/systemd-networkd-ext/hooks/parse-kcl-for-networkd.sh
index cdf080a3..0f9c698f 100644
--- a/builder/modules.d/systemd-networkd-ext/hooks/parse-kcl-for-networkd.sh
+++ b/builder/modules.d/systemd-networkd-ext/hooks/parse-kcl-for-networkd.sh
@@ -1,98 +1,148 @@
#!/bin/bash
#
-# This script was mostly stolen from 40network/parse-ip-opts.sh. Its
-# actions are adapted to write .network files to /etc/systemd/network
-# in the initramfs instead o
+# This script was mostly stolen from 40network/parse-ip-opts.sh. It was
+# adapted to generate .network files for systemd-networkd using the IP
+# configuration from PXE/Syslinux in addition to domain, dns and hostname
command -v getarg >/dev/null || . /lib/dracut-lib.sh
-main_work() {
- local IPCONF="$(getarg ip=)"
- local BOOTIF="$(getarg BOOTIF=)"
+# static names for the boot interface and its bridge
+# TODO could be configurable from the KCL
+declare -rg BOOTIF_NAME="boot0"
+declare -rg BRIDGE_NAME="br0"
+#declare -rg BRIDGED="bridged"
- if [ -z "${IPCONF}" ] && [ -z "${BOOTIF}" ]; then
- # No ip= argument(s) given by PXE, TODO try dhcp
- return;
- fi
+# Get all the ip-related arguments from the KCL
+parse_kernel_command_line() {
+ ## KCL "BOOTIF": MAC address of the interface that DHCP'ed during PXE
+ declare -g BOOTIF="$(getarg BOOTIF=)"
+ # Remove the hardware type prefix of BOOTIF if it has 20 chars to get
+ # the plain MAC address. The hardware type prefix has length 3, e.g. "01-".
+ [ -n "${BOOTIF}" ] && [ ${#BOOTIF} -eq 20 ] && BOOTIF="${BOOTIF#???}"
+ BOOTIF="$(tr '-' ':' <<< $BOOTIF)"
+ readonly BOOTIF
- # ip= is expected in following format (syslinux IPAPPEND3):
+ ## KCL "ip": is expected in following format (syslinux IPAPPEND3):
+ declare -rg IPCONF="$(getarg ip=)"
# <CLIENT_IP>:<PXE_SERVER_IP>:<GATEWAY_IP>:<NETMASK>
- local CLIENT_IP=
- local SERVER_IP=
- local GATEWAY_IP=
- local NETMASK=
+ declare -g CLIENT_IP=
+ declare -g SERVER_IP=
+ declare -g GATEWAY_IP=
+ declare -g NETMASK=
read -r CLIENT_IP SERVER_IP GATEWAY_IP NETMASK <<< $( awk -F: '{print $1" "$2" "$3" "$4}' <<< "${IPCONF}" )
+ readonly CLIENT_IP SERVER_IP GATEWAY_IP NETMASK
- # BOOTIF= contains the MAC address of the boot interface
- # and a hardware type prefix of length 2, e.g. "01-"
- # So if BOOTIF has 20 chars, then we got the prefix.
- # This needs to be stripped to get the MAC address only
- [ -n "${BOOTIF}" ] && [ ${#BOOTIF} -eq 20 ] && BOOTIF="${BOOTIF#???}"
- BOOTIF="$(tr '-' ':' <<< $BOOTIF)"
-
- # TODO sanity checks
-
- # Taken from parse-ip-opts.sh
- # Convert the netmask to CIDR notation
+ # Taken from parse-ip-opts.sh: Convert the netmask to CIDR notation
+ declare -g CIDR
if [[ "x$NETMASK" =~ ^x[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
CIDR=$(mask2cidr "$NETMASK")
elif [ -n "$NETMASK" -a "x${NETMASK//[0-9]/}" = 'x' ]; then
# The mask is already a prefix length (uint), so validate it
[[ "x$CLIENT_IP" == x*:*:* && "$NETMASK" -le 128 || "$NETMASK" -le 32 ]] && CIDR=$NETMASK
fi
+ readonly CIDR
+ # KCL "hostname"
+ declare -rg HOSTNAME="$(getarg hostname=)"
+ [ -n "$HOSTNAME" ] && echo "$HOSTNAME" > /proc/sys/kernel/hostname
- # Generate network and link file for networkd
- NETWORK_FILE=/etc/systemd/network/01-boot-lan.network
- mkdir -p $(dirname $NETWORK_FILE)
- echo '[Match]' > $NETWORK_FILE
- echo 'Name=bootnet' >> $NETWORK_FILE
- # Hardcode bootnet as our boot interface
- [ -n "$BOOTIF" ] && echo "MACAddress=$BOOTIF" >> $NETWORK_FILE
- echo '[Network]' >> $NETWORK_FILE
- echo 'Bridge=br0' >> $NETWORK_FILE
-
- ## Boot interface has 'bootnet' as dedicated name
- LINK_FILE=/etc/systemd/network/00-boot-lan.link
- echo '[Match]' > $LINK_FILE
- [ -n "$BOOTIF" ] && echo "MACAddress=$BOOTIF" >> $LINK_FILE
- echo '[Link]' >> $LINK_FILE
- echo "Name=bootnet" >> $LINK_FILE
-
- # HACK pro bridge setup
- BRIDGE_DEV_CONF=/etc/systemd/network/10-bridge-lan.netdev
- echo '[NetDev]' > $BRIDGE_DEV_CONF
- echo 'Name=br0' >> $BRIDGE_DEV_CONF
- echo 'Kind=bridge' >> $BRIDGE_DEV_CONF
-
- BRIDGE_IF_CONF=/etc/systemd/network/11-bridge-lan.network
- echo '[Match]' > $BRIDGE_IF_CONF
- echo "Name=br0" >> $BRIDGE_IF_CONF
- echo '[Network]' >> $BRIDGE_IF_CONF
- [ -n "$CLIENT_IP" ] && echo "Address=${CLIENT_IP}/${CIDR:-24}" >> $BRIDGE_IF_CONF
- [ -n "$GATEWAY_IP" ] && echo "Gateway=${GATEWAY_IP}" >> $BRIDGE_IF_CONF
+ # KCL "dns"
+ declare -rg DNS="$(getarg dns=)"
+ # KCL "domain"
+ declare -rg DOMAIN="$(getarg domain=)"
+}
+# Helper to echo a mac address matching [Match] section
+print_match_mac() {
+ [ $# -ne 1 ] && echo "No MAC given!" && return 1
+ echo '[Match]'
+ echo "MACAddress=${1}"
+}
+# Helper to echo the static configuration, including
+# DNS and Domain if given per KCL
+print_static_ip_conf() {
+ [ $# -ne 2 ] && echo "Need 2 args: <ip/cidr> <gateway>. Given: $@" && return 1
+ echo "Address=${1}"
+ echo "Gateway=${2}"
+ [ -n "${DNS}" ] && echo "DNS=${DNS}"
+ [ -n "${DOMAIN}" ] && echo "Domains=${DOMAIN}"
+}
+
+# Create udev rule to rename the PXE boot interface to BOOTIF_NAME
+create_bootif_udev_name_rule() {
+ [ -z "${BOOTIF}" ] && echo "No BOOTIF set, was it present in the kernel command line?" && return 1
+ # priority 70 < 80-net-name-slot.rules.
+ echo 'SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="'${BOOTIF}'\
+ ", NAME="'${BOOTIF_NAME}'"' > /etc/udev/rules.d/70-pxe-boot-interface.rules
+
+}
+
+## Generate network and link file(s) for networkd
+# Checks if an IP configuration was forwarded by
+generate_networkd_config() {
+ mkdir -p "/etc/systemd/network"
+ local BOOTIF_NETWORK_CONF="/etc/systemd/network/01-boot-lan.network"
+ print_match_mac "${BOOTIF}" > "${BOOTIF_NETWORK_CONF}"
+ echo '[Network]' >> "${BOOTIF_NETWORK_CONF}"
+ if [ -n "${BRIDGED}" ]; then
+ echo "Bridge=${BRIDGE_NAME}" >> "${BOOTIF_NETWORK_CONF}"
+ elif [ -n "${CLIENT_IP}" -a -n "${GATEWAY_IP}" ]; then
+ print_static_ip_conf "${CLIENT_IP}/${CIDR:-24}" "${GATEWAY_IP}" >> "${BOOTIF_NETWORK_CONF}"
+ else
+ echo "DHCP=ipv4" >> "${BRIDGE_IF_CONF}"
+ fi
+ # we're done unless running in bridged mode
+ [ -n "${BRIDGED}" ] || return 0
+
+ # bridge setup
+ local BRIDGE_DEV_CONF="/etc/systemd/network/10-bridge-lan.netdev"
+ echo '[NetDev]' > "${BRIDGE_DEV_CONF}"
+ echo "Name=${BRIDGE_NAME}" >> "${BRIDGE_DEV_CONF}"
+ echo 'Kind=bridge' >> "${BRIDGE_DEV_CONF}"
+
+ local BRIDGE_NETWORK_CONF="/etc/systemd/network/11-bridge-lan.network"
+ echo '[Match]' > "${BRIDGE_NETWORK_CONF}"
+ echo "Name=${BRIDGE_NAME}" >> "${BRIDGE_NETWORK_CONF}"
+ echo '[Network]' >> "${BRIDGE_NETWORK_CONF}"
+ if [ -n "${CLIENT_IP}" -a -n "${GATEWAY_IP}" ]; then
+ print_static_ip_conf "${CLIENT_IP}/${CIDR:-24}" "${GATEWAY_IP}" >> "${BRIDGE_NETWORK_CONF}"
+ else
+ # bad/no IP info, fallback to DHCP
+ echo "DHCP=ipv4" >> "${BRIDGE_NETWORK_CONF}"
+ fi
+ return 0
}
# from parse-ip-opts.sh
# Takes a netmask and outputs the corresponding CIDR
# e.g.
# mask2cidr 255.255.255.0
# returns: 24
-function mask2cidr() {
- local -i bits=0
- for octet in ${1//./ }; do
- for i in {0..8}; do
- [ "$octet" -eq $(( 256 - (1 << i) )) ] && bits+=$((8-i)) &