* [bug#29732] [PATCH 0/1] Add a DHCP daemon service @ 2017-12-16 8:35 Chris Marusich 2017-12-16 8:52 ` [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration> Chris Marusich 2017-12-16 22:05 ` [bug#29732] [PATCH 0/1] Add a DHCP daemon service Christopher Baines 0 siblings, 2 replies; 11+ messages in thread From: Chris Marusich @ 2017-12-16 8:35 UTC (permalink / raw) To: 29732; +Cc: Chris Marusich Hi, The following patch adds a DHCP daemon service. It applies cleanly to commit 341bddb31542d03bef35b1234e6e9466be337798. I haven't found the time to add system tests yet, and I'm not sure how easy it would be to do that (wouldn't such a system test require at least two marionetted VMs? Or is it possible to do it with just one?). Any thoughts about how to do that would be welcome. In addition, I decided not to provide any kind of Guile scheme representation for the daemon's config file, since that was the quickest way for me to get a working DHCP daemon service. I think it makes sense to let a user specify a config file explicitly, like this patch does. I also think it would be neat to provide a way to configure the daemon in Guile scheme, like we do for other services such as openssh. Any thoughts on this front would be welcome, too. Chris Marusich (1): services: Add dhcpd-service-type and <dhcpd-configuration>. doc/guix.texi | 17 +++++++++++ gnu/services/networking.scm | 72 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) -- 2.15.1 ^ permalink raw reply [flat|nested] 11+ messages in thread
* [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration>. 2017-12-16 8:35 [bug#29732] [PATCH 0/1] Add a DHCP daemon service Chris Marusich @ 2017-12-16 8:52 ` Chris Marusich 2018-02-27 10:31 ` Clément Lassieur 2017-12-16 22:05 ` [bug#29732] [PATCH 0/1] Add a DHCP daemon service Christopher Baines 1 sibling, 1 reply; 11+ messages in thread From: Chris Marusich @ 2017-12-16 8:52 UTC (permalink / raw) To: 29732; +Cc: Chris Marusich * doc/guix.texi (Networking Services): Document it. * gnu/services/networking.scm (dhcpd-service-type): Add it. (dhcpd-configuration, dhcpd-configuration?): Add it. (dhcpd-configuration-package): Add it. (dhcpd-configuration-config-file): Add it. (dhcpd-configuration-ip-version): Add it. (dhcpd-configuration-run-directory): Add it. (dhcpd-configuration-lease-file): Add it. (dhcpd-configuration-pid-file): Add it. (dhcpd-configuration-interfaces): Add it. --- doc/guix.texi | 17 +++++++++++ gnu/services/networking.scm | 72 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/doc/guix.texi b/doc/guix.texi index 64f73b38a..3b62a0578 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -10357,6 +10357,23 @@ Return a service that runs @var{dhcp}, a Dynamic Host Configuration Protocol (DHCP) client, on all the non-loopback network interfaces. @end deffn +@deffn {Scheme Procedure} dhcpd-service-type +This type defines a DHCP daemon. To create a service of this type, you +must supply a @code{<dhcpd-configuration>}. For example: + +@example +(service dhcpd-service-type + (dhcpd-configuration (config-file (local-file "my-dhcpd.conf")) + (interfaces '("enp2s0f0")))) +@end example + +Here, @file{my-dhcpd.conf} is a local file that defines a valid +@command{dhcpd} configuration. Any ``file-like'' object will do here. +For example, you could use @code{plain-file} instead of +@code{local-file} if you prefer to embed the @code{dhcpd} configuration +file in your scheme code. +@end deffn + @defvr {Scheme Variable} static-networking-service-type This is the type for statically-configured network interfaces. @c TODO Document <static-networking> data structures. diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index b0c23aafc..d562b7011 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -55,6 +55,18 @@ static-networking-service static-networking-service-type dhcp-client-service + + dhcpd-service-type + dhcpd-configuration + dhcpd-configuration? + dhcpd-configuration-package + dhcpd-configuration-config-file + dhcpd-configuration-ip-version + dhcpd-configuration-run-directory + dhcpd-configuration-lease-file + dhcpd-configuration-pid-file + dhcpd-configuration-interfaces + %ntp-servers ntp-configuration @@ -338,6 +350,66 @@ to handle." Protocol (DHCP) client, on all the non-loopback network interfaces." (service dhcp-client-service-type dhcp)) +(define-record-type* <dhcpd-configuration> dhcpd-configuration + make-dhcpd-configuration + dhcpd-configuration? + (package dhcpd-configuration-package ;<package> + (default isc-dhcp)) + (config-file dhcpd-configuration-config-file ;file-like + (default #f)) + (ip-version dhcpd-ip-version ; either "4" or "6" + (default "4")) + (run-directory dhcpd-run-directory + (default "/run/dhcpd")) + (lease-file dhcpd-lease-file + (default "/var/db/dhcpd.leases")) + (pid-file dhcpd-pid-file + (default "/run/dhcpd/dhcpd.pid")) + (interfaces dhcpd-interfaces ; list of strings, e.g. (list "enp0s25") + (default '()))) + +(define dhcpd-shepherd-service + (match-lambda + (($ <dhcpd-configuration> package config-file ip-version _ lease-file pid-file interfaces) + (when (null-list? interfaces) + (error "Must specify at least one interface for DHCP daemon to use")) + (unless config-file + (error "Must supply a config-file")) + (list (shepherd-service + (provision '(dhcp-daemon)) + (documentation "Run the DHCP daemon.") + (requirement '(networking)) + (start #~(make-forkexec-constructor + '(#$(file-append package "/sbin/dhcpd") + #$(string-append "-" ip-version) + "-lf" #$lease-file + "-pf" #$pid-file + "-cf" #$config-file + #$@interfaces) + #:pid-file #$pid-file)) + (stop #~(make-kill-destructor))))))) + +(define dhcpd-activation + (match-lambda + (($ <dhcpd-configuration> package config-file _ run-directory lease-file _ _) + #~(begin + (unless (file-exists? #$run-directory) + (mkdir #$run-directory)) + ;; According to the DHCP manual (man dhcpd.leases), the lease + ;; database must be present for dhcpd to start successfully. + (unless (file-exists? #$lease-file) + (with-output-to-file #$lease-file + (lambda _ (display "")))) + ;; Validate the config. + (zero? (system* #$(file-append package "/sbin/dhcpd") "-t" "-cf" #$config-file)))))) + +(define dhcpd-service-type + (service-type + (name 'dhcpd) + (extensions + (list (service-extension shepherd-root-service-type dhcpd-shepherd-service) + (service-extension activation-service-type dhcpd-activation))))) + (define %ntp-servers ;; Default set of NTP servers. These URLs are managed by the NTP Pool project. ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact -- 2.15.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration>. 2017-12-16 8:52 ` [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration> Chris Marusich @ 2018-02-27 10:31 ` Clément Lassieur 2018-04-13 7:41 ` Chris Marusich 0 siblings, 1 reply; 11+ messages in thread From: Clément Lassieur @ 2018-02-27 10:31 UTC (permalink / raw) To: Chris Marusich; +Cc: 29732 Hi Chris, thank you for this service! A few comments: Chris Marusich <cmmarusich@gmail.com> writes: > * doc/guix.texi (Networking Services): Document it. > * gnu/services/networking.scm (dhcpd-service-type): Add it. > (dhcpd-configuration, dhcpd-configuration?): Add it. > (dhcpd-configuration-package): Add it. > (dhcpd-configuration-config-file): Add it. > (dhcpd-configuration-ip-version): Add it. > (dhcpd-configuration-run-directory): Add it. > (dhcpd-configuration-lease-file): Add it. > (dhcpd-configuration-pid-file): Add it. > (dhcpd-configuration-interfaces): Add it. > --- > doc/guix.texi | 17 +++++++++++ > gnu/services/networking.scm | 72 +++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 89 insertions(+) > > diff --git a/doc/guix.texi b/doc/guix.texi > index 64f73b38a..3b62a0578 100644 > --- a/doc/guix.texi > +++ b/doc/guix.texi > @@ -10357,6 +10357,23 @@ Return a service that runs @var{dhcp}, a Dynamic Host Configuration > Protocol (DHCP) client, on all the non-loopback network interfaces. > @end deffn > > +@deffn {Scheme Procedure} dhcpd-service-type > +This type defines a DHCP daemon. To create a service of this type, you > +must supply a @code{<dhcpd-configuration>}. For example: > + > +@example > +(service dhcpd-service-type > + (dhcpd-configuration (config-file (local-file "my-dhcpd.conf")) > + (interfaces '("enp2s0f0")))) > +@end example > + > +Here, @file{my-dhcpd.conf} is a local file that defines a valid > +@command{dhcpd} configuration. Any ``file-like'' object will do here. > +For example, you could use @code{plain-file} instead of > +@code{local-file} if you prefer to embed the @code{dhcpd} configuration > +file in your scheme code. > +@end deffn > + > @defvr {Scheme Variable} static-networking-service-type > This is the type for statically-configured network interfaces. > @c TODO Document <static-networking> data structures. > diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm > index b0c23aafc..d562b7011 100644 > --- a/gnu/services/networking.scm > +++ b/gnu/services/networking.scm > @@ -55,6 +55,18 @@ > static-networking-service > static-networking-service-type > dhcp-client-service > + > + dhcpd-service-type > + dhcpd-configuration > + dhcpd-configuration? > + dhcpd-configuration-package > + dhcpd-configuration-config-file > + dhcpd-configuration-ip-version > + dhcpd-configuration-run-directory > + dhcpd-configuration-lease-file > + dhcpd-configuration-pid-file > + dhcpd-configuration-interfaces > + > %ntp-servers > > ntp-configuration > @@ -338,6 +350,66 @@ to handle." > Protocol (DHCP) client, on all the non-loopback network interfaces." > (service dhcp-client-service-type dhcp)) > > +(define-record-type* <dhcpd-configuration> dhcpd-configuration > + make-dhcpd-configuration > + dhcpd-configuration? > + (package dhcpd-configuration-package ;<package> > + (default isc-dhcp)) > + (config-file dhcpd-configuration-config-file ;file-like > + (default #f)) > + (ip-version dhcpd-ip-version ; either "4" or "6" > + (default "4")) Upstream defaults to "6". I guess it's because they want to encourage people to use IPv6. Maybe we should respect their choice and default to "6" as well? > + (run-directory dhcpd-run-directory > + (default "/run/dhcpd")) > + (lease-file dhcpd-lease-file > + (default "/var/db/dhcpd.leases")) > + (pid-file dhcpd-pid-file > + (default "/run/dhcpd/dhcpd.pid")) I wonder, does it make sense to run two instances of the daemon, one for IPv4 and another for IPv6? Would having the IP version included in the pid file name make it possible? (dhcpd-4.pid and dhcp-6.pid) > + (interfaces dhcpd-interfaces ; list of strings, e.g. (list "enp0s25") > + (default '()))) I don't really understand the logic of the indentation and alignment of this whole block :-). > +(define dhcpd-shepherd-service > + (match-lambda > + (($ <dhcpd-configuration> package config-file ip-version _ lease-file pid-file interfaces) > + (when (null-list? interfaces) > + (error "Must specify at least one interface for DHCP daemon to use")) > + (unless config-file > + (error "Must supply a config-file")) > + (list (shepherd-service > + (provision '(dhcp-daemon)) > + (documentation "Run the DHCP daemon.") > + (requirement '(networking)) > + (start #~(make-forkexec-constructor > + '(#$(file-append package "/sbin/dhcpd") > + #$(string-append "-" ip-version) > + "-lf" #$lease-file > + "-pf" #$pid-file > + "-cf" #$config-file > + #$@interfaces) > + #:pid-file #$pid-file)) > + (stop #~(make-kill-destructor))))))) > + > +(define dhcpd-activation > + (match-lambda > + (($ <dhcpd-configuration> package config-file _ run-directory lease-file _ _) > + #~(begin > + (unless (file-exists? #$run-directory) > + (mkdir #$run-directory)) mkdir-p I guess > + ;; According to the DHCP manual (man dhcpd.leases), the lease > + ;; database must be present for dhcpd to start successfully. > + (unless (file-exists? #$lease-file) > + (with-output-to-file #$lease-file > + (lambda _ (display "")))) > + ;; Validate the config. > + (zero? (system* #$(file-append package "/sbin/dhcpd") "-t" "-cf" #$config-file)))))) > + > +(define dhcpd-service-type > + (service-type > + (name 'dhcpd) > + (extensions > + (list (service-extension shepherd-root-service-type dhcpd-shepherd-service) > + (service-extension activation-service-type dhcpd-activation))))) > + > (define %ntp-servers > ;; Default set of NTP servers. These URLs are managed by the NTP Pool project. > ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact Also, could you stick to 80 columns? Thank you! Clément ^ permalink raw reply [flat|nested] 11+ messages in thread
* [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration>. 2018-02-27 10:31 ` Clément Lassieur @ 2018-04-13 7:41 ` Chris Marusich 2018-04-13 9:02 ` Clément Lassieur 0 siblings, 1 reply; 11+ messages in thread From: Chris Marusich @ 2018-04-13 7:41 UTC (permalink / raw) To: Clément Lassieur; +Cc: 29732 [-- Attachment #1: Type: text/plain, Size: 4150 bytes --] Hi Clément and Ludo, Thank you for the review! Clément Lassieur <clement@lassieur.org> writes: >> + (ip-version dhcpd-ip-version ; either "4" or "6" >> + (default "4")) > > Upstream defaults to "6". I guess it's because they want to encourage > people to use IPv6. Maybe we should respect their choice and default to > "6" as well? Are you sure about this? The manual (man 8 dhcpd) says: COMMAND LINE OPTIONS -4 Run as a DHCP server. This is the default and cannot be combined with -6. -6 Run as a DHCPv6 server. This cannot be combined with -4. -4o6 port Participate in the DHCPv4 over DHCPv6 protocol specified by RFC 7341. This associates a DHCPv4 and a DHCPv6 server to allow the v4 server to receive v4 requests that were encapsulated in a v6 packet. Communication between the two servers is done on a pair of UDP sockets bound to ::1 port and port + 1. Both servers must be launched using the same port argument. I agree we should respect the default that upstream sets. Where did you see it indicated that upstream sets the default to 6? In addition, I didn't even know about the -4o6 option, but thankfully my patch would still allow someone to specify that as the ip-version, too. > I wonder, does it make sense to run two instances of the daemon, one for > IPv4 and another for IPv6? Would having the IP version included in the > pid file name make it possible? (dhcpd-4.pid and dhcp-6.pid) That would make it possible, yes. However, I think that it should be up to the user to decide whether or not to run two services. If they want to run two (or three) dhcpd services for the different IP protocol versions, then they should be able to do so easily. I might need to adjust the "provision" part of the dhcpd-shepherd-service to allow that, though. I'm not sure what happens if two services try to provision the same "provision" symbol - probably nothing good. >> + (interfaces dhcpd-interfaces ; list of strings, e.g. (list "enp0s25") >> + (default '()))) > > I don't really understand the logic of the indentation and alignment > of this whole block :-). I try to follow the indentation style mentioned in the Guix manual (see: (guix) Coding Style), but I may have let a few rough spots slip through. If you have specific suggestions for how to improve the indentation, I would be glad to hear them. >> +(define dhcpd-activation >> + (match-lambda >> + (($ <dhcpd-configuration> package config-file _ run-directory lease-file _ _) >> + #~(begin >> + (unless (file-exists? #$run-directory) >> + (mkdir #$run-directory)) > > mkdir-p I guess Yeah, that's probably better. I'll see about adjusting it. >> + ;; According to the DHCP manual (man dhcpd.leases), the lease >> + ;; database must be present for dhcpd to start successfully. >> + (unless (file-exists? #$lease-file) >> + (with-output-to-file #$lease-file >> + (lambda _ (display "")))) >> + ;; Validate the config. >> + (zero? (system* #$(file-append package "/sbin/dhcpd") "-t" "-cf" #$config-file)))))) >> + >> +(define dhcpd-service-type >> + (service-type >> + (name 'dhcpd) >> + (extensions >> + (list (service-extension shepherd-root-service-type dhcpd-shepherd-service) >> + (service-extension activation-service-type dhcpd-activation))))) >> + >> (define %ntp-servers >> ;; Default set of NTP servers. These URLs are managed by the NTP Pool project. >> ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact > > Also, could you stick to 80 columns? Certainly - looks like I accidentally missed a few long lines. I've got a new patch almost ready to share which will improve the formatting and, most importantly, add a couple tests! I'll try to clean it up and post it by the end of January. ;-) -- Chris [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 832 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration>. 2018-04-13 7:41 ` Chris Marusich @ 2018-04-13 9:02 ` Clément Lassieur 2018-04-17 5:51 ` Chris Marusich 0 siblings, 1 reply; 11+ messages in thread From: Clément Lassieur @ 2018-04-13 9:02 UTC (permalink / raw) To: Chris Marusich; +Cc: 29732 Chris Marusich <cmmarusich@gmail.com> writes: > Hi Clément and Ludo, > > Thank you for the review! > > Clément Lassieur <clement@lassieur.org> writes: > >>> + (ip-version dhcpd-ip-version ; either "4" or "6" >>> + (default "4")) >> >> Upstream defaults to "6". I guess it's because they want to encourage >> people to use IPv6. Maybe we should respect their choice and default to >> "6" as well? > > Are you sure about this? The manual (man 8 dhcpd) says: > > COMMAND LINE OPTIONS > -4 Run as a DHCP server. This is the default and cannot be > combined with -6. > > -6 Run as a DHCPv6 server. This cannot be combined with -4. > > -4o6 port > Participate in the DHCPv4 over DHCPv6 protocol specified > by RFC 7341. This associates a DHCPv4 and a DHCPv6 > server to allow the v4 server to receive v4 requests > that were encapsulated in a v6 packet. Communication > between the two servers is done on a pair of UDP sockets > bound to ::1 port and port + 1. Both servers must be > launched using the same port argument. > > I agree we should respect the default that upstream sets. Where did you > see it indicated that upstream sets the default to 6? Indeed, you are right. I saw it there: https://linux.die.net/man/8/dhcpd, but it seems like it's an old version of the documentation, which contains an error. The error was fixed in commit 802fdea172f0d2f59298a69efb7ccfd492feb7f0 of https://source.isc.org/git/dhcp.git - Documentation cleanup [ISC-Bugs #23326] Updated References document, several man page updates Which contains --8<---------------cut here---------------start------------->8--- modified server/dhcpd.8 @@ -28,7 +28,7 @@ .\" Support and other services are available for ISC products - see .\" https://www.isc.org for more information or to learn more about ISC. .\" -.\" $Id: dhcpd.8,v 1.34 2011/04/15 21:58:12 sar Exp $ +.\" $Id: dhcpd.8,v 1.35 2011/05/20 13:48:33 tomasz Exp $ .\" .TH dhcpd 8 .SH NAME @@ -190,11 +190,11 @@ possible, and listen for DHCP broadcasts on each interface. .SH COMMAND LINE OPTIONS .TP .BI \-4 -Run as a DHCP server. This cannot be combined with \fB\-6\fR. +Run as a DHCP server. This is the default and cannot be combined with +\fB\-6\fR. .TP .BI \-6 -Run as a DHCPv6 server. This is the default and cannot be combined -with \fB\-4\fR. +Run as a DHCPv6 server. This cannot be combined with \fB\-4\fR. .TP .BI \-p \ port The udp port number on which --8<---------------cut here---------------end--------------->8--- > In addition, I didn't even know about the -4o6 option, but thankfully my > patch would still allow someone to specify that as the ip-version, too. > >> I wonder, does it make sense to run two instances of the daemon, one for >> IPv4 and another for IPv6? Would having the IP version included in the >> pid file name make it possible? (dhcpd-4.pid and dhcp-6.pid) > > That would make it possible, yes. However, I think that it should be up > to the user to decide whether or not to run two services. If they want > to run two (or three) dhcpd services for the different IP protocol > versions, then they should be able to do so easily. I might need to > adjust the "provision" part of the dhcpd-shepherd-service to allow that, > though. I'm not sure what happens if two services try to provision the > same "provision" symbol - probably nothing good. > >>> + (interfaces dhcpd-interfaces ; list of strings, e.g. (list "enp0s25") >>> + (default '()))) >> >> I don't really understand the logic of the indentation and alignment >> of this whole block :-). > > I try to follow the indentation style mentioned in the Guix manual (see: > (guix) Coding Style), but I may have let a few rough spots slip through. > If you have specific suggestions for how to improve the indentation, I > would be glad to hear them. I don't remember why I said this, sorry about it. >>> +(define dhcpd-activation >>> + (match-lambda >>> + (($ <dhcpd-configuration> package config-file _ run-directory lease-file _ _) >>> + #~(begin >>> + (unless (file-exists? #$run-directory) >>> + (mkdir #$run-directory)) >> >> mkdir-p I guess > > Yeah, that's probably better. I'll see about adjusting it. > >>> + ;; According to the DHCP manual (man dhcpd.leases), the lease >>> + ;; database must be present for dhcpd to start successfully. >>> + (unless (file-exists? #$lease-file) >>> + (with-output-to-file #$lease-file >>> + (lambda _ (display "")))) >>> + ;; Validate the config. >>> + (zero? (system* #$(file-append package "/sbin/dhcpd") "-t" "-cf" #$config-file)))))) >>> + >>> +(define dhcpd-service-type >>> + (service-type >>> + (name 'dhcpd) >>> + (extensions >>> + (list (service-extension shepherd-root-service-type dhcpd-shepherd-service) >>> + (service-extension activation-service-type dhcpd-activation))))) >>> + >>> (define %ntp-servers >>> ;; Default set of NTP servers. These URLs are managed by the NTP Pool project. >>> ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact >> >> Also, could you stick to 80 columns? > > Certainly - looks like I accidentally missed a few long lines. I've got > a new patch almost ready to share which will improve the formatting and, > most importantly, add a couple tests! Cool! This one looks good to me anyway. > I'll try to clean it up and post it by the end of January. ;-) That's very ambitious! Take your time :-) ^ permalink raw reply [flat|nested] 11+ messages in thread
* [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration>. 2018-04-13 9:02 ` Clément Lassieur @ 2018-04-17 5:51 ` Chris Marusich 2018-04-18 20:28 ` Ludovic Courtès 0 siblings, 1 reply; 11+ messages in thread From: Chris Marusich @ 2018-04-17 5:51 UTC (permalink / raw) To: Clément Lassieur, Ludovic Courtès; +Cc: 29732 [-- Attachment #1.1: Type: text/plain, Size: 760 bytes --] Hi Clément and Ludo! Here's a new patch. It mainly tidies up some formatting, makes it possible to run more than one version of the DHCP daemon at the same time (e.g., for IPv4, IPv6, and IPv4 over IPv6), and adds a system test to verify that the DHCPv4 daemon can start up without error. I tried adding a test case for DHCPv6, but I ran into complications. Specifically, I'm not sure how to give an IPv6 address and subnet to the eth0 interface within the test VM using the static-networking-service. The DHCPv6 daemon requires the interface to have an IPv6 subnet configured, so it refuses to run on that interface. For now, it's nice enough, I think, that we have a DHCPv4 system test! Please let me know what you think. -- Chris [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1.2: 0001-services-Add-dhcpd-service-type-and-dhcpd-configurat.patch --] [-- Type: text/x-patch, Size: 9924 bytes --] From 5dd2e6853f1a332e55f3a4ba69b9baf199458fcb Mon Sep 17 00:00:00 2001 From: Chris Marusich <cmmarusich@gmail.com> Date: Sat, 16 Dec 2017 00:52:42 -0800 Subject: [PATCH] services: Add dhcpd-service-type and <dhcpd-configuration>. * doc/guix.texi (Networking Services): Document it. * gnu/services/networking.scm (dhcpd-service-type): Add it. (dhcpd-configuration, dhcpd-configuration?): Add it. (dhcpd-configuration-package): Add it. (dhcpd-configuration-config-file): Add it. (dhcpd-configuration-version): Add it. (dhcpd-configuration-run-directory): Add it. (dhcpd-configuration-lease-file): Add it. (dhcpd-configuration-pid-file): Add it. (dhcpd-configuration-interfaces): Add it. --- doc/guix.texi | 17 +++++++ gnu/services/networking.scm | 80 ++++++++++++++++++++++++++++++ gnu/tests/networking.scm | 97 ++++++++++++++++++++++++++++++++++++- 3 files changed, 193 insertions(+), 1 deletion(-) diff --git a/doc/guix.texi b/doc/guix.texi index d825f39e0..1875fb80a 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -10694,6 +10694,23 @@ Return a service that runs @var{dhcp}, a Dynamic Host Configuration Protocol (DHCP) client, on all the non-loopback network interfaces. @end deffn +@deffn {Scheme Procedure} dhcpd-service-type +This type defines a DHCP daemon. To create a service of this type, you +must supply a @code{<dhcpd-configuration>}. For example: + +@example +(service dhcpd-service-type + (dhcpd-configuration (config-file (local-file "my-dhcpd.conf")) + (interfaces '("enp2s0f0")))) +@end example + +Here, @file{my-dhcpd.conf} is a local file that defines a valid +@command{dhcpd} configuration. Any ``file-like'' object will do here. +For example, you could use @code{plain-file} instead of +@code{local-file} if you prefer to embed the @code{dhcpd} configuration +file in your scheme code. +@end deffn + @defvr {Scheme Variable} static-networking-service-type This is the type for statically-configured network interfaces. @c TODO Document <static-networking> data structures. diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index 6ac440fd2..7eb031861 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -57,6 +57,18 @@ static-networking-service static-networking-service-type dhcp-client-service + + dhcpd-service-type + dhcpd-configuration + dhcpd-configuration? + dhcpd-configuration-package + dhcpd-configuration-config-file + dhcpd-configuration-version + dhcpd-configuration-run-directory + dhcpd-configuration-lease-file + dhcpd-configuration-pid-file + dhcpd-configuration-interfaces + %ntp-servers ntp-configuration @@ -341,6 +353,74 @@ to handle." Protocol (DHCP) client, on all the non-loopback network interfaces." (service dhcp-client-service-type dhcp)) +(define-record-type* <dhcpd-configuration> + dhcpd-configuration make-dhcpd-configuration + dhcpd-configuration? + (package dhcpd-configuration-package ;<package> + (default isc-dhcp)) + (config-file dhcpd-configuration-config-file ;file-like + (default #f)) + (version dhcpd-configuration-version ;"4", "6", or "4o6" + (default "6")) + (run-directory dhcpd-configuration-run-directory + (default "/run/dhcpd")) + (lease-file dhcpd-configuration-lease-file + (default "/var/db/dhcpd.leases")) + (pid-file dhcpd-configuration-pid-file + (default "/run/dhcpd/dhcpd.pid")) + ;; list of strings, e.g. (list "enp0s25") + (interfaces dhcpd-configuration-interfaces + (default '()))) + +(define dhcpd-shepherd-service + (match-lambda + (($ <dhcpd-configuration> package config-file version run-directory + lease-file pid-file interfaces) + (when (null-list? interfaces) + (error "Must specify at least one interface for DHCP daemon to use")) + (unless config-file + (error "Must supply a config-file")) + (list (shepherd-service + ;; Allow users to easily run multiple versions simultaneously. + (provision (list (string->symbol + (string-append "dhcpv" version "-daemon")))) + (documentation (string-append "Run the DHCPv" version " daemon")) + (requirement '(networking)) + (start #~(make-forkexec-constructor + '(#$(file-append package "/sbin/dhcpd") + #$(string-append "-" version) + "-lf" #$lease-file + "-pf" #$pid-file + "-cf" #$config-file + #$@interfaces) + #:pid-file #$pid-file)) + (stop #~(make-kill-destructor))))))) + +(define dhcpd-activation + (match-lambda + (($ <dhcpd-configuration> package config-file version run-directory + lease-file pid-file interfaces) + (with-imported-modules '((guix build utils)) + #~(begin + (unless (file-exists? #$run-directory) + (mkdir #$run-directory)) + ;; According to the DHCP manual (man dhcpd.leases), the lease + ;; database must be present for dhcpd to start successfully. + (unless (file-exists? #$lease-file) + (with-output-to-file #$lease-file + (lambda _ (display "")))) + ;; Validate the config. + (invoke + #$(file-append package "/sbin/dhcpd") "-t" "-cf" + #$config-file)))))) + +(define dhcpd-service-type + (service-type + (name 'dhcpd) + (extensions + (list (service-extension shepherd-root-service-type dhcpd-shepherd-service) + (service-extension activation-service-type dhcpd-activation))))) + (define %ntp-servers ;; Default set of NTP servers. These URLs are managed by the NTP Pool project. ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm index d7d9166fa..171c636e5 100644 --- a/gnu/tests/networking.scm +++ b/gnu/tests/networking.scm @@ -29,7 +29,7 @@ #:use-module (gnu packages bash) #:use-module (gnu packages networking) #:use-module (gnu services shepherd) - #:export (%test-inetd %test-openvswitch)) + #:export (%test-inetd %test-openvswitch %test-dhcpd)) (define %inetd-os ;; Operating system with 2 inetd services. @@ -243,3 +243,98 @@ port 7, and a dict service on port 2628." (name "openvswitch") (description "Test a running OpenvSwitch configuration.") (value (run-openvswitch-test)))) + +\f +;;; +;;; DHCP Daemon +;;; + +(define minimal-dhcpd-v4-config-file + (plain-file "dhcpd.conf" + "\ +default-lease-time 600; +max-lease-time 7200; + +subnet 192.168.1.0 netmask 255.255.255.0 { + range 192.168.1.100 192.168.1.200; + option routers 192.168.1.1; + option domain-name-servers 192.168.1.2, 192.168.1.3; + option domain-name \"dummy.domain.name.abc123xyz\"; +} +")) + +(define dhcpd-v4-configuration + (dhcpd-configuration + (config-file minimal-dhcpd-v4-config-file) + (version "4") + (interfaces '("eth0")))) + +(define %dhcpd-os + (simple-operating-system + (static-networking-service "eth0" "192.168.1.4" + #:netmask "255.255.255.0" + #:gateway "192.168.1.1" + #:name-servers '("192.168.1.2" "192.168.1.3")) + (service dhcpd-service-type dhcpd-v4-configuration))) + +(define (run-dhcpd-test) + (define os + (marionette-operating-system %dhcpd-os + #:imported-modules '((gnu services herd)))) + + (define test + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (gnu build marionette) + (ice-9 popen) + (ice-9 rdelim) + (srfi srfi-64)) + + (define marionette + (make-marionette (list #$(virtual-machine os)))) + + (mkdir #$output) + (chdir #$output) + + (test-begin "dhcpd") + + (test-assert "pid file exists" + (marionette-eval + '(file-exists? + #$(dhcpd-configuration-pid-file dhcpd-v4-configuration)) + marionette)) + + (test-assert "lease file exists" + (marionette-eval + '(file-exists? + #$(dhcpd-configuration-lease-file dhcpd-v4-configuration)) + marionette)) + + (test-assert "run directory exists" + (marionette-eval + '(file-exists? + #$(dhcpd-configuration-run-directory dhcpd-v4-configuration)) + marionette)) + + (test-assert "dhcpd is alive" + (marionette-eval + '(begin + (use-modules (gnu services herd) + (srfi srfi-1)) + (live-service-running + (find (lambda (live) + (memq 'dhcpv4-daemon + (live-service-provision live))) + (current-services)))) + marionette)) + + (test-end) + (exit (= (test-runner-fail-count (test-runner-current)) 0))))) + + (gexp->derivation "dhcpd-test" test)) + +(define %test-dhcpd + (system-test + (name "dhcpd") + (description "Test a running DHCP daemon configuration.") + (value (run-dhcpd-test)))) -- 2.17.0 [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 832 bytes --] ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration>. 2018-04-17 5:51 ` Chris Marusich @ 2018-04-18 20:28 ` Ludovic Courtès 2018-04-22 7:44 ` bug#29732: " Chris Marusich 0 siblings, 1 reply; 11+ messages in thread From: Ludovic Courtès @ 2018-04-18 20:28 UTC (permalink / raw) To: Chris Marusich; +Cc: 29732, Clément Lassieur Hello Chris, Chris Marusich <cmmarusich@gmail.com> skribis: > Here's a new patch. It mainly tidies up some formatting, makes it > possible to run more than one version of the DHCP daemon at the same > time (e.g., for IPv4, IPv6, and IPv4 over IPv6), and adds a system test > to verify that the DHCPv4 daemon can start up without error. > > I tried adding a test case for DHCPv6, but I ran into complications. > Specifically, I'm not sure how to give an IPv6 address and subnet to the > eth0 interface within the test VM using the static-networking-service. > The DHCPv6 daemon requires the interface to have an IPv6 subnet > configured, so it refuses to run on that interface. OK. > For now, it's nice enough, I think, that we have a DHCPv4 system test! > Please let me know what you think. I agree, nice job! > From 5dd2e6853f1a332e55f3a4ba69b9baf199458fcb Mon Sep 17 00:00:00 2001 > From: Chris Marusich <cmmarusich@gmail.com> > Date: Sat, 16 Dec 2017 00:52:42 -0800 > Subject: [PATCH] services: Add dhcpd-service-type and <dhcpd-configuration>. > > * doc/guix.texi (Networking Services): Document it. > * gnu/services/networking.scm (dhcpd-service-type): Add it. > (dhcpd-configuration, dhcpd-configuration?): Add it. > (dhcpd-configuration-package): Add it. > (dhcpd-configuration-config-file): Add it. > (dhcpd-configuration-version): Add it. > (dhcpd-configuration-run-directory): Add it. > (dhcpd-configuration-lease-file): Add it. > (dhcpd-configuration-pid-file): Add it. > (dhcpd-configuration-interfaces): Add it. > --- > doc/guix.texi | 17 +++++++ > gnu/services/networking.scm | 80 ++++++++++++++++++++++++++++++ > gnu/tests/networking.scm | 97 ++++++++++++++++++++++++++++++++++++- Please mention the gnu/tests/networking.scm changes in the log. Otherwise LGTM, thank you! Ludo’. ^ permalink raw reply [flat|nested] 11+ messages in thread
* bug#29732: [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration>. 2018-04-18 20:28 ` Ludovic Courtès @ 2018-04-22 7:44 ` Chris Marusich 0 siblings, 0 replies; 11+ messages in thread From: Chris Marusich @ 2018-04-22 7:44 UTC (permalink / raw) To: Ludovic Courtès; +Cc: 29732-done, Clément Lassieur [-- Attachment #1: Type: text/plain, Size: 619 bytes --] ludo@gnu.org (Ludovic Courtès) writes: >> For now, it's nice enough, I think, that we have a DHCPv4 system test! >> Please let me know what you think. > > I agree, nice job! Thank you! I hope this service proves useful to somebody besides just me! > Please mention the gnu/tests/networking.scm changes in the log. Good catch; I've fixed the ChangeLog entry. I've also added documentation for <dhcpd-configuration> in the manual, since users deserve good documentation. I've committed all this as f1104d900978900addad731dfec4e0e6e5765fbe. Thank you both for your helpful review! -- Chris [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 832 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* [bug#29732] [PATCH 0/1] Add a DHCP daemon service 2017-12-16 8:35 [bug#29732] [PATCH 0/1] Add a DHCP daemon service Chris Marusich 2017-12-16 8:52 ` [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration> Chris Marusich @ 2017-12-16 22:05 ` Christopher Baines 2017-12-19 7:33 ` Chris Marusich 1 sibling, 1 reply; 11+ messages in thread From: Christopher Baines @ 2017-12-16 22:05 UTC (permalink / raw) To: Chris Marusich; +Cc: 29732 Chris Marusich writes: > Hi, > > The following patch adds a DHCP daemon service. It applies cleanly to > commit 341bddb31542d03bef35b1234e6e9466be337798. > > I haven't found the time to add system tests yet, and I'm not sure how > easy it would be to do that (wouldn't such a system test require at > least two marionetted VMs? Or is it possible to do it with just > one?). Any thoughts about how to do that would be welcome. > > In addition, I decided not to provide any kind of Guile scheme > representation for the daemon's config file, since that was the > quickest way for me to get a working DHCP daemon service. I think it > makes sense to let a user specify a config file explicitly, like this > patch does. I also think it would be neat to provide a way to > configure the daemon in Guile scheme, like we do for other services > such as openssh. Any thoughts on this front would be welcome, too. > > Chris Marusich (1): > services: Add dhcpd-service-type and <dhcpd-configuration>. > > doc/guix.texi | 17 +++++++++++ > gnu/services/networking.scm | 72 +++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 89 insertions(+) I had a quick look at the patch, and it looks good to me. A system test would be nice. I think the important thing to test is the Guix part of the service, so if it's possible to get it to start on a VM, I think just checking the status of the shepherd service would be a good test. I think not providing a Guile configuration approach is fine as well. Thanks, Chris ^ permalink raw reply [flat|nested] 11+ messages in thread
* [bug#29732] [PATCH 0/1] Add a DHCP daemon service 2017-12-16 22:05 ` [bug#29732] [PATCH 0/1] Add a DHCP daemon service Christopher Baines @ 2017-12-19 7:33 ` Chris Marusich 2018-02-27 9:48 ` Ludovic Courtès 0 siblings, 1 reply; 11+ messages in thread From: Chris Marusich @ 2017-12-19 7:33 UTC (permalink / raw) To: Christopher Baines; +Cc: 29732 [-- Attachment #1: Type: text/plain, Size: 458 bytes --] Christopher Baines <mail@cbaines.net> writes: > I had a quick look at the patch, and it looks good to me. Thank you for taking a look! > A system test would be nice. I think the important thing to test is the > Guix part of the service, so if it's possible to get it to start on a > VM, I think just checking the status of the shepherd service would be a > good test. OK. I'll find time to add something by the end of January. -- Chris [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 832 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* [bug#29732] [PATCH 0/1] Add a DHCP daemon service 2017-12-19 7:33 ` Chris Marusich @ 2018-02-27 9:48 ` Ludovic Courtès 0 siblings, 0 replies; 11+ messages in thread From: Ludovic Courtès @ 2018-02-27 9:48 UTC (permalink / raw) To: Chris Marusich; +Cc: 29732 Heya Chris, Looks like this patch is pretty much ready. Would you have time to take a look again? TIA, Ludo’. Chris Marusich <cmmarusich@gmail.com> skribis: > Christopher Baines <mail@cbaines.net> writes: > >> I had a quick look at the patch, and it looks good to me. > > Thank you for taking a look! > >> A system test would be nice. I think the important thing to test is the >> Guix part of the service, so if it's possible to get it to start on a >> VM, I think just checking the status of the shepherd service would be a >> good test. > > OK. I'll find time to add something by the end of January. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2018-04-22 7:45 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-12-16 8:35 [bug#29732] [PATCH 0/1] Add a DHCP daemon service Chris Marusich 2017-12-16 8:52 ` [bug#29732] [PATCH 1/1] services: Add dhcpd-service-type and <dhcpd-configuration> Chris Marusich 2018-02-27 10:31 ` Clément Lassieur 2018-04-13 7:41 ` Chris Marusich 2018-04-13 9:02 ` Clément Lassieur 2018-04-17 5:51 ` Chris Marusich 2018-04-18 20:28 ` Ludovic Courtès 2018-04-22 7:44 ` bug#29732: " Chris Marusich 2017-12-16 22:05 ` [bug#29732] [PATCH 0/1] Add a DHCP daemon service Christopher Baines 2017-12-19 7:33 ` Chris Marusich 2018-02-27 9:48 ` Ludovic Courtès
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/guix.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).