| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 |
|
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 |
|
| 27 | (define-module (gnu services syncthing)
|
| 28 | #:use-module (gnu packages syncthing)
|
| 29 | #:use-module (gnu services)
|
| 30 | #:use-module (gnu services shepherd)
|
| 31 | #:use-module (guix gexp)
|
| 32 | #:use-module (guix records)
|
| 33 | #:use-module (ice-9 match)
|
| 34 | #:use-module (srfi srfi-1)
|
| 35 | #:use-module (sxml simple)
|
| 36 | #:export (syncthing-configuration
|
| 37 | syncthing-configuration?
|
| 38 | syncthing-device
|
| 39 | syncthing-device?
|
| 40 | syncthing-config-file
|
| 41 | syncthing-config-file?
|
| 42 | syncthing-folder-device
|
| 43 | syncthing-folder-device?
|
| 44 | syncthing-folder
|
| 45 | syncthing-folder?
|
| 46 | syncthing-service-type
|
| 47 | syncthing-shepherd-service
|
| 48 | syncthing-files-service))
|
| 49 |
|
| 50 | (define (bool->xml-string bool)
|
| 51 | |
| 52 | |
| 53 | (if (string? bool) bool
|
| 54 | |
| 55 | (if bool "true" "false")))
|
| 56 |
|
| 57 | (define-record-type* <syncthing-device>
|
| 58 | syncthing-device make-syncthing-device
|
| 59 | syncthing-device?
|
| 60 | (id syncthing-device-id)
|
| 61 | (name syncthing-device-name (default ""))
|
| 62 | (compression syncthing-device-compression (default "metadata"))
|
| 63 | (introducer? syncthing-device-introducer? (default #f))
|
| 64 | (skip-introduction-removals? syncthing-device-skip-introduction-removals? (default #f))
|
| 65 | (introduced-by syncthing-device-introduced-by (default ""))
|
| 66 | (addresses syncthing-device-addresses (default '("dynamic")))
|
| 67 | (paused? syncthing-device-paused? (default #f))
|
| 68 | (auto-accept-folders? syncthing-device-auto-accept-folders? (default #f))
|
| 69 | (max-send-kbps syncthing-device-max-send-kbps (default 0))
|
| 70 | (max-receive-kbps syncthing-device-max-receive-kbps (default 0))
|
| 71 | (max-request-kib syncthing-device-max-request-kib (default 0))
|
| 72 | (untrusted? syncthing-device-untrusted? (default #f))
|
| 73 | (remote-gui-port syncthing-device-remote-gui-port (default 0))
|
| 74 | (num-connections syncthing-device-num-connections (default 0)))
|
| 75 |
|
| 76 | (define syncthing-device->sxml
|
| 77 | (match-record-lambda <syncthing-device>
|
| 78 | (id
|
| 79 | name compression introducer? skip-introduction-removals? introduced-by
|
| 80 | addresses paused? auto-accept-folders? max-send-kbps max-receive-kbps
|
| 81 | max-request-kib untrusted? remote-gui-port num-connections)
|
| 82 | `(device (@ (id ,id)
|
| 83 | (name ,name)
|
| 84 | (compression ,compression)
|
| 85 | (introducer ,(bool->xml-string introducer?))
|
| 86 | (skipIntroductionRemovals ,(bool->xml-string skip-introduction-removals?))
|
| 87 | (introducedBy ,introduced-by))
|
| 88 | ,@(map (lambda (address) `(address ,address)) addresses)
|
| 89 | (paused ,(bool->xml-string paused?))
|
| 90 | (autoAcceptFolders ,(bool->xml-string auto-accept-folders?))
|
| 91 | (maxSendKbps ,max-send-kbps)
|
| 92 | (maxRecvKbps ,max-receive-kbps)
|
| 93 | (maxRequestKiB ,max-request-kib)
|
| 94 | (untrusted ,(bool->xml-string untrusted?))
|
| 95 | (remoteGUIPort ,remote-gui-port)
|
| 96 | (numConnections ,num-connections))))
|
| 97 |
|
| 98 | (define-record-type* <syncthing-folder-device>
|
| 99 | syncthing-folder-device make-syncthing-folder-device
|
| 100 | syncthing-folder-device?
|
| 101 | (device syncthing-folder-device-device)
|
| 102 | (introduced-by syncthing-folder-device-introduced-by (default (syncthing-device (id ""))))
|
| 103 | (encryption-password syncthing-folder-device-encryption-password (default "")))
|
| 104 |
|
| 105 | (define syncthing-folder-device->sxml
|
| 106 | (match-record-lambda <syncthing-folder-device>
|
| 107 | (device introduced-by encryption-password)
|
| 108 | `(device (@ (id ,(syncthing-device-id device))
|
| 109 | (introducedBy ,(syncthing-device-id introduced-by)))
|
| 110 | (encryptionPassword ,encryption-password))))
|
| 111 |
|
| 112 | (define-record-type* <syncthing-folder>
|
| 113 | syncthing-folder make-syncthing-folder
|
| 114 | syncthing-folder?
|
| 115 | (id syncthing-folder-id (default #f))
|
| 116 | (label syncthing-folder-label)
|
| 117 | (path syncthing-folder-path)
|
| 118 | (type syncthing-folder-type (default "sendreceive"))
|
| 119 | (rescan-interval-seconds syncthing-folder-rescan-interval-seconds (default 3600))
|
| 120 | (file-system-watcher-enabled? syncthing-folder-file-system-watcher-enabled? (default #t))
|
| 121 | (file-system-watcher-delay-seconds syncthing-folder-file-system-watcher-delay-seconds (default 10))
|
| 122 | (file-system-watcher-timeout-seconds syncthing-folder-file-system-watcher-timeout-seconds (default 0))
|
| 123 | (ignore-permissions? syncthing-folder-ignore-permissions? (default #f))
|
| 124 | (auto-normalize? syncthing-folder-auto-normalize? (default #t))
|
| 125 | (devices syncthing-folder-devices (default '())
|
| 126 | (sanitize (lambda (folder-device-list)
|
| 127 | (map (lambda (device)
|
| 128 | (if (syncthing-folder-device? device)
|
| 129 | device
|
| 130 | (syncthing-folder-device (device device))))
|
| 131 | folder-device-list))))
|
| 132 | (filesystem-type syncthing-folder-filesystem-type (default "basic"))
|
| 133 | (min-disk-free-unit syncthing-folder-min-disk-free-unit (default "%"))
|
| 134 | (min-disk-free syncthing-folder-min-disk-free (default 1))
|
| 135 | (versioning-type syncthing-folder-versioning-type (default #f))
|
| 136 | (versioning-file-system-path syncthing-folder-versioning-file-system-path (default ""))
|
| 137 | (versioning-file-system-type syncthing-folder-versioning-file-system-type (default "basic"))
|
| 138 | (versioning-cleanup-interval-seconds syncthing-folder-versioning-cleanup-interval-seconds (default 3600))
|
| 139 | (versioning-cleanout-days syncthing-folder-versioning-cleanout-days (default #f))
|
| 140 | (versioning-keep syncthing-folder-versioning-keep (default #f))
|
| 141 | (versioning-max-age syncthing-folder-versioning-max-age (default #f))
|
| 142 | (versioning-command syncthing-folder-versioning-command (default #f))
|
| 143 | (copiers syncthing-folder-copiers (default 0))
|
| 144 | (puller-max-pending-kib syncthing-folder-puller-max-pending-kib (default 0))
|
| 145 | (hashers syncthing-folder-hashers (default 0))
|
| 146 | (order syncthing-folder-order (default "random"))
|
| 147 | (ignore-delete? syncthing-folder-ignore-delete? (default #f))
|
| 148 | (scan-progress-interval-seconds syncthing-folder-scan-progress-interval-seconds (default 0))
|
| 149 | (puller-pause-seconds syncthing-folder-puller-pause-seconds (default 0))
|
| 150 | (max-conflicts syncthing-folder-max-conflicts (default 10))
|
| 151 | (disable-sparse-files? syncthing-folder-disable-sparse-files? (default #f))
|
| 152 | (disable-temp-indexes? syncthing-folder-disable-temp-indexes? (default #f))
|
| 153 | (paused? syncthing-folder-paused? (default #f))
|
| 154 | (weak-hash-threshold-percentage syncthing-folder-weak-hash-threshold-percentage (default 25))
|
| 155 | (marker-name syncthing-folder-marker-name (default ".stfolder"))
|
| 156 | (copy-ownership-from-parent? syncthing-folder-copy-ownership-from-parent? (default #f))
|
| 157 | (mod-time-window-seconds syncthing-folder-mod-time-window-seconds (default 0))
|
| 158 | (max-concurrent-writes syncthing-folder-max-concurrent-writes (default 16))
|
| 159 | (disable-fsync? syncthing-folder-disable-fsync? (default #f))
|
| 160 | (block-pull-order syncthing-folder-block-pull-order (default "standard"))
|
| 161 | (copy-range-method syncthing-folder-copy-range-method (default "standard"))
|
| 162 | (case-sensitive-file-system? syncthing-folder-case-sensitive-file-system? (default #f))
|
| 163 | (junctions-as-dirs? syncthing-folder-junctions-as-dirs? (default #f))
|
| 164 | (sync-ownership? syncthing-folder-sync-ownership? (default #f))
|
| 165 | (send-ownership? syncthing-folder-send-ownership? (default #f))
|
| 166 | (sync-xattrs? syncthing-folder-sync-xattrs? (default #f))
|
| 167 | (send-xattrs? syncthing-folder-send-xattrs? (default #f))
|
| 168 | (xattr-filter-max-single-entry-size syncthing-folder-xattr-filter-max-single-entry-size (default 1024))
|
| 169 | (xattr-filter-max-total-size syncthing-folder-xattr-filter-max-total-size (default 4096)))
|
| 170 |
|
| 171 | |
| 172 | |
| 173 | |
| 174 | (define (maybe-param symbol value)
|
| 175 | (if value `((param (@ (key ,(symbol->string symbol)) (val ,value)) "")) '()))
|
| 176 |
|
| 177 | (define syncthing-folder->sxml
|
| 178 | (match-record-lambda <syncthing-folder>
|
| 179 | (id
|
| 180 | label path type rescan-interval-seconds file-system-watcher-enabled?
|
| 181 | file-system-watcher-delay-seconds file-system-watcher-timeout-seconds
|
| 182 | ignore-permissions? auto-normalize? devices filesystem-type
|
| 183 | min-disk-free-unit min-disk-free versioning-type
|
| 184 | versioning-file-system-path versioning-file-system-type
|
| 185 | versioning-cleanup-interval-seconds versioning-cleanout-days
|
| 186 | versioning-keep versioning-max-age versioning-command copiers
|
| 187 | puller-max-pending-kib hashers order ignore-delete?
|
| 188 | scan-progress-interval-seconds puller-pause-seconds max-conflicts
|
| 189 | disable-sparse-files? disable-temp-indexes? paused?
|
| 190 | weak-hash-threshold-percentage marker-name copy-ownership-from-parent?
|
| 191 | mod-time-window-seconds max-concurrent-writes disable-fsync?
|
| 192 | block-pull-order copy-range-method case-sensitive-file-system?
|
| 193 | junctions-as-dirs? sync-ownership? send-ownership? sync-xattrs?
|
| 194 | send-xattrs? xattr-filter-max-single-entry-size
|
| 195 | xattr-filter-max-total-size)
|
| 196 | `(folder (@ (id ,(if id id label))
|
| 197 | (label ,label)
|
| 198 | (path ,path)
|
| 199 | (type ,type)
|
| 200 | (rescanIntervalS ,rescan-interval-seconds)
|
| 201 | (fsWatcherEnabled ,(bool->xml-string file-system-watcher-enabled?))
|
| 202 | (fsWatcherDelayS ,file-system-watcher-delay-seconds)
|
| 203 | (fsWatcherTimeoutS ,file-system-watcher-timeout-seconds)
|
| 204 | (ignorePerms ,(bool->xml-string ignore-permissions?))
|
| 205 | (autoNormalize ,(bool->xml-string auto-normalize?)))
|
| 206 | (filesystemType ,filesystem-type)
|
| 207 | ,@(map syncthing-folder-device->sxml
|
| 208 | devices)
|
| 209 | (minDiskFree (@ (unit ,min-disk-free-unit))
|
| 210 | ,min-disk-free)
|
| 211 | (versioning ,@(if versioning-type
|
| 212 | `((@ (type ,versioning-type)))
|
| 213 | '())
|
| 214 | ,@(maybe-param 'cleanoutDays versioning-cleanout-days)
|
| 215 | ,@(maybe-param 'keep versioning-keep)
|
| 216 | ,@(maybe-param 'maxAge versioning-max-age)
|
| 217 | ,@(maybe-param 'command versioning-command)
|
| 218 | (cleanupIntervalS ,versioning-cleanup-interval-seconds)
|
| 219 | (fsPath ,versioning-file-system-path)
|
| 220 | (fsType ,versioning-file-system-type))
|
| 221 | (copiers ,copiers)
|
| 222 | (pullerMaxPendingKiB ,puller-max-pending-kib)
|
| 223 | (hashers ,hashers)
|
| 224 | (order ,order)
|
| 225 | (ignoreDelete ,(bool->xml-string ignore-delete?))
|
| 226 | (scanProgressIntervalS ,scan-progress-interval-seconds)
|
| 227 | (pullerPauseS ,puller-pause-seconds)
|
| 228 | (maxConflicts ,max-conflicts)
|
| 229 | (disableSparseFiles ,(bool->xml-string disable-sparse-files?))
|
| 230 | (disableTempIndexes ,(bool->xml-string disable-temp-indexes?))
|
| 231 | (paused ,(bool->xml-string paused?))
|
| 232 | (weakHashThresholdPct ,weak-hash-threshold-percentage)
|
| 233 | (markerName ,marker-name)
|
| 234 | (copyOwnershipFromParent ,(bool->xml-string copy-ownership-from-parent?))
|
| 235 | (modTimeWindowS ,mod-time-window-seconds)
|
| 236 | (maxConcurrentWrites ,max-concurrent-writes)
|
| 237 | (disableFsync ,(bool->xml-string disable-fsync?))
|
| 238 | (blockPullOrder ,block-pull-order)
|
| 239 | (copyRangeMethod ,copy-range-method)
|
| 240 | (caseSensitiveFS ,(bool->xml-string case-sensitive-file-system?))
|
| 241 | (junctionsAsDirs ,(bool->xml-string junctions-as-dirs?))
|
| 242 | (syncOwnership ,(bool->xml-string sync-ownership?))
|
| 243 | (sendOwnership ,(bool->xml-string send-ownership?))
|
| 244 | (syncXattrs ,(bool->xml-string sync-xattrs?))
|
| 245 | (sendXattrs ,(bool->xml-string send-xattrs?))
|
| 246 | (xattrFilter (maxSingleEntrySize ,xattr-filter-max-single-entry-size)
|
| 247 | (maxTotalSize ,xattr-filter-max-total-size)))))
|
| 248 |
|
| 249 | (define-record-type* <syncthing-config-file>
|
| 250 | syncthing-config-file make-syncthing-config-file
|
| 251 | syncthing-config-file?
|
| 252 | (folders syncthing-config-folders
|
| 253 | |
| 254 | (default (list (syncthing-folder (id "default")
|
| 255 | (label "Default Folder")
|
| 256 | (path "~/Sync")))))
|
| 257 | (devices syncthing-config-devices
|
| 258 | (default '()))
|
| 259 | (gui-enabled? syncthing-config-gui-enabled? (default #t))
|
| 260 | (gui-tls? syncthing-config-gui-tls? (default #f))
|
| 261 | (gui-debugging? syncthing-config-gui-debugging? (default #f))
|
| 262 | (gui-send-basic-authorization-prompt? syncthing-config-gui-send-basic-authorization-prompt? (default #f))
|
| 263 | (gui-address syncthing-config-gui-address (default "127.0.0.1:8384"))
|
| 264 | (gui-user syncthing-config-gui-user (default #f))
|
| 265 | (gui-password syncthing-config-gui-password (default #f))
|
| 266 | (gui-apikey syncthing-config-gui-apikey (default #f))
|
| 267 | (gui-theme syncthing-config-gui-theme (default "default"))
|
| 268 | (ldap-enabled? syncthing-config-ldap-enabled? (default #f))
|
| 269 | (ldap-address syncthing-config-ldap-address (default ""))
|
| 270 | (ldap-bind-dn syncthing-config-ldap-bind-dn (default ""))
|
| 271 | (ldap-transport syncthing-config-ldap-transport (default ""))
|
| 272 | (ldap-insecure-skip-verify syncthing-config-ldap-insecure-skip-verify (default ""))
|
| 273 | (ldap-search-base-dn syncthing-config-ldap-search-base-dn (default ""))
|
| 274 | (ldap-search-filter syncthing-config-ldap-search-filter (default ""))
|
| 275 | (listen-address syncthing-config-listen-address (default "default"))
|
| 276 | (global-announce-server syncthing-config-global-announce-server (default "default"))
|
| 277 | (global-announce-enabled? syncthing-config-global-announce-enabled? (default #t))
|
| 278 | (local-announce-enabled? syncthing-config-local-announce-enabled? (default #t))
|
| 279 | (local-announce-port syncthing-config-local-announce-port (default 21027))
|
| 280 | (local-announce-mac-address syncthing-config-local-announce-mac-address (default "[ff12::8384]:21027"))
|
| 281 | (max-send-kbps syncthing-config-max-send-kbps (default 0))
|
| 282 | (max-receive-kbps syncthing-config-max-receive-kbps (default 0))
|
| 283 | (reconnection-interval-seconds syncthing-config-reconnection-interval-seconds (default 20))
|
| 284 | (relays-enabled? syncthing-config-relays-enabled? (default #t))
|
| 285 | (relay-reconnect-interval-minutes syncthing-config-relay-reconnect-interval-minutes (default 10))
|
| 286 | (start-browser? syncthing-config-start-browser? (default #t))
|
| 287 | (nat-enabled? syncthing-config-nat-enabled? (default #t))
|
| 288 | (nat-lease-minutes syncthing-config-nat-lease-minutes (default 60))
|
| 289 | (nat-renewal-minutes syncthing-config-nat-renewal-minutes (default 30))
|
| 290 | (nat-timeout-seconds syncthing-config-nat-timeout-seconds (default 10))
|
| 291 | (usage-reporting-accepted syncthing-config-usage-reporting-accepted (default 0))
|
| 292 | (usage-reporting-seen syncthing-config-usage-reporting-seen (default 0))
|
| 293 | (usage-reporting-unique-id syncthing-config-usage-reporting-unique-id (default ""))
|
| 294 | (usage-reporting-url syncthing-config-usage-reporting-url (default "https://data.syncthing.net/newdata"))
|
| 295 | (usage-reporting-post-insecurely? syncthing-config-usage-reporting-post-insecurely? (default #f))
|
| 296 | (usage-reporting-initial-delay-seconds syncthing-config-usage-reporting-initial-delay-seconds (default 1800))
|
| 297 | (auto-upgrade-interval-hours syncthing-config-auto-upgrade-interval-hours (default 12))
|
| 298 | (upgrade-to-pre-releases? syncthing-config-upgrade-to-pre-releases? (default #f))
|
| 299 | (keep-temporaries-hours syncthing-config-keep-temporaries-hours (default 24))
|
| 300 | (cache-ignored-files? syncthing-config-cache-ignored-files? (default #f))
|
| 301 | (progress-update-interval-seconds syncthing-config-progress-update-interval-seconds (default 5))
|
| 302 | (limit-bandwidth-in-lan? syncthing-config-limit-bandwidth-in-lan? (default #f))
|
| 303 | (min-home-disk-free-unit syncthing-config-min-home-disk-free-unit (default "%"))
|
| 304 | (min-home-disk-free syncthing-config-min-home-disk-free (default 1))
|
| 305 | (releases-url syncthing-config-releases-url (default "https://upgrades.syncthing.net/meta.json"))
|
| 306 | (overwrite-remote-device-names-on-connect? syncthing-config-overwrite-remote-device-names-on-connect? (default #f))
|
| 307 | (temp-index-min-blocks syncthing-config-temp-index-min-blocks (default 10))
|
| 308 | (unacked-notification-id syncthing-config-unacked-notification-id (default "authenticationUserAndPassword"))
|
| 309 | (traffic-class syncthing-config-traffic-class (default 0))
|
| 310 | (set-low-priority? syncthing-config-set-low-priority? (default #t))
|
| 311 | (max-folder-concurrency syncthing-config-max-folder-concurrency (default 0))
|
| 312 | (crash-reporting-url syncthing-config-crash-reporting-url (default "https://crash.syncthing.net/newcrash"))
|
| 313 | (crash-reporting-enabled? syncthing-config-crash-reporting-enabled? (default #t))
|
| 314 | (stun-keepalive-start-seconds syncthing-config-stun-keepalive-start-seconds (default 180))
|
| 315 | (stun-keepalive-min-seconds syncthing-config-stun-keepalive-min-seconds (default 20))
|
| 316 | (stun-server syncthing-config-stun-server (default "default"))
|
| 317 | (database-tuning syncthing-config-database-tuning (default "auto"))
|
| 318 | (max-concurrent-incoming-request-kib syncthing-config-max-concurrent-incoming-request-kib (default 0))
|
| 319 | (announce-lan-addresses? syncthing-config-announce-lan-addresses? (default #t))
|
| 320 | (send-full-index-on-upgrade? syncthing-config-send-full-index-on-upgrade? (default #f))
|
| 321 | (connection-limit-enough syncthing-config-connection-limit-enough (default 0))
|
| 322 | (connection-limit-max syncthing-config-connection-limit-max (default 0))
|
| 323 | (insecure-allow-old-tls-versions? syncthing-config-insecure-allow-old-tls-versions? (default #f))
|
| 324 | (connection-priority-tcp-lan syncthing-config-connection-priority-tcp-lan (default 10))
|
| 325 | (connection-priority-quic-lan syncthing-config-connection-priority-quic-lan (default 20))
|
| 326 | (connection-priority-tcp-wan syncthing-config-connection-priority-tcp-wan (default 30))
|
| 327 | (connection-priority-quic-wan syncthing-config-connection-priority-quic-wan (default 40))
|
| 328 | (connection-priority-relay syncthing-config-connection-priority-relay (default 50))
|
| 329 | (connection-priority-upgrade-threshold syncthing-config-connection-priority-upgrade-threshold (default 0))
|
| 330 | (default-folder syncthing-config-default-folder
|
| 331 | (default (syncthing-folder (label "") (path "~"))))
|
| 332 | (default-device syncthing-config-default-device
|
| 333 | (default (syncthing-device (id ""))))
|
| 334 | (default-ignores syncthing-config-default-ignores (default "")))
|
| 335 |
|
| 336 | (define syncthing-config-file->sxml
|
| 337 | (match-record-lambda <syncthing-config-file>
|
| 338 | (folders
|
| 339 | devices gui-enabled? gui-tls? gui-debugging?
|
| 340 | gui-send-basic-authorization-prompt? gui-address gui-user gui-password
|
| 341 | gui-apikey gui-theme ldap-enabled? ldap-address ldap-bind-dn
|
| 342 | ldap-transport ldap-insecure-skip-verify ldap-search-base-dn
|
| 343 | ldap-search-filter listen-address global-announce-server
|
| 344 | global-announce-enabled? local-announce-enabled? local-announce-port
|
| 345 | local-announce-mac-address max-send-kbps max-receive-kbps
|
| 346 | reconnection-interval-seconds relays-enabled?
|
| 347 | relay-reconnect-interval-minutes start-browser? nat-enabled?
|
| 348 | nat-lease-minutes nat-renewal-minutes nat-timeout-seconds
|
| 349 | usage-reporting-accepted usage-reporting-seen usage-reporting-unique-id
|
| 350 | usage-reporting-url usage-reporting-post-insecurely?
|
| 351 | usage-reporting-initial-delay-seconds auto-upgrade-interval-hours
|
| 352 | upgrade-to-pre-releases? keep-temporaries-hours cache-ignored-files?
|
| 353 | progress-update-interval-seconds limit-bandwidth-in-lan?
|
| 354 | min-home-disk-free-unit min-home-disk-free releases-url
|
| 355 | overwrite-remote-device-names-on-connect? temp-index-min-blocks
|
| 356 | unacked-notification-id traffic-class set-low-priority?
|
| 357 | max-folder-concurrency crash-reporting-url crash-reporting-enabled?
|
| 358 | stun-keepalive-start-seconds stun-keepalive-min-seconds stun-server
|
| 359 | database-tuning max-concurrent-incoming-request-kib
|
| 360 | announce-lan-addresses? send-full-index-on-upgrade?
|
| 361 | connection-limit-enough connection-limit-max
|
| 362 | insecure-allow-old-tls-versions? connection-priority-tcp-lan
|
| 363 | connection-priority-quic-lan connection-priority-tcp-wan
|
| 364 | connection-priority-quic-wan connection-priority-relay
|
| 365 | connection-priority-upgrade-threshold default-folder default-device
|
| 366 | default-ignores)
|
| 367 | `(configuration (@ (version "52"))
|
| 368 | ,@(map syncthing-folder->sxml
|
| 369 | folders)
|
| 370 | |
| 371 | |
| 372 | ,@(map syncthing-device->sxml
|
| 373 | (delete-duplicates
|
| 374 | (append devices
|
| 375 | (apply append
|
| 376 | (map (lambda (folder)
|
| 377 | (map syncthing-folder-device-device
|
| 378 | (syncthing-folder-devices folder)))
|
| 379 | folders)))
|
| 380 | |
| 381 | (lambda (device1 device2)
|
| 382 | (string= (syncthing-device-id device1)
|
| 383 | (syncthing-device-id device2)))))
|
| 384 | (gui (@ (enabled ,(bool->xml-string gui-enabled?))
|
| 385 | (tls ,(bool->xml-string gui-tls?))
|
| 386 | (debugging ,(bool->xml-string gui-debugging?))
|
| 387 | (sendBasicAuthPrompt ,(bool->xml-string gui-send-basic-authorization-prompt?)))
|
| 388 | (address ,gui-address)
|
| 389 | ,@(if gui-user `((user ,gui-user)) '())
|
| 390 | ,@(if gui-password `((password ,gui-password)) '())
|
| 391 | ,@(if gui-apikey `((apikey ,gui-apikey)) '())
|
| 392 | (theme ,gui-theme))
|
| 393 | (ldap ,(if ldap-enabled?
|
| 394 | `((address ,ldap-address)
|
| 395 | (bindDN ,ldap-bind-dn)
|
| 396 | ,@(if ldap-transport
|
| 397 | `((transport ,ldap-transport))
|
| 398 | '())
|
| 399 | ,@(if ldap-insecure-skip-verify
|
| 400 | `((insecureSkipVerify ,ldap-insecure-skip-verify))
|
| 401 | '())
|
| 402 | ,@(if ldap-search-base-dn
|
| 403 | `((searchBaseDN ,ldap-search-base-dn))
|
| 404 | '())
|
| 405 | ,@(if ldap-search-filter
|
| 406 | `((searchFilter ,ldap-search-filter))
|
| 407 | '()))
|
| 408 | ""))
|
| 409 | (options (listenAddress ,listen-address)
|
| 410 | (globalAnnounceServer ,global-announce-server)
|
| 411 | (globalAnnounceEnabled ,(bool->xml-string global-announce-enabled?))
|
| 412 | (localAnnounceEnabled ,(bool->xml-string local-announce-enabled?))
|
| 413 | (localAnnouncePort ,local-announce-port)
|
| 414 | (localAnnounceMCAddr ,local-announce-mac-address)
|
| 415 | (maxSendKbps ,max-send-kbps)
|
| 416 | (maxRecvKbps ,max-receive-kbps)
|
| 417 | (reconnectionIntervalS ,reconnection-interval-seconds)
|
| 418 | (relaysEnabled ,(bool->xml-string relays-enabled?))
|
| 419 | (relayReconnectIntervalM ,relay-reconnect-interval-minutes)
|
| 420 | (startBrowser ,(bool->xml-string start-browser?))
|
| 421 | (natEnabled ,(bool->xml-string nat-enabled?))
|
| 422 | (natLeaseMinutes ,nat-lease-minutes)
|
| 423 | (natRenewalMinutes ,nat-renewal-minutes)
|
| 424 | (natTimeoutSeconds ,nat-timeout-seconds)
|
| 425 | (urAccepted ,usage-reporting-accepted)
|
| 426 | (urSeen ,usage-reporting-seen)
|
| 427 | (urUniqueID ,usage-reporting-unique-id)
|
| 428 | (urURL ,usage-reporting-url)
|
| 429 | (urPostInsecurely ,(bool->xml-string usage-reporting-post-insecurely?))
|
| 430 | (urInitialDelayS ,usage-reporting-initial-delay-seconds)
|
| 431 | (autoUpgradeIntervalH ,auto-upgrade-interval-hours)
|
| 432 | (upgradeToPreReleases ,(bool->xml-string upgrade-to-pre-releases?))
|
| 433 | (keepTemporariesH ,keep-temporaries-hours)
|
| 434 | (cacheIgnoredFiles ,(bool->xml-string cache-ignored-files?))
|
| 435 | (progressUpdateIntervalS ,progress-update-interval-seconds)
|
| 436 | (limitBandwidthInLan ,(bool->xml-string limit-bandwidth-in-lan?))
|
| 437 | (minHomeDiskFree (@ (unit ,min-home-disk-free-unit))
|
| 438 | ,min-home-disk-free)
|
| 439 | (releasesURL ,releases-url)
|
| 440 | (overwriteRemoteDeviceNamesOnConnect ,(bool->xml-string overwrite-remote-device-names-on-connect?))
|
| 441 | (tempIndexMinBlocks ,temp-index-min-blocks)
|
| 442 | (unackedNotificationID ,unacked-notification-id)
|
| 443 | (trafficClass ,traffic-class)
|
| 444 | (setLowPriority ,(bool->xml-string set-low-priority?))
|
| 445 | (maxFolderConcurrency ,max-folder-concurrency)
|
| 446 | (crashReportingURL ,crash-reporting-url)
|
| 447 | (crashReportingEnabled ,(bool->xml-string crash-reporting-enabled?))
|
| 448 | (stunKeepaliveStartS ,stun-keepalive-start-seconds)
|
| 449 | (stunKeepaliveMinS ,stun-keepalive-min-seconds)
|
| 450 | (stunServer ,stun-server)
|
| 451 | (databaseTuning ,database-tuning)
|
| 452 | (maxConcurrentIncomingRequestKiB ,max-concurrent-incoming-request-kib)
|
| 453 | (announceLANAddresses ,(bool->xml-string announce-lan-addresses?))
|
| 454 | (sendFullIndexOnUpgrade ,(bool->xml-string send-full-index-on-upgrade?))
|
| 455 | (connectionLimitEnough ,connection-limit-enough)
|
| 456 | (connectionLimitMax ,connection-limit-max)
|
| 457 | (insecureAllowOldTLSVersions ,(bool->xml-string insecure-allow-old-tls-versions?))
|
| 458 | (connectionPriorityTcpLan ,connection-priority-tcp-lan)
|
| 459 | (connectionPriorityQuicLan ,connection-priority-quic-lan)
|
| 460 | (connectionPriorityTcpWan ,connection-priority-tcp-wan)
|
| 461 | (connectionPriorityQuicWan ,connection-priority-quic-wan)
|
| 462 | (connectionPriorityRelay ,connection-priority-relay)
|
| 463 | (connectionPriorityUpgradeThreshold ,connection-priority-upgrade-threshold))
|
| 464 | (defaults
|
| 465 | ,(syncthing-folder->sxml default-folder)
|
| 466 | ,(syncthing-device->sxml default-device)
|
| 467 | (ignores ,default-ignores)))))
|
| 468 |
|
| 469 |
|
| 470 | (define (serialize-syncthing-config-file config)
|
| 471 | (with-output-to-string
|
| 472 | (lambda ()
|
| 473 | (sxml->xml (cons '*TOP* (list (syncthing-config-file->sxml config)))))))
|
| 474 |
|
| 475 | (define-record-type* <syncthing-configuration>
|
| 476 | syncthing-configuration make-syncthing-configuration
|
| 477 | syncthing-configuration?
|
| 478 | (syncthing syncthing-configuration-syncthing |
| 479 | (default syncthing))
|
| 480 | (arguments syncthing-configuration-arguments |
| 481 | (default '()))
|
| 482 | (logflags syncthing-configuration-logflags |
| 483 | (default 0))
|
| 484 | (user syncthing-configuration-user |
| 485 | (default #f))
|
| 486 | (group syncthing-configuration-group |
| 487 | (default "users"))
|
| 488 | (home syncthing-configuration-home |
| 489 | (default #f))
|
| 490 | (config-file syncthing-configuration-config-file
|
| 491 | (default #f)) |
| 492 | (home-service? syncthing-configuration-home-service?
|
| 493 | (default for-home?) (innate)))
|
| 494 |
|
| 495 | (define syncthing-shepherd-service
|
| 496 | (match-record-lambda <syncthing-configuration>
|
| 497 | (syncthing arguments logflags user group home home-service? config-file)
|
| 498 | (list
|
| 499 | (shepherd-service
|
| 500 | (provision (if home-service?
|
| 501 | '(syncthing)
|
| 502 | (list (string->symbol
|
| 503 | (string-append "syncthing-" user)))))
|
| 504 | (documentation "Run syncthing.")
|
| 505 | (requirement (if home-service? '() '(loopback user-processes)))
|
| 506 | (start #~(lambda _
|
| 507 | |
| 508 | |
| 509 | |
| 510 | |
| 511 | (unless (or #$(not config-file) #$home-service?)
|
| 512 | (let ((user-pw (getpw #$user)))
|
| 513 | (chown (string-append "/var/lib/syncthing-" #$user)
|
| 514 | (passwd:uid user-pw)
|
| 515 | (passwd:gid user-pw)))
|
| 516 | (chmod (string-append "/var/lib/syncthing-" #$user) #o700))
|
| 517 |
|
| 518 | (fork+exec-command
|
| 519 | (append (list (string-append #$syncthing "/bin/syncthing")
|
| 520 | |
| 521 | "--no-browser"
|
| 522 | |
| 523 | "--no-restart"
|
| 524 | (string-append "--logflags=" (number->string #$logflags)))
|
| 525 | |
| 526 | |
| 527 | (if (or #$(not config-file) #$home-service?) '()
|
| 528 | (list (string-append "--home=/var/lib/syncthing-" #$user)))
|
| 529 | '#$arguments)
|
| 530 | #:user #$(and (not home-service?) user)
|
| 531 | #:group #$(and (not home-service?) group)
|
| 532 | #:environment-variables
|
| 533 | (append
|
| 534 | (list
|
| 535 | (string-append "HOME="
|
| 536 | (or #$home
|
| 537 | (passwd:dir
|
| 538 | (getpw (if (and #$home-service?
|
| 539 | (not #$user))
|
| 540 | (getuid)
|
| 541 | #$user)))))
|
| 542 | "SSL_CERT_DIR=/etc/ssl/certs"
|
| 543 | "SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt")
|
| 544 | (filter (negate |
| 545 | (lambda (str)
|
| 546 | (or (string-prefix? "HOME=" str)
|
| 547 | (string-prefix? "SSL_CERT_DIR=" str)
|
| 548 | (string-prefix? "SSL_CERT_FILE=" str))))
|
| 549 | (environ))))))
|
| 550 | (respawn? #f)
|
| 551 | (stop #~(make-kill-destructor))))))
|
| 552 |
|
| 553 | (define syncthing-files-service
|
| 554 | (match-record-lambda <syncthing-configuration> (config-file user home home-service?)
|
| 555 | (if config-file
|
| 556 | |
| 557 | |
| 558 | |
| 559 | |
| 560 | `((,(if home-service?
|
| 561 | ".local/state/syncthing/config.xml"
|
| 562 | (string-append "/var/lib/syncthing-" user "/config.xml"))
|
| 563 | ,(if (file-like? config-file)
|
| 564 | config-file
|
| 565 | (plain-file "syncthing-config.xml" (serialize-syncthing-config-file
|
| 566 | config-file)))))
|
| 567 | '())))
|
| 568 |
|
| 569 | (define syncthing-service-type
|
| 570 | (service-type (name 'syncthing)
|
| 571 | (extensions (list (service-extension shepherd-root-service-type
|
| 572 | syncthing-shepherd-service)
|
| 573 | (service-extension special-files-service-type
|
| 574 | syncthing-files-service)))
|
| 575 | (description
|
| 576 | "Run @uref{https://github.com/syncthing/syncthing, Syncthing}
|
| 577 | decentralized continuous file system synchronization.")))
|
| 578 |
|
| 579 | |