guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/01: services: Add ddclient service.


From: Oleg Pykhalov
Subject: 01/01: services: Add ddclient service.
Date: Wed, 29 Aug 2018 18:44:01 -0400 (EDT)

wigust pushed a commit to branch master
in repository guix.

commit 8490a8346b5c8207f5798be55bea1de865b0bd42
Author: Oleg Pykhalov <address@hidden>
Date:   Fri Jul 13 11:49:13 2018 +0300

    services: Add ddclient service.
    
    * gnu/services/dns.scm (ddclient-configuration, ddclient-service-type): New
    variables.
    (uglify-field-name, serialize-field, serialize-boolean, serialize-integer,
    serialize-string, serialize-list, serialize-extra-options,
    ddclient-activation, ddclient-shepherd-service,
    generate-ddclient-documentation): New procedures.
    * doc/guix.texi (DNS Services): Document it.
---
 doc/guix.texi        | 108 +++++++++++++++++++++++++++++++++
 gnu/services/dns.scm | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 275 insertions(+), 1 deletion(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index cd0e74a..97631d5 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -17263,6 +17263,114 @@ When false, disable negative caching.
 @end table
 @end deftp
 
address@hidden ddclient Service
+
address@hidden ddclient
+The ddclient service described below runs the ddclient daemon, which takes
+care of automatically updating DNS entries for service providers such as
address@hidden://dyn.com/dns/, Dyn}.
+
+The following example show instantiates the service with its default
+configuration:
+
address@hidden
+(service ddclient-service-type)
address@hidden example
+
+Note that ddclient needs to access credentials that are stored in a
address@hidden file}, by default @file{/etc/ddclient/secrets} (see
address@hidden below.)  You are expected to create this file manually, in
+an ``out-of-band'' fashion (you @emph{could} make this file part of the
+service configuration, for instance by using @code{plain-file}, but it will be
+world-readable @i{via} @file{/gnu/store}.)  See the examples in the
address@hidden/ddclient} directory of the @code{ddclient} package.
+
address@hidden %start of fragment
+
+Available @code{ddclient-configuration} fields are:
+
address@hidden address@hidden parameter} package ddclient
+The ddclient package.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} integer daemon
+The period after which ddclient will retry to check IP and domain name.
+
+Defaults to @samp{300}.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} boolean syslog
+Use syslog for the output.
+
+Defaults to @samp{#t}.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} string mail
+Mail to user.
+
+Defaults to @samp{"root"}.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} string mail-failure
+Mail failed update to user.
+
+Defaults to @samp{"root"}.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} string pid
+The ddclient PID file.
+
+Defaults to @samp{"/var/run/ddclient/ddclient.pid"}.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} boolean ssl
+Enable SSL support.
+
+Defaults to @samp{#t}.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} string user
+Specifies the user name or ID that is used when running ddclient
+program.
+
+Defaults to @samp{"ddclient"}.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} string group
+Group of the user who will run the ddclient program.
+
+Defaults to @samp{"ddclient"}.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} string secret-file
+Secret file which will be appended to @file{ddclient.conf} file.  This
+file contains credentials for use by ddclient.  You are expected to
+create it manually.
+
+Defaults to @samp{"/etc/ddclient/secrets.conf"}.
+
address@hidden deftypevr
+
address@hidden address@hidden parameter} list extra-options
+Extra options will be appended to @file{ddclient.conf} file.
+
+Defaults to @samp{()}.
+
address@hidden deftypevr
+
+
address@hidden %end of fragment
+
+
 @node VPN Services
 @subsubsection VPN Services
 @cindex VPN (virtual private network)
diff --git a/gnu/services/dns.scm b/gnu/services/dns.scm
index 2c57a36..16bd039 100644
--- a/gnu/services/dns.scm
+++ b/gnu/services/dns.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2017 Julien Lepiller <address@hidden>
+;;; Copyright © 2018 Oleg Pykhalov <address@hidden>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -45,7 +46,10 @@
             zone-entry
 
             dnsmasq-service-type
-            dnsmasq-configuration))
+            dnsmasq-configuration
+
+            ddclient-service-type
+            ddclient-configuration))
 
 ;;;
 ;;; Knot DNS.
@@ -670,3 +674,165 @@
                              (compose list dnsmasq-shepherd-service))))
    (default-value (dnsmasq-configuration))
    (description "Run the dnsmasq DNS server.")))
+
+
+;;;
+;;; ddclient
+;;;
+
+(define (uglify-field-name field-name)
+  (string-delete #\? (symbol->string field-name)))
+
+(define (serialize-field field-name val)
+  (format #t "~a=~a\n" (uglify-field-name field-name) val))
+
+(define (serialize-boolean field-name val)
+  (serialize-field field-name (if val "yes" "no")))
+
+(define (serialize-integer field-name val)
+  (serialize-field field-name (number->string val)))
+
+(define (serialize-string field-name val)
+  (if (and (string? val) (string=? val ""))
+      ""
+      (serialize-field field-name val)))
+
+(define (serialize-list field-name val)
+  (if (null? val) "" (serialize-field field-name (string-join val))))
+
+(define (serialize-extra-options extra-options)
+  (string-join extra-options "\n" 'suffix))
+
+(define-configuration ddclient-configuration
+  (ddclient
+   (package ddclient)
+   "The ddclient package.")
+  (daemon
+   (integer 300)
+   "The period after which ddclient will retry to check IP and domain name.")
+  (syslog
+   (boolean #t)
+   "Use syslog for the output.")
+  (mail
+   (string "root")
+   "Mail to user.")
+  (mail-failure
+   (string "root")
+   "Mail failed update to user.")
+  (pid
+   (string "/var/run/ddclient/ddclient.pid")
+   "The ddclient PID file.")
+  (ssl
+   (boolean #t)
+   "Enable SSL support.")
+  (user
+   (string "ddclient")
+   "Specifies the user name or ID that is used when running ddclient
+program.")
+  (group
+   (string "ddclient")
+   "Group of the user who will run the ddclient program.")
+  (secret-file
+   (string "/etc/ddclient/secrets.conf")
+   "Secret file which will be appended to @file{ddclient.conf} file.  This
+file contains credentials for use by ddclient.  You are expected to create it
+manually.")
+  (extra-options
+   (list '())
+   "Extra options will be appended to @file{ddclient.conf} file."))
+
+(define (ddclient-account config)
+  "Return the user accounts and user groups for CONFIG."
+  (let ((ddclient-user (ddclient-configuration-user config))
+        (ddclient-group (ddclient-configuration-group config)))
+    (list (user-group
+           (name ddclient-group)
+           (system? #t))
+          (user-account
+           (name ddclient-user)
+           (system? #t)
+           (group ddclient-group)
+           (comment "ddclientd privilege separation user")
+           (home-directory (string-append "/var/run/" ddclient-user))))))
+
+(define (ddclient-activation config)
+  "Return the activation GEXP for CONFIG."
+  (with-imported-modules '((guix build utils)
+                           (ice-9 rdelim))
+    #~(begin
+        (use-modules (guix build utils)
+                     (ice-9 rdelim))
+        (let ((ddclient-user
+               #$(passwd:uid (getpw (ddclient-configuration-user config))))
+              (ddclient-group
+               #$(passwd:gid (getpw (ddclient-configuration-group config))))
+              (ddclient-secret-file
+               #$(ddclient-configuration-secret-file config)))
+          ;; 'ddclient' complains about ddclient.conf file permissions, which
+          ;; rules out /gnu/store.  Thus we copy the ddclient.conf to /etc.
+          (for-each (lambda (dir)
+                      (mkdir-p dir)
+                      (chmod dir #o700)
+                      (chown dir ddclient-user ddclient-group))
+                    '("/var/cache/ddclient" "/var/run/ddclient"
+                      "/etc/ddclient"))
+          (with-output-to-file "/etc/ddclient/ddclient.conf"
+            (lambda ()
+              (display
+               (string-append
+                "# Generated by 'ddclient-service'.\n\n"
+                #$(with-output-to-string
+                    (lambda ()
+                      (serialize-configuration config
+                                               ddclient-configuration-fields)))
+                (if (string-null? ddclient-secret-file)
+                    ""
+                    (format #f "\n\n# Appended from '~a'.\n\n~a"
+                            ddclient-secret-file
+                            (with-input-from-file ddclient-secret-file
+                              read-string)))))))
+          (chmod "/etc/ddclient/ddclient.conf" #o600)
+          (chown "/etc/ddclient/ddclient.conf"
+                 ddclient-user ddclient-group)))))
+
+(define (ddclient-shepherd-service config)
+  "Return a <shepherd-service> for ddclient with CONFIG."
+  (let ((ddclient (ddclient-configuration-ddclient config))
+        (ddclient-pid (ddclient-configuration-pid config))
+        (ddclient-user (ddclient-configuration-user config))
+        (ddclient-group (ddclient-configuration-group config)))
+    (list (shepherd-service
+           (provision '(ddclient))
+           (documentation "Run ddclient daemon.")
+           (start #~(make-forkexec-constructor
+                     (list #$(file-append ddclient "/bin/ddclient")
+                           "-foreground"
+                           "-file" "/etc/ddclient/ddclient.conf")
+                     #:pid-file #$ddclient-pid
+                     #:environment-variables
+                     (list "SSL_CERT_DIR=/run/current-system/profile\
+/etc/ssl/certs"
+                           "SSL_CERT_FILE=/run/current-system/profile\
+/etc/ssl/certs/ca-certificates.crt")
+                     #:user #$ddclient-user
+                     #:group #$ddclient-group))
+           (stop #~(make-kill-destructor))))))
+
+(define ddclient-service-type
+  (service-type
+   (name 'ddclient)
+   (extensions
+    (list (service-extension account-service-type
+                             ddclient-account)
+          (service-extension shepherd-root-service-type
+                             ddclient-shepherd-service)
+          (service-extension activation-service-type
+                             ddclient-activation)))
+   (default-value (ddclient-configuration))
+   (description "Configure address updating utility for dynamic DNS services,
+ddclient.")))
+
+(define (generate-ddclient-documentation)
+  (generate-documentation
+   `((ddclient-configuration ,ddclient-configuration-fields))
+   'ddclient-configuration))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]