mirror of https://github.com/borgbackup/borg.git
key import: allow reading from stdin
This commit is contained in:
parent
c9e71672bb
commit
29646d5b5e
|
@ -341,7 +341,7 @@ class Archiver:
|
||||||
if not args.path:
|
if not args.path:
|
||||||
self.print_error("input file to import key from expected")
|
self.print_error("input file to import key from expected")
|
||||||
return EXIT_ERROR
|
return EXIT_ERROR
|
||||||
if not os.path.exists(args.path):
|
if args.path != '-' and not os.path.exists(args.path):
|
||||||
self.print_error("input file does not exist: " + args.path)
|
self.print_error("input file does not exist: " + args.path)
|
||||||
return EXIT_ERROR
|
return EXIT_ERROR
|
||||||
manager.import_keyfile(args)
|
manager.import_keyfile(args)
|
||||||
|
@ -2695,7 +2695,7 @@ class Archiver:
|
||||||
subparser.add_argument('location', metavar='REPOSITORY', nargs='?', default='',
|
subparser.add_argument('location', metavar='REPOSITORY', nargs='?', default='',
|
||||||
type=location_validator(archive=False))
|
type=location_validator(archive=False))
|
||||||
subparser.add_argument('path', metavar='PATH', nargs='?', type=str,
|
subparser.add_argument('path', metavar='PATH', nargs='?', type=str,
|
||||||
help='path to the backup')
|
help='path to the backup (\'-\' to read from stdin)')
|
||||||
subparser.add_argument('--paper', dest='paper', action='store_true',
|
subparser.add_argument('--paper', dest='paper', action='store_true',
|
||||||
help='interactively import from a backup done with ``--paper``')
|
help='interactively import from a backup done with ``--paper``')
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import textwrap
|
||||||
from binascii import unhexlify, a2b_base64, b2a_base64
|
from binascii import unhexlify, a2b_base64, b2a_base64
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
|
|
||||||
from ..helpers import Manifest, NoManifestError, Error, yes, bin_to_hex
|
from ..helpers import Manifest, NoManifestError, Error, yes, bin_to_hex, open_file_or_stdin
|
||||||
from ..repository import Repository
|
from ..repository import Repository
|
||||||
|
|
||||||
from .key import KeyfileKey, KeyfileNotFoundError, KeyBlobStorage, identify_key
|
from .key import KeyfileKey, KeyfileNotFoundError, KeyBlobStorage, identify_key
|
||||||
|
@ -130,7 +130,7 @@ class KeyManager:
|
||||||
def import_keyfile(self, args):
|
def import_keyfile(self, args):
|
||||||
file_id = KeyfileKey.FILE_ID
|
file_id = KeyfileKey.FILE_ID
|
||||||
first_line = file_id + ' ' + bin_to_hex(self.repository.id) + '\n'
|
first_line = file_id + ' ' + bin_to_hex(self.repository.id) + '\n'
|
||||||
with open(args.path, 'r') as fd:
|
with open_file_or_stdin(args.path, 'r') as fd:
|
||||||
file_first_line = fd.read(len(first_line))
|
file_first_line = fd.read(len(first_line))
|
||||||
if file_first_line != first_line:
|
if file_first_line != first_line:
|
||||||
if not file_first_line.startswith(file_id):
|
if not file_first_line.startswith(file_id):
|
||||||
|
|
|
@ -2162,3 +2162,17 @@ def popen_with_error_handling(cmd_line: str, log_prefix='', **kwargs):
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
logger.error('%spermission denied: %s', log_prefix, command[0])
|
logger.error('%spermission denied: %s', log_prefix, command[0])
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def open_file_or_stdin(path, mode):
|
||||||
|
if path == '-':
|
||||||
|
if 'b' in mode:
|
||||||
|
return sys.stdin.buffer
|
||||||
|
else:
|
||||||
|
return sys.stdin
|
||||||
|
else:
|
||||||
|
return open(path, mode)
|
||||||
|
|
||||||
|
|
||||||
|
def is_terminal(fd=sys.stdout):
|
||||||
|
return hasattr(fd, 'isatty') and fd.isatty() and (sys.platform != 'win32' or 'ANSICON' in os.environ)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import io
|
import io
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from .helpers import is_terminal
|
||||||
|
|
||||||
|
|
||||||
class TextPecker:
|
class TextPecker:
|
||||||
def __init__(self, s):
|
def __init__(self, s):
|
||||||
|
@ -205,7 +206,7 @@ def rst_to_terminal(rst, references=None, destination=sys.stdout):
|
||||||
If *destination* is a file-like object connected to a terminal,
|
If *destination* is a file-like object connected to a terminal,
|
||||||
enrich text with suitable ANSI escapes. Otherwise return plain text.
|
enrich text with suitable ANSI escapes. Otherwise return plain text.
|
||||||
"""
|
"""
|
||||||
if hasattr(destination, 'isatty') and destination.isatty() and (sys.platform != 'win32' or 'ANSICON' in os.environ):
|
if is_terminal(destination):
|
||||||
rst_state_hook = ansi_escapes
|
rst_state_hook = ansi_escapes
|
||||||
else:
|
else:
|
||||||
rst_state_hook = None
|
rst_state_hook = None
|
||||||
|
|
|
@ -28,6 +28,7 @@ from ..helpers import swidth_slice
|
||||||
from ..helpers import chunkit
|
from ..helpers import chunkit
|
||||||
from ..helpers import safe_ns, safe_s, SUPPORT_32BIT_PLATFORMS
|
from ..helpers import safe_ns, safe_s, SUPPORT_32BIT_PLATFORMS
|
||||||
from ..helpers import popen_with_error_handling
|
from ..helpers import popen_with_error_handling
|
||||||
|
from ..helpers import open_file_or_stdin
|
||||||
|
|
||||||
from . import BaseTestCase, FakeInputs
|
from . import BaseTestCase, FakeInputs
|
||||||
|
|
||||||
|
@ -942,3 +943,8 @@ class TestPopenWithErrorHandling:
|
||||||
def test_shell(self):
|
def test_shell(self):
|
||||||
with pytest.raises(AssertionError):
|
with pytest.raises(AssertionError):
|
||||||
popen_with_error_handling('', shell=True)
|
popen_with_error_handling('', shell=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_open_file_or_stdin():
|
||||||
|
assert open_file_or_stdin('-', 'r') is sys.stdin
|
||||||
|
assert open_file_or_stdin('-', 'rb') is sys.stdin.buffer
|
||||||
|
|
Loading…
Reference in New Issue