gnu: python-aiohttp-socks: Update to 0.7.1.
[jackhill/guix/guix.git] / gnu / services / rsync.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2017 Oleg Pykhalov <go.wigust@gmail.com>
3 ;;; Copyright © 2021 Ludovic Courtès <ludo@gnu.org>
4 ;;;
5 ;;; This file is part of GNU Guix.
6 ;;;
7 ;;; GNU Guix is free software; you can redistribute it and/or modify it
8 ;;; under the terms of the GNU General Public License as published by
9 ;;; the Free Software Foundation; either version 3 of the License, or (at
10 ;;; your option) any later version.
11 ;;;
12 ;;; GNU Guix is distributed in the hope that it will be useful, but
13 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;;; GNU General Public License for more details.
16 ;;;
17 ;;; You should have received a copy of the GNU General Public License
18 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19
20 (define-module (gnu services rsync)
21 #:use-module (gnu services)
22 #:use-module (gnu services base)
23 #:use-module (gnu services shepherd)
24 #:use-module (gnu system shadow)
25 #:use-module (gnu packages rsync)
26 #:use-module (gnu packages admin)
27 #:use-module (guix records)
28 #:use-module (guix gexp)
29 #:use-module (guix diagnostics)
30 #:use-module (guix i18n)
31 #:use-module (srfi srfi-1)
32 #:use-module (srfi srfi-26)
33 #:use-module (ice-9 match)
34 #:export (rsync-configuration
35 rsync-configuration?
36 rsync-configuration-modules
37
38 rsync-module
39 rsync-module?
40 rsync-module-name
41 rsync-module-file-name
42 rsync-module-comment
43 rsync-module-read-only
44 rsync-module-timeout
45
46 rsync-service-type))
47
48 ;;;; Commentary:
49 ;;;
50 ;;; This module implements a service that to run instance of Rsync,
51 ;;; files synchronization tool.
52 ;;;
53 ;;;; Code:
54
55 (define-with-syntax-properties (warn-share-field-deprecation (value properties))
56 (unless (unspecified? value)
57 (warning (source-properties->location properties)
58 (G_ "the 'share-path' and 'share-comment' fields is deprecated, \
59 please use 'modules' instead~%")))
60 value)
61
62 (define-record-type* <rsync-configuration>
63 rsync-configuration
64 make-rsync-configuration
65 rsync-configuration?
66 (package rsync-configuration-package ; file-like
67 (default rsync))
68 (address rsync-configuration-address ; string | #f
69 (default #f))
70 (port-number rsync-configuration-port-number ; integer
71 (default 873))
72 (pid-file rsync-configuration-pid-file ; string
73 (default "/var/run/rsyncd/rsyncd.pid"))
74 (lock-file rsync-configuration-lock-file ; string
75 (default "/var/run/rsyncd/rsyncd.lock"))
76 (log-file rsync-configuration-log-file ; string
77 (default "/var/log/rsyncd.log"))
78 (use-chroot? rsync-configuration-use-chroot? ; boolean
79 (sanitize warn-share-field-deprecation)
80 (default *unspecified*))
81 (modules rsync-configuration-actual-modules ;list of <rsync-module>
82 (default %default-modules)) ;TODO: eventually remove default
83 (share-path rsync-configuration-share-path ; string
84 (sanitize warn-share-field-deprecation)
85 (default *unspecified*))
86 (share-comment rsync-configuration-share-comment ; string
87 (sanitize warn-share-field-deprecation)
88 (default *unspecified*))
89 (read-only? rsync-configuration-read-only? ; boolean
90 (sanitize warn-share-field-deprecation)
91 (default *unspecified*))
92 (timeout rsync-configuration-timeout ; integer
93 (sanitize warn-share-field-deprecation)
94 (default *unspecified*))
95 (user rsync-configuration-user ; string
96 (default "root"))
97 (group rsync-configuration-group ; string
98 (default "root"))
99 (uid rsync-configuration-uid ; string
100 (default "rsyncd"))
101 (gid rsync-configuration-gid ; string
102 (default "rsyncd")))
103
104 ;; Rsync "module": a directory exported the rsync protocol.
105 (define-record-type* <rsync-module>
106 rsync-module make-rsync-module
107 rsync-module?
108 (name rsync-module-name) ;string
109 (file-name rsync-module-file-name) ;string
110 (comment rsync-module-comment ;string
111 (default ""))
112 (read-only? rsync-module-read-only? ;boolean
113 (default #t))
114 (chroot? rsync-module-chroot? ;boolean
115 (default #t))
116 (timeout rsync-module-timeout ;integer
117 (default 300)))
118
119 (define %default-modules
120 ;; Default modules, provided for backward compatibility.
121 (list (rsync-module (name "files")
122 (file-name "/srv/rsyncd")
123 (comment "Rsync share")
124 (read-only? #f)))) ;yes, that was the default
125
126 (define (rsync-configuration-modules config)
127 (match-record config <rsync-configuration>
128 (modules
129 share-path share-comment use-chroot? read-only? timeout) ;deprecated
130 (if (unspecified? share-path)
131 (rsync-configuration-actual-modules config)
132 (list (rsync-module ;backward compatibility
133 (name "files")
134 (file-name share-path)
135 (comment "Rsync share")
136 (chroot?
137 (if (unspecified? use-chroot?) #t use-chroot?))
138 (read-only?
139 (if (unspecified? read-only?) #f read-only?))
140 (timeout
141 (if (unspecified? timeout) 300 timeout)))))))
142
143 (define (rsync-account config)
144 "Return the user accounts and user groups for CONFIG."
145 (let ((rsync-user (if (rsync-configuration-uid config)
146 (rsync-configuration-uid config)
147 (rsync-configuration-user config)))
148 (rsync-group (if (rsync-configuration-gid config)
149 (rsync-configuration-gid config)
150 (rsync-configuration-group config))))
151 (list (user-group (name rsync-group) (system? #t))
152 (user-account
153 (name rsync-user)
154 (system? #t)
155 (group rsync-group)
156 (comment "rsyncd privilege separation user")
157 (home-directory (string-append "/var/run/"
158 rsync-user))
159 (shell (file-append shadow "/sbin/nologin"))))))
160
161 (define (rsync-activation config)
162 "Return the activation GEXP for CONFIG."
163 (with-imported-modules '((guix build utils))
164 #~(begin
165 (let ((user (getpw (if #$(rsync-configuration-uid config)
166 #$(rsync-configuration-uid config)
167 #$(rsync-configuration-user config))))
168 (group (getpw (if #$(rsync-configuration-gid config)
169 #$(rsync-configuration-gid config)
170 #$(rsync-configuration-group config)))))
171 (mkdir-p (dirname #$(rsync-configuration-pid-file config)))
172 (for-each (lambda (directory)
173 (mkdir-p directory)
174 (chown directory (passwd:uid user) (group:gid group)))
175 '#$(map rsync-module-file-name
176 (rsync-configuration-modules config)))))))
177
178 (define (rsync-config-file config)
179 ;; Return the rsync configuration file corresponding to CONFIG.
180 (define (module-config module)
181 (match-record module <rsync-module>
182 (name file-name comment chroot? read-only? timeout)
183 (list "[" name "]\n"
184 " path = " file-name "\n"
185 " use chroot = " (if chroot? "true" "false") "\n"
186 " comment = " comment "\n"
187 " read only = " (if read-only? "true" "false") "\n"
188 " timeout = " (number->string timeout) "\n")))
189
190 (define modules
191 (rsync-configuration-modules config))
192
193 (match-record config <rsync-configuration>
194 (package address port-number pid-file lock-file log-file
195 user group uid gid)
196 (unless (string=? user "root")
197 (cond
198 ((<= port-number 1024)
199 (error (string-append "rsync-service: to run on port "
200 (number->string port-number)
201 ", user must be root.")))
202 ((find rsync-module-chroot? modules)
203 (error (string-append "rsync-service: to run in a chroot"
204 ", user must be root.")))
205 (uid
206 (error "rsync-service: to use uid, user must be root."))
207 (gid
208 (error "rsync-service: to use gid, user must be root."))))
209
210 (apply mixed-text-file "rsync.conf"
211 "# Generated by 'rsync-service'.\n\n"
212 "pid file = " pid-file "\n"
213 "lock file = " lock-file "\n"
214 "log file = " log-file "\n"
215 (if address (string-append "address = " address "\n") "")
216 "port = " (number->string port-number) "\n"
217 (if uid (string-append "uid = " uid "\n") "")
218 "gid = " (if gid gid "nogroup") "\n" ; no group nobody
219 "\n\n"
220 (append-map module-config modules))))
221
222 (define (rsync-shepherd-service config)
223 "Return a <shepherd-service> for rsync with CONFIG."
224 (let* ((rsync (rsync-configuration-package config))
225 (pid-file (rsync-configuration-pid-file config))
226 (port-number (rsync-configuration-port-number config))
227 (user (rsync-configuration-user config))
228 (group (rsync-configuration-group config)))
229 (list (shepherd-service
230 (provision '(rsync))
231 (documentation "Run rsync daemon.")
232 (start #~(make-forkexec-constructor
233 (list (string-append #$rsync "/bin/rsync")
234 "--config" #$(rsync-config-file config)
235 "--daemon")
236 #:pid-file #$pid-file
237 #:user #$user
238 #:group #$group))
239 (stop #~(make-kill-destructor))))))
240
241 (define rsync-service-type
242 (service-type
243 (name 'rsync)
244 (extensions
245 (list (service-extension shepherd-root-service-type rsync-shepherd-service)
246 (service-extension account-service-type rsync-account)
247 (service-extension activation-service-type rsync-activation)))
248 (default-value (rsync-configuration))
249 (description
250 "Run the rsync file copying tool in daemon mode. This allows remote hosts
251 to keep synchronized copies of the files exported by rsync.")))