@@ -18404,6 +18404,14 @@ Available @code{dovecot-configuration} fields are:
The dovecot package.
@end deftypevr
+@deftypevr {@code{dovecot-configuration} parameter} package-list extensions
+Plugins and extensions to the Dovecot package. Specify a list of
+dovecot plugins that needs to be available for dovecot and its modules.
+
+Defaults to @samp{()}.
+
+@end deftypevr
+
@deftypevr {@code{dovecot-configuration} parameter} comma-separated-string-list listen
A list of IPs or hosts where to listen for connections. @samp{*}
listens on all IPv4 interfaces, @samp{::} listens on all IPv6
@@ -468,11 +468,21 @@ as @code{#t}.)")
(serialize-namespace-configuration field-name val))
val))
+(define (package-list? val)
+ (and (list? val) (and-map package? val)))
+(define (serialize-package-list field-name val)
+ #f)
+
(define-configuration dovecot-configuration
(dovecot
(package dovecot)
"The dovecot package.")
+ (extensions
+ (package-list '())
+ "Plugins and extensions to the Dovecot package. Specify a list of dovecot
+plugins that needs to be available for dovecot and its modules.")
+
(listen
(comma-separated-string-list '("*" "::"))
"A list of IPs or hosts where to listen in for connections. @samp{*}
@@ -1439,6 +1449,11 @@ greyed out, instead of only later giving \"not selectable\" popup error.
(package dovecot)
"The dovecot package.")
+ (extensions
+ (package-list '())
+ "Plugins and extensions to the Dovecot package. Specify a list of dovecot
+plugins that needs to be available for dovecot and its modules.")
+
(string
(string (configuration-missing-field 'opaque-dovecot-configuration
'string))
@@ -1464,6 +1479,29 @@ greyed out, instead of only later giving \"not selectable\" popup error.
(home-directory "/var/empty")
(shell (file-append shadow "/sbin/nologin")))))
+(define (%dovecot-moduledir packages)
+ ;; Create a union of the set of modules and dovecot itself.
+ (computed-file
+ "dovecot-moduledir"
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (mkdir #$output)
+ (for-each
+ (lambda (package)
+ (let ((path (string-append package "/lib/dovecot")))
+ (for-each
+ (lambda (src)
+ (let* ((tail (substring src (string-length path)))
+ (dst (string-append #$output tail)))
+ (mkdir-p (dirname dst))
+ (if (file-exists? dst)
+ (format (current-error-port) "warning: ~a exists\n" dst)
+ (symlink src dst))))
+ (find-files path))))
+ (list #$@packages))
+ #t))))
+
(define (%dovecot-activation config)
;; Activation gexp.
(let ((config-str
@@ -1474,7 +1512,15 @@ greyed out, instead of only later giving \"not selectable\" popup error.
(with-output-to-string
(lambda ()
(serialize-configuration config
- dovecot-configuration-fields)))))))
+ dovecot-configuration-fields))))))
+ (moduledir-directory
+ (cond
+ ((opaque-dovecot-configuration? config)
+ (%dovecot-moduledir (cons* (opaque-dovecot-configuration-dovecot config)
+ (opaque-dovecot-configuration-extensions config))))
+ (else
+ (%dovecot-moduledir (cons* (dovecot-configuration-dovecot config)
+ (dovecot-configuration-extensions config)))))))
#~(begin
(use-modules (guix build utils))
(define (mkdir-p/perms directory owner perms)
@@ -1521,13 +1567,18 @@ greyed out, instead of only later giving \"not selectable\" popup error.
(else
(format (current-error-port)
"Failed to create public key at ~a.\n" public-key)))))
- (let ((user (getpwnam "dovecot")))
+ (let ((user (getpwnam "dovecot"))
+ (moduledir-symlink "/usr/lib/dovecot"))
(mkdir-p/perms "/var/run/dovecot" user #o755)
(mkdir-p/perms "/var/lib/dovecot" user #o755)
(mkdir-p/perms "/etc/dovecot" user #o755)
(copy-file #$(plain-file "dovecot.conf" config-str)
"/etc/dovecot/dovecot.conf")
(mkdir-p/perms "/etc/dovecot/private" user #o700)
+ (mkdir-p (dirname moduledir-symlink))
+ (when (file-exists? moduledir-symlink)
+ (delete-file moduledir-symlink))
+ (symlink #$moduledir-directory moduledir-symlink)
(create-self-signed-certificate-if-absent
#:private-key "/etc/dovecot/private/default.pem"
#:public-key "/etc/dovecot/default.pem"