gnu: nnn: Don't use NAME in source URI.
[jackhill/guix/guix.git] / gnu / packages / backup.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2014, 2015 Eric Bavier <bavier@member.fsf.org>
3 ;;; Copyright © 2014 Ian Denhardt <ian@zenhack.net>
4 ;;; Copyright © 2015, 2016, 2017 Leo Famulari <leo@famulari.name>
5 ;;; Copyright © 2017, 2018 Tobias Geerinckx-Rice <me@tobias.gr>
6 ;;; Copyright © 2017 Thomas Danckaert <post@thomasdanckaert.be>
7 ;;; Copyright © 2017 Arun Isaac <arunisaac@systemreboot.net>
8 ;;; Copyright © 2017 Kei Kebreau <kkebreau@posteo.net>
9 ;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
10 ;;; Copyright © 2017 Christopher Allan Webber <cwebber@dustycloud.org>
11 ;;; Copyright © 2017 Rutger Helling <rhelling@mykolab.com>
12 ;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
13 ;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
14 ;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
15 ;;; Copyright © 2019 Alex Vong <alexvong1995@gmail.com>
16 ;;;
17 ;;; This file is part of GNU Guix.
18 ;;;
19 ;;; GNU Guix is free software; you can redistribute it and/or modify it
20 ;;; under the terms of the GNU General Public License as published by
21 ;;; the Free Software Foundation; either version 3 of the License, or (at
22 ;;; your option) any later version.
23 ;;;
24 ;;; GNU Guix is distributed in the hope that it will be useful, but
25 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
26 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 ;;; GNU General Public License for more details.
28 ;;;
29 ;;; You should have received a copy of the GNU General Public License
30 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
31
32 (define-module (gnu packages backup)
33 #:use-module (guix packages)
34 #:use-module ((guix licenses) #:prefix license:)
35 #:use-module (guix git-download)
36 #:use-module (guix download)
37 #:use-module (guix utils)
38 #:use-module (guix build-system gnu)
39 #:use-module (guix build-system go)
40 #:use-module (guix build-system python)
41 #:use-module (gnu packages)
42 #:use-module (gnu packages acl)
43 #:use-module (gnu packages autotools)
44 #:use-module (gnu packages base)
45 #:use-module (gnu packages check)
46 #:use-module (gnu packages compression)
47 #:use-module (gnu packages crypto)
48 #:use-module (gnu packages databases)
49 #:use-module (gnu packages dbm)
50 #:use-module (gnu packages dejagnu)
51 #:use-module (gnu packages ftp)
52 #:use-module (gnu packages glib)
53 #:use-module (gnu packages gnupg)
54 #:use-module (gnu packages golang)
55 #:use-module (gnu packages gperf)
56 #:use-module (gnu packages guile)
57 #:use-module (gnu packages linux)
58 #:use-module (gnu packages mcrypt)
59 #:use-module (gnu packages nettle)
60 #:use-module (gnu packages pcre)
61 #:use-module (gnu packages perl)
62 #:use-module (gnu packages pkg-config)
63 #:use-module (gnu packages python)
64 #:use-module (gnu packages python-crypto)
65 #:use-module (gnu packages python-web)
66 #:use-module (gnu packages python-xyz)
67 #:use-module (gnu packages rsync)
68 #:use-module (gnu packages ssh)
69 #:use-module (gnu packages tls)
70 #:use-module (gnu packages xml))
71
72 (define-public duplicity
73 (package
74 (name "duplicity")
75 (version "0.7.18.1")
76 (source
77 (origin
78 (method url-fetch)
79 (uri (string-append "https://code.launchpad.net/duplicity/"
80 (version-major+minor version)
81 "-series/" version "/+download/duplicity-"
82 version ".tar.gz"))
83 (sha256
84 (base32
85 "17c0203y5qz9w8iyhs26l44qf6a1vp26b5ykz1ypdr2kv6g02df9"))))
86 (build-system python-build-system)
87 (native-inputs
88 `(("util-linux" ,util-linux) ; setsid command, for the tests
89 ("par2cmdline" ,par2cmdline)
90 ("python-pexpect" ,python2-pexpect)
91 ("python-fasteners" ,python2-fasteners)
92 ("mock" ,python2-mock)))
93 (propagated-inputs
94 `(("lockfile" ,python2-lockfile)
95 ("urllib3" ,python2-urllib3)))
96 (inputs
97 `(("librsync" ,librsync)
98 ("lftp" ,lftp)
99 ("gnupg" ,gnupg) ; gpg executable needed
100 ("util-linux" ,util-linux) ; for setsid
101 ("tzdata" ,tzdata)))
102 (arguments
103 `(#:python ,python-2 ; setup assumes Python 2
104 #:test-target "test"
105 #:phases
106 (modify-phases %standard-phases
107 (add-before 'build 'use-store-file-names
108 (lambda* (#:key inputs #:allow-other-keys)
109 (substitute* "duplicity/gpginterface.py"
110 (("self.call = 'gpg'")
111 (string-append "self.call = '" (assoc-ref inputs "gnupg") "/bin/gpg'")))
112
113 (substitute* '("testing/functional/__init__.py"
114 "testing/overrides/bin/lftp")
115 (("/bin/sh") (which "sh")))
116 #t))
117 (add-before 'check 'check-setup
118 (lambda* (#:key inputs #:allow-other-keys)
119 (setenv "HOME" (getcwd)) ; gpg needs to write to $HOME
120 (setenv "TZDIR" ; some timestamp checks need TZDIR
121 (string-append (assoc-ref inputs "tzdata")
122 "/share/zoneinfo"))
123 #t)))))
124 (home-page "http://duplicity.nongnu.org/index.html")
125 (synopsis "Encrypted backup using rsync algorithm")
126 (description
127 "Duplicity backs up directories by producing encrypted tar-format volumes
128 and uploading them to a remote or local file server. Because duplicity uses
129 librsync, the incremental archives are space efficient and only record the
130 parts of files that have changed since the last backup. Because duplicity
131 uses GnuPG to encrypt and/or sign these archives, they will be safe from
132 spying and/or modification by the server.")
133 (license license:gpl2+)))
134
135 (define-public par2cmdline
136 (package
137 (name "par2cmdline")
138 (version "0.8.0")
139 (source (origin
140 (method git-fetch)
141 (uri (git-reference
142 (url "https://github.com/Parchive/par2cmdline.git")
143 (commit (string-append "v" version))))
144 (file-name (git-file-name name version))
145 (sha256
146 (base32
147 "0f1jsd5sw2wynjzi7yjqjaf13yhyjfdid91p8yh0jn32y03kjyrz"))))
148 (native-inputs
149 `(("automake" ,automake)
150 ("autoconf" ,autoconf)))
151 (build-system gnu-build-system)
152 (synopsis "File verification and repair tools")
153 (description "Par2cmdline uses Reed-Solomon error-correcting codes to
154 generate and verify PAR2 recovery files. These files can be distributed
155 alongside the source files or stored together with back-ups to protect against
156 transmission errors or @dfn{bit rot}, the degradation of storage media over
157 time.
158 Unlike a simple checksum, PAR2 doesn't merely detect errors: as long as the
159 damage isn't too extensive (and smaller than the size of the recovery file), it
160 can even repair them.")
161 (home-page "https://github.com/Parchive/par2cmdline")
162 (license license:gpl3+)))
163
164 (define-public hdup
165 (package
166 (name "hdup")
167 (version "2.0.14")
168 (source
169 (origin
170 (method url-fetch)
171 (uri "https://fossies.org/linux/privat/old/hdup-2.0.14.tar.bz2")
172 (sha256
173 (base32
174 "02bnczg01cyhajmm4rhbnc0ja0dd9ikv9fwv28asxh1rlx9yr0b7"))))
175 (build-system gnu-build-system)
176 (native-inputs `(("pkg-config" ,pkg-config)))
177 (inputs
178 `(("glib" ,glib)
179 ("tar" ,tar)
180 ("lzop" ,lzop)
181 ("mcrypt" ,mcrypt)
182 ("openssh" ,openssh)
183 ("gnupg" ,gnupg-1)))
184 (arguments
185 `(#:configure-flags
186 `(,(string-append "--sbindir=" (assoc-ref %outputs "out") "/bin"))
187 #:tests? #f))
188 (home-page "http://archive.miek.nl/projects/hdup/index.html")
189 (synopsis "Simple incremental backup tool")
190 (description
191 "Hdup2 is a backup utility, its aim is to make backup really simple. The
192 backup scheduling is done by means of a cron job. It supports an
193 include/exclude mechanism, remote backups, encrypted backups and split
194 backups (called chunks) to allow easy burning to CD/DVD.")
195 (license license:gpl2)))
196
197 (define-public libarchive
198 (package
199 (name "libarchive")
200 (replacement libarchive-3.3.3)
201 (version "3.3.2")
202 (source
203 (origin
204 (method url-fetch)
205 (uri (string-append "https://libarchive.org/downloads/libarchive-"
206 version ".tar.gz"))
207 (patches (search-patches "libarchive-CVE-2017-14166.patch"
208 "libarchive-CVE-2017-14502.patch"))
209 (sha256
210 (base32
211 "1km0mzfl6in7l5vz9kl09a88ajx562rw93ng9h2jqavrailvsbgd"))))
212 (build-system gnu-build-system)
213 (inputs
214 `(("zlib" ,zlib)
215 ("nettle" ,nettle)
216 ("lzo" ,lzo)
217 ("bzip2" ,bzip2)
218 ("libxml2" ,libxml2)
219 ("xz" ,xz)))
220 (arguments
221 `(#:phases
222 (modify-phases %standard-phases
223 (add-before 'build 'patch-pwd
224 (lambda _
225 (substitute* "Makefile"
226 (("/bin/pwd") (which "pwd")))
227 #t))
228 (replace 'check
229 (lambda _
230 ;; XXX: The test_owner_parse, test_read_disk, and
231 ;; test_write_disk_lookup tests expect user 'root' to exist, but
232 ;; the chroot's /etc/passwd doesn't have it. Turn off those tests.
233 ;;
234 ;; The tests allow one to disable tests matching a globbing pattern.
235 (invoke "make" "libarchive_test" "bsdcpio_test" "bsdtar_test")
236 ;; XXX: This glob disables too much.
237 (invoke "./libarchive_test" "^test_*_disk*")
238 (invoke "./bsdcpio_test" "^test_owner_parse")
239 (invoke "./bsdtar_test")))
240 (add-after 'install 'add--L-in-libarchive-pc
241 (lambda* (#:key inputs outputs #:allow-other-keys)
242 (let* ((out (assoc-ref outputs "out"))
243 (lib (string-append out "/lib"))
244 (nettle (assoc-ref inputs "nettle"))
245 (libxml2 (assoc-ref inputs "libxml2"))
246 (xz (assoc-ref inputs "xz"))
247 (zlib (assoc-ref inputs "zlib"))
248 (bzip2 (assoc-ref inputs "bzip2")))
249 (substitute* (string-append lib "/pkgconfig/libarchive.pc")
250 (("-lnettle")
251 (string-append "-L" nettle "/lib -lnettle"))
252 (("-lxml2")
253 (string-append "-L" libxml2 "/lib -lxml2"))
254 (("-llzma")
255 (string-append "-L" xz "/lib -llzma"))
256 (("-lz")
257 (string-append "-L" zlib "/lib -lz"))
258 (("-lbz2")
259 (string-append "-L" bzip2 "/lib -lbz2")))
260 #t))))
261
262 ;; libarchive/test/test_write_format_gnutar_filenames.c needs to be
263 ;; compiled with C99 or C11 or a gnu variant.
264 #:configure-flags '("CFLAGS=-O2 -g -std=c99")))
265 (home-page "https://libarchive.org/")
266 (synopsis "Multi-format archive and compression library")
267 (description
268 "Libarchive provides a flexible interface for reading and writing
269 archives in various formats such as tar and cpio. Libarchive also supports
270 reading and writing archives compressed using various compression filters such
271 as gzip and bzip2. The library is inherently stream-oriented; readers
272 serially iterate through the archive, writers serially add things to the
273 archive. In particular, note that there is currently no built-in support for
274 random access nor for in-place modification.")
275 (license license:bsd-2)))
276
277 (define-public libarchive-3.3.3
278 (package
279 (inherit libarchive)
280 (version "3.3.3")
281 (source
282 (origin
283 (method url-fetch)
284 (uri (string-append "https://libarchive.org/downloads/libarchive-"
285 version ".tar.gz"))
286 (patches (search-patches "libarchive-CVE-2018-1000877.patch"
287 "libarchive-CVE-2018-1000878.patch"
288 "libarchive-CVE-2018-1000880.patch"))
289 (sha256
290 (base32
291 "0bhfncid058p7n1n8v29l6wxm3mhdqfassscihbsxfwz3iwb2zms"))))))
292
293 (define-public rdup
294 (package
295 (name "rdup")
296 (version "1.1.15")
297 (source
298 (origin
299 (method url-fetch)
300 (file-name (string-append name "-" version ".tar.gz"))
301 (uri (string-append "https://github.com/miekg/rdup/archive/"
302 version ".tar.gz"))
303 (sha256
304 (base32
305 "1jr91hgcf0rrpanqlwws72ql9db6d6grs2i122ki1s4bx0vqqyvq"))))
306 (build-system gnu-build-system)
307 (native-inputs
308 `(("autoconf" ,autoconf)
309 ("automake" ,automake)
310 ("pkg-config" ,pkg-config)
311
312 ;; For tests.
313 ("dejagnu" ,dejagnu)))
314 (inputs
315 `(("glib" ,glib)
316 ("pcre" ,pcre)
317 ("libarchive" ,libarchive)
318 ("mcrypt" ,mcrypt)
319 ("nettle" ,nettle)))
320 (arguments
321 `(#:parallel-build? #f ;race conditions
322 #:phases
323 (modify-phases %standard-phases
324 (add-before 'build 'qualify-inputs
325 (lambda* (#:key inputs #:allow-other-keys)
326 ;; This script is full of pitfalls. Fix some that particularly
327 ;; affect Guix users & leave the rest as reader excercises.
328 (substitute* "rdup-simple"
329 ;; Use the input ‘mcrypt’, not whatever's in $PATH at run time.
330 (("([' ])mcrypt " all delimiter)
331 (string-append delimiter (which "mcrypt") " "))
332 ;; Avoid frivolous dependency on ‘which’ with a shell builtin.
333 (("which") "command -v"))
334 #t))
335 (add-before 'check 'pre-check
336 (lambda _
337 (setenv "HOME" (getcwd))
338 (substitute* "testsuite/rdup/rdup.rdup-up-t-with-file.exp"
339 (("/bin/cat") (which "cat")))
340 #t)))))
341 (home-page "https://github.com/miekg/rdup")
342 (synopsis "Provide a list of files to backup")
343 (description
344 "Rdup is a utility inspired by rsync and the plan9 way of doing backups.
345 Rdup itself does not backup anything, it only print a list of absolute
346 file names to standard output. Auxiliary scripts are needed that act on this
347 list and implement the backup strategy.")
348 (license license:gpl3+)))
349
350 (define-public btar
351 (package
352 (name "btar")
353 (version "1.1.1")
354 (source
355 (origin
356 (method url-fetch)
357 (uri (string-append "http://vicerveza.homeunix.net/~viric/soft/btar/"
358 "btar-" version ".tar.gz"))
359 (sha256
360 (base32
361 "0miklk4bqblpyzh1bni4x6lqn88fa8fjn15x1k1n8bxkx60nlymd"))))
362 (build-system gnu-build-system)
363 (inputs
364 `(("librsync" ,librsync)))
365 (arguments
366 `(#:make-flags `(,(string-append "PREFIX=" (assoc-ref %outputs "out"))
367 "CC=gcc")
368 #:tests? #f ;test input not distributed
369 #:phases
370 ;; no configure phase
371 (modify-phases %standard-phases
372 (delete 'configure))))
373 (home-page "http://viric.name/cgi-bin/btar/doc/trunk/doc/home.wiki")
374 (synopsis "Tar-compatible archiver")
375 (description
376 "Btar is a tar-compatible archiver which allows arbitrary compression and
377 ciphering, redundancy, differential backup, indexed extraction, multicore
378 compression, input and output serialisation, and tolerance to partial archive
379 errors.")
380 (license license:gpl3+)))
381
382 (define-public rdiff-backup
383 (package
384 (name "rdiff-backup")
385 (version "1.2.8")
386 (source
387 (origin
388 (method url-fetch)
389 (uri (string-append "mirror://savannah/rdiff-backup/rdiff-backup-"
390 version ".tar.gz"))
391 (sha256
392 (base32
393 "1nwmmh816f96h0ff1jxk95ad38ilbhbdl5dgibx1d4cl81dsi48d"))))
394 (build-system python-build-system)
395 (inputs
396 `(("python" ,python-2)
397 ("librsync" ,librsync)))
398 (arguments
399 `(#:python ,python-2
400 #:tests? #f))
401 (home-page "https://www.nongnu.org/rdiff-backup/")
402 (synopsis "Local/remote mirroring+incremental backup")
403 (description
404 "Rdiff-backup backs up one directory to another, possibly over a network.
405 The target directory ends up a copy of the source directory, but extra reverse
406 diffs are stored in a special subdirectory of that target directory, so you
407 can still recover files lost some time ago. The idea is to combine the best
408 features of a mirror and an incremental backup. Rdiff-backup also preserves
409 subdirectories, hard links, dev files, permissions, uid/gid ownership,
410 modification times, extended attributes, acls, and resource forks. Also,
411 rdiff-backup can operate in a bandwidth efficient manner over a pipe, like
412 rsync. Thus you can use rdiff-backup and ssh to securely back a hard drive up
413 to a remote location, and only the differences will be transmitted. Finally,
414 rdiff-backup is easy to use and settings have sensible defaults.")
415 (license license:gpl2+)))
416
417 (define-public rsnapshot
418 (package
419 (name "rsnapshot")
420 (version "1.4.2")
421 (source
422 (origin
423 (method url-fetch)
424 (uri (string-append
425 "https://github.com/rsnapshot/rsnapshot/releases/download/"
426 version "/rsnapshot-" version ".tar.gz"))
427 (sha256
428 (base32
429 "05jfy99a0xs6lvsjfp3wz21z0myqhmwl2grn3jr9clijbg282ah4"))))
430 (build-system gnu-build-system)
431 (arguments
432 `(#:phases
433 (modify-phases %standard-phases
434 (replace 'check
435 (lambda _
436 (substitute* '("t/cmd-post_pre-exec/conf/pre-true-post-true.conf"
437 "t/backup_exec/conf/backup_exec_fail.conf"
438 "t/backup_exec/conf/backup_exec.conf")
439 (("/bin/true") (which "true"))
440 (("/bin/false") (which "false")))
441 (invoke "make" "test"))))))
442 (inputs
443 `(("perl" ,perl)
444 ("rsync" ,rsync)))
445 (home-page "http://rsnapshot.org")
446 (synopsis "Deduplicating snapshot backup utility based on rsync")
447 (description "rsnapshot is a file system snapshot utility based on rsync.
448 rsnapshot makes it easy to make periodic snapshots of local machines, and
449 remote machines over SSH. To reduce the disk space required for each backup,
450 rsnapshot uses hard links to deduplicate identical files.")
451 (license license:gpl2+)))
452
453 (define-public libchop
454 (package
455 (name "libchop")
456 (version "0.5.2")
457 (source (origin
458 (method url-fetch)
459 (uri (string-append "mirror://savannah/libchop/libchop-"
460 version ".tar.gz"))
461 (sha256
462 (base32
463 "0fpdyxww41ba52d98blvnf543xvirq1v9xz1i3x1gm9lzlzpmc2g"))
464 (patches (search-patches "diffutils-gets-undeclared.patch"))))
465 (build-system gnu-build-system)
466 (arguments
467 '(#:phases (modify-phases %standard-phases
468 (add-before 'configure 'adjust-configure-script
469 (lambda _
470 ;; Mimic upstream commit
471 ;; 25750ab5ef82fd3cfce5205d5f1ef07b47098091.
472 (substitute* "configure"
473 (("GUILE=(.*)--variable bindir`" _ middle)
474 (string-append "GUILE=" middle
475 "--variable bindir`/guile")))
476 #t))
477 (add-before 'check 'skip-test
478 (lambda _
479 ;; XXX: This test fails (1) because current GnuTLS no
480 ;; longer supports OpenPGP authentication, and (2) for
481 ;; some obscure reason. Better skip it.
482 (setenv "XFAIL_TESTS" "utils/block-server")
483 #t)))))
484 (native-inputs
485 `(("guile" ,guile-2.0)
486 ("gperf" ,gperf-3.0) ;see <https://bugs.gnu.org/32382>
487 ("pkg-config" ,pkg-config)))
488 (inputs
489 `(("guile" ,guile-2.0)
490 ("util-linux" ,util-linux)
491 ("gnutls" ,gnutls)
492 ("tdb" ,tdb)
493 ("bdb" ,bdb)
494 ("gdbm" ,gdbm)
495 ("libgcrypt" ,libgcrypt)
496 ("lzo" ,lzo)
497 ("bzip2" ,bzip2)
498 ("zlib" ,zlib)))
499 (home-page "https://nongnu.org/libchop/")
500 (synopsis "Tools & library for data backup and distributed storage")
501 (description
502 "Libchop is a set of utilities and library for data backup and
503 distributed storage. Its main application is @command{chop-backup}, an
504 encrypted backup program that supports data integrity checks, versioning,
505 distribution among several sites, selective sharing of stored data, adaptive
506 compression, and more. The library itself implements storage techniques such
507 as content-addressable storage, content hash keys, Merkle trees, similarity
508 detection, and lossless compression.")
509 (license license:gpl3+)))
510
511 (define-public borg
512 (package
513 (name "borg")
514 (version "1.1.8")
515 (source
516 (origin
517 (method url-fetch)
518 (uri (pypi-uri "borgbackup" version))
519 (sha256
520 (base32
521 "0qqvcscn1l4y83x4sh3izdpmr8zq38j8chjkpfq4q4d01i470hqb"))
522 (modules '((guix build utils)))
523 (snippet
524 '(begin
525 ;; Delete files generated by Cython. We used to have a regex
526 ;; that created the list of generated files but Borg has
527 ;; added new non-generated C files that cause the regex to
528 ;; generate the wrong list.
529 (for-each delete-file
530 '("src/borg/algorithms/checksums.c"
531 "src/borg/chunker.c"
532 "src/borg/compress.c"
533 "src/borg/crypto/low_level.c"
534 "src/borg/hashindex.c"
535 "src/borg/item.c"
536 "src/borg/platform/darwin.c"
537 "src/borg/platform/freebsd.c"
538 "src/borg/platform/linux.c"
539 "src/borg/platform/posix.c"))
540 ;; Remove bundled shared libraries.
541 (with-directory-excursion "src/borg/algorithms"
542 (for-each delete-file-recursively
543 (list "blake2" "lz4" "zstd")))
544 #t))))
545 (build-system python-build-system)
546 (arguments
547 `(#:modules ((srfi srfi-26) ; for cut
548 (guix build utils)
549 (guix build python-build-system))
550 #:phases
551 (modify-phases %standard-phases
552 (add-after 'unpack 'set-env
553 (lambda* (#:key inputs #:allow-other-keys)
554 (let ((openssl (assoc-ref inputs "openssl"))
555 (libb2 (assoc-ref inputs "libb2"))
556 (lz4 (assoc-ref inputs "lz4"))
557 (zstd (assoc-ref inputs "zstd")))
558 (setenv "BORG_OPENSSL_PREFIX" openssl)
559 (setenv "BORG_LIBB2_PREFIX" libb2)
560 (setenv "BORG_LIBLZ4_PREFIX" lz4)
561 (setenv "BORG_LIBZSTD_PREFIX" zstd)
562 (setenv "PYTHON_EGG_CACHE" "/tmp")
563 ;; The test 'test_return_codes[python]' fails when
564 ;; HOME=/homeless-shelter.
565 (setenv "HOME" "/tmp")
566 #t)))
567 (add-after 'unpack 'remove-documentation-timestamps ; reproducibility
568 (lambda _
569 (substitute* "setup.py"
570 (("write\\(':Date:'.*") "\n"))
571 #t))
572 ;; The tests need to be run after Borg is installed.
573 (delete 'check)
574 (add-after 'install 'check
575 (lambda* (#:key inputs outputs #:allow-other-keys)
576 ;; Make the installed package available for the test suite.
577 (add-installed-pythonpath inputs outputs)
578 ;; The tests should be run in an empty directory.
579 (mkdir-p "tests")
580 (with-directory-excursion "tests"
581 (invoke "py.test" "-v" "--pyargs" "borg.testsuite" "-k"
582 (string-append
583 ;; These tests need to write to '/var'.
584 "not test_get_cache_dir "
585 "and not test_get_config_dir "
586 "and not test_get_keys_dir "
587 "and not test_get_security_dir "
588 ;; These tests assume there is a root user in
589 ;; '/etc/passwd'.
590 "and not test_access_acl "
591 "and not test_default_acl "
592 "and not test_non_ascii_acl "
593 ;; This test needs the unpackaged pytest-benchmark.
594 "and not benchmark "
595 ;; These tests assume the kernel supports FUSE.
596 "and not test_fuse "
597 "and not test_fuse_allow_damaged_files "
598 "and not test_mount_hardlinks")))))
599 (add-after 'install 'install-doc
600 (lambda* (#:key inputs outputs #:allow-other-keys)
601 (let* ((out (assoc-ref outputs "out"))
602 (man (string-append out "/share/man/man1"))
603 (misc (string-append out "/share/borg/misc")))
604 (for-each (cut install-file <> misc)
605 '("docs/misc/create_chunker-params.txt"
606 "docs/misc/internals-picture.txt"
607 "docs/misc/prune-example.txt"))
608 (add-installed-pythonpath inputs outputs)
609 (invoke "python3" "setup.py" "build_man")
610 (copy-recursively "docs/man" man)
611 #t))))))
612 (native-inputs
613 `(("python-cython" ,python-cython)
614 ("python-setuptools-scm" ,python-setuptools-scm)
615 ("python-pytest" ,python-pytest)
616 ;; For generating the documentation.
617 ("python-sphinx" ,python-sphinx)
618 ("python-guzzle-sphinx-theme" ,python-guzzle-sphinx-theme)))
619 (inputs
620 `(("acl" ,acl)
621 ("libb2" ,libb2)
622 ("lz4" ,lz4)
623 ("openssl" ,openssl)
624 ("python-llfuse" ,python-llfuse)
625 ;; The Python msgpack library changed its name so Borg requires this
626 ;; transitional package for now:
627 ;; <https://bugs.gnu.org/30662>
628 ("python-msgpack" ,python-msgpack-transitional)
629 ("zstd" ,zstd)))
630 (synopsis "Deduplicated, encrypted, authenticated and compressed backups")
631 (description "Borg is a deduplicating backup program. Optionally, it
632 supports compression and authenticated encryption. The main goal of Borg is to
633 provide an efficient and secure way to backup data. The data deduplication
634 technique used makes Borg suitable for daily backups since only changes are
635 stored. The authenticated encryption technique makes it suitable for backups
636 to not fully trusted targets. Borg is a fork of Attic.")
637 (home-page "https://www.borgbackup.org/")
638 (license license:bsd-3)))
639
640 (define-public attic
641 (package
642 (name "attic")
643 (version "0.16")
644 (source (origin
645 (method url-fetch)
646 (uri (pypi-uri "Attic" version))
647 (sha256
648 (base32
649 "0b5skd36r4c0915lwpkqg5hxm49gls9pprs1b7hc40910wlcsl36"))))
650 (build-system python-build-system)
651 (arguments
652 `(;; The tests assume they are run as root:
653 ;; https://github.com/jborg/attic/issues/7
654 #:tests? #f
655 #:phases
656 (modify-phases %standard-phases
657 (add-before
658 'build 'set-openssl-prefix
659 (lambda* (#:key inputs #:allow-other-keys)
660 (setenv "ATTIC_OPENSSL_PREFIX" (assoc-ref inputs "openssl"))
661 #t)))))
662 (inputs
663 `(("acl" ,acl)
664 ("openssl" ,openssl)
665 ("python-msgpack" ,python-msgpack)
666
667 ;; Attic is probably incompatible with llfuse > 0.41.
668 ;; These links are to discussions of llfuse compatibility from
669 ;; the borg project. Borg is a recent fork of attic, and attic
670 ;; has not been updated since the fork, so it's likely that
671 ;; llfuse compatibility requirements are still the same.
672 ;; https://github.com/borgbackup/borg/issues/642
673 ;; https://github.com/borgbackup/borg/issues/643
674 ("python-llfuse" ,python-llfuse-0.41)))
675 (synopsis "Deduplicating backup program")
676 (description "Attic is a deduplicating backup program. The main goal of
677 Attic is to provide an efficient and secure way to backup data. The data
678 deduplication technique used makes Attic suitable for daily backups since only
679 changes are stored.")
680 (home-page "https://attic-backup.org/")
681 (license license:bsd-3)
682 (properties `((superseded . ,borg)))))
683
684 (define-public wimlib
685 (package
686 (name "wimlib")
687 (version "1.12.0")
688 (source (origin
689 (method url-fetch)
690 (uri (string-append "https://wimlib.net/downloads/"
691 name "-" version ".tar.gz"))
692 (sha256
693 (base32
694 "0ks6hq7vwq13ljkzxp3a490bf8dnracgl2azf57rg49ad2fzab45"))))
695 (build-system gnu-build-system)
696 (native-inputs
697 `(("pkg-config" ,pkg-config)))
698 (inputs
699 `(("fuse" ,fuse)
700 ("libxml2" ,libxml2)
701 ("ntfs-3g" ,ntfs-3g)
702 ("openssl" ,openssl)))
703 (arguments
704 `(#:configure-flags (list "--enable-test-support")))
705 (home-page "https://wimlib.net/")
706 (synopsis "WIM file manipulation library and utilities")
707 (description "wimlib is a C library and set of command-line utilities for
708 creating, modifying, extracting, and mounting archives in the Windows Imaging
709 Format (@dfn{WIM files}). It can capture and apply WIMs directly from and to
710 NTFS volumes using @code{ntfs-3g}, preserving NTFS-specific attributes.")
711 ;; wimlib is dual-licenced under version 3 or later of either the GPL or
712 ;; LGPL, except those files explicitly marked as being released into the
713 ;; public domain (CC0) in their headers.
714 (license (list license:gpl3+
715 license:lgpl3+
716 license:cc0))))
717
718 (define-public obnam
719 (package
720 (name "obnam")
721 (version "1.21")
722 (source
723 (origin
724 (method url-fetch)
725 (uri (string-append
726 "http://code.liw.fi/debian/pool/main/o/obnam/obnam_"
727 version ".orig.tar.xz"))
728 (sha256
729 (base32
730 "0qlipsq50hca71zc0dp1mg9zs12qm0sbblw7qfzl0hj6mk2rv1by"))))
731 (build-system python-build-system)
732 (arguments
733 `(#:python ,python-2
734 #:phases
735 (modify-phases %standard-phases
736 (replace 'check
737 (lambda _
738 (substitute* "obnamlib/vfs_local_tests.py"
739 ;; Check for the nobody user instead of root.
740 (("self.fs.get_username\\(0\\), 'root'")
741 "self.fs.get_username(65534), 'nobody'")
742 ;; Disable tests checking for root group.
743 (("self.fs.get_groupname\\(0\\)") "'root'"))
744 (substitute* "obnamlib/vfs_local.py"
745 ;; Don't cover get_groupname function.
746 (("def get_groupname\\(self, gid\\):")
747 "def get_groupname(self, gid): # pragma: no cover"))
748 ;; Can't run network tests.
749 (invoke "./check" "--unit-tests"))))))
750 (inputs
751 `(("python2-cliapp" ,python2-cliapp)
752 ("python2-larch" ,python2-larch)
753 ("python2-paramiko" ,python2-paramiko)
754 ("python2-pyaml" ,python2-pyaml)
755 ("python2-tracing" ,python2-tracing)
756 ("python2-ttystatus" ,python2-ttystatus)))
757 (native-inputs
758 `(("gnupg" ,gnupg)
759 ("python2-coverage" ,python2-coverage)
760 ("python2-coverage-test-runner" ,python2-coverage-test-runner)
761 ("python2-pep8" ,python2-pep8)
762 ("python2-pylint" ,python2-pylint)))
763 (home-page "https://obnam.org/")
764 (synopsis "Retired backup program")
765 (description
766 "Warning: @uref{https://blog.liw.fi/posts/2017/08/13/retiring_obnam/,
767 the Obnam project is retired}. You should use another backup solution instead.
768
769 Obnam was an easy, secure backup program. Features included snapshot backups,
770 data de-duplication and encrypted backups using GnuPG. Backups can be stored on
771 local hard disks, or online via the SSH SFTP protocol. The backup server, if
772 used, does not require any special software, on top of SSH.")
773 (license license:gpl3+)))
774
775 (define-public dirvish
776 (package
777 (name "dirvish")
778 (version "1.2.1")
779 (build-system gnu-build-system)
780 (source (origin
781 (method url-fetch)
782 (uri (string-append
783 "http://dirvish.org/dirvish-" version ".tgz"))
784 (sha256
785 (base32
786 "1kbxa1irszp2zw8hd5qzqnrrzb4vxfivs1vn64yxnj0lak1jjzvb"))))
787 (arguments
788 `(#:modules ((ice-9 match) (ice-9 rdelim)
789 ,@%gnu-build-system-modules)
790 #:phases
791 ;; This mostly mirrors the steps taken in the install.sh that ships
792 ;; with dirvish, but simplified because we aren't prompting interactively
793 (modify-phases %standard-phases
794 (delete 'configure)
795 (delete 'build)
796 (delete 'check)
797 (replace 'install
798 (lambda* (#:key inputs outputs #:allow-other-keys)
799 ;; These are mostly the same steps the install.sh that comes with
800 ;; dirvish does
801 (let* (;; Files we'll be copying
802 (executables
803 '("dirvish" "dirvish-runall"
804 "dirvish-expire" "dirvish-locate"))
805 (man-pages
806 '(("dirvish" "8") ("dirvish-runall" "8")
807 ("dirvish-expire" "8") ("dirvish-locate" "8")
808 ("dirvish.conf" "5")))
809
810 (output-dir
811 (assoc-ref outputs "out"))
812
813 ;; Just a default... not so useful on guixsd though
814 ;; You probably want to a service with file(s) to point to.
815 (confdir "/etc/dirvish")
816
817 (perl (string-append (assoc-ref %build-inputs "perl")
818 "/bin/perl"))
819 (loadconfig.pl (call-with-input-file "loadconfig.pl"
820 read-string)))
821
822
823 (define (write-pl filename)
824 (define pl-header
825 (string-append "#!" perl "\n\n"
826 "$CONFDIR = \"" confdir "\";\n\n"))
827 (define input-file-location
828 (string-append filename ".pl"))
829 (define target-file-location
830 (string-append output-dir "/bin/" filename ".pl"))
831 (define text-to-write
832 (string-append pl-header
833 (call-with-input-file input-file-location
834 read-string)
835 "\n" loadconfig.pl))
836 (with-output-to-file target-file-location
837 (lambda ()
838 (display text-to-write)))
839 (chmod target-file-location #o755)
840 (wrap-program target-file-location
841 `("PERL5LIB" ":" prefix
842 ,(map (lambda (l) (string-append (assoc-ref %build-inputs l)
843 "/lib/perl5/site_perl"))
844 '("perl-libtime-period"
845 "perl-libtime-parsedate")))))
846
847 (define write-man
848 (match-lambda
849 ((file-base man-num)
850 (let* ((filename
851 (string-append file-base "." man-num))
852 (output-path
853 (string-append output-dir
854 "/share/man/man" man-num
855 "/" filename)))
856 (copy-file filename output-path)))))
857
858 ;; Make directories
859 (mkdir-p (string-append output-dir "/bin/"))
860 (mkdir-p (string-append output-dir "/share/man/man8/"))
861 (mkdir-p (string-append output-dir "/share/man/man5/"))
862
863 ;; Write out executables
864 (for-each write-pl executables)
865 ;; Write out man pages
866 (for-each write-man man-pages)
867 #t))))))
868 (inputs
869 `(("perl" ,perl)
870 ("rsync" ,rsync)
871 ("perl-libtime-period" ,perl-libtime-period)
872 ("perl-libtime-parsedate" ,perl-libtime-parsedate)))
873 (home-page "http://dirvish.org/")
874 (synopsis "Fast, disk based, rotating network backup system")
875 (description
876 "With dirvish you can maintain a set of complete images of your
877 file systems with unattended creation and expiration. A dirvish backup vault
878 is like a time machine for your data. ")
879 (license (license:fsf-free "file://COPYING"
880 "Open Software License 2.0"))))
881
882 (define-public restic
883 (package
884 (name "restic")
885 (version "0.9.3")
886 ;; TODO Try packaging the bundled / vendored dependencies in the 'vendor/'
887 ;; directory.
888 (source (origin
889 (method url-fetch)
890 (uri (string-append
891 "https://github.com/restic/restic/releases/download/"
892 "v" version "/restic-" version ".tar.gz"))
893 (file-name (string-append name "-" version ".tar.gz"))
894 (sha256
895 (base32
896 "1l1ddnf61pfsrry97qwhhdzywin2mgnbrkhcc9pabsdfk602anmr"))))
897 (build-system go-build-system)
898 (arguments
899 `(#:import-path "github.com/restic/restic"
900 #:unpack-path "github.com/restic"
901 ;; We don't need to install the source code for end-user applications.
902 #:install-source? #f
903 #:phases
904 (modify-phases %standard-phases
905 (replace 'build
906 (lambda* (#:key inputs #:allow-other-keys)
907 (with-directory-excursion (string-append
908 "src/github.com/restic/restic-"
909 ,version)
910 ;; Disable 'restic self-update'. It makes little sense in Guix.
911 (substitute* "build.go" (("selfupdate") ""))
912 (setenv "HOME" (getcwd)) ; for $HOME/.cache/go-build
913 (invoke "go" "run" "build.go"))))
914
915 (replace 'check
916 (lambda _
917 (with-directory-excursion (string-append
918 "src/github.com/restic/restic-"
919 ,version)
920 ;; Disable FUSE tests.
921 (setenv "RESTIC_TEST_FUSE" "0")
922 (invoke "go" "run" "build.go" "--test"))))
923
924 (replace 'install
925 (lambda* (#:key outputs #:allow-other-keys)
926 (let ((out (assoc-ref outputs "out"))
927 (src (string-append "src/github.com/restic/restic-"
928 ,version)))
929 (install-file (string-append src "/restic")
930 (string-append out "/bin"))
931 #t)))
932
933 (add-after 'install 'install-docs
934 (lambda* (#:key outputs #:allow-other-keys)
935 (let* ((out (assoc-ref outputs "out"))
936 (man "/share/man")
937 (man-section (string-append man "/man"))
938 (src (string-append "src/github.com/restic/restic-"
939 ,version "/doc/man/")))
940 ;; Install all the man pages to "out".
941 (for-each
942 (lambda (file)
943 (install-file file
944 (string-append out man-section
945 (string-take-right file 1))))
946 (find-files src "\\.[1-9]"))
947 #t)))
948
949 (add-after 'install-docs 'install-shell-completion
950 (lambda* (#:key outputs #:allow-other-keys)
951 (let* ((out (assoc-ref outputs "out"))
952 (bin (string-append out "/bin"))
953 (etc (string-append out "/etc"))
954 (share (string-append out "/share")))
955 (for-each
956 (lambda (shell)
957 (let* ((shell-name (symbol->string shell))
958 (dir (string-append "etc/completion/" shell-name)))
959 (mkdir-p dir)
960 (invoke (string-append bin "/restic") "generate"
961 (string-append "--" shell-name "-completion")
962 (string-append dir "/"
963 (case shell
964 ((bash) "restic")
965 ((zsh) "_restic"))))))
966 '(bash zsh))
967 (with-directory-excursion "etc/completion"
968 (install-file "bash/restic"
969 (string-append etc "/bash_completion.d"))
970 (install-file "zsh/_restic"
971 (string-append share "/zsh/site-functions")))
972 #t))))))
973 (home-page "https://restic.net/")
974 (synopsis "Backup program with multiple revisions, encryption and more")
975 (description "Restic is a program that does backups right and was designed
976 with the following principles in mind:
977
978 @itemize
979 @item Easy: Doing backups should be a frictionless process, otherwise you
980 might be tempted to skip it. Restic should be easy to configure and use, so
981 that, in the event of a data loss, you can just restore it. Likewise,
982 restoring data should not be complicated.
983
984 @item Fast: Backing up your data with restic should only be limited by your
985 network or hard disk bandwidth so that you can backup your files every day.
986 Nobody does backups if it takes too much time. Restoring backups should only
987 transfer data that is needed for the files that are to be restored, so that
988 this process is also fast.
989
990 @item Verifiable: Much more important than backup is restore, so restic
991 enables you to easily verify that all data can be restored. @item Secure:
992 Restic uses cryptography to guarantee confidentiality and integrity of your
993 data. The location the backup data is stored is assumed not to be a trusted
994 environment (e.g. a shared space where others like system administrators are
995 able to access your backups). Restic is built to secure your data against
996 such attackers.
997
998 @item Efficient: With the growth of data, additional snapshots should only
999 take the storage of the actual increment. Even more, duplicate data should be
1000 de-duplicated before it is actually written to the storage back end to save
1001 precious backup space.
1002 @end itemize")
1003 (license license:bsd-2)))