rsync.scm 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. (define-module (gnu services rsync)
  20. #:use-module (gnu services)
  21. #:use-module (gnu services base)
  22. #:use-module (gnu services shepherd)
  23. #:use-module (gnu system shadow)
  24. #:use-module (gnu packages rsync)
  25. #:use-module (gnu packages admin)
  26. #:use-module (guix records)
  27. #:use-module (guix gexp)
  28. #:use-module (guix diagnostics)
  29. #:use-module (guix i18n)
  30. #:use-module (srfi srfi-1)
  31. #:use-module (srfi srfi-26)
  32. #:use-module (ice-9 match)
  33. #:export (rsync-configuration
  34. rsync-configuration?
  35. rsync-configuration-modules
  36. rsync-module
  37. rsync-module?
  38. rsync-module-name
  39. rsync-module-file-name
  40. rsync-module-comment
  41. rsync-module-read-only
  42. rsync-module-timeout
  43. rsync-service-type))
  44. ;;;; Commentary:
  45. ;;;
  46. ;;; This module implements a service that to run instance of Rsync,
  47. ;;; files synchronization tool.
  48. ;;;
  49. ;;;; Code:
  50. (define-with-syntax-properties (warn-share-field-deprecation (value properties))
  51. (unless (unspecified? value)
  52. (warning (source-properties->location properties)
  53. (G_ "the 'share-path' and 'share-comment' fields is deprecated, \
  54. please use 'modules' instead~%")))
  55. value)
  56. (define-record-type* <rsync-configuration>
  57. rsync-configuration
  58. make-rsync-configuration
  59. rsync-configuration?
  60. (package rsync-configuration-package ; file-like
  61. (default rsync))
  62. (address rsync-configuration-address ; string | #f
  63. (default #f))
  64. (port-number rsync-configuration-port-number ; integer
  65. (default 873))
  66. (pid-file rsync-configuration-pid-file ; string
  67. (default "/var/run/rsyncd/rsyncd.pid"))
  68. (lock-file rsync-configuration-lock-file ; string
  69. (default "/var/run/rsyncd/rsyncd.lock"))
  70. (log-file rsync-configuration-log-file ; string
  71. (default "/var/log/rsyncd.log"))
  72. (use-chroot? rsync-configuration-use-chroot? ; boolean
  73. (sanitize warn-share-field-deprecation)
  74. (default *unspecified*))
  75. (modules rsync-configuration-actual-modules ;list of <rsync-module>
  76. (default %default-modules)) ;TODO: eventually remove default
  77. (share-path rsync-configuration-share-path ; string
  78. (sanitize warn-share-field-deprecation)
  79. (default *unspecified*))
  80. (share-comment rsync-configuration-share-comment ; string
  81. (sanitize warn-share-field-deprecation)
  82. (default *unspecified*))
  83. (read-only? rsync-configuration-read-only? ; boolean
  84. (sanitize warn-share-field-deprecation)
  85. (default *unspecified*))
  86. (timeout rsync-configuration-timeout ; integer
  87. (sanitize warn-share-field-deprecation)
  88. (default *unspecified*))
  89. (user rsync-configuration-user ; string
  90. (default "root"))
  91. (group rsync-configuration-group ; string
  92. (default "root"))
  93. (uid rsync-configuration-uid ; string
  94. (default "rsyncd"))
  95. (gid rsync-configuration-gid ; string
  96. (default "rsyncd")))
  97. ;; Rsync "module": a directory exported the rsync protocol.
  98. (define-record-type* <rsync-module>
  99. rsync-module make-rsync-module
  100. rsync-module?
  101. (name rsync-module-name) ;string
  102. (file-name rsync-module-file-name) ;string
  103. (comment rsync-module-comment ;string
  104. (default ""))
  105. (read-only? rsync-module-read-only? ;boolean
  106. (default #t))
  107. (chroot? rsync-module-chroot? ;boolean
  108. (default #t))
  109. (timeout rsync-module-timeout ;integer
  110. (default 300)))
  111. (define %default-modules
  112. ;; Default modules, provided for backward compatibility.
  113. (list (rsync-module (name "files")
  114. (file-name "/srv/rsyncd")
  115. (comment "Rsync share")
  116. (read-only? #f)))) ;yes, that was the default
  117. (define (rsync-configuration-modules config)
  118. (match-record config <rsync-configuration>
  119. (modules
  120. share-path share-comment use-chroot? read-only? timeout) ;deprecated
  121. (if (unspecified? share-path)
  122. (rsync-configuration-actual-modules config)
  123. (list (rsync-module ;backward compatibility
  124. (name "files")
  125. (file-name share-path)
  126. (comment "Rsync share")
  127. (chroot?
  128. (if (unspecified? use-chroot?) #t use-chroot?))
  129. (read-only?
  130. (if (unspecified? read-only?) #f read-only?))
  131. (timeout
  132. (if (unspecified? timeout) 300 timeout)))))))
  133. (define (rsync-account config)
  134. "Return the user accounts and user groups for CONFIG."
  135. (let ((rsync-user (if (rsync-configuration-uid config)
  136. (rsync-configuration-uid config)
  137. (rsync-configuration-user config)))
  138. (rsync-group (if (rsync-configuration-gid config)
  139. (rsync-configuration-gid config)
  140. (rsync-configuration-group config))))
  141. (list (user-group (name rsync-group) (system? #t))
  142. (user-account
  143. (name rsync-user)
  144. (system? #t)
  145. (group rsync-group)
  146. (comment "rsyncd privilege separation user")
  147. (home-directory (string-append "/var/run/"
  148. rsync-user))
  149. (shell (file-append shadow "/sbin/nologin"))))))
  150. (define (rsync-activation config)
  151. "Return the activation GEXP for CONFIG."
  152. (with-imported-modules '((guix build utils))
  153. #~(begin
  154. (let ((user (getpw (if #$(rsync-configuration-uid config)
  155. #$(rsync-configuration-uid config)
  156. #$(rsync-configuration-user config))))
  157. (group (getpw (if #$(rsync-configuration-gid config)
  158. #$(rsync-configuration-gid config)
  159. #$(rsync-configuration-group config)))))
  160. (mkdir-p (dirname #$(rsync-configuration-pid-file config)))
  161. (for-each (lambda (directory)
  162. (mkdir-p directory)
  163. (chown directory (passwd:uid user) (group:gid group)))
  164. '#$(map rsync-module-file-name
  165. (rsync-configuration-modules config)))))))
  166. (define (rsync-config-file config)
  167. ;; Return the rsync configuration file corresponding to CONFIG.
  168. (define (module-config module)
  169. (match-record module <rsync-module>
  170. (name file-name comment chroot? read-only? timeout)
  171. (list "[" name "]\n"
  172. " path = " file-name "\n"
  173. " use chroot = " (if chroot? "true" "false") "\n"
  174. " comment = " comment "\n"
  175. " read only = " (if read-only? "true" "false") "\n"
  176. " timeout = " (number->string timeout) "\n")))
  177. (define modules
  178. (rsync-configuration-modules config))
  179. (match-record config <rsync-configuration>
  180. (package address port-number pid-file lock-file log-file
  181. user group uid gid)
  182. (unless (string=? user "root")
  183. (cond
  184. ((<= port-number 1024)
  185. (error (string-append "rsync-service: to run on port "
  186. (number->string port-number)
  187. ", user must be root.")))
  188. ((find rsync-module-chroot? modules)
  189. (error (string-append "rsync-service: to run in a chroot"
  190. ", user must be root.")))
  191. (uid
  192. (error "rsync-service: to use uid, user must be root."))
  193. (gid
  194. (error "rsync-service: to use gid, user must be root."))))
  195. (apply mixed-text-file "rsync.conf"
  196. "# Generated by 'rsync-service'.\n\n"
  197. "pid file = " pid-file "\n"
  198. "lock file = " lock-file "\n"
  199. "log file = " log-file "\n"
  200. (if address (string-append "address = " address "\n") "")
  201. "port = " (number->string port-number) "\n"
  202. (if uid (string-append "uid = " uid "\n") "")
  203. "gid = " (if gid gid "nogroup") "\n" ; no group nobody
  204. "\n\n"
  205. (append-map module-config modules))))
  206. (define (rsync-shepherd-service config)
  207. "Return a <shepherd-service> for rsync with CONFIG."
  208. (let* ((rsync (rsync-configuration-package config))
  209. (pid-file (rsync-configuration-pid-file config))
  210. (port-number (rsync-configuration-port-number config))
  211. (user (rsync-configuration-user config))
  212. (group (rsync-configuration-group config)))
  213. (list (shepherd-service
  214. (provision '(rsync))
  215. (documentation "Run rsync daemon.")
  216. (start #~(make-forkexec-constructor
  217. (list (string-append #$rsync "/bin/rsync")
  218. "--config" #$(rsync-config-file config)
  219. "--daemon")
  220. #:pid-file #$pid-file
  221. #:user #$user
  222. #:group #$group))
  223. (stop #~(make-kill-destructor))))))
  224. (define rsync-service-type
  225. (service-type
  226. (name 'rsync)
  227. (extensions
  228. (list (service-extension shepherd-root-service-type rsync-shepherd-service)
  229. (service-extension account-service-type rsync-account)
  230. (service-extension activation-service-type rsync-activation)))
  231. (default-value (rsync-configuration))
  232. (description
  233. "Run the rsync file copying tool in daemon mode. This allows remote hosts
  234. to keep synchronized copies of the files exported by rsync.")))