~ruther/guix-local

82ccc499f7262982beb2da9827d5706967a334f0 — Carlo Zancanaro 9 years ago 79f09fa
services: Add exim-service-type.

* gnu/services/mail.scm (<exim-configuration>): New record type.
(exim-computed-config-file, exim-shepherd-service, exim-activation, exim-etc,
exim-profile): New procedures.
(exim-service-type, %exim-accounts): New variables.
* doc/guix.text (Mail Services): Document it.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2 files changed, 142 insertions(+), 2 deletions(-)

M doc/guix.texi
M gnu/services/mail.scm
M doc/guix.texi => doc/guix.texi +41 -1
@@ 32,7 32,8 @@ Copyright @copyright{} 2016 Julien Lepiller@*
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 Federico Beffa@*
Copyright @copyright{} 2017 Carlo Zancanaro

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or


@@ 12206,6 12207,45 @@ remote servers.  Run @command{man smtpd.conf} for more information.
@end table
@end deftp

@subsubheading Exim Service

@deffn {Scheme Variable} exim-service-type
This is the type of the @uref{https://exim.org, Exim} service, whose value
should be an @code{exim-configuration} object as in this example:

@example
(service exim-service-type
         (exim-configuration
           (config-file (local-file "./my-exim.conf"))
           (aliases '(("postmaster" "bob")
                      ("bob" "bob@@example.com" "bob@@example2.com")))))
@end example
@end deffn

@deftp {Data Type} exim-configuration
Data type representing the configuration of exim.

@table @asis
@item @code{package} (default: @var{exim})
Package object of the Exim server.

@item @code{config-file} (default: @code{#f})
File-like object of the Exim configuration file to use. If its value is
@code{#f} then use the default configuration file from the package
provided in @code{package}. The resulting configuration file is loaded
after setting the @code{exim_user} and @code{exim_group} configuration
variables.

@item @code{aliases} (default: @code{'()})
List of aliases to use when delivering mail on this system. The
@code{car} of each list is used to match incoming mail, with the
@code{cdr} of each list designating how to deliver it. There may be many
delivery methods provided, in which case the mail is delivered to them
all.

@end table
@end deftp

@node Messaging Services
@subsubsection Messaging Services


M gnu/services/mail.scm => gnu/services/mail.scm +101 -1
@@ 1,6 1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
;;; Copyright © 2017 Carlo Zancanaro <carlo@zancanaro.id.au>
;;;
;;; This file is part of GNU Guix.
;;;


@@ 33,6 34,7 @@
  #:use-module (guix packages)
  #:use-module (guix gexp)
  #:use-module (ice-9 match)
  #:use-module (ice-9 format)
  #:export (dovecot-service
            dovecot-service-type
            dovecot-configuration


@@ 53,7 55,12 @@
            opensmtpd-configuration
            opensmtpd-configuration?
            opensmtpd-service-type
            %default-opensmtpd-config-file))
            %default-opensmtpd-config-file

            exim-configuration
            exim-configuration?
            exim-service-type
            %default-exim-config-file))

;;; Commentary:
;;;


@@ 1620,3 1627,96 @@ accept from local for any relay
                             (compose list opensmtpd-configuration-package))
          (service-extension shepherd-root-service-type
                             opensmtpd-shepherd-service)))))


;;;
;;; Exim.
;;;

(define-record-type* <exim-configuration> exim-configuration
  make-exim-configuration
  exim-configuration?
  (package       exim-configuration-package ;<package>
                 (default exim))
  (config-file   exim-configuration-config-file ;file-like
                 (default #f))
  (aliases       exim-configuration-aliases ;; list of lists
                 (default '())))

(define %exim-accounts
  (list (user-group
         (name "exim")
         (system? #t))
        (user-account
         (name "exim")
         (group "exim")
         (system? #t)
         (comment "Exim Daemon")
         (home-directory "/var/empty")
         (shell (file-append shadow "/sbin/nologin")))))

(define (exim-computed-config-file package config-file)
  (computed-file "exim.conf"
                 #~(call-with-output-file #$output
                     (lambda (port)
                       (format port "
exim_user = exim
exim_group = exim
.include ~a"
                               #$(or config-file
                                     (file-append package "/etc/exim.conf")))))))

(define exim-shepherd-service
  (match-lambda
    (($ <exim-configuration> package config-file aliases)
     (list (shepherd-service
            (provision '(exim mta))
            (documentation "Run the exim daemon.")
            (requirement '(networking))
            (start #~(make-forkexec-constructor
                      '(#$(file-append package "/bin/exim")
                        "-bd" "-v" "-C"
                        #$(exim-computed-config-file package config-file))))
            (stop #~(make-kill-destructor)))))))

(define exim-activation
  (match-lambda
    (($ <exim-configuration> package config-file aliases)
     (with-imported-modules '((guix build utils))
       #~(begin
           (use-modules (guix build utils))

           (let ((uid (passwd:uid (getpw "exim")))
                 (gid (group:gid (getgr "exim"))))
             (mkdir-p "/var/spool/exim")
             (chown "/var/spool/exim" uid gid))

           (zero? (system* #$(file-append package "/bin/exim")
                           "-bV" "-C" #$(exim-computed-config-file package config-file))))))))

(define exim-etc
  (match-lambda
    (($ <exim-configuration> package config-file aliases)
     `(("aliases" ,(plain-file "aliases"
                               ;; Ideally we'd use a format string like
                               ;; "~:{~a: ~{~a~^,~}\n~}", but it gives a
                               ;; warning that I can't figure out how to fix,
                               ;; so we'll just use string-join below instead.
                               (format #f "~:{~a: ~a\n~}"
                                       (map (lambda (entry)
                                              (list (car entry)
                                                    (string-join (cdr entry) ",")))
                                            aliases))))))))

(define exim-profile
  (compose list exim-configuration-package))

(define exim-service-type
  (service-type
   (name 'exim)
   (extensions
    (list (service-extension shepherd-root-service-type exim-shepherd-service)
          (service-extension account-service-type (const %exim-accounts))
          (service-extension activation-service-type exim-activation)
          (service-extension profile-service-type exim-profile)
          (service-extension etc-service-type exim-etc)))))