allow for numbers of missing and failed files to differ in recovery test
[python-delta-tar] / backup.py
CommitLineData
e4a93a2f
ERE
1#!/usr/bin/env python3
2
3# Copyright (C) 2013 Intra2net AG
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published
7# by the Free Software Foundation; either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see
17# <http://www.gnu.org/licenses/lgpl-3.0.html>
18
10c70dc6
ERE
19import argparse
20import binascii
21import json
22import logging
23import os
24import re
25import random
26import shutil
27from datetime import datetime
28from functools import partial
29
30from deltatar.deltatar import DeltaTar, NO_MATCH, MATCH, PARENT_MATCH
31from deltatar.tarfile import TarFile, GNU_FORMAT
32
10c70dc6
ERE
33consoleLogger = logging.StreamHandler()
34consoleLogger.setLevel(logging.DEBUG)
35
36def check_equal_dirs(path1, path2, deltatar):
37 '''
38 compare the two directories source_dir and target_dir and check
39 # they are the same
40 '''
41 nbars1 = len(path1.split('/'))
42 nbars2 = len(path2.split('/'))
43
44 source_it = deltatar._recursive_walk_dir(path1)
45 source_it = deltatar.jsonize_path_iterator(source_it, strip=nbars1)
46 target_it = deltatar._recursive_walk_dir(path2)
47 target_it = deltatar.jsonize_path_iterator(target_it, strip=nbars2)
48 while True:
49 try:
e4a93a2f
ERE
50 sitem = next(source_it)
51 titem = next(target_it)
10c70dc6
ERE
52 except StopIteration:
53 try:
e4a93a2f 54 titem = next(target_it)
10c70dc6
ERE
55 raise Exception("iterators do not stop at the same time")
56 except StopIteration:
57 break
58 try:
59 assert deltatar._equal_stat_dicts(sitem, titem)
e4a93a2f
ERE
60 except Exception as e:
61 print(sitem)
62 print(titem)
63 print("FAIL")
10c70dc6
ERE
64 raise
65
66if __name__ == "__main__":
1046c582
ERE
67 #import tracemalloc
68 #tracemalloc.enable()
69 #top = tracemalloc.DisplayTop(25)
70 #top.show_lineno = True
253d4cdd 71 #top.start(20)
10c70dc6
ERE
72 parser = argparse.ArgumentParser()
73
74 parser.add_argument("-m", "--mode", default='',
47fb2d67
PG
75 help=
76 """Mode in which to read/write the backup.
77 Valid modes are:
78 '' open uncompressed;
79 'gz' open with gzip compression;
80 'bz2' open with bzip2 compression;
e0631598
PG
81 '#gz' encrypted stream of individually
82 compressed tar blocks.
83 To enable encryption, supply a password.
47fb2d67
PG
84 """)
85 parser.add_argument("-t", "--targetpath", help="Target path directory.")
86 parser.add_argument("-s", "--sourcepath", help="Source path directory.")
ecb9676d
PG
87 epw = os.getenv ("PDTCRYPT_PASSWORD")
88 parser.add_argument("-p", "--password",
89 default=epw.strip () if epw is not None else None,
90 help="Password for symmetric encryption. "
91 "The environment variable PDTCRYPT_PASSWORD should "
e0631598 92 "be preferred to this. Enables encryption.")
47fb2d67
PG
93 parser.add_argument("-v", "--volsize", default=None,
94 help="Maximum volume size, in megabytes.")
95 parser.add_argument("-r", "--restore", action='store_true',
96 help="Restore a backup.")
e93f83f1
PG
97 parser.add_argument("-R", "--recover", action='store_true',
98 help="Restore a backup with an index file.")
47fb2d67
PG
99 parser.add_argument("-f", "--full", action='store_true',
100 help="Create a full backup.")
101 parser.add_argument("-d", "--diff", action='store_true',
102 help="Create a diff backup.")
103 parser.add_argument("-i", "--indexes", nargs='+', help="Indexes paths.")
104 parser.add_argument("-l", "--list-files", action='store_true',
105 help="List files in a tarball.")
8c65a2b1 106 parser.add_argument("-x", "--excluded", nargs='+', default=[],
47fb2d67 107 help="Files to exclude from backup.")
4cbed687 108 parser.add_argument("-inc", "--included", nargs='+', default=[],
47fb2d67 109 help="Files to include in the backup.")
4cbed687 110 parser.add_argument("-ip", "--included-path", default=None,
47fb2d67 111 help="Path to a file containing a list of included paths.")
8c65a2b1 112 parser.add_argument("-xp", "--excluded-path", default=None,
47fb2d67
PG
113 help="Path to a file containing a list of excluded paths.")
114 parser.add_argument("-e", "--equals", action='store_true',
115 help="Check if two dirs are equal.")
10c70dc6
ERE
116
117 args = parser.parse_args()
8c65a2b1
ERE
118
119 if args.excluded_path:
120 f = open(args.excluded_path, 'r')
121 excluded_files = f.readlines()
122 f.close()
123 else:
124 excluded_files = args.excluded
125
4cbed687
ERE
126 if args.included_path:
127 f = open(args.included_path, 'r')
128 included_files = f.readlines()
129 f.close()
130 else:
131 included_files = args.included
132
8c65a2b1 133 deltatar = DeltaTar(mode=args.mode, password=args.password,
4cbed687
ERE
134 logger=consoleLogger, excluded_files=excluded_files,
135 included_files=included_files)
10c70dc6
ERE
136
137 if args.full:
138 deltatar.create_full_backup(args.sourcepath, args.targetpath, args.volsize)
139 elif args.diff:
140 deltatar.create_diff_backup(args.sourcepath, args.targetpath, args.indexes[0], args.volsize)
8c65a2b1 141 elif args.list_files:
ec96293d 142 deltatar.list_backup(args.sourcepath, lambda e: print (e.name))
10c70dc6
ERE
143 elif args.restore:
144 if args.indexes is not None:
145 deltatar.restore_backup(args.targetpath, backup_indexes_paths=args.indexes)
146 else:
147 deltatar.restore_backup(args.targetpath, backup_tar_path=args.sourcepath)
e93f83f1
PG
148 elif args.recover:
149 failed = deltatar.recover_backup(args.targetpath,
150 backup_indexes_paths=args.indexes,
151 backup_tar_path=args.sourcepath)
152 if len (failed) > 0:
153 logger = logging.getLogger('deltatar.DeltaTar')
154 print ("%d files could not be restored:" % len (failed))
155 for i, f in enumerate (failed):
156 print (" [%d] %s (%s)" % (i, f [0], f [1]))
157
10c70dc6 158 elif args.equals:
1817bfb4
PG
159 check_equal_dirs(os.path.abspath(args.sourcepath), os.path.abspath(args.targetpath), deltatar)
160 else:
161 import sys
162 print("Nothing to do.\nPlease specify one of --full, --diff, --list-files, "
163 "--restore, --equals.\n", file=sys.stderr)
164 parser.print_help(file=sys.stderr)
165
e93f83f1 166