diff mbox series

[bug#72072] gnu: isc-dhcp: Patch dhclient to support resolvconf.

Message ID 2PLKK1GND1Y65.3DPU3DJOTRHJH@wilsonb.com
State New
Headers show
Series [bug#72072] gnu: isc-dhcp: Patch dhclient to support resolvconf. | expand

Commit Message

B. Wilson July 12, 2024, 9:50 a.m. UTC
Hey Guix,

This patch updates libexec/dhclient-script to use resolvconf instead of
directly editing /etc/resolv.conf, similar to dhcpcd and friends.

This allows dhclient to play nicely with other clients which may want to
contend for /etc/resolv.conf control. My particular use case is running a local
dnsmasq instance, configured to allow using the various DNS servers of multiple
simultaneous VPN connections.

Ideally, this would be an upstream patch, but ISC announced end of maintenance
in 2022, so until we migrate dhcp-client-service-type to something else, I
believe it makes sense to have the patch here.

Using a bare-bones.scm VM, I have confirmed that this transparently works in
the default case where no /etc/resolvconf.conf is setup. In a separate patch, I
will be sharing my resolvconf-service-type definition that enables the dnsmasq
integration I mention.

Note, however, that switching to this via a system reconfigure has the
possibility of nuking DNS until the next time dhclient tries to update them.
Simply restarting the networking service is enough to force this, though.

Thoughts?
diff mbox series

Patch

From c96e6489117b2087db86161cc2b3fe0e813ac09f Mon Sep 17 00:00:00 2001
From: "B. Wilson" <elaexuotee@wilsonb.com>
Date: Fri, 12 Jul 2024 18:03:48 +0900
Subject: [PATCH] gnu: isc-dhcp: Patch dhclient to support resolvconf.

* gnu/packages/patches/dhclient-script-resolvconf-support.patch: New patch.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/admin.scm (isc-dhcp): Patch dhclient-script and update wrapper.
---
 gnu/local.mk                                  |  1 +
 gnu/packages/admin.scm                        | 21 ++++---
 .../dhclient-script-resolvconf-support.patch  | 58 +++++++++++++++++++
 3 files changed, 72 insertions(+), 8 deletions(-)
 create mode 100644 gnu/packages/patches/dhclient-script-resolvconf-support.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index ea4cc251ae..e574154ef3 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1116,6 +1116,7 @@  dist_patch_DATA =						\
   %D%/packages/patches/debops-debops-defaults-fall-back-to-less.patch \
   %D%/packages/patches/dee-vapi.patch			\
   %D%/packages/patches/dfu-programmer-fix-libusb.patch		\
+  %D%/packages/patches/dhclient-script-resolvconf-support.patch	\
   %D%/packages/patches/diffutils-fix-signal-processing.patch	\
   %D%/packages/patches/directfb-davinci-glibc-228-compat.patch	\
   %D%/packages/patches/dkimproxy-add-ipv6-support.patch		\
diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index f0aa6adc85..509dfaba20 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -1477,7 +1477,9 @@  (define-public isc-dhcp
                                     version "/dhcp-" version ".tar.gz"))
                 (sha256
                  (base32
-                  "1ivkvhhvqxap6c51cli7pa6xn76ngxri1zbl45ishz4ranxidi0a"))))
+                  "1ivkvhhvqxap6c51cli7pa6xn76ngxri1zbl45ishz4ranxidi0a"))
+                (patches (search-patches
+                           "dhclient-script-resolvconf-support.patch"))))
       (build-system gnu-build-system)
       (arguments
        `(#:parallel-build? #f
@@ -1571,12 +1573,13 @@  (define-public isc-dhcp
              (lambda* (#:key inputs outputs #:allow-other-keys)
                ;; Install the dhclient script for GNU/Linux and make sure
                ;; if finds all the programs it needs.
-               (let* ((out       (assoc-ref outputs "out"))
-                      (libexec   (string-append out "/libexec"))
-                      (coreutils (assoc-ref inputs "coreutils*"))
-                      (inetutils (assoc-ref inputs "inetutils"))
-                      (grep      (assoc-ref inputs "grep*"))
-                      (sed       (assoc-ref inputs "sed*"))
+               (let* ((out        (assoc-ref outputs "out"))
+                      (libexec    (string-append out "/libexec"))
+                      (coreutils  (assoc-ref inputs "coreutils*"))
+                      (inetutils  (assoc-ref inputs "inetutils"))
+                      (grep       (assoc-ref inputs "grep*"))
+                      (resolvconf (assoc-ref inputs "resolvconf*"))
+                      (sed        (assoc-ref inputs "sed*"))
                       (debianutils (assoc-ref inputs "debianutils")))
                  (substitute* "client/scripts/linux"
                    (("/sbin/ip")
@@ -1592,7 +1595,8 @@  (define-public isc-dhcp
                      ,(map (lambda (dir)
                              (string-append dir "/bin:"
                                             dir "/sbin"))
-                           (list inetutils coreutils grep sed debianutils))))))))))
+                           (list inetutils coreutils grep sed resolvconf
+                                 debianutils))))))))))
 
       (native-inputs
        (list config perl file))
@@ -1621,6 +1625,7 @@  (define-public isc-dhcp
 
                 ("coreutils*" ,coreutils)
                 ("grep*" ,grep)
+                ("resolvconf*" ,openresolv)
                 ("sed*" ,sed)))
 
       (home-page "https://www.isc.org/dhcp/")
diff --git a/gnu/packages/patches/dhclient-script-resolvconf-support.patch b/gnu/packages/patches/dhclient-script-resolvconf-support.patch
new file mode 100644
index 0000000000..e4fd8f649e
--- /dev/null
+++ b/gnu/packages/patches/dhclient-script-resolvconf-support.patch
@@ -0,0 +1,58 @@ 
+Implement resolvconf support
+
+Due to the potential for multiple sources contenting for /etc/resol.conf
+control, this patch replaces direct file munging with resolvconf indirection.
+
+--- a/client/scripts/linux	1970-01-01 09:00:01.000000000 +0900
++++ b/client/scripts/linux	1970-01-01 09:00:01.000000000 +0900
+@@ -36,11 +36,11 @@
+ # This updated version mostly follows Debian script by Andrew Pollock et al.
+ make_resolv_conf() {
+     local new_resolv_conf
++    new_resolv_conf=$(mktemp)
+ 
+     # DHCPv4
+     if [ -n "$new_domain_search" ] || [ -n "$new_domain_name" ] ||
+-       [ -n "$new_domain_name_servers" ]; then
+-        new_resolv_conf=/etc/resolv.conf.dhclient-new
++        [ -n "$new_domain_name_servers" ]; then
+         rm -f $new_resolv_conf
+ 
+         if [ -n "$new_domain_name" ]; then
+@@ -70,17 +70,12 @@
+                 echo nameserver $nameserver >>$new_resolv_conf
+             done
+         else # keep 'old' nameservers
+-            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf
++            resolvconf -l "$interface.dhcp" | sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p >>$new_resolv_conf
+         fi
+ 
+-	if [ -f /etc/resolv.conf ]; then
+-	    chown --reference=/etc/resolv.conf $new_resolv_conf
+-	    chmod --reference=/etc/resolv.conf $new_resolv_conf
+-	fi
+-        mv -f $new_resolv_conf /etc/resolv.conf
++        resolvconf -a "$interface.dhpc" <"$new_resolv_conf"
+     # DHCPv6
+     elif [ -n "$new_dhcp6_domain_search" ] || [ -n "$new_dhcp6_name_servers" ]; then
+-        new_resolv_conf=/etc/resolv.conf.dhclient-new
+         rm -f $new_resolv_conf
+ 
+         if [ -n "$new_dhcp6_domain_search" ]; then
+@@ -97,14 +92,10 @@
+                 echo nameserver $nameserver >>$new_resolv_conf
+             done
+         else # keep 'old' nameservers
+-            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf
++            resolvconf -l "$interface.dhcp6" | sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p >>$new_resolv_conf
+         fi
+ 
+-	if [ -f /etc/resolv.conf ]; then
+-            chown --reference=/etc/resolv.conf $new_resolv_conf
+-            chmod --reference=/etc/resolv.conf $new_resolv_conf
+-	fi
+-        mv -f $new_resolv_conf /etc/resolv.conf
++        resolvconf -a "$interface.dhpc6" <"$new_resolv_conf"
+     fi
+ }
+ 
-- 
2.45.2