diff --git a/doc/guix.texi b/doc/guix.texi index 732f4312a4..18821b9a9e 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -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 diff --git a/gnu/services/mail.scm b/gnu/services/mail.scm index 30b1672d33..b211ab61a5 100644 --- a/gnu/services/mail.scm +++ b/gnu/services/mail.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015 Andy Wingo ;;; Copyright © 2017 Clément Lassieur +;;; Copyright © 2017 Carlo Zancanaro ;;; ;;; 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 + make-exim-configuration + exim-configuration? + (package exim-configuration-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 + (($ 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 + (($ 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 + (($ 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)))))