grab password from envp if not supplied on CLI
[python-delta-tar] / backup.py
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
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
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:
50             sitem = next(source_it)
51             titem = next(target_it)
52         except StopIteration:
53             try:
54                 titem = next(target_it)
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)
60         except Exception as e:
61             print(sitem)
62             print(titem)
63             print("FAIL")
64             raise
65
66 if __name__ == "__main__":
67     #import tracemalloc
68     #tracemalloc.enable()
69     #top = tracemalloc.DisplayTop(25)
70     #top.show_lineno = True
71     #top.start(20)
72     parser = argparse.ArgumentParser()
73
74     parser.add_argument("-m", "--mode", default='',
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;
81                                        '#gz.aes128' open an aes128 encrypted stream of gzip
82                                                     compressed tar blocks;
83                                        '#aes128'    open an aes128 encrypted stream of tar
84                                                     blocks.
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.")
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("-f", "--full", action='store_true',
99                         help="Create a full backup.")
100     parser.add_argument("-d", "--diff", action='store_true',
101                         help="Create a diff backup.")
102     parser.add_argument("-i", "--indexes", nargs='+', help="Indexes paths.")
103     parser.add_argument("-l", "--list-files", action='store_true',
104                         help="List files in a tarball.")
105     parser.add_argument("-x", "--excluded", nargs='+', default=[],
106                         help="Files to exclude from backup.")
107     parser.add_argument("-inc", "--included", nargs='+', default=[],
108                         help="Files to include in the backup.")
109     parser.add_argument("-ip", "--included-path", default=None,
110                         help="Path to a file containing a list of included paths.")
111     parser.add_argument("-xp", "--excluded-path", default=None,
112                         help="Path to a file containing a list of excluded paths.")
113     parser.add_argument("-e", "--equals", action='store_true',
114                         help="Check if two dirs are equal.")
115
116     args = parser.parse_args()
117
118     if args.excluded_path:
119         f = open(args.excluded_path, 'r')
120         excluded_files = f.readlines()
121         f.close()
122     else:
123         excluded_files = args.excluded
124
125     if args.included_path:
126         f = open(args.included_path, 'r')
127         included_files = f.readlines()
128         f.close()
129     else:
130         included_files = args.included
131
132     deltatar = DeltaTar(mode=args.mode, password=args.password,
133         logger=consoleLogger, excluded_files=excluded_files,
134         included_files=included_files)
135
136     if args.full:
137         deltatar.create_full_backup(args.sourcepath, args.targetpath, args.volsize)
138     elif args.diff:
139         deltatar.create_diff_backup(args.sourcepath, args.targetpath, args.indexes[0], args.volsize)
140     elif args.list_files:
141         deltatar.list_backup(args.sourcepath, lambda e: print (e.name))
142     elif args.restore:
143         if args.indexes is not None:
144             deltatar.restore_backup(args.targetpath, backup_indexes_paths=args.indexes)
145         else:
146             deltatar.restore_backup(args.targetpath, backup_tar_path=args.sourcepath)
147     elif args.equals:
148         check_equal_dirs(os.path.abspath(args.sourcepath), os.path.abspath(args.targetpath), deltatar)
149     else:
150         import sys
151         print("Nothing to do.\nPlease specify one of --full, --diff, --list-files, "
152               "--restore, --equals.\n", file=sys.stderr)
153         parser.print_help(file=sys.stderr)
154