~ed.so/duplicity/reuse-passphrase-for-signing-fix

335 by loafman
patch #6675: Add modelines
1
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
2
#
404 by loafman
Add/update copyright statements in all distribution source files
3
# Copyright 2002 Ben Escoto <ben@emerose.org>
4
# Copyright 2007 Kenneth Loafman <kenneth@loafman.com>
1 by bescoto
Initial checkin
5
#
6
# This file is part of duplicity.
7
#
2 by bescoto
Added full GPL statement in source files at request of Jaime Villate
8
# Duplicity is free software; you can redistribute it and/or modify it
9
# under the terms of the GNU General Public License as published by the
476 by loafman
After email voting among known duplicity contributors,
10
# Free Software Foundation; either version 2 of the License, or (at your
2 by bescoto
Added full GPL statement in source files at request of Jaime Villate
11
# option) any later version.
12
#
13
# Duplicity is distributed in the hope that it will be useful, but
14
# WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
# General Public License for more details.
17
#
18
# You should have received a copy of the GNU General Public License
19
# along with duplicity; if not, write to the Free Software Foundation,
20
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1 by bescoto
Initial checkin
21
22
"""Parse command line, check for consistency, and set globals"""
23
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
24
from copy import copy
25
import optparse
290 by loafman
patch #6596: re-organize backend module structure
26
import os
27
import re
28
import sys
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
29
import socket
290 by loafman
patch #6596: re-organize backend module structure
30
525.1.10 by kenneth at loafman
Avoid deprecation warning for md5 in Python 2.6.
31
try:
32
    from hashlib import md5
33
except ImportError:
34
    from md5 import new as md5
35
290 by loafman
patch #6596: re-organize backend module structure
36
from duplicity import backend
37
from duplicity import dup_time
38
from duplicity import globals
39
from duplicity import gpg
40
from duplicity import log
41
from duplicity import path
42
from duplicity import selection
43
1 by bescoto
Initial checkin
44
546 by Kenneth Loafman
Fixed issues in Checkpoint/Restart:
45
select_opts = []            # Will hold all the selection options
46
select_files = []           # Will hold file objects when filelist given
490 by loafman
Move ssh and imap backend globals to globals.py.
47
546 by Kenneth Loafman
Fixed issues in Checkpoint/Restart:
48
full_backup = None          # Will be set to true if full command given
49
list_current = None         # Will be set to true if list-current command given
50
collection_status = None    # Will be set to true if collection-status command given
51
cleanup = None              # Set to true if cleanup command given
52
verify = None               # Set to true if verify command given
1 by bescoto
Initial checkin
53
179 by loafman
There is a new command line syntax to separate actions and
54
commands = ["cleanup",
304 by loafman
Untabify all files. To compare against previous
55
            "collection-status",
56
            "full",
57
            "incremental",
58
            "list-current-files",
59
            "remove-older-than",
60
            "remove-all-but-n-full",
651.1.2 by olivier
Adding new remove-all-inc-of-but-n-full command as a variant of remove-all-but-n-full
61
            "remove-all-inc-of-but-n-full",
304 by loafman
Untabify all files. To compare against previous
62
            "restore",
63
            "verify",
64
            ]
179 by loafman
There is a new command line syntax to separate actions and
65
431 by loafman
Add deprecation warnings for options affected by old filenames.
66
def old_fn_deprecation(opt):
432 by loafman
Changes for 0.5.10.
67
    print >>sys.stderr, _("Warning: Option %s is pending deprecation "
68
                          "and will be removed in a future release.\n"
69
                          "Use of default filenames is strongly suggested.") % opt
431 by loafman
Add deprecation warnings for options affected by old filenames.
70
521 by loafman
After merge of Checkpoint/Restart.
71
72
def expand_fn(filename):
73
    return os.path.expanduser(os.path.expandvars(filename))
74
541.2.1 by kenneth at loafman
* Change handling of smart archive dir so both archive and name can be changed.
75
76
def expand_archive_dir(archdir, backname):
525.1.2 by Peter Schuller
* support expansion of %DUPLICITY_ARGS_HASH% in --archive-dir value
77
    """
541.2.1 by kenneth at loafman
* Change handling of smart archive dir so both archive and name can be changed.
78
    Return expanded version of archdir joined with backname.
525.1.4 by Peter Schuller
* introduce --name parameter to specify symbolic name of a backup
79
    """
80
    assert globals.backup_name is not None, \
602.2.21 by ken
487686 re-add scp backend and make available via command line option
81
        "expand_archive_dir() called prior to globals.backup_name being set"
525.1.4 by Peter Schuller
* introduce --name parameter to specify symbolic name of a backup
82
541.2.1 by kenneth at loafman
* Change handling of smart archive dir so both archive and name can be changed.
83
    return expand_fn(os.path.join(archdir, backname))
84
525.1.4 by Peter Schuller
* introduce --name parameter to specify symbolic name of a backup
85
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
86
def generate_default_backup_name(backend_url):
525.1.4 by Peter Schuller
* introduce --name parameter to specify symbolic name of a backup
87
    """
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
88
    @param backend_url: URL to backend.
525.1.4 by Peter Schuller
* introduce --name parameter to specify symbolic name of a backup
89
    @returns A default backup name (string).
90
    """
91
    # For default, we hash args to obtain a reasonably safe default.
92
    # We could be smarter and resolve things like relative paths, but
93
    # this should actually be a pretty good compromise. Normally only
94
    # the destination will matter since you typically only restart
95
    # backups of the same thing to a given destination. The inclusion
96
    # of the source however, does protect against most changes of
97
    # source directory (for whatever reason, such as
98
    # /path/to/different/snapshot). If the user happens to have a case
99
    # where relative paths are used yet the relative path is the same
100
    # (but duplicity is run from a different directory or similar),
101
    # then it is simply up to the user to set --archive-dir properly.
525.1.10 by kenneth at loafman
Avoid deprecation warning for md5 in Python 2.6.
102
    burlhash = md5()
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
103
    burlhash.update(backend_url)
104
    return burlhash.hexdigest()
521 by loafman
After merge of Checkpoint/Restart.
105
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
106
def check_file(option, opt, value):
107
    return expand_fn(value)
108
109
def check_time(option, opt, value):
110
    try:
111
        return dup_time.genstrtotime(value)
112
    except dup_time.TimeException, e:
113
        raise optparse.OptionValueError(str(e))
114
115
def check_verbosity(option, opt, value):
116
    fail = False
117
118
    value = value.lower()
119
    if value in ['e', 'error']:
120
        verb = log.ERROR
121
    elif value in ['w', 'warning']:
122
        verb = log.WARNING
123
    elif value in ['n', 'notice']:
124
        verb = log.NOTICE
125
    elif value in ['i', 'info']:
126
        verb = log.INFO
127
    elif value in ['d', 'debug']:
128
        verb = log.DEBUG
129
    else:
130
        try:
131
            verb = int(value)
664 by Kenneth Loafman
615449 Command-line verbosity parsing crash
132
            if verb < 0 or verb > 9:
133
                fail = True
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
134
        except ValueError:
135
            fail = True
136
137
    if fail:
138
        # TRANSL: In this portion of the usage instructions, "[ewnid]" indicates which
139
        # characters are permitted (e, w, n, i, or d); the brackets imply their own
140
        # meaning in regex; i.e., only one of the characters is allowed in an instance.
141
        raise optparse.OptionValueError("Verbosity must be one of: digit [0-9], character [ewnid], "
142
                                        "or word ['error', 'warning', 'notice', 'info', 'debug']. "
143
                                        "The default is 4 (Notice).  It is strongly recommended "
144
                                        "that verbosity level is set at 2 (Warning) or higher.")
145
146
    return verb
147
148
class DupOption(optparse.Option):
149
    TYPES = optparse.Option.TYPES + ("file", "time", "verbosity",)
150
    TYPE_CHECKER = copy(optparse.Option.TYPE_CHECKER)
151
    TYPE_CHECKER["file"] = check_file
152
    TYPE_CHECKER["time"] = check_time
153
    TYPE_CHECKER["verbosity"] = check_verbosity
154
155
    ACTIONS = optparse.Option.ACTIONS + ("extend",)
156
    STORE_ACTIONS = optparse.Option.STORE_ACTIONS + ("extend",)
157
    TYPED_ACTIONS = optparse.Option.TYPED_ACTIONS + ("extend",)
158
    ALWAYS_TYPED_ACTIONS = optparse.Option.ALWAYS_TYPED_ACTIONS + ("extend",)
159
160
    def take_action(self, action, dest, opt, value, values, parser):
161
        if action == "extend":
642.1.1 by Michael Terry
fix crash on empty gpg-options argument
162
            if not value:
163
                return
642.1.2 by Michael Terry
and handle initial, empty value for extend commandline actions
164
            if hasattr(values, dest) and getattr(values, dest):
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
165
                setattr(values, dest, getattr(values, dest) + ' ' + value)
166
            else:
167
                setattr(values, dest, value)
168
        else:
169
            optparse.Option.take_action(
170
                self, action, dest, opt, value, values, parser)
541.2.1 by kenneth at loafman
* Change handling of smart archive dir so both archive and name can be changed.
171
1 by bescoto
Initial checkin
172
def parse_cmdline_options(arglist):
304 by loafman
Untabify all files. To compare against previous
173
    """Parse argument list"""
174
    global select_opts, select_files, full_backup
175
    global list_current, collection_status, cleanup, remove_time, verify
176
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
177
    def use_gio(*args):
178
        try:
179
            import duplicity.backends.giobackend
180
            backend.force_backend(duplicity.backends.giobackend.GIOBackend)
181
        except ImportError:
182
            log.FatalError(_("Unable to load gio module"), log.ErrorCode.gio_not_available)
183
184
    def set_log_fd(fd):
185
        if fd < 1:
186
            raise optparse.OptionValueError("log-fd must be greater than zero.")
602.7.1 by Michael Terry
merge lp:~mterry/duplicity/optparse
187
        log.add_fd(fd)
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
188
189
    def set_time_sep(sep, opt):
190
        if sep == '-':
191
            raise optparse.OptionValueError("Dash ('-') not valid for time-separator.")
192
        globals.time_separator = sep
193
        old_fn_deprecation(opt)
194
195
    def add_selection(o, s, v, p):
196
        select_opts.append((s, v))
197
198
    def add_filelist(o, s, v, p):
602.7.1 by Michael Terry
merge lp:~mterry/duplicity/optparse
199
        filename = v
200
        select_opts.append((s, filename))
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
201
        try:
202
            select_files.append(open(filename, "r"))
304 by loafman
Untabify all files. To compare against previous
203
        except IOError:
355 by loafman
patch #6700: Make duplicity translatable
204
            log.FatalError(_("Error opening file %s") % filename,
339 by loafman
patch #6686: Add error codes for all fatal errors
205
                           log.ErrorCode.cant_open_filelist)
304 by loafman
Untabify all files. To compare against previous
206
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
207
    def print_ver(o, s, v, p):
208
        print "duplicity %s" % (globals.version)
209
        sys.exit(0)
210
627.1.2 by Michael Terry
add --rename argument
211
    def add_rename(o, s, v, p):
212
        globals.rename[os.path.normcase(os.path.normpath(v[0]))] = v[1]
213
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
214
    parser = optparse.OptionParser(option_class=DupOption, usage=usage())
215
216
    # If this is true, only warn and don't raise fatal error when backup
217
    # source directory doesn't match previous backup source directory.
218
    parser.add_option("--allow-source-mismatch", action="store_true")
219
220
    # Set to the path of the archive directory (the directory which
221
    # contains the signatures and manifests of the relevent backup
222
    # collection), and for checkpoint state between volumes.
223
    # TRANSL: Used in usage help to represent a Unix-style path name. Example:
224
    # --archive-dir <path>
225
    parser.add_option("--archive-dir", type="file", metavar=_("path"))
226
227
    # Asynchronous put/get concurrency limit
228
    # (default of 0 disables asynchronicity).
229
    parser.add_option("--asynchronous-upload", action="store_const", const=1,
230
                      dest="async_concurrency")
231
232
    # config dir for future use
233
    parser.add_option("--config-dir", type="file", metavar=_("path"),
234
                      help=optparse.SUPPRESS_HELP)
235
713 by Kenneth Loafman
579958 Assertion error "time not moving forward at appropriate pace"
236
    # for testing -- set current time
237
    parser.add_option("--current-time", type="int",
238
                      dest="current_time", help=optparse.SUPPRESS_HELP)
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
239
240
    # Don't actually do anything, but still report what would be done
241
    parser.add_option("--dry-run", action="store_true")
242
243
    # TRANSL: Used in usage help to represent an ID for a GnuPG key. Example:
244
    # --encrypt-key <gpg_key_id>
245
    parser.add_option("--encrypt-key", type="string", metavar=_("gpg-key-id"),
246
                      dest="", action="callback",
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
247
                      callback=lambda o, s, v, p: globals.gpg_profile.recipients.append(v)) #@UndefinedVariable
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
248
722.4.1 by Lekensteyn
- invalid function description fixed for get_passphrase in duplicity-bin
249
    # secret keyring in which the private encrypt key can be found
250
    parser.add_option("--encrypt-secret-keyring", type="string", metavar=_("path"))
761.3.1 by ede
- introduce --encrypt-sign-key parameter
251
    
252
    parser.add_option("--encrypt-sign-key", type="string", metavar=_("gpg-key-id"),
253
                      dest="", action="callback",
254
                      callback=lambda o, s, v, p: ( globals.gpg_profile.recipients.append(v), set_sign_key(v)) )
722.4.1 by Lekensteyn
- invalid function description fixed for get_passphrase in duplicity-bin
255
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
256
    # TRANSL: Used in usage help to represent a "glob" style pattern for
257
    # matching one or more files, as described in the documentation.
258
    # Example:
259
    # --exclude <shell_pattern>
260
    parser.add_option("--exclude", action="callback", metavar=_("shell_pattern"),
261
                      dest="", type="string", callback=add_selection)
262
263
    parser.add_option("--exclude-device-files", action="callback",
264
                      dest="", callback=add_selection)
265
266
    parser.add_option("--exclude-filelist", type="file", metavar=_("filename"),
267
                      dest="", action="callback", callback=add_filelist)
268
269
    parser.add_option("--exclude-filelist-stdin", action="callback", dest="",
270
                      callback=lambda o, s, v, p: (select_opts.append(("--exclude-filelist", "standard input")),
271
                                                   select_files.append(sys.stdin)))
272
273
    parser.add_option("--exclude-globbing-filelist", type="file", metavar=_("filename"),
274
                      dest="", action="callback", callback=add_filelist)
275
276
    # TRANSL: Used in usage help to represent the name of a file. Example:
277
    # --log-file <filename>
278
    parser.add_option("--exclude-if-present", metavar=_("filename"), dest="",
279
                      type="file", action="callback", callback=add_selection)
280
281
    parser.add_option("--exclude-other-filesystems", action="callback",
282
                      dest="", callback=add_selection)
283
284
    # TRANSL: Used in usage help to represent a regular expression (regexp).
285
    parser.add_option("--exclude-regexp", metavar=_("regular_expression"),
286
                      dest="", type="string", action="callback", callback=add_selection)
287
288
    # Whether we should be particularly aggressive when cleaning up
289
    parser.add_option("--extra-clean", action="store_true")
290
291
    # used in testing only - raises exception after volume
292
    parser.add_option("--fail-on-volume", type="int",
293
                      help=optparse.SUPPRESS_HELP)
294
295
    # If set, restore only the subdirectory or file specified, not the
296
    # whole root.
297
    # TRANSL: Used in usage help to represent a Unix-style path name. Example:
298
    # --archive-dir <path>
299
    parser.add_option("--file-to-restore", "-r", action="callback", type="file",
300
                      metavar=_("path"), dest="restore_dir",
301
                      callback=lambda o, s, v, p: setattr(p.values, "restore_dir", v.rstrip('/')))
302
303
    # Used to confirm certain destructive operations like deleting old files.
304
    parser.add_option("--force", action="store_true")
305
306
    # FTP data connection type
307
    parser.add_option("--ftp-passive", action="store_const", const="passive", dest="ftp_connection")
308
    parser.add_option("--ftp-regular", action="store_const", const="regular", dest="ftp_connection")
309
310
    # If set, forces a full backup if the last full backup is older than
311
    # the time specified
312
    parser.add_option("--full-if-older-than", type="time", dest="full_force_time", metavar=_("time"))
313
314
    parser.add_option("--gio", action="callback", callback=use_gio)
315
316
    parser.add_option("--gpg-options", action="extend", metavar=_("options"))
317
318
    # ignore (some) errors during operations; supposed to make it more
319
    # likely that you are able to restore data under problematic
320
    # circumstances. the default should absolutely always be False unless
321
    # you know what you are doing.
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
322
    parser.add_option("--ignore-errors", action="callback",
667 by Kenneth Loafman
589495 duplicity --short-filenames crashes with TypeError
323
                      dest="ignore_errors",
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
324
                      callback=lambda o, s, v, p: (log.Warn(
325
                          _("Running in 'ignore errors' mode due to %s; please "
326
                            "re-consider if this was not intended") % s),
669.1.1 by Kenneth Loafman
Changes for 0.6.10.
327
                          setattr(p.values, "ignore errors", True)))
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
328
329
    # Whether to use the full email address as the user name when
330
    # logging into an imap server. If false just the user name
331
    # part of the email address is used.
332
    parser.add_option("--imap-full-address", action="store_true",
333
                      help=optparse.SUPPRESS_HELP)
334
335
    # Name of the imap folder where we want to store backups.
336
    # Can be changed with a command line argument.
337
    # TRANSL: Used in usage help to represent an imap mailbox
338
    parser.add_option("--imap-mailbox", metavar=_("imap_mailbox"))
339
340
    parser.add_option("--include", action="callback", metavar=_("shell_pattern"),
341
                      dest="", type="string", callback=add_selection)
342
    parser.add_option("--include-filelist", type="file", metavar=_("filename"),
343
                      dest="", action="callback", callback=add_filelist)
726 by Kenneth Loafman
705499 "include-filelist-stdin" not implemented on version 0.6.11
344
    parser.add_option("--include-filelist-stdin", action="callback", dest="",
345
                      callback=lambda o, s, v, p: (select_opts.append(("--include-filelist", "standard input")),
346
                                                   select_files.append(sys.stdin)))
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
347
    parser.add_option("--include-globbing-filelist", type="file", metavar=_("filename"),
348
                      dest="", action="callback", callback=add_filelist)
349
    parser.add_option("--include-regexp", metavar=_("regular_expression"), dest="",
350
                      type="string", action="callback", callback=add_selection)
351
352
    parser.add_option("--log-fd", type="int", metavar=_("file_descriptor"),
353
                      dest="", action="callback",
354
                      callback=lambda o, s, v, p: set_log_fd(v))
355
356
    # TRANSL: Used in usage help to represent the name of a file. Example:
357
    # --log-file <filename>
358
    parser.add_option("--log-file", type="file", metavar=_("filename"),
359
                      dest="", action="callback",
360
                      callback=lambda o, s, v, p: log.add_file(v))
361
362
    # TRANSL: Used in usage help (noun)
363
    parser.add_option("--name", dest="backup_name", metavar=_("backup name"))
364
365
    # If set to false, then do not encrypt files on remote system
366
    parser.add_option("--no-encryption", action="store_false", dest="encryption")
367
368
    # If set, print the statistics after every backup session
369
    parser.add_option("--no-print-statistics", action="store_false", dest="print_statistics")
370
371
    # If true, filelists and directory statistics will be split on
372
    # nulls instead of newlines.
373
    parser.add_option("--null-separator", action="store_true")
374
375
    # number of retries on network operations
376
    # TRANSL: Used in usage help to represent a desired number of
377
    # something. Example:
378
    # --num-retries <number>
379
    parser.add_option("--num-retries", type="int", metavar=_("number"))
380
381
    # Whether the old filename format is in effect.
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
382
    parser.add_option("--old-filenames", action="callback",
667 by Kenneth Loafman
589495 duplicity --short-filenames crashes with TypeError
383
                      dest="old_filenames",
602.7.1 by Michael Terry
merge lp:~mterry/duplicity/optparse
384
                      callback=lambda o, s, v, p: (setattr(p.values, o.dest, True),
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
385
                                                   old_fn_deprecation(s)))
386
708 by Kenneth Loafman
Add (undocumented) option --pydevd to allow easier debugging when executing long chains of duplicity executions.
387
    # option to trigger Pydev debugger
388
    parser.add_option("--pydevd", action="store_true")
389
390
    # option to rename files during restore
627.1.2 by Michael Terry
add --rename argument
391
    parser.add_option("--rename", type="file", action="callback", nargs=2,
392
                      callback=add_rename)
393
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
394
    # Restores will try to bring back the state as of the following time.
395
    # If it is None, default to current time.
396
    # TRANSL: Used in usage help to represent a time spec for a previous
397
    # point in time, as described in the documentation. Example:
398
    # duplicity remove-older-than time [options] target_url
399
    parser.add_option("--restore-time", "--time", "-t", type="time", metavar=_("time"))
400
401
    # Whether to create European buckets (sorry, hard-coded to only
402
    # support european for now).
403
    parser.add_option("--s3-european-buckets", action="store_true")
404
661 by Kenneth Loafman
582962 Diminishing performance on large files
405
    # Whether to use S3 Reduced Redudancy Storage
406
    parser.add_option("--s3-use-rrs", action="store_true")
407
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
408
    # Whether to use "new-style" subdomain addressing for S3 buckets. Such
409
    # use is not backwards-compatible with upper-case buckets, or buckets
410
    # that are otherwise not expressable in a valid hostname.
411
    parser.add_option("--s3-use-new-style", action="store_true")
412
673.1.1 by Martin Pool
Add --s3-unencrypted-connection (bug 433970)
413
    # Whether to use plain HTTP (without SSL) to send data to S3
414
    # See <https://bugs.launchpad.net/duplicity/+bug/433970>.
415
    parser.add_option("--s3-unencrypted-connection", action="store_true")
416
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
417
    # scp command to use
418
    # TRANSL: noun
419
    parser.add_option("--scp-command", metavar=_("command"))
420
421
    # sftp command to use
422
    # TRANSL: noun
423
    parser.add_option("--sftp-command", metavar=_("command"))
424
425
    # If set, use short (< 30 char) filenames for all the remote files.
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
426
    parser.add_option("--short-filenames", action="callback",
667 by Kenneth Loafman
589495 duplicity --short-filenames crashes with TypeError
427
                      dest="short_filenames",
602.7.1 by Michael Terry
merge lp:~mterry/duplicity/optparse
428
                      callback=lambda o, s, v, p: (setattr(p.values, o.dest, True),
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
429
                                                   old_fn_deprecation(s)))
430
431
    # TRANSL: Used in usage help to represent an ID for a GnuPG key. Example:
432
    # --encrypt-key <gpg_key_id>
433
    parser.add_option("--sign-key", type="string", metavar=_("gpg-key-id"),
434
                      dest="", action="callback",
435
                      callback=lambda o, s, v, p: set_sign_key(v))
436
437
    # default to batch mode using public-key encryption
438
    parser.add_option("--ssh-askpass", action="store_true")
439
440
    # user added ssh options
441
    parser.add_option("--ssh-options", action="extend", metavar=_("options"))
442
443
    # Working directory for the tempfile module. Defaults to /tmp on most systems.
444
    parser.add_option("--tempdir", dest="temproot", type="file", metavar=_("path"))
445
446
    # network timeout value
447
    # TRANSL: Used in usage help. Example:
448
    # --timeout <seconds>
449
    parser.add_option("--timeout", type="int", metavar=_("seconds"))
450
451
    # Character used like the ":" in time strings like
452
    # 2002-08-06T04:22:00-07:00.  The colon isn't good for filenames on
453
    # windows machines.
454
    # TRANSL: abbreviation for "character" (noun)
455
    parser.add_option("--time-separator", type="string", metavar=_("char"),
456
                      action="callback",
457
                      callback=lambda o, s, v, p: set_time_sep(v, s))
458
459
    # Whether to specify --use-agent in GnuPG options
460
    parser.add_option("--use-agent", action="store_true")
461
627.1.1 by Michael Terry
add back accidentally-dropped --use-scp option from commandline merge
462
    parser.add_option("--use-scp", action="store_true")
463
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
464
    parser.add_option("--verbosity", "-v", type="verbosity", metavar="[0-9]",
465
                      dest="", action="callback",
466
                      callback=lambda o, s, v, p: log.setverbosity(v))
467
468
    parser.add_option("-V", "--version", action="callback", callback=print_ver)
469
470
    # volume size
471
    # TRANSL: Used in usage help to represent a desired number of
472
    # something. Example:
473
    # --num-retries <number>
474
    parser.add_option("--volsize", type="int", action="callback", metavar=_("number"),
475
                      callback=lambda o, s, v, p: setattr(p.values, "volsize", v*1024*1024))
476
477
    (options, args) = parser.parse_args()
478
479
    # Copy all arguments and their values to the globals module.  Don't copy
480
    # attributes that are 'hidden' (start with an underscore) or whose name is
481
    # the empty string (used for arguments that don't directly store a value
482
    # by using dest="")
483
    for f in filter(lambda x: x and not x.startswith("_"), dir(options)):
484
        v = getattr(options, f)
602.7.1 by Michael Terry
merge lp:~mterry/duplicity/optparse
485
        # Only set if v is not None because None is the default for all the
486
        # variables.  If user didn't set it, we'll use defaults in globals.py
487
        if v is not None:
488
            setattr(globals, f, v)
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
489
490
    socket.setdefaulttimeout(globals.timeout)
491
304 by loafman
Untabify all files. To compare against previous
492
    # expect no cmd and two positional args
493
    cmd = ""
494
    num_expect = 2
430 by loafman
bug #19988: Incompatibility to Samba/SMB share
495
304 by loafman
Untabify all files. To compare against previous
496
    # process first arg as command
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
497
    if args:
498
        cmd = args.pop(0)
304 by loafman
Untabify all files. To compare against previous
499
        possible = [c for c in commands if c.startswith(cmd)]
500
        # no unique match, that's an error
501
        if len(possible) > 1:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
502
            command_line_error("command '%s' not unique, could be %s" % (cmd, possible))
304 by loafman
Untabify all files. To compare against previous
503
        # only one match, that's a keeper
504
        elif len(possible) == 1:
505
            cmd = possible[0]
506
        # no matches, assume no cmd
507
        elif not possible:
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
508
            args.insert(0, cmd)
430 by loafman
bug #19988: Incompatibility to Samba/SMB share
509
304 by loafman
Untabify all files. To compare against previous
510
    if cmd == "cleanup":
511
        cleanup = True
512
        num_expect = 1
513
    elif cmd == "collection-status":
514
        collection_status = True
515
        num_expect = 1
516
    elif cmd == "full":
517
        full_backup = True
518
        num_expect = 2
519
    elif cmd == "incremental":
520
        globals.incremental = True
521
        num_expect = 2
522
    elif cmd == "list-current-files":
523
        list_current = True
524
        num_expect = 1
525
    elif cmd == "remove-older-than":
526
        try:
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
527
            arg = args.pop(0)
747.1.1 by Michael Terry
always catch Exceptions, not BaseExceptions
528
        except Exception:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
529
            command_line_error("Missing time string for remove-older-than")
304 by loafman
Untabify all files. To compare against previous
530
        globals.remove_time = dup_time.genstrtotime(arg)
531
        num_expect = 1
651.1.2 by olivier
Adding new remove-all-inc-of-but-n-full command as a variant of remove-all-but-n-full
532
    elif cmd == "remove-all-but-n-full" or cmd == "remove-all-inc-of-but-n-full":
533
        if cmd == "remove-all-but-n-full" :
651.1.6 by olivier
Fix remove-older-than which would no longer work
534
            globals.remove_all_but_n_full_mode = True
651.1.2 by olivier
Adding new remove-all-inc-of-but-n-full command as a variant of remove-all-but-n-full
535
        if cmd == "remove-all-inc-of-but-n-full" :
651.1.6 by olivier
Fix remove-older-than which would no longer work
536
            globals.remove_all_inc_of_but_n_full_mode = True
304 by loafman
Untabify all files. To compare against previous
537
        try:
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
538
            arg = args.pop(0)
747.1.1 by Michael Terry
always catch Exceptions, not BaseExceptions
539
        except Exception:
651.1.2 by olivier
Adding new remove-all-inc-of-but-n-full command as a variant of remove-all-but-n-full
540
            command_line_error("Missing count for " + cmd)
304 by loafman
Untabify all files. To compare against previous
541
        globals.keep_chains = int(arg)
542
        if not globals.keep_chains > 0:
651.1.2 by olivier
Adding new remove-all-inc-of-but-n-full command as a variant of remove-all-but-n-full
543
            command_line_error(cmd + " count must be > 0")
304 by loafman
Untabify all files. To compare against previous
544
        num_expect = 1
545
    elif cmd == "verify":
546
        verify = True
547
548
    if len(args) != num_expect:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
549
        command_line_error("Expected %d args, got %d" % (num_expect, len(args)))
304 by loafman
Untabify all files. To compare against previous
550
521 by loafman
After merge of Checkpoint/Restart.
551
    # expand pathname args, but not URL
497 by loafman
Added tilde and variable expansion to the source or
552
    for loc in range(len(args)):
553
        if not '://' in args[loc]:
554
            args[loc] = expand_fn(args[loc])
555
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
556
    # Note that ProcessCommandLine depends on us verifying the arg
557
    # count here; do not remove without fixing it. We must make the
558
    # checks here in order to make enough sense of args to identify
559
    # the backend URL/lpath for args_to_path_backend().
560
    if len(args) < 1:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
561
        command_line_error("Too few arguments")
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
562
    elif len(args) == 1:
563
        backend_url = args[0]
564
    elif len(args) == 2:
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
565
        lpath, backend_url = args_to_path_backend(args[0], args[1]) #@UnusedVariable
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
566
    else:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
567
        command_line_error("Too many arguments")
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
568
525.1.4 by Peter Schuller
* introduce --name parameter to specify symbolic name of a backup
569
    if globals.backup_name is None:
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
570
        globals.backup_name = generate_default_backup_name(backend_url)
525.1.4 by Peter Schuller
* introduce --name parameter to specify symbolic name of a backup
571
521 by loafman
After merge of Checkpoint/Restart.
572
    # set and expand archive dir
541.2.1 by kenneth at loafman
* Change handling of smart archive dir so both archive and name can be changed.
573
    set_archive_dir(expand_archive_dir(globals.archive_dir,
574
                                       globals.backup_name))
521 by loafman
After merge of Checkpoint/Restart.
575
548.1.1 by Peter Schuller
* print archive directory in a more readable fashion #394627
576
    log.Info(_("Using archive dir: %s") % (globals.archive_dir.name,))
525.1.4 by Peter Schuller
* introduce --name parameter to specify symbolic name of a backup
577
    log.Info(_("Using backup name: %s") % (globals.backup_name,))
578
304 by loafman
Untabify all files. To compare against previous
579
    return args
1 by bescoto
Initial checkin
580
521 by loafman
After merge of Checkpoint/Restart.
581
1 by bescoto
Initial checkin
582
def command_line_error(message):
304 by loafman
Untabify all files. To compare against previous
583
    """Indicate a command line error and exit"""
355 by loafman
patch #6700: Make duplicity translatable
584
    log.FatalError(_("Command line error: %s") % (message,) + "\n" +
585
                   _("Enter 'duplicity --help' for help screen."),
327 by loafman
patch #6670: Machine Readable Output
586
                   log.ErrorCode.command_line)
1 by bescoto
Initial checkin
587
521 by loafman
After merge of Checkpoint/Restart.
588
116 by loafman
Patch 6033 - Alexander Zangerl <az@debian.org>:
589
def usage():
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
590
    """Returns terse usage info. The code is broken down into pieces for ease of
567.1.3 by Larry Gilbert
Broke up the usage() help info to simplify translation maintenance.
591
    translation maintenance. Any comments that look extraneous or redundant should
592
    be assumed to be for the benefit of translators, since they can get each string
593
    (paired with its preceding comment, if any) independently of the others."""
594
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
595
    dict = {
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
596
        # TRANSL: Used in usage help to represent a Unix-style path name. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
597
        # rsync://user[:password]@other_host[:port]//absolute_path
598
        'absolute_path'  : _("absolute_path"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
599
600
        # TRANSL: Used in usage help. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
601
        # tahoe://alias/some_dir
602
        'alias'          : _("alias"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
603
604
        # TRANSL: Used in help to represent a "bucket name" for Amazon Web
605
        # Services' Simple Storage Service (S3). Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
606
        # s3://other.host/bucket_name[/prefix]
607
        'bucket_name'    : _("bucket_name"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
608
609
        # TRANSL: abbreviation for "character" (noun)
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
610
        'char'           : _("char"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
611
612
        # TRANSL: noun
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
613
        'command'        : _("command"),
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
614
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
615
        # TRANSL: Used in usage help to represent the name of a container in
616
        # Amazon Web Services' Cloudfront. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
617
        # cf+http://container_name
618
        'container_name' : _("container_name"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
619
620
        # TRANSL: noun
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
621
        'count'          : _("count"),
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
622
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
623
        # TRANSL: Used in usage help to represent the name of a file directory
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
624
        'directory'      : _("directory"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
625
626
        # TRANSL: Used in usage help to represent the name of a file. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
627
        # --log-file <filename>
628
        'filename'       : _("filename"),
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
629
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
630
        # TRANSL: Used in usage help to represent an ID for a GnuPG key. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
631
        # --encrypt-key <gpg_key_id>
632
        'gpg_key_id'     : _("gpg-key-id"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
633
634
        # TRANSL: Used in usage help, e.g. to represent the name of a code
635
        # module. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
636
        # rsync://user[:password]@other.host[:port]::/module/some_dir
637
        'module'         : _("module"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
638
639
        # TRANSL: Used in usage help to represent a desired number of
640
        # something. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
641
        # --num-retries <number>
642
        'number'         : _("number"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
643
644
        # TRANSL: Used in usage help. (Should be consistent with the "Options:"
645
        # header.) Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
646
        # duplicity [full|incremental] [options] source_dir target_url
647
        'options'        : _("options"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
648
649
        # TRANSL: Used in usage help to represent an internet hostname. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
650
        # ftp://user[:password]@other.host[:port]/some_dir
651
        'other_host'     : _("other.host"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
652
653
        # TRANSL: Used in usage help. Example:
654
        # ftp://user[:password]@other.host[:port]/some_dir
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
655
        'password'       : _("password"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
656
657
        # TRANSL: Used in usage help to represent a Unix-style path name. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
658
        # --archive-dir <path>
659
        'path'           : _("path"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
660
661
        # TRANSL: Used in usage help to represent a TCP port number. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
662
        # ftp://user[:password]@other.host[:port]/some_dir
663
        'port'           : _("port"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
664
665
        # TRANSL: Used in usage help. This represents a string to be used as a
666
        # prefix to names for backup files created by Duplicity. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
667
        # s3://other.host/bucket_name[/prefix]
668
        'prefix'         : _("prefix"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
669
670
        # TRANSL: Used in usage help to represent a Unix-style path name. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
671
        # rsync://user[:password]@other.host[:port]/relative_path
672
        'relative_path'  : _("relative_path"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
673
674
        # TRANSL: Used in usage help. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
675
        # --timeout <seconds>
676
        'seconds'        : _("seconds"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
677
678
        # TRANSL: Used in usage help to represent a "glob" style pattern for
679
        # matching one or more files, as described in the documentation.
680
        # Example:
681
        # --exclude <shell_pattern>
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
682
        'shell_pattern'  : _("shell_pattern"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
683
684
        # TRANSL: Used in usage help to represent the name of a single file
685
        # directory or a Unix-style path to a directory. Example:
686
        # file:///some_dir
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
687
        'some_dir'       : _("some_dir"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
688
689
        # TRANSL: Used in usage help to represent the name of a single file
690
        # directory or a Unix-style path to a directory where files will be
691
        # coming FROM. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
692
        # duplicity [full|incremental] [options] source_dir target_url
693
        'source_dir'     : _("source_dir"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
694
695
        # TRANSL: Used in usage help to represent a URL files will be coming
696
        # FROM. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
697
        # duplicity [restore] [options] source_url target_dir
698
        'source_url'     : _("source_url"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
699
700
        # TRANSL: Used in usage help to represent the name of a single file
701
        # directory or a Unix-style path to a directory. where files will be
702
        # going TO. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
703
        # duplicity [restore] [options] source_url target_dir
704
        'target_dir'     : _("target_dir"),
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
705
706
        # TRANSL: Used in usage help to represent a URL files will be going TO.
707
        # Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
708
        # duplicity [full|incremental] [options] source_dir target_url
709
        'target_url'     : _("target_url"),
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
710
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
711
        # TRANSL: Used in usage help to represent a time spec for a previous
712
        # point in time, as described in the documentation. Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
713
        # duplicity remove-older-than time [options] target_url
714
        'time'           : _("time"),
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
715
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
716
        # TRANSL: Used in usage help to represent a user name (i.e. login).
717
        # Example:
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
718
        # ftp://user[:password]@other.host[:port]/some_dir
719
        'user'           : _("user") }
567.1.3 by Larry Gilbert
Broke up the usage() help info to simplify translation maintenance.
720
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
721
    # TRANSL: Header in usage help
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
722
    msg = """
723
  duplicity [full|incremental] [%(options)s] %(source_dir)s %(target_url)s
724
  duplicity [restore] [%(options)s] %(source_url)s %(target_dir)s
725
  duplicity verify [%(options)s] %(source_url)s %(target_dir)s
726
  duplicity collection-status [%(options)s] %(target_url)s
727
  duplicity list-current-files [%(options)s] %(target_url)s
728
  duplicity cleanup [%(options)s] %(target_url)s
729
  duplicity remove-older-than %(time)s [%(options)s] %(target_url)s
730
  duplicity remove-all-but-n-full %(count)s [%(options)s] %(target_url)s
651.1.2 by olivier
Adding new remove-all-inc-of-but-n-full command as a variant of remove-all-but-n-full
731
  duplicity remove-all-inc-of-but-n-full %(count)s [%(options)s] %(target_url)s
567.1.3 by Larry Gilbert
Broke up the usage() help info to simplify translation maintenance.
732
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
733
""" % dict
567.1.3 by Larry Gilbert
Broke up the usage() help info to simplify translation maintenance.
734
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
735
    # TRANSL: Header in usage help
567.1.3 by Larry Gilbert
Broke up the usage() help info to simplify translation maintenance.
736
    msg = msg + _("Backends and their URL formats:") + """
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
737
  cf+http://%(container_name)s
738
  file:///%(some_dir)s
739
  ftp://%(user)s[:%(password)s]@%(other_host)s[:%(port)s]/%(some_dir)s
697 by Kenneth Loafman
626915 ftps support using lftp (ftpsbackend)
740
  ftps://%(user)s[:%(password)s]@%(other_host)s[:%(port)s]/%(some_dir)s
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
741
  hsi://%(user)s[:%(password)s]@%(other_host)s[:%(port)s]/%(some_dir)s
742
  imap://%(user)s[:%(password)s]@%(other_host)s[:%(port)s]/%(some_dir)s
743
  rsync://%(user)s[:%(password)s]@%(other_host)s[:%(port)s]::/%(module)s/%(some_dir)s
744
  rsync://%(user)s[:%(password)s]@%(other_host)s[:%(port)s]/%(relative_path)s
745
  rsync://%(user)s[:%(password)s]@%(other_host)s[:%(port)s]//%(absolute_path)s
746
  s3://%(other_host)s/%(bucket_name)s[/%(prefix)s]
747
  s3+http://%(bucket_name)s[/%(prefix)s]
748
  scp://%(user)s[:%(password)s]@%(other_host)s[:%(port)s]/%(some_dir)s
749
  ssh://%(user)s[:%(password)s]@%(other_host)s[:%(port)s]/%(some_dir)s
750
  tahoe://%(alias)s/%(directory)s
751
  webdav://%(user)s[:%(password)s]@%(other_host)s/%(some_dir)s
752
  webdavs://%(user)s[:%(password)s]@%(other_host)s/%(some_dir)s
567.1.3 by Larry Gilbert
Broke up the usage() help info to simplify translation maintenance.
753
567.1.4 by Larry Gilbert
Redid dictionary in usage to use a local hash instead of a bunch of local
754
""" % dict
567.1.3 by Larry Gilbert
Broke up the usage() help info to simplify translation maintenance.
755
598.1.1 by Larry Gilbert
When generating PO[T] files, only use code comments starting with "TRANSL:"
756
    # TRANSL: Header in usage help
567.1.3 by Larry Gilbert
Broke up the usage() help info to simplify translation maintenance.
757
    msg = msg + _("Commands:") + """
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
758
  cleanup <%(target_url)s>
759
  collection-status <%(target_url)s>
760
  full <%(source_dir)s> <%(target_url)s>
761
  incr <%(source_dir)s> <%(target_url)s>
762
  list-current-files <%(target_url)s>
763
  restore <%(target_url)s> <%(source_dir)s>
764
  remove-older-than <%(time)s> <%(target_url)s>
765
  remove-all-but-n-full <%(count)s> <%(target_url)s>
651.1.2 by olivier
Adding new remove-all-inc-of-but-n-full command as a variant of remove-all-but-n-full
766
  remove-all-inc-of-but-n-full <%(count)s> <%(target_url)s>
618.1.1 by Michael Terry
first pass at getopt->optparse conversion
767
  verify <%(target_url)s> <%(source_dir)s>""" % dict
768
769
    return msg
770
1 by bescoto
Initial checkin
771
772
def set_archive_dir(dirstring):
304 by loafman
Untabify all files. To compare against previous
773
    """Check archive dir and set global"""
521 by loafman
After merge of Checkpoint/Restart.
774
    if not os.path.exists(dirstring):
775
        try:
776
            os.makedirs(dirstring)
747.1.1 by Michael Terry
always catch Exceptions, not BaseExceptions
777
        except Exception:
521 by loafman
After merge of Checkpoint/Restart.
778
            pass
779
    archive_dir = path.Path(dirstring)
304 by loafman
Untabify all files. To compare against previous
780
    if not archive_dir.isdir():
355 by loafman
patch #6700: Make duplicity translatable
781
        log.FatalError(_("Specified archive directory '%s' does not exist, "
782
                         "or is not a directory") % (archive_dir.name,),
339 by loafman
patch #6686: Add error codes for all fatal errors
783
                       log.ErrorCode.bad_archive_dir)
304 by loafman
Untabify all files. To compare against previous
784
    globals.archive_dir = archive_dir
1 by bescoto
Initial checkin
785
521 by loafman
After merge of Checkpoint/Restart.
786
1 by bescoto
Initial checkin
787
def set_sign_key(sign_key):
304 by loafman
Untabify all files. To compare against previous
788
    """Set globals.sign_key assuming proper key given"""
789
    if not len(sign_key) == 8 or not re.search("^[0-9A-F]*$", sign_key):
355 by loafman
patch #6700: Make duplicity translatable
790
        log.FatalError(_("Sign key should be an 8 character hex string, like "
791
                         "'AA0E73D2'.\nReceived '%s' instead.") % (sign_key,),
339 by loafman
patch #6686: Add error codes for all fatal errors
792
                       log.ErrorCode.bad_sign_key)
304 by loafman
Untabify all files. To compare against previous
793
    globals.gpg_profile.sign_key = sign_key
1 by bescoto
Initial checkin
794
521 by loafman
After merge of Checkpoint/Restart.
795
1 by bescoto
Initial checkin
796
def set_selection():
304 by loafman
Untabify all files. To compare against previous
797
    """Return selection iter starting at filename with arguments applied"""
798
    global select_opts, select_files
799
    sel = selection.Select(globals.local_path)
800
    sel.ParseArgs(select_opts, select_files)
801
    globals.select = sel.set_iter()
1 by bescoto
Initial checkin
802
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
803
def args_to_path_backend(arg1, arg2):
804
    """
805
    Given exactly two arguments, arg1 and arg2, figure out which one
806
    is the backend URL and which one is a local path, and return
807
    (local, backend).
304 by loafman
Untabify all files. To compare against previous
808
    """
525.1.6 by Peter Schuller
* figure out which arg is a backend url without actually instantiating a backend
809
    arg1_is_backend, arg2_is_backend = backend.is_backend_url(arg1), backend.is_backend_url(arg2)
810
811
    if not arg1_is_backend and not arg2_is_backend:
339 by loafman
patch #6686: Add error codes for all fatal errors
812
        command_line_error(
602.2.21 by ken
487686 re-add scp backend and make available via command line option
813
"""One of the arguments must be an URL.  Examples of URL strings are
1 by bescoto
Initial checkin
814
"scp://user@host.net:1234/path" and "file:///usr/local".  See the man
602.2.21 by ken
487686 re-add scp backend and make available via command line option
815
page for more information.""")
525.1.6 by Peter Schuller
* figure out which arg is a backend url without actually instantiating a backend
816
    if arg1_is_backend and arg2_is_backend:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
817
        command_line_error("Two URLs specified.  "
818
                           "One argument should be a path.")
525.1.6 by Peter Schuller
* figure out which arg is a backend url without actually instantiating a backend
819
    if arg1_is_backend:
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
820
        return (arg2, arg1)
525.1.6 by Peter Schuller
* figure out which arg is a backend url without actually instantiating a backend
821
    elif arg2_is_backend:
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
822
        return (arg1, arg2)
525.1.6 by Peter Schuller
* figure out which arg is a backend url without actually instantiating a backend
823
    else:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
824
        raise AssertionError('should not be reached')
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
825
826
def set_backend(arg1, arg2):
827
    """Figure out which arg is url, set backend
828
829
    Return value is pair (path_first, path) where is_first is true iff
830
    path made from arg1.
831
832
    """
833
    path, bend = args_to_path_backend(arg1, arg2)
834
835
    globals.backend = backend.get_backend(bend)
836
837
    if path == arg2:
838
        return (None, arg2) # False?
839
    else:
840
        return (1, arg1) # True?
1 by bescoto
Initial checkin
841
521 by loafman
After merge of Checkpoint/Restart.
842
1 by bescoto
Initial checkin
843
def process_local_dir(action, local_pathname):
304 by loafman
Untabify all files. To compare against previous
844
    """Check local directory, set globals.local_path"""
845
    local_path = path.Path(path.Path(local_pathname).get_canonical())
846
    if action == "restore":
847
        if (local_path.exists() and not local_path.isemptydir()) and not globals.force:
355 by loafman
patch #6700: Make duplicity translatable
848
            log.FatalError(_("Restore destination directory %s already "
849
                             "exists.\nWill not overwrite.") % (local_pathname,),
339 by loafman
patch #6686: Add error codes for all fatal errors
850
                           log.ErrorCode.restore_dir_exists)
304 by loafman
Untabify all files. To compare against previous
851
    elif action == "verify":
852
        if not local_path.exists():
355 by loafman
patch #6700: Make duplicity translatable
853
            log.FatalError(_("Verify directory %s does not exist") %
339 by loafman
patch #6686: Add error codes for all fatal errors
854
                           (local_path.name,),
855
                           log.ErrorCode.verify_dir_doesnt_exist)
304 by loafman
Untabify all files. To compare against previous
856
    else:
857
        assert action == "full" or action == "inc"
858
        if not local_path.exists():
355 by loafman
patch #6700: Make duplicity translatable
859
            log.FatalError(_("Backup source directory %s does not exist.")
339 by loafman
patch #6686: Add error codes for all fatal errors
860
                           % (local_path.name,),
861
                           log.ErrorCode.backup_dir_doesnt_exist)
430 by loafman
bug #19988: Incompatibility to Samba/SMB share
862
304 by loafman
Untabify all files. To compare against previous
863
    globals.local_path = local_path
1 by bescoto
Initial checkin
864
521 by loafman
After merge of Checkpoint/Restart.
865
1 by bescoto
Initial checkin
866
def check_consistency(action):
304 by loafman
Untabify all files. To compare against previous
867
    """Final consistency check, see if something wrong with command line"""
868
    global full_backup, select_opts, list_current
869
    def assert_only_one(arglist):
870
        """Raises error if two or more of the elements of arglist are true"""
871
        n = 0
872
        for m in arglist:
437 by loafman
One statement per line.
873
            if m:
874
                n+=1
304 by loafman
Untabify all files. To compare against previous
875
        assert n <= 1, "Invalid syntax, two conflicting modes specified"
876
    if action in ["list-current", "collection-status",
651.1.2 by olivier
Adding new remove-all-inc-of-but-n-full command as a variant of remove-all-but-n-full
877
                  "cleanup", "remove-old", "remove-all-but-n-full", "remove-all-inc-of-but-n-full"]:
304 by loafman
Untabify all files. To compare against previous
878
        assert_only_one([list_current, collection_status, cleanup,
879
                         globals.remove_time is not None])
880
    elif action == "restore" or action == "verify":
881
        if full_backup:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
882
            command_line_error("--full option cannot be used when "
883
                               "restoring or verifying")
304 by loafman
Untabify all files. To compare against previous
884
        elif globals.incremental:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
885
            command_line_error("--incremental option cannot be used when "
886
                               "restoring or verifying")
304 by loafman
Untabify all files. To compare against previous
887
        if select_opts and action == "restore":
722.1.1 by ed
as restoring is non-destructive by default (overideable with --force) there is no need to raie fata errors if not supported in/exclude parameters are given as parameters.
888
            log.Warn( _("Command line warning: %s") % _("Selection options --exclude/--include\n"
889
                                                        "currently work only when backing up,"
890
                                                        "not restoring.") )
304 by loafman
Untabify all files. To compare against previous
891
    else:
892
        assert action == "inc" or action == "full"
437 by loafman
One statement per line.
893
        if verify:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
894
            command_line_error("--verify option cannot be used "
895
                                      "when backing up")
304 by loafman
Untabify all files. To compare against previous
896
        if globals.restore_dir:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
897
            command_line_error("restore option incompatible with %s backup"
898
                               % (action,))
899
521 by loafman
After merge of Checkpoint/Restart.
900
1 by bescoto
Initial checkin
901
def ProcessCommandLine(cmdline_list):
304 by loafman
Untabify all files. To compare against previous
902
    """Process command line, set globals, return action
903
904
    action will be "list-current", "collection-status", "cleanup",
905
    "remove-old", "restore", "verify", "full", or "inc".
906
907
    """
908
    globals.gpg_profile = gpg.GPGProfile()
909
910
    args = parse_cmdline_options(cmdline_list)
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
911
563 by Kenneth Loafman
* First pass at bug 394757 - Optional Backends
912
    # we can now try to import all the backends
631 by ken
Fix real errors found by PyLint. Remove unneeded includes. Tag spurious errors so they don't annoy.
913
    backend.import_backends()
563 by Kenneth Loafman
* First pass at bug 394757 - Optional Backends
914
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
915
    # parse_cmdline_options already verified that we got exactly 1 or 2
916
    # non-options arguments
602.2.21 by ken
487686 re-add scp backend and make available via command line option
917
    assert len(args) >= 1 and len(args) <= 2, "arg count should have been checked already"
525.1.5 by Peter Schuller
* make default value to --name be the has of the backend URL specifically, rather than
918
919
    if len(args) == 1:
437 by loafman
One statement per line.
920
        if list_current:
921
            action = "list-current"
922
        elif collection_status:
923
            action = "collection-status"
924
        elif cleanup:
925
            action = "cleanup"
926
        elif globals.remove_time is not None:
927
            action = "remove-old"
651.1.6 by olivier
Fix remove-older-than which would no longer work
928
        elif globals.remove_all_but_n_full_mode:
437 by loafman
One statement per line.
929
            action = "remove-all-but-n-full"
651.1.6 by olivier
Fix remove-older-than which would no longer work
930
        elif globals.remove_all_inc_of_but_n_full_mode:
651.1.2 by olivier
Adding new remove-all-inc-of-but-n-full command as a variant of remove-all-but-n-full
931
            action = "remove-all-inc-of-but-n-full"
437 by loafman
One statement per line.
932
        else:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
933
            command_line_error("Too few arguments")
304 by loafman
Untabify all files. To compare against previous
934
        globals.backend = backend.get_backend(args[0])
437 by loafman
One statement per line.
935
        if not globals.backend:
936
            log.FatalError(_("""Bad URL '%s'.
11 by bescoto
Added --list-current-files option
937
Examples of URL strings are "scp://user@host.net:1234/path" and
355 by loafman
patch #6700: Make duplicity translatable
938
"file:///usr/local".  See the man page for more information.""") % (args[0],),
339 by loafman
patch #6686: Add error codes for all fatal errors
939
                                               log.ErrorCode.bad_url)
437 by loafman
One statement per line.
940
    elif len(args) == 2:
941
        # Figure out whether backup or restore
304 by loafman
Untabify all files. To compare against previous
942
        backup, local_pathname = set_backend(args[0], args[1])
943
        if backup:
437 by loafman
One statement per line.
944
            if full_backup:
945
                action = "full"
946
            else:
947
                action = "inc"
304 by loafman
Untabify all files. To compare against previous
948
        else:
437 by loafman
One statement per line.
949
            if verify:
950
                action = "verify"
951
            else:
952
                action = "restore"
304 by loafman
Untabify all files. To compare against previous
953
954
        process_local_dir(action, local_pathname)
437 by loafman
One statement per line.
955
        if action in ['full', 'inc', 'verify']:
956
            set_selection()
957
    elif len(args) > 2:
602.2.21 by ken
487686 re-add scp backend and make available via command line option
958
        raise AssertionError("this code should not be reachable")
304 by loafman
Untabify all files. To compare against previous
959
960
    check_consistency(action)
470 by loafman
Changed from log.Log with numbered log levels to log.Debug,
961
    log.Info(_("Main action: ") + action)
304 by loafman
Untabify all files. To compare against previous
962
    return action