Commit | Line | Data |
---|---|---|
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 |
19 | import argparse |
20 | import binascii | |
21 | import json | |
22 | import logging | |
23 | import os | |
24 | import re | |
25 | import random | |
26 | import shutil | |
27 | from datetime import datetime | |
28 | from functools import partial | |
29 | ||
30 | from deltatar.deltatar import DeltaTar, NO_MATCH, MATCH, PARENT_MATCH | |
31 | from deltatar.tarfile import TarFile, GNU_FORMAT | |
32 | ||
10c70dc6 ERE |
33 | consoleLogger = logging.StreamHandler() |
34 | consoleLogger.setLevel(logging.DEBUG) | |
35 | ||
36 | def 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 | ||
66 | if __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 |