bpo-32713: Fix tarfile.itn for large/negative float values. (GH-5434)
[python-delta-tar] / backup.py
... / ...
CommitLineData
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
19import argparse
20import binascii
21import json
22import logging
23import os
24import re
25import random
26import shutil
27import sys
28from datetime import datetime
29from functools import partial
30
31from deltatar.deltatar import DeltaTar, NO_MATCH, MATCH, PARENT_MATCH
32from deltatar.tarfile import TarFile, GNU_FORMAT
33
34consoleLogger = logging.StreamHandler()
35consoleLogger.setLevel(logging.DEBUG)
36
37def check_equal_dirs(path1, path2, deltatar):
38 '''
39 compare the two directories source_dir and target_dir and check
40 # they are the same
41 '''
42 nbars1 = len(path1.split('/'))
43 nbars2 = len(path2.split('/'))
44
45 source_it = deltatar._recursive_walk_dir(path1)
46 source_it = deltatar.jsonize_path_iterator(source_it, strip=nbars1)
47 target_it = deltatar._recursive_walk_dir(path2)
48 target_it = deltatar.jsonize_path_iterator(target_it, strip=nbars2)
49 while True:
50 try:
51 sitem = next(source_it)
52 titem = next(target_it)
53 except StopIteration:
54 try:
55 titem = next(target_it)
56 raise Exception("iterators do not stop at the same time")
57 except StopIteration:
58 break
59 try:
60 assert deltatar._equal_stat_dicts(sitem, titem)
61 except Exception as e:
62 print(sitem)
63 print(titem)
64 print("FAIL")
65 raise
66
67if __name__ == "__main__":
68 #import tracemalloc
69 #tracemalloc.enable()
70 #top = tracemalloc.DisplayTop(25)
71 #top.show_lineno = True
72 #top.start(20)
73 parser = argparse.ArgumentParser()
74
75 parser.add_argument("-m", "--mode", default='',
76 help=
77 """Mode in which to read/write the backup.
78 Valid modes are:
79 '' open uncompressed;
80 'gz' open with gzip compression;
81 'bz2' open with bzip2 compression;
82 '#gz' encrypted stream of individually
83 compressed tar blocks.
84 To enable encryption, supply a password.
85 """)
86 parser.add_argument("-t", "--targetpath", help="Target path directory.")
87 parser.add_argument("-s", "--sourcepath", help="Source path directory.")
88 epw = os.getenv ("PDTCRYPT_PASSWORD")
89 parser.add_argument("-p", "--password",
90 default=epw.strip () if epw is not None else None,
91 help="Password for symmetric encryption. "
92 "The environment variable PDTCRYPT_PASSWORD should "
93 "be preferred to this. Enables encryption.")
94 parser.add_argument("-v", "--volsize", default=None,
95 help="Maximum volume size, in megabytes.")
96 parser.add_argument("-r", "--restore", action='store_true',
97 help="Restore a backup.")
98 parser.add_argument("-R", "--recover", action='store_true',
99 help="Recover a potentially damaged backup with an index "
100 "file. **Caution**: recovery mode is insecure; it ignores "
101 "data integrity checks on encrypted backup sets which may "
102 "allow unauthorized decryption of confidential information.")
103 parser.add_argument("-f", "--full", action='store_true',
104 help="Create a full backup.")
105 parser.add_argument("-d", "--diff", action='store_true',
106 help="Create a diff backup.")
107 parser.add_argument("-i", "--indexes", nargs='+', help="Indexes paths.")
108 parser.add_argument("-l", "--list-files", action='store_true',
109 help="List files in a tarball.")
110 parser.add_argument("-x", "--excluded", nargs='+', default=[],
111 help="Files to exclude from backup.")
112 parser.add_argument("-inc", "--included", nargs='+', default=[],
113 help="Files to include in the backup.")
114 parser.add_argument("-ip", "--included-path", default=None,
115 help="Path to a file containing a list of included paths.")
116 parser.add_argument("-xp", "--excluded-path", default=None,
117 help="Path to a file containing a list of excluded paths.")
118 parser.add_argument("-e", "--equals", action='store_true',
119 help="Check if two dirs are equal.")
120
121 args = parser.parse_args()
122
123 if args.excluded_path:
124 f = open(args.excluded_path, 'r')
125 excluded_files = f.readlines()
126 f.close()
127 else:
128 excluded_files = args.excluded
129
130 if args.included_path:
131 f = open(args.included_path, 'r')
132 included_files = f.readlines()
133 f.close()
134 else:
135 included_files = args.included
136
137 deltatar = DeltaTar(mode=args.mode, password=args.password,
138 logger=consoleLogger, excluded_files=excluded_files,
139 included_files=included_files)
140
141 if args.full:
142 deltatar.create_full_backup(args.sourcepath, args.targetpath, args.volsize)
143 elif args.diff:
144 deltatar.create_diff_backup(args.sourcepath, args.targetpath, args.indexes[0], args.volsize)
145 elif args.list_files:
146 deltatar.list_backup(args.sourcepath, lambda e: print (e.name))
147 elif args.restore:
148 if args.indexes is not None:
149 deltatar.restore_backup(args.targetpath, backup_indexes_paths=args.indexes)
150 else:
151 deltatar.restore_backup(args.targetpath, backup_tar_path=args.sourcepath)
152 elif args.recover:
153 if args.sourcepath is not None:
154 print("Disaster recovery conflicts with --sourcepath; please supply"
155 " an\nindex file (--indexes).", file=sys.stderr)
156 failed = deltatar.recover_backup(args.targetpath,
157 backup_indexes_paths=args.indexes)
158 if len (failed) > 0:
159 logger = logging.getLogger('deltatar.DeltaTar')
160 print ("%d files could not be restored:" % len (failed))
161 for i, f in enumerate (failed):
162 print (" [%d] %s (%s)" % (i, f [0], f [1]))
163
164 elif args.equals:
165 check_equal_dirs(os.path.abspath(args.sourcepath), os.path.abspath(args.targetpath), deltatar)
166 else:
167 print("Nothing to do.\nPlease specify one of --full, --diff, --list-files, "
168 "--restore, --equals.\n", file=sys.stderr)
169 parser.print_help(file=sys.stderr)
170
171