From: Jonathan Calmels Date: Fri, 8 Dec 2017 06:04:36 +0000 (-0800) Subject: hooks: dhclient hook improvements X-Git-Tag: lxc-3.0.0.beta1~98^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84bf5645ed0b0c4380ca0a05c148e4c833d1383c;p=thirdparty%2Flxc.git hooks: dhclient hook improvements - Merge dhclient-start and dhclient-stop into a single hook. - Wait for a lease before returning from the hook. - Generate a logfile when LXC log level is either DEBUG or TRACE. - Rely on namespace file descriptors for the stop hook. - Use settings from //lxc/dhclient.conf if available. - Attempt to cleanup if dhclient fails to shutdown properly. Signed-off-by: Jonathan Calmels --- diff --git a/.gitignore b/.gitignore index 8385ef793..f4b74c762 100644 --- a/.gitignore +++ b/.gitignore @@ -136,8 +136,7 @@ doc/manpage.refs doc/api/html/* hooks/unmount-namespace -hooks/dhclient-start -hooks/dhclient-stop +hooks/dhclient m4/ diff --git a/configure.ac b/configure.ac index 6bde154db..bf92f08db 100644 --- a/configure.ac +++ b/configure.ac @@ -889,8 +889,7 @@ AC_CONFIG_FILES([ doc/ko/see_also.sgml hooks/Makefile - hooks/dhclient-start - hooks/dhclient-stop + hooks/dhclient templates/Makefile templates/lxc-alpine diff --git a/hooks/Makefile.am b/hooks/Makefile.am index 90dd7d8c0..5ae73d72c 100644 --- a/hooks/Makefile.am +++ b/hooks/Makefile.am @@ -6,8 +6,7 @@ hooks_SCRIPTS = \ mountecryptfsroot \ ubuntu-cloud-prep \ dhclient-script \ - dhclient-start \ - dhclient-stop \ + dhclient \ squid-deb-proxy-client \ nvidia diff --git a/hooks/dhclient-start.in b/hooks/dhclient-start.in deleted file mode 100755 index 29a33645d..000000000 --- a/hooks/dhclient-start.in +++ /dev/null @@ -1,13 +0,0 @@ -#! /bin/bash - -set -e - -LXC_HOOK_DIR="@LXCHOOKDIR@" - -rootfs="${LXC_ROOTFS_PATH##*:}" -pidfile="${rootfs%/*}/dhclient.pid" - -mkdir -p "${rootfs}/var/lib/dhclient" - -nsenter -u -U -n -t "${LXC_PID}" -- \ - /sbin/dhclient -nw -1 -pf ${pidfile} -lf ${rootfs}/var/lib/dhclient/dhclient.leases -e ROOTFS=${rootfs} -sf ${LXC_HOOK_DIR}/dhclient-script diff --git a/hooks/dhclient-stop.in b/hooks/dhclient-stop.in deleted file mode 100755 index 63998aee5..000000000 --- a/hooks/dhclient-stop.in +++ /dev/null @@ -1,15 +0,0 @@ -#! /bin/bash - -set -e - -LXC_HOOK_DIR="@LXCHOOKDIR@" - -rootfs="${LXC_ROOTFS_PATH##*:}" -pidfile="${rootfs%/*}/dhclient.pid" - -# XXX Stop hook namespace arguments are wrong for some reason, those are the host namespaces not the container ones. -# Retrieve the namespaces from the dhclient pidfile instead. -nsenter -u -U -n -t $(< ${pidfile}) -- \ - /sbin/dhclient -r -pf ${pidfile} -lf ${rootfs}/var/lib/dhclient/dhclient.leases -e ROOTFS=${rootfs} -sf ${LXC_HOOK_DIR}/dhclient-script - -rm -f ${pidfile} diff --git a/hooks/dhclient.in b/hooks/dhclient.in new file mode 100755 index 000000000..d92107c5f --- /dev/null +++ b/hooks/dhclient.in @@ -0,0 +1,96 @@ +#! /bin/bash + +set -eu + +LXC_DHCP_SCRIPT="@LXCHOOKDIR@/dhclient-script" +LXC_DHCP_CONFIG="@SYSCONFDIR@/lxc/dhclient.conf" + +rootfs_path="${LXC_ROOTFS_PATH#*:}" +hookdir="${rootfs_path/%rootfs/hook}" + +conffile_arg="" +if [ -e "${LXC_DHCP_CONFIG}" ]; then + conffile_arg="-cf ${LXC_DHCP_CONFIG}" +fi + +debugfile="/dev/null" +if [ "${LXC_LOG_LEVEL}" = "DEBUG" ] || [ "${LXC_LOG_LEVEL}" = "TRACE" ]; then + debugfile="${hookdir}/dhclient.log" + echo "INFO: Writing dhclient log at ${debugfile}." >&2 +fi + +pidfile="${hookdir}/dhclient.pid" +leasefile="${hookdir}/dhclient.leases" + +usage() { + echo "Usage: ${0##*/} lxc {start-host|stop}" +} + +dhclient_start() { + ns_args=("--uts" "--net") + if [ -z "$(readlink /proc/${LXC_PID}/ns/user /proc/self/ns/user | uniq -d)" ]; then + ns_args+=("--user") + fi + + mkdir -p "${hookdir}" + + if [ -e "${pidfile}" ]; then + echo "WARN: DHCP client is already running, skipping start hook." >> "${debugfile}" + else + echo "INFO: Starting DHCP client and acquiring a lease..." >> "${debugfile}" + nsenter ${ns_args[@]} --target "${LXC_PID}" -- \ + /sbin/dhclient -1 ${conffile_arg} -pf "${pidfile}" -lf "${leasefile}" -e "ROOTFS=${rootfs_path}" -sf "${LXC_DHCP_SCRIPT}" -v >> "${debugfile}" 2>&1 + fi +} + +dhclient_stop() { + # We can't use LXC_PID here since the container process has exited, + # use the namespace file descriptors in the hook arguments instead. + ns_args=("") + if [ "${LXC_HOOK_VERSION:-0}" -eq 0 ]; then + for arg in "$@"; do + case "${arg}" in + uts:* | user:* | net:*) ns_args+=("--${arg/:/=}") ;; + *) ;; + esac + done + else + ns_args+=("--uts=${LXC_UTS_NS}") + ns_args+=("--net=${LXC_NET_NS}") + [ -n "${LXC_USER_NS:+x}" ] && ns_args+=("--user=${LXC_USER_NS}") + fi + + if [ -e "${pidfile}" ]; then + echo "INFO: Stopping DHCP client and releasing leases..." >> "${debugfile}" + nsenter ${ns_args[@]} -- \ + /sbin/dhclient -r ${conffile_arg} -pf "${pidfile}" -lf "${leasefile}" -e "ROOTFS=${rootfs_path}" -sf "${LXC_DHCP_SCRIPT}" -v >> "${debugfile}" 2>&1 + else + echo "WARN: DHCP client is not running, skipping stop hook." >> "${debugfile}" + fi + + # dhclient could fail to release the lease and shutdown, try to cleanup after ourselves just in case. + nsenter ${ns_args[@]} -- \ + /bin/sh -c 'pkill --ns $$ --nslist net -f "^/sbin/dhclient"' || true + rm -f "${pidfile}" +} + +HOOK_SECTION= +HOOK_TYPE= +case "${LXC_HOOK_VERSION:-0}" in + 0) HOOK_SECTION="${2:-}"; HOOK_TYPE="${3:-}"; shift 3;; + 1) HOOK_SECTION="${LXC_HOOK_SECTION:-}"; HOOK_TYPE="${LXC_HOOK_TYPE:-}";; + *) echo "ERROR: Unsupported hook version: ${LXC_HOOK_VERSION}." >&2; exit 1;; +esac + +if [ "${HOOK_SECTION}" != "lxc" ]; then + echo "ERROR: Not running through LXC." >&2 + exit 1 +fi + +case "${HOOK_TYPE}" in + start-host) dhclient_start $@;; + stop) dhclient_stop $@;; + *) usage; exit 1;; +esac + +exit 0