GNU bug report logs - #26099
[PATCH] services: Add inetd-service-type.

Previous Next

Package: guix-patches;

Reported by: Thomas Danckaert <post <at> thomasdanckaert.be>

Date: Tue, 14 Mar 2017 19:54:02 UTC

Severity: normal

Tags: patch

Done: Thomas Danckaert <post <at> thomasdanckaert.be>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 26099 in the body.
You can then email your comments to 26099 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#26099; Package guix-patches. (Tue, 14 Mar 2017 19:54:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Thomas Danckaert <post <at> thomasdanckaert.be>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Tue, 14 Mar 2017 19:54:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Thomas Danckaert <post <at> thomasdanckaert.be>
To: guix-patches <at> gnu.org
Subject: [PATCH] services: Add inetd-service-type.
Date: Tue, 14 Mar 2017 20:52:54 +0100 (CET)
[Message part 1 (text/plain, inline)]
Hi Guix,

this patch adds an inetd-service.  The service is configured using a list of <inetd-entry> records, which correspond to lines in the inetd.conf file (documented in the inetutils info manual).  The following example will start inetd with the built-in “echo” service, and with an smtp service, which uses ssh to tunnel smtp traffic to a server “smtp-server” behind a gateway “hostname”:

(service inetd-service-type
                           (list
                            (inetd-entry
                             (name "echo")
                             (socket-type 'stream)
                             (protocol "tcp")
                             (wait? #t)
                             (user "root")) ; no program and arguments fields required for inetd's "internal" services such as echo
                            (inetd-entry
                             (node "127.0.0.1")
                             (name "smtp")
                             (socket-type 'stream)
                             (protocol "tcp")
                             (wait? #f)
                             (user "root")
                             (program (file-append openssh "/bin/ssh"))
                             (arguments "-q -T -i /path/to/key -W smtp-server:25 user <at> hostname"))))

This will run inetd with a config file containing these 2 lines::
<---------------------------------------------------------------------------->
echo stream tcp wait root internal internal
127.0.0.1:smtp stream tcp nowait root /gnu/store/kdn1099drrdd2xbypg8x006a0aknskx8-openssh-7.4p1/bin/ssh -q -T -i /path/to/key -W smtp-server:25 user <at> hostname
<---------------------------------------------------------------------------->

The configuration doesn't include an “escape hatch” option where the user can specify an arbitrary inetd.conf, but I think the current configuration method captures all possibilities, and inetd's configuration format is unlikely to change radically?  Or perhaps the (inetd-config-file) procedure can be exported, so users can either use the procedure with a list of <inetd-entry>'s, or directly pass a (mixed-text-file) or any other file-like.

Obviously documentation is still missing, but I wanted to wait for a first round of comments before writing the docs.  Let me know if I should already include them anyway.

Thomas
[0001-services-Add-inetd-service-type.patch (text/x-patch, inline)]
From 85b01d04d8b140ed3a1960b1678cc133367b916b Mon Sep 17 00:00:00 2001
From: Thomas Danckaert <post <at> thomasdanckaert.be>
Date: Tue, 14 Mar 2017 18:12:34 +0100
Subject: [PATCH] services: Add inetd-service-type.

* gnu/services/networking.scm (<inetd-entry>): New record type.
(inetd-config-file, inetd-shepherd-service): New procedures.
(inetd-service-type): New variable.
---
 gnu/services/networking.scm | 64 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index 18bce2a2b..3fad77ab4 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2016 Efraim Flashner <efraim <at> flashner.co.il>
 ;;; Copyright © 2016 John Darrington <jmd <at> gnu.org>
 ;;; Copyright © 2017 Clément Lassieur <clement <at> lassieur.org>
+;;; Copyright © 2017 Thomas Danckaert <post <at> thomasdanckaert.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -61,6 +62,9 @@
             ntp-service
             ntp-service-type
 
+            inetd-entry
+            inetd-service-type
+
             tor-configuration
             tor-configuration?
             tor-hidden-service
@@ -429,6 +433,66 @@ make an initial adjustment of more than 1,000 seconds."
 
 
 ;;;
+;;; Inetd.
+;;;
+
+(define-record-type* <inetd-entry> inetd-entry make-inetd-entry
+  inetd-entry?
+  (node inetd-entry-node (default #f))   ;string or #f
+  (name inetd-entry-name)                ;string, from /etc/services
+  (socket-type inetd-entry-socket-type)  ;stream | dgram | raw | rdm | seqpacket
+  (protocol inetd-entry-protocol)        ;string, from /etc/protocols ("tcp", "udp", ...)
+  (wait? inetd-entry-wait? (default #t)) ;Boolean
+  (user inetd-entry-user)                ;string
+  (program inetd-entry-program           ;string or file-like
+           (default "internal"))
+  (arguments inetd-entry-arguments       ;string
+           (default "internal")))
+
+(define (inetd-config-file service-list)
+  (apply mixed-text-file "inetd.conf"
+         (fold-right ; The order of address lines in inetd.conf matters.
+          (lambda (s prev)
+            (append
+             (list
+              (let* ((node (inetd-entry-node s))
+                     (name (inetd-entry-name s))
+                     (socket
+                      (if node (string-append node ":" name) name))
+                     (type
+                      (match (inetd-entry-socket-type s)
+                        ((or 'stream 'dgram 'raw 'rdm 'seqpacket)
+                         (symbol->string (inetd-entry-socket-type s)))))
+                     (protocol (inetd-entry-protocol s))
+                     (wait (if (inetd-entry-wait? s) "wait" "nowait"))
+                     (user (inetd-entry-user s))
+                     (program (inetd-entry-program s))
+                     (args (inetd-entry-arguments s)))
+                #~(string-join
+                   (list #$@(list socket type protocol wait user program args))
+                   " "))
+              "\n") prev)) '() service-list)))
+
+(define (inetd-shepherd-service config)
+  (list
+   (shepherd-service
+    (documentation "Run inetd.")
+    (provision '(inetd))
+    (requirement '(user-processes networking syslogd))
+    (start #~(make-forkexec-constructor
+              (list (string-append #$inetutils "/libexec/inetd")
+                    #$(inetd-config-file config))
+              #:pid-file "/var/run/inetd.pid"))
+    (stop #~(make-kill-destructor)))))
+
+(define-public inetd-service-type
+  (service-type
+   (name 'inetd)
+   (extensions
+    (list (service-extension shepherd-root-service-type inetd-shepherd-service)))))
+
+
+;;;
 ;;; Tor.
 ;;;
 
-- 
2.11.1


Information forwarded to guix-patches <at> gnu.org:
bug#26099; Package guix-patches. (Wed, 15 Mar 2017 08:44:01 GMT) Full text and rfc822 format available.

Message #8 received at 26099 <at> debbugs.gnu.org (full text, mbox):

From: ludo <at> gnu.org (Ludovic Courtès)
To: Thomas Danckaert <post <at> thomasdanckaert.be>
Cc: 26099 <at> debbugs.gnu.org
Subject: Re: bug#26099: [PATCH] services: Add inetd-service-type.
Date: Wed, 15 Mar 2017 09:43:42 +0100
Hi Thomas,

Thomas Danckaert <post <at> thomasdanckaert.be> skribis:

> this patch adds an inetd-service.  The service is configured using a list of <inetd-entry> records, which correspond to lines in the inetd.conf file (documented in the inetutils info manual).  The following example will start inetd with the built-in “echo” service, and with an smtp service, which uses ssh to tunnel smtp traffic to a server “smtp-server” behind a gateway “hostname”:
>
> (service inetd-service-type
>                            (list
>                             (inetd-entry
>                              (name "echo")
>                              (socket-type 'stream)
>                              (protocol "tcp")
>                              (wait? #t)
>                              (user "root")) ; no program and arguments fields required for inetd's "internal" services such as echo
>                             (inetd-entry
>                              (node "127.0.0.1")
>                              (name "smtp")
>                              (socket-type 'stream)
>                              (protocol "tcp")
>                              (wait? #f)
>                              (user "root")
>                              (program (file-append openssh "/bin/ssh"))
>                              (arguments "-q -T -i /path/to/key -W smtp-server:25 user <at> hostname"))))

Very nice!

> The configuration doesn't include an “escape hatch” option where the user can specify an arbitrary inetd.conf, but I think the current configuration method captures all possibilities, and inetd's configuration format is unlikely to change radically?  Or perhaps the (inetd-config-file) procedure can be exported, so users can either use the procedure with a list of <inetd-entry>'s, or directly pass a (mixed-text-file) or any other file-like.

As you write, I think an escape hatch isn’t needed in this case.
<inetd-entry> is expressive enough and inetd.conf isn’t going to change
overnight.

> Obviously documentation is still missing, but I wanted to wait for a first round of comments before writing the docs.  Let me know if I should already include them anyway.

Sure.  :-)  Make sure to include an example like the one above (but wrap
lines to 80 chars).

Some very minor cosmetic comments:

> From 85b01d04d8b140ed3a1960b1678cc133367b916b Mon Sep 17 00:00:00 2001
> From: Thomas Danckaert <post <at> thomasdanckaert.be>
> Date: Tue, 14 Mar 2017 18:12:34 +0100
> Subject: [PATCH] services: Add inetd-service-type.
>
> * gnu/services/networking.scm (<inetd-entry>): New record type.
> (inetd-config-file, inetd-shepherd-service): New procedures.
> (inetd-service-type): New variable.

[...]

> +(define-record-type* <inetd-entry> inetd-entry make-inetd-entry
> +  inetd-entry?
> +  (node inetd-entry-node (default #f))   ;string or #f
> +  (name inetd-entry-name)                ;string, from /etc/services
> +  (socket-type inetd-entry-socket-type)  ;stream | dgram | raw | rdm | seqpacket
> +  (protocol inetd-entry-protocol)        ;string, from /etc/protocols ("tcp", "udp", ...)
> +  (wait? inetd-entry-wait? (default #t)) ;Boolean
> +  (user inetd-entry-user)                ;string
> +  (program inetd-entry-program           ;string or file-like
> +           (default "internal"))
> +  (arguments inetd-entry-arguments       ;string
> +           (default "internal")))

It would be nice to add a ‘package’ field that would default to
‘inetutils’, so that users can choose which package or variant inetd is
taken from.

> +(define (inetd-config-file service-list)
> +  (apply mixed-text-file "inetd.conf"
> +         (fold-right ; The order of address lines in inetd.conf matters.
> +          (lambda (s prev)

Please avoid one-letter identifier.  If it makes lines too long, you can
always move the ‘lambda’ to an internal ‘define’ above.

Also I have a slight preference for “services” rather than
“service-list”.  :-)

> +            (append
> +             (list
> +              (let* ((node (inetd-entry-node s))
> +                     (name (inetd-entry-name s))
> +                     (socket
> +                      (if node (string-append node ":" name) name))
> +                     (type
> +                      (match (inetd-entry-socket-type s)
> +                        ((or 'stream 'dgram 'raw 'rdm 'seqpacket)
> +                         (symbol->string (inetd-entry-socket-type s)))))
> +                     (protocol (inetd-entry-protocol s))
> +                     (wait (if (inetd-entry-wait? s) "wait" "nowait"))
> +                     (user (inetd-entry-user s))
> +                     (program (inetd-entry-program s))
> +                     (args (inetd-entry-arguments s)))
> +                #~(string-join
> +                   (list #$@(list socket type protocol wait user program args))
> +                   " "))
> +              "\n") prev)) '() service-list)))

I think you could just use (map entry->inetd.conf-line service-list),
where ‘entry->inetd.conf-line’ is the lambda above, no?

> +(define-public inetd-service-type
> +  (service-type
> +   (name 'inetd)
> +   (extensions
> +    (list (service-extension shepherd-root-service-type inetd-shepherd-service)))))

I think you also need to add ‘extend’ and ‘compose’ such that other
services (say, OpenSSH) can add inetd entries via service extensions.

Thank you!

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#26099; Package guix-patches. (Wed, 15 Mar 2017 08:48:02 GMT) Full text and rfc822 format available.

Message #11 received at 26099 <at> debbugs.gnu.org (full text, mbox):

From: ludo <at> gnu.org (Ludovic Courtès)
To: Thomas Danckaert <post <at> thomasdanckaert.be>
Cc: 26099 <at> debbugs.gnu.org
Subject: Re: bug#26099: [PATCH] services: Add inetd-service-type.
Date: Wed, 15 Mar 2017 09:47:07 +0100
Oh, I forgot to suggest writing a test.  :-)

I imagine it could test the built-in echo service and maybe a simple one
involving an external program.

Also:

>                             (arguments "-q -T -i /path/to/key -W smtp-server:25 user <at> hostname"))))

I think it would be nice if it were a list of strings rather than a
list.  We can always ‘string-join’ it when writing to inetd.conf.

That’s all!  :-)

Ludo’.




Information forwarded to guix-patches <at> gnu.org:
bug#26099; Package guix-patches. (Mon, 20 Mar 2017 21:13:02 GMT) Full text and rfc822 format available.

Message #14 received at 26099 <at> debbugs.gnu.org (full text, mbox):

From: Thomas Danckaert <post <at> thomasdanckaert.be>
To: 26099 <at> debbugs.gnu.org
Subject: Re: bug#26099: [PATCH] services: Add inetd-service-type.
Date: Mon, 20 Mar 2017 22:11:55 +0100 (CET)
[Message part 1 (text/plain, inline)]
Hi!

Thanks for the review.  I've attached an improved version of the 
patch.  Overview of what was changed:

 - some coding style changes as requested.

 - added an <inetd-configuration> type, which consists of a list and
   an optional "program" field, a file-like expression, default to
   (file-append inetutils "libexec/inetd").  I did it like this
   instead of adding a package field, because some packages put the
   inetd executable in a ".../bin" directory, others use ”.../sbin",
   en inetutils uses ".../libexec".

 - <inetd-entry> arguments field is now a list of strings/file-like
   objects.  It's much more useful like this!

 - added a test (new file tests/networking.scm, I stole a lot from 
the
   nginx-test code, without fully understanding the details, but it
   works!). The test uses the built-in echo, and a fantasy version of
   a dict service, implemented as a bash script :-)

 - added documentation.

Some questions:

 - AFAIU, there is currently no easy way to extend /etc/services with
   custom services in the os configuration?  Should we provide
   something like "sudoers-file" for services?

 - Does it make sense to provide more defaults in the inetd-entry?
   e.g. make user default to "root", make "nowait" the default, set a
   default socket type and protocol?  I've always used inetd for a
   very specific purpose, and have no idea what is the typical way
   people use it.

 - Should we provide configuration settings for all inetd command 
line
   arguments?  inetutils' inetd provides --environment, --pidfile,
   --resolve and --rate options.  I think other inetd's have still
   other arguments, so if we want the service to work with many
   different inetd implementations, providing the option to specifiy
   an arbitrary command line in the forkexec-constructor might be
   good?

 - Other inetd packages might (optionally) have slightly different
   configuration syntax.  e.g. openbsd-inetd (not packaged for Guix
   atm) provides some extra configuration options in the "wait" 
field.
   Perhaps add an “escape hatch” after all?

cheers!

Thomas
[0001-services-Add-inetd-service-type.patch (text/x-patch, inline)]
From 7df61f7d442cb5f97d84ece5cc427a13c678a3c3 Mon Sep 17 00:00:00 2001
From: Thomas Danckaert <post <at> thomasdanckaert.be>
Date: Tue, 14 Mar 2017 18:12:34 +0100
Subject: [PATCH] services: Add inetd-service-type.

* gnu/services/networking.scm (<inetd-configuration>, <inetd-entry>): New
record types.
(inetd-config-file, inetd-shepherd-service): New procedures.
(inetd-service-type): New variable.
* doc/guix.texi (Networking Services): Document it.
* gnu/tests/networking.scm: New file.
* gnu/local.mk: Add it.
---
 doc/guix.texi               |  93 +++++++++++++++++++++++++++-
 gnu/local.mk                |   1 +
 gnu/services/networking.scm |  89 +++++++++++++++++++++++++++
 gnu/tests/networking.scm    | 147 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 329 insertions(+), 1 deletion(-)
 create mode 100644 gnu/tests/networking.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index f4cc207e7..40eb30748 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -33,7 +33,8 @@ Copyright @copyright{} 2016 Alex ter Weele@*
 Copyright @copyright{} 2017 Clément Lassieur@*
 Copyright @copyright{} 2017 Mathieu Othacehe@*
 Copyright @copyright{} 2017 Federico Beffa@*
-Copyright @copyright{} 2017 Carlo Zancanaro
+Copyright @copyright{} 2017 Carlo Zancanaro@*
+Copyright @copyright{} 2017 Thomas Danckaert
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -9255,6 +9256,96 @@ make an initial adjustment of more than 1,000 seconds.
 List of host names used as the default NTP servers.
 @end defvr
 
+@cindex inetd
+@deffn {Scheme variable} inetd-service-type
+This service runs the inetd daemon.  inetd listens for connections on
+internet sockets, and can run various server programs to service
+requests on those sockets.
+
+The value of this service is an @code{inetd-configuration} object.  The
+following example configures the inetd daemon to provide the built-in
+@code{echo} service, as well as an smtp service forwards smtp traffic
+over ssh to a server @code{smtp-server} behind a gateway
+@code{hostname}:
+
+@example
+(service
+ inetd-service-type
+ (inetd-configuration
+  (entries (list
+            (inetd-entry
+             (name "echo")
+             (socket-type 'stream)
+             (protocol "tcp")
+             (wait? #f)
+             (user "root"))
+            (inetd-entry
+             (node "127.0.0.1")
+             (name "smtp")
+             (socket-type 'stream)
+             (protocol "tcp")
+             (wait? #f)
+             (user "root")
+             (program (file-append openssh "/bin/ssh"))
+             (arguments
+              '("ssh" "-qT" "-i" "/path/to/ssh_key"
+                "-W" "smtp-server:25" "user@@hostname")))))
+@end example
+
+See below for more details about @code{inetd-configuration}.
+@end deffn
+
+@deftp {Data Type} inetd-configuration
+Data type representing the configuration of inetd.
+
+@table @asis
+@item @code{program} (default: @code{(file-append inetutils "/libexec/inetd")})
+The inetd executable to use.
+
+@item @code{entries} (default: @code{'()})
+A list of inetd service entries.  Each entry should be created by the
+@code{inetd-entry} constructor.
+@end table
+@end deftp
+
+@deftp {Data Type} inetd-entry
+Data type representing an entry in the inetd configuration.  Each entry
+corresponds to a socket where inetd will listen for requests.
+
+@table @asis
+@item @code{node} (default: @code{#f})
+Optional string, a comma-separated list of local addresses inetd should
+use when listening for this service.  @xref{Configuration file,,,
+inetutils, GNU Inetutils} for a complete description of all options.
+@item @code{name}
+A string, the name must correspond to an entry in @code{/etc/services}.
+@item @code{socket-type}
+One of @code{'stream}, @code{'dgram}, @code{'raw}, @code{'rdm} or
+@code{'seqpacket}.
+@item @code{protocol}
+A string, must correspond to an entry in @code{/etc/protocols}.
+@item @code{wait?} (default: @code{#t})
+Whether inetd should wait for the server to exit before listening to new
+service requests.
+@item @code{user}
+A string containing the user (and, optionally, group) name of the user
+as whom the server should run.  The group name can be specified in a
+suffix, separated by a colon or period, i.e. @code{"user"},
+@code{"user:group"} or @code{"user.group"}.
+@item @code{program} (default: @code{"internal"})
+The server program which will serve the requests, or @code{"internal"}
+if inetd should use a built-in service.
+@item @code{arguments} (default: @code{'()})
+A list strings or file-like objects, which are the server program's
+arguments, starting with the zeroth argument, i.e. the name of the
+program itself.  For inetd's internal services, this entry must be
+@code{'()} or @code{'("internal")}.
+@end table
+
+@xref{Configuration file,,, inetutils, GNU Inetutils} for a more
+detailed discussion of each configuration field.
+@end deftp
+
 @cindex Tor
 @deffn {Scheme Procedure} tor-service [@var{config-file}] [#:tor @var{tor}]
 Return a service to run the @uref{https://torproject.org, Tor} anonymous
diff --git a/gnu/local.mk b/gnu/local.mk
index c1b076a5f..1fb1cb9d9 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -461,6 +461,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/tests/install.scm				\
   %D%/tests/mail.scm				\
   %D%/tests/messaging.scm			\
+  %D%/tests/networking.scm			\
   %D%/tests/ssh.scm				\
   %D%/tests/web.scm
 
diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index 18bce2a2b..553269359 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2016 Efraim Flashner <efraim <at> flashner.co.il>
 ;;; Copyright © 2016 John Darrington <jmd <at> gnu.org>
 ;;; Copyright © 2017 Clément Lassieur <clement <at> lassieur.org>
+;;; Copyright © 2017 Thomas Danckaert <post <at> thomasdanckaert.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -61,6 +62,10 @@
             ntp-service
             ntp-service-type
 
+            inetd-configuration
+            inetd-entry
+            inetd-service-type
+
             tor-configuration
             tor-configuration?
             tor-hidden-service
@@ -429,6 +434,90 @@ make an initial adjustment of more than 1,000 seconds."
 
 
 ;;;
+;;; Inetd.
+;;;
+
+(define-record-type* <inetd-configuration> inetd-configuration
+  make-inetd-configuration
+  inetd-configuration?
+  (program           inetd-configuration-program   ;file-like
+                     (default (file-append inetutils "/libexec/inetd")))
+  (entries           inetd-configuration-entries   ;list of <inetd-entry>
+                     (default '())))
+
+(define-record-type* <inetd-entry> inetd-entry make-inetd-entry
+  inetd-entry?
+  (node              inetd-entry-node         ;string or #f
+                     (default #f))
+  (name              inetd-entry-name)        ;string, from /etc/services
+
+  (socket-type       inetd-entry-socket-type) ;stream | dgram | raw |
+                                              ;rdm | seqpacket
+  (protocol          inetd-entry-protocol)    ;string, from /etc/protocols
+
+  (wait?             inetd-entry-wait?        ;Boolean
+                     (default #t))
+  (user              inetd-entry-user)        ;string
+
+  (program           inetd-entry-program      ;string or file-like object
+                     (default "internal"))
+  (arguments         inetd-entry-arguments    ;list of strings or file-like objects
+                     (default '())))
+
+(define (inetd-config-file entries)
+  (apply mixed-text-file "inetd.conf"
+         (map
+          (lambda (entry)
+            (let* ((node (inetd-entry-node entry))
+                   (name (inetd-entry-name entry))
+                   (socket
+                    (if node (string-append node ":" name) name))
+                   (type
+                    (match (inetd-entry-socket-type entry)
+                      ((or 'stream 'dgram 'raw 'rdm 'seqpacket)
+                       (symbol->string (inetd-entry-socket-type entry)))))
+                   (protocol (inetd-entry-protocol entry))
+                   (wait (if (inetd-entry-wait? entry) "wait" "nowait"))
+                   (user (inetd-entry-user entry))
+                   (program (inetd-entry-program entry))
+                   (args (inetd-entry-arguments entry)))
+              #~(string-append
+                 (string-join
+                  (list #$@(list socket type protocol wait user program) #$@args)
+                  " ") "\n")))
+          entries)))
+
+(define inetd-shepherd-service
+  (match-lambda
+    (($ <inetd-configuration> program ()) '()) ; empty list of entries -> do nothing
+    (($ <inetd-configuration> program entries)
+     (list
+      (shepherd-service
+       (documentation "Run inetd.")
+       (provision '(inetd))
+       (requirement '(user-processes networking syslogd))
+       (start #~(make-forkexec-constructor
+                 (list #$program #$(inetd-config-file entries))
+                 #:pid-file "/var/run/inetd.pid"))
+       (stop #~(make-kill-destructor)))))))
+
+(define-public inetd-service-type
+  (service-type
+   (name 'inetd)
+   (extensions
+    (list (service-extension shepherd-root-service-type
+                             inetd-shepherd-service)))
+
+   ;; The service can be extended with additional lists of entries.
+   (compose concatenate)
+   (extend (lambda (config entries)
+             (inetd-configuration
+              (inherit config)
+              (entries (append (inetd-configuration-entries config)
+                               entries)))))))
+
+
+;;;
 ;;; Tor.
 ;;;
 
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
new file mode 100644
index 000000000..531231409
--- /dev/null
+++ b/gnu/tests/networking.scm
@@ -0,0 +1,147 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Thomas Danckaert <post <at> thomasdanckaert.be>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu tests networking)
+  #:use-module (gnu tests)
+  #:use-module (gnu system)
+  #:use-module (gnu system grub)
+  #:use-module (gnu system file-systems)
+  #:use-module (gnu system shadow)
+  #:use-module (gnu system vm)
+  #:use-module (gnu services)
+  #:use-module (gnu services base)
+  #:use-module (gnu services networking)
+  #:use-module (guix gexp)
+  #:use-module (guix store)
+  #:use-module (guix monads)
+  #:use-module (gnu packages bash)
+  #:export (%test-inetd))
+
+(define %inetd-os
+  ;; Operating system with 2 inetd services.
+  (operating-system
+    (host-name "komputilo")
+    (timezone "Europe/Brussels")
+    (locale "en_US.utf8")
+
+    (bootloader (grub-configuration (device "/dev/sdX")))
+    (file-systems %base-file-systems)
+    (firmware '())
+    (users %base-user-accounts)
+    (services (cons* (dhcp-client-service)
+                     (service inetd-service-type
+                              (inetd-configuration
+                               (entries (list
+                                         (inetd-entry
+                                          (name "echo")
+                                          (socket-type 'stream)
+                                          (protocol "tcp")
+                                          (wait? #f)
+                                          (user "root"))
+                                         (inetd-entry
+                                          (name "dict")
+                                          (socket-type 'stream)
+                                          (protocol "tcp")
+                                          (wait? #f)
+                                          (user "root")
+                                          (program (file-append bash
+                                                                "/bin/bash"))
+                                          (arguments
+                                           (list "bash" (plain-file "my-dict.sh" "\
+while read line
+do
+    if [[ $line =~ ^DEFINE\\ (.*)$ ]]
+    then
+        case ${BASH_REMATCH[1]} in
+            Guix)
+                echo GNU Guix is a package management tool for the GNU system.
+                ;;
+            G-expression)
+                echo Like an S-expression but with a G.
+                ;;
+            *)
+                echo NO DEFINITION FOUND
+                ;;
+        esac
+    else
+        echo ERROR
+    fi
+done" ))))))))
+                     %base-services))))
+
+(define* (run-inetd-test)
+  "Run tests in %INETD-OS, where the inetd service provides an echo service on
+port 7, and a dict service on port 2628."
+  (mlet* %store-monad ((os -> (marionette-operating-system %inetd-os))
+                       (command (system-qemu-image/shared-store-script
+                                 os #:graphic? #f)))
+    (define test
+      (with-imported-modules '((gnu build marionette))
+        #~(begin
+            (use-modules (ice-9 rdelim)
+                         (srfi srfi-64)
+                         (gnu build marionette))
+            (define marionette
+              ;; Forward guest ports 7 and 2628 to host ports 8007 and 8628.
+              (make-marionette (list #$command "-net"
+                                     (string-append
+                                      "user"
+                                      ",hostfwd=tcp::8007-:7"
+                                      ",hostfwd=tcp::8628-:2628"))))
+
+            (mkdir #$output)
+            (chdir #$output)
+
+            (test-begin "inetd")
+
+            ;; Make sure the PID file is created.
+            (test-assert "PID file"
+              (marionette-eval
+               '(file-exists? "/var/run/inetd.pid")
+              marionette))
+
+            ;; Test the echo service.
+            (test-equal "echo response"
+              "Hello, Guix!"
+              (let ((echo (socket PF_INET SOCK_STREAM 0))
+                    (addr (make-socket-address AF_INET INADDR_LOOPBACK 8007)))
+                (begin
+                  (connect echo addr)
+                  (display "Hello, Guix!\n" echo)
+                  (read-line echo)))) ; TODO ensure socket is closed?
+
+            ;; Test the dict service
+            (test-equal "dict response"
+              "GNU Guix is a package management tool for the GNU system."
+              (let ((dict (socket PF_INET SOCK_STREAM 0))
+                    (addr (make-socket-address AF_INET INADDR_LOOPBACK 8628)))
+                (begin
+                  (connect dict addr)
+                  (display "DEFINE Guix\n" dict)
+                  (read-line dict))))
+
+            (test-end)
+            (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+    (gexp->derivation "inetd-test" test)))
+
+(define %test-inetd
+  (system-test
+   (name "inetd")
+   (description "Connect to a host with an INETD server.")
+   (value (run-inetd-test))))
-- 
2.11.1


Information forwarded to guix-patches <at> gnu.org:
bug#26099; Package guix-patches. (Wed, 22 Mar 2017 09:03:01 GMT) Full text and rfc822 format available.

Message #17 received at 26099 <at> debbugs.gnu.org (full text, mbox):

From: Thomas Danckaert <post <at> thomasdanckaert.be>
To: 26099 <at> debbugs.gnu.org
Subject: Re: bug#26099: [PATCH] services: Add inetd-service-type.
Date: Wed, 22 Mar 2017 10:02:24 +0100 (CET)
[Message part 1 (text/plain, inline)]
Previous patch still included a TODO in the tests, updated patch in 
attachment...

What is the idiomatic way to ensure a socket is closed when it's no 
longer needed?  I looked for something like a “with-open-socket” 
form, but that doesn't seem to exist.  My workaround feels a little 
clumsy:

              (let ((dict (socket PF_INET SOCK_STREAM 0))
                    (addr (make-socket-address AF_INET 
INADDR_LOOPBACK 8628)))
                (connect dict addr)
                (display "DEFINE Guix\n" dict)
                (let ((response (read-line dict)))
                  (close dict)
                  response)))

Thomas
[0001-services-Add-inetd-service-type.patch (text/x-patch, inline)]
From cf2a3450e9656bc2749492ddf40f5e35c7a73157 Mon Sep 17 00:00:00 2001
From: Thomas Danckaert <post <at> thomasdanckaert.be>
Date: Tue, 14 Mar 2017 18:12:34 +0100
Subject: [PATCH] services: Add inetd-service-type.

* gnu/services/networking.scm (<inetd-configuration>, <inetd-entry>): New
record types.
(inetd-config-file, inetd-shepherd-service): New procedures.
(inetd-service-type): New variable.
* doc/guix.texi (Networking Services): Document it.
* gnu/tests/networking.scm: New file.
* gnu/local.mk: Add it.
---
 doc/guix.texi               |  93 ++++++++++++++++++++++++++-
 gnu/local.mk                |   1 +
 gnu/services/networking.scm |  89 ++++++++++++++++++++++++++
 gnu/tests/networking.scm    | 149 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 331 insertions(+), 1 deletion(-)
 create mode 100644 gnu/tests/networking.scm

diff --git a/doc/guix.texi b/doc/guix.texi
index f4cc207e7..40eb30748 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -33,7 +33,8 @@ Copyright @copyright{} 2016 Alex ter Weele@*
 Copyright @copyright{} 2017 Clément Lassieur@*
 Copyright @copyright{} 2017 Mathieu Othacehe@*
 Copyright @copyright{} 2017 Federico Beffa@*
-Copyright @copyright{} 2017 Carlo Zancanaro
+Copyright @copyright{} 2017 Carlo Zancanaro@*
+Copyright @copyright{} 2017 Thomas Danckaert
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -9255,6 +9256,96 @@ make an initial adjustment of more than 1,000 seconds.
 List of host names used as the default NTP servers.
 @end defvr
 
+@cindex inetd
+@deffn {Scheme variable} inetd-service-type
+This service runs the inetd daemon.  inetd listens for connections on
+internet sockets, and can run various server programs to service
+requests on those sockets.
+
+The value of this service is an @code{inetd-configuration} object.  The
+following example configures the inetd daemon to provide the built-in
+@code{echo} service, as well as an smtp service forwards smtp traffic
+over ssh to a server @code{smtp-server} behind a gateway
+@code{hostname}:
+
+@example
+(service
+ inetd-service-type
+ (inetd-configuration
+  (entries (list
+            (inetd-entry
+             (name "echo")
+             (socket-type 'stream)
+             (protocol "tcp")
+             (wait? #f)
+             (user "root"))
+            (inetd-entry
+             (node "127.0.0.1")
+             (name "smtp")
+             (socket-type 'stream)
+             (protocol "tcp")
+             (wait? #f)
+             (user "root")
+             (program (file-append openssh "/bin/ssh"))
+             (arguments
+              '("ssh" "-qT" "-i" "/path/to/ssh_key"
+                "-W" "smtp-server:25" "user@@hostname")))))
+@end example
+
+See below for more details about @code{inetd-configuration}.
+@end deffn
+
+@deftp {Data Type} inetd-configuration
+Data type representing the configuration of inetd.
+
+@table @asis
+@item @code{program} (default: @code{(file-append inetutils "/libexec/inetd")})
+The inetd executable to use.
+
+@item @code{entries} (default: @code{'()})
+A list of inetd service entries.  Each entry should be created by the
+@code{inetd-entry} constructor.
+@end table
+@end deftp
+
+@deftp {Data Type} inetd-entry
+Data type representing an entry in the inetd configuration.  Each entry
+corresponds to a socket where inetd will listen for requests.
+
+@table @asis
+@item @code{node} (default: @code{#f})
+Optional string, a comma-separated list of local addresses inetd should
+use when listening for this service.  @xref{Configuration file,,,
+inetutils, GNU Inetutils} for a complete description of all options.
+@item @code{name}
+A string, the name must correspond to an entry in @code{/etc/services}.
+@item @code{socket-type}
+One of @code{'stream}, @code{'dgram}, @code{'raw}, @code{'rdm} or
+@code{'seqpacket}.
+@item @code{protocol}
+A string, must correspond to an entry in @code{/etc/protocols}.
+@item @code{wait?} (default: @code{#t})
+Whether inetd should wait for the server to exit before listening to new
+service requests.
+@item @code{user}
+A string containing the user (and, optionally, group) name of the user
+as whom the server should run.  The group name can be specified in a
+suffix, separated by a colon or period, i.e. @code{"user"},
+@code{"user:group"} or @code{"user.group"}.
+@item @code{program} (default: @code{"internal"})
+The server program which will serve the requests, or @code{"internal"}
+if inetd should use a built-in service.
+@item @code{arguments} (default: @code{'()})
+A list strings or file-like objects, which are the server program's
+arguments, starting with the zeroth argument, i.e. the name of the
+program itself.  For inetd's internal services, this entry must be
+@code{'()} or @code{'("internal")}.
+@end table
+
+@xref{Configuration file,,, inetutils, GNU Inetutils} for a more
+detailed discussion of each configuration field.
+@end deftp
+
 @cindex Tor
 @deffn {Scheme Procedure} tor-service [@var{config-file}] [#:tor @var{tor}]
 Return a service to run the @uref{https://torproject.org, Tor} anonymous
diff --git a/gnu/local.mk b/gnu/local.mk
index c1b076a5f..1fb1cb9d9 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -461,6 +461,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/tests/install.scm				\
   %D%/tests/mail.scm				\
   %D%/tests/messaging.scm			\
+  %D%/tests/networking.scm			\
   %D%/tests/ssh.scm				\
   %D%/tests/web.scm
 
diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index 18bce2a2b..553269359 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2016 Efraim Flashner <efraim <at> flashner.co.il>
 ;;; Copyright © 2016 John Darrington <jmd <at> gnu.org>
 ;;; Copyright © 2017 Clément Lassieur <clement <at> lassieur.org>
+;;; Copyright © 2017 Thomas Danckaert <post <at> thomasdanckaert.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -61,6 +62,10 @@
             ntp-service
             ntp-service-type
 
+            inetd-configuration
+            inetd-entry
+            inetd-service-type
+
             tor-configuration
             tor-configuration?
             tor-hidden-service
@@ -429,6 +434,90 @@ make an initial adjustment of more than 1,000 seconds."
 
 
 ;;;
+;;; Inetd.
+;;;
+
+(define-record-type* <inetd-configuration> inetd-configuration
+  make-inetd-configuration
+  inetd-configuration?
+  (program           inetd-configuration-program   ;file-like
+                     (default (file-append inetutils "/libexec/inetd")))
+  (entries           inetd-configuration-entries   ;list of <inetd-entry>
+                     (default '())))
+
+(define-record-type* <inetd-entry> inetd-entry make-inetd-entry
+  inetd-entry?
+  (node              inetd-entry-node         ;string or #f
+                     (default #f))
+  (name              inetd-entry-name)        ;string, from /etc/services
+
+  (socket-type       inetd-entry-socket-type) ;stream | dgram | raw |
+                                              ;rdm | seqpacket
+  (protocol          inetd-entry-protocol)    ;string, from /etc/protocols
+
+  (wait?             inetd-entry-wait?        ;Boolean
+                     (default #t))
+  (user              inetd-entry-user)        ;string
+
+  (program           inetd-entry-program      ;string or file-like object
+                     (default "internal"))
+  (arguments         inetd-entry-arguments    ;list of strings or file-like objects
+                     (default '())))
+
+(define (inetd-config-file entries)
+  (apply mixed-text-file "inetd.conf"
+         (map
+          (lambda (entry)
+            (let* ((node (inetd-entry-node entry))
+                   (name (inetd-entry-name entry))
+                   (socket
+                    (if node (string-append node ":" name) name))
+                   (type
+                    (match (inetd-entry-socket-type entry)
+                      ((or 'stream 'dgram 'raw 'rdm 'seqpacket)
+                       (symbol->string (inetd-entry-socket-type entry)))))
+                   (protocol (inetd-entry-protocol entry))
+                   (wait (if (inetd-entry-wait? entry) "wait" "nowait"))
+                   (user (inetd-entry-user entry))
+                   (program (inetd-entry-program entry))
+                   (args (inetd-entry-arguments entry)))
+              #~(string-append
+                 (string-join
+                  (list #$@(list socket type protocol wait user program) #$@args)
+                  " ") "\n")))
+          entries)))
+
+(define inetd-shepherd-service
+  (match-lambda
+    (($ <inetd-configuration> program ()) '()) ; empty list of entries -> do nothing
+    (($ <inetd-configuration> program entries)
+     (list
+      (shepherd-service
+       (documentation "Run inetd.")
+       (provision '(inetd))
+       (requirement '(user-processes networking syslogd))
+       (start #~(make-forkexec-constructor
+                 (list #$program #$(inetd-config-file entries))
+                 #:pid-file "/var/run/inetd.pid"))
+       (stop #~(make-kill-destructor)))))))
+
+(define-public inetd-service-type
+  (service-type
+   (name 'inetd)
+   (extensions
+    (list (service-extension shepherd-root-service-type
+                             inetd-shepherd-service)))
+
+   ;; The service can be extended with additional lists of entries.
+   (compose concatenate)
+   (extend (lambda (config entries)
+             (inetd-configuration
+              (inherit config)
+              (entries (append (inetd-configuration-entries config)
+                               entries)))))))
+
+
+;;;
 ;;; Tor.
 ;;;
 
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
new file mode 100644
index 000000000..53c80a4ac
--- /dev/null
+++ b/gnu/tests/networking.scm
@@ -0,0 +1,149 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Thomas Danckaert <post <at> thomasdanckaert.be>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu tests networking)
+  #:use-module (gnu tests)
+  #:use-module (gnu system)
+  #:use-module (gnu system grub)
+  #:use-module (gnu system file-systems)
+  #:use-module (gnu system shadow)
+  #:use-module (gnu system vm)
+  #:use-module (gnu services)
+  #:use-module (gnu services base)
+  #:use-module (gnu services networking)
+  #:use-module (guix gexp)
+  #:use-module (guix store)
+  #:use-module (guix monads)
+  #:use-module (gnu packages bash)
+  #:export (%test-inetd))
+
+(define %inetd-os
+  ;; Operating system with 2 inetd services.
+  (operating-system
+    (host-name "komputilo")
+    (timezone "Europe/Brussels")
+    (locale "en_US.utf8")
+
+    (bootloader (grub-configuration (device "/dev/sdX")))
+    (file-systems %base-file-systems)
+    (firmware '())
+    (users %base-user-accounts)
+    (services (cons* (dhcp-client-service)
+                     (service inetd-service-type
+                              (inetd-configuration
+                               (entries (list
+                                         (inetd-entry
+                                          (name "echo")
+                                          (socket-type 'stream)
+                                          (protocol "tcp")
+                                          (wait? #f)
+                                          (user "root"))
+                                         (inetd-entry
+                                          (name "dict")
+                                          (socket-type 'stream)
+                                          (protocol "tcp")
+                                          (wait? #f)
+                                          (user "root")
+                                          (program (file-append bash
+                                                                "/bin/bash"))
+                                          (arguments
+                                           (list "bash" (plain-file "my-dict.sh" "\
+while read line
+do
+    if [[ $line =~ ^DEFINE\\ (.*)$ ]]
+    then
+        case ${BASH_REMATCH[1]} in
+            Guix)
+                echo GNU Guix is a package management tool for the GNU system.
+                ;;
+            G-expression)
+                echo Like an S-expression but with a G.
+                ;;
+            *)
+                echo NO DEFINITION FOUND
+                ;;
+        esac
+    else
+        echo ERROR
+    fi
+done" ))))))))
+                     %base-services))))
+
+(define* (run-inetd-test)
+  "Run tests in %INETD-OS, where the inetd service provides an echo service on
+port 7, and a dict service on port 2628."
+  (mlet* %store-monad ((os -> (marionette-operating-system %inetd-os))
+                       (command (system-qemu-image/shared-store-script
+                                 os #:graphic? #f)))
+    (define test
+      (with-imported-modules '((gnu build marionette))
+        #~(begin
+            (use-modules (ice-9 rdelim)
+                         (srfi srfi-64)
+                         (gnu build marionette))
+            (define marionette
+              ;; Forward guest ports 7 and 2628 to host ports 8007 and 8628.
+              (make-marionette (list #$command "-net"
+                                     (string-append
+                                      "user"
+                                      ",hostfwd=tcp::8007-:7"
+                                      ",hostfwd=tcp::8628-:2628"))))
+
+            (mkdir #$output)
+            (chdir #$output)
+
+            (test-begin "inetd")
+
+            ;; Make sure the PID file is created.
+            (test-assert "PID file"
+              (marionette-eval
+               '(file-exists? "/var/run/inetd.pid")
+              marionette))
+
+            ;; Test the echo service.
+            (test-equal "echo response"
+              "Hello, Guix!"
+              (let ((echo (socket PF_INET SOCK_STREAM 0))
+                    (addr (make-socket-address AF_INET INADDR_LOOPBACK 8007)))
+                (connect echo addr)
+                (display "Hello, Guix!\n" echo)
+                (let ((response (read-line echo)))
+                  (close echo)
+                  response)))
+
+            ;; Test the dict service
+            (test-equal "dict response"
+              "GNU Guix is a package management tool for the GNU system."
+              (let ((dict (socket PF_INET SOCK_STREAM 0))
+                    (addr (make-socket-address AF_INET INADDR_LOOPBACK 8628)))
+                (connect dict addr)
+                (display "DEFINE Guix\n" dict)
+                (let ((response (read-line dict)))
+                  (close dict)
+                  response)))
+
+            (test-end)
+            (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+    (gexp->derivation "inetd-test" test)))
+
+(define %test-inetd
+  (system-test
+   (name "inetd")
+   (description "Connect to a host with an INETD server.")
+   (value (run-inetd-test))))
-- 
2.11.1


Information forwarded to guix-patches <at> gnu.org:
bug#26099; Package guix-patches. (Thu, 23 Mar 2017 22:08:02 GMT) Full text and rfc822 format available.

Message #20 received at 26099 <at> debbugs.gnu.org (full text, mbox):

From: ludo <at> gnu.org (Ludovic Courtès)
To: Thomas Danckaert <post <at> thomasdanckaert.be>
Cc: 26099 <at> debbugs.gnu.org
Subject: Re: bug#26099: [PATCH] services: Add inetd-service-type.
Date: Thu, 23 Mar 2017 23:07:10 +0100
Hi Thomas!

Thomas Danckaert <post <at> thomasdanckaert.be> skribis:

>  - added an <inetd-configuration> type, which consists of a list and
>    an optional "program" field, a file-like expression, default to
>    (file-append inetutils "libexec/inetd").  I did it like this
>    instead of adding a package field, because some packages put the
>    inetd executable in a ".../bin" directory, others use ”.../sbin",
>    en inetutils uses ".../libexec".

Good idea.

> Some questions:
>
>  - AFAIU, there is currently no easy way to extend /etc/services with
>    custom services in the os configuration?  Should we provide
>    something like "sudoers-file" for services?

To me /etc/services is supposed to be immutable.  However, if there’s a
need to add entries there, we should do something about it, but that’s
probably orthogonal to this patch (we could make ‘etc-service-type’ more
cutomizable to begin with, something I promised to Alex Kost long ago!).

>  - Does it make sense to provide more defaults in the inetd-entry?
>    e.g. make user default to "root", make "nowait" the default, set a
>    default socket type and protocol?  I've always used inetd for a
>    very specific purpose, and have no idea what is the typical way
>    people use it.

It’s probably fine this way.

>  - Should we provide configuration settings for all inetd command line
>    arguments?  inetutils' inetd provides --environment, --pidfile,
>    --resolve and --rate options.  I think other inetd's have still
>    other arguments, so if we want the service to work with many
>    different inetd implementations, providing the option to specifiy
>    an arbitrary command line in the forkexec-constructor might be
>    good?

I guess we can keep it this way for now maybe?

>  - Other inetd packages might (optionally) have slightly different
>    configuration syntax.  e.g. openbsd-inetd (not packaged for Guix
>    atm) provides some extra configuration options in the "wait" field.
>    Perhaps add an “escape hatch” after all?

I’d be in favor of keeping it this way for now and see what needs to be
done when the need arises.  One thing at a time.  ;-)

> What is the idiomatic way to ensure a socket is closed when it's no
> longer needed?  I looked for something like a “with-open-socket” form,
> but that doesn't seem to exist.  My workaround feels a little clumsy:
>
>               (let ((dict (socket PF_INET SOCK_STREAM 0))
>                     (addr (make-socket-address AF_INET INADDR_LOOPBACK
> 8628)))
>                 (connect dict addr)
>                 (display "DEFINE Guix\n" dict)
>                 (let ((response (read-line dict)))
>                   (close dict)
>                   response)))

We could do define a ‘with-open-socket’ macro, which would expand to
‘dynamic-wind’, which would close the socket when exiting the dynamic
extent of its body.  But for the tests, it’s OK to keep things simple.

> From cf2a3450e9656bc2749492ddf40f5e35c7a73157 Mon Sep 17 00:00:00 2001
> From: Thomas Danckaert <post <at> thomasdanckaert.be>
> Date: Tue, 14 Mar 2017 18:12:34 +0100
> Subject: [PATCH] services: Add inetd-service-type.
>
> * gnu/services/networking.scm (<inetd-configuration>, <inetd-entry>): New
> record types.
> (inetd-config-file, inetd-shepherd-service): New procedures.
> (inetd-service-type): New variable.
> * doc/guix.texi (Networking Services): Document it.
> * gnu/tests/networking.scm: New file.
> * gnu/local.mk: Add it.

[...]

> +@deffn {Scheme variable} inetd-service-type
> +This service runs the inetd daemon.  inetd listens for connections on
                                      ^
(@pxref{inetd invocation,,, inetutils, GNU Inetutils})
Also, @command{inetd}.

> +internet sockets, and can run various server programs to service
> +requests on those sockets.

After the comma, something like: “and lazily starts the specified server
program when a connection is made on one of the listening sockets.”
This emphasizes the “laziness” part, as opposed to what the Shepherd
does.

> +(define %test-inetd
> +  (system-test
> +   (name "inetd")
> +   (description "Connect to a host with an INETD server.")
> +   (value (run-inetd-test))))

Nice test, thanks a lot for taking the time to write it!

OK to push with these changes, thank you!

Ludo’.




bug closed, send any further explanations to 26099 <at> debbugs.gnu.org and Thomas Danckaert <post <at> thomasdanckaert.be> Request was from Thomas Danckaert <post <at> thomasdanckaert.be> to control <at> debbugs.gnu.org. (Fri, 24 Mar 2017 18:19:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 22 Apr 2017 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 8 years and 138 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.