From c398076f064c49a06f859d8c53622f431b6c6f29 Mon Sep 17 00:00:00 2001 From: Rob Browning Date: Fri, 12 Feb 2021 14:34:04 -0600 Subject: [PATCH] import-duplicity: convert to internal command Signed-off-by: Rob Browning --- lib/bup/cmd/import_duplicity.py | 145 ++++++++++++++------------------ lib/cmd/bup | 1 + 2 files changed, 65 insertions(+), 81 deletions(-) diff --git a/lib/bup/cmd/import_duplicity.py b/lib/bup/cmd/import_duplicity.py index 43b2dee..b2b011a 100755 --- a/lib/bup/cmd/import_duplicity.py +++ b/lib/bup/cmd/import_duplicity.py @@ -1,32 +1,12 @@ -#!/bin/sh -"""": # -*-python-*- -# https://sourceware.org/bugzilla/show_bug.cgi?id=26034 -export "BUP_ARGV_0"="$0" -arg_i=1 -for arg in "$@"; do - export "BUP_ARGV_${arg_i}"="$arg" - shift - arg_i=$((arg_i + 1)) -done -# Here to end of preamble replaced during install -bup_python="$(dirname "$0")/../../../config/bin/python" || exit $? -exec "$bup_python" "$0" -""" -# end of bup preamble from __future__ import absolute_import - -# Intentionally replace the dirname "$0" that python prepends -import os, sys -sys.path[0] = os.path.dirname(os.path.realpath(__file__)) + '/../..' - from calendar import timegm from pipes import quote from subprocess import check_call from time import strftime, strptime -import tempfile +import os, sys, tempfile -from bup import compat, git, helpers, options +from bup import git, helpers, options from bup.compat import argv_bytes, str_type from bup.helpers import (handle_ctrl_c, log, @@ -36,25 +16,26 @@ from bup.helpers import (handle_ctrl_c, unlink) import bup.path + optspec = """ bup import-duplicity [-n] -- n,dry-run don't do anything; just print what would be done """ +dry_run = False + def logcmd(cmd): log(shstr(cmd).decode(errors='backslashreplace') + '\n') def exc(cmd, shell=False): - global opt logcmd(cmd) - if not opt.dry_run: + if not dry_run: check_call(cmd, shell=shell) def exo(cmd, shell=False, preexec_fn=None, close_fds=True): - global opt logcmd(cmd) - if not opt.dry_run: + if not dry_run: return helpers.exo(cmd, shell=shell, preexec_fn=preexec_fn, close_fds=close_fds)[0] @@ -63,58 +44,60 @@ def redirect_dup_output(): os.dup2(1, 2) -handle_ctrl_c() - -log('\nbup: import-duplicity is EXPERIMENTAL (proceed with caution)\n\n') - -o = options.Options(optspec) -opt, flags, extra = o.parse(compat.argv[1:]) - -if len(extra) < 1 or not extra[0]: - o.fatal('duplicity source URL required') -if len(extra) < 2 or not extra[1]: - o.fatal('bup destination save name required') -if len(extra) > 2: - o.fatal('too many arguments') - -source_url, save_name = extra -source_url = argv_bytes(source_url) -save_name = argv_bytes(save_name) -bup = bup.path.exe() - -git.check_repo_or_die() - -tmpdir = tempfile.mkdtemp(prefix=b'bup-import-dup-') -try: - dup = [b'duplicity', b'--archive-dir', tmpdir + b'/dup-cache'] - restoredir = tmpdir + b'/restore' - tmpidx = tmpdir + b'/index' - - collection_status = \ - exo(dup + [b'collection-status', b'--log-fd=3', source_url], - close_fds=False, preexec_fn=redirect_dup_output) # i.e. 3>&1 1>&2 - # Duplicity output lines of interest look like this (one leading space): - # full 20150222T073111Z 1 noenc - # inc 20150222T073233Z 1 noenc - dup_timestamps = [] - for line in collection_status.splitlines(): - if line.startswith(b' inc '): - assert(len(line) >= len(b' inc 20150222T073233Z')) - dup_timestamps.append(line[5:21]) - elif line.startswith(b' full '): - assert(len(line) >= len(b' full 20150222T073233Z')) - dup_timestamps.append(line[6:22]) - for i, dup_ts in enumerate(dup_timestamps): - tm = strptime(dup_ts.decode('ascii'), '%Y%m%dT%H%M%SZ') - exc([b'rm', b'-rf', restoredir]) - exc(dup + [b'restore', b'-t', dup_ts, source_url, restoredir]) - exc([bup, b'index', b'-uxf', tmpidx, restoredir]) - exc([bup, b'save', b'--strip', b'--date', b'%d' % timegm(tm), - b'-f', tmpidx, b'-n', save_name, restoredir]) - sys.stderr.flush() -finally: - exc([b'rm', b'-rf', tmpdir]) - -if saved_errors: - log('warning: %d errors encountered\n' % len(saved_errors)) - sys.exit(1) +def main(argv): + global dry_run + + log('\nbup: import-duplicity is EXPERIMENTAL (proceed with caution)\n\n') + + o = options.Options(optspec) + opt, flags, extra = o.parse_bytes(argv[1:]) + dry_run = opt.dry_run + + if len(extra) < 1 or not extra[0]: + o.fatal('duplicity source URL required') + if len(extra) < 2 or not extra[1]: + o.fatal('bup destination save name required') + if len(extra) > 2: + o.fatal('too many arguments') + + source_url, save_name = extra + source_url = argv_bytes(source_url) + save_name = argv_bytes(save_name) + bup_path = bup.path.exe() + + git.check_repo_or_die() + + tmpdir = tempfile.mkdtemp(prefix=b'bup-import-dup-') + try: + dup = [b'duplicity', b'--archive-dir', tmpdir + b'/dup-cache'] + restoredir = tmpdir + b'/restore' + tmpidx = tmpdir + b'/index' + + collection_status = \ + exo(dup + [b'collection-status', b'--log-fd=3', source_url], + close_fds=False, preexec_fn=redirect_dup_output) # i.e. 3>&1 1>&2 + # Duplicity output lines of interest look like this (one leading space): + # full 20150222T073111Z 1 noenc + # inc 20150222T073233Z 1 noenc + dup_timestamps = [] + for line in collection_status.splitlines(): + if line.startswith(b' inc '): + assert(len(line) >= len(b' inc 20150222T073233Z')) + dup_timestamps.append(line[5:21]) + elif line.startswith(b' full '): + assert(len(line) >= len(b' full 20150222T073233Z')) + dup_timestamps.append(line[6:22]) + for i, dup_ts in enumerate(dup_timestamps): + tm = strptime(dup_ts.decode('ascii'), '%Y%m%dT%H%M%SZ') + exc([b'rm', b'-rf', restoredir]) + exc(dup + [b'restore', b'-t', dup_ts, source_url, restoredir]) + exc([bup_path, b'index', b'-uxf', tmpidx, restoredir]) + exc([bup_path, b'save', b'--strip', b'--date', b'%d' % timegm(tm), + b'-f', tmpidx, b'-n', save_name, restoredir]) + sys.stderr.flush() + finally: + exc([b'rm', b'-rf', tmpdir]) + + if saved_errors: + log('warning: %d errors encountered\n' % len(saved_errors)) + sys.exit(1) diff --git a/lib/cmd/bup b/lib/cmd/bup index caf5249..0fe3e19 100755 --- a/lib/cmd/bup +++ b/lib/cmd/bup @@ -194,6 +194,7 @@ try: b'ftp', b'gc', b'help', + b'import-duplicity', b'index', b'init', b'join', -- 2.39.2