mirror of https://github.com/digint/btrbk
btrbk_restore_raw.py: add dry-run mode
parent
7e80e0cbba
commit
025a7709e3
|
@ -11,6 +11,9 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
class TransformProcess:
|
||||
def run(self, bfile, options, **kw):
|
||||
return subprocess.Popen(self.get_cmd(bfile, options), **kw)
|
||||
|
||||
def get_cmd(self, bfile, options):
|
||||
raise NotImplementedError()
|
||||
|
||||
@classmethod
|
||||
|
@ -20,13 +23,14 @@ class TransformProcess:
|
|||
|
||||
class TransformOpensslDecrypt(TransformProcess):
|
||||
@staticmethod
|
||||
def run(bfile, options, **kw):
|
||||
return subprocess.Popen([
|
||||
def get_cmd(bfile, options):
|
||||
return [
|
||||
'openssl', 'enc', '-d', '-' + bfile.info['cipher'], '-K',
|
||||
open(options.openssl_keyfile, 'r').read(), '-iv', bfile.info['iv']], **kw)
|
||||
open(options.openssl_keyfile, 'r').read(), '-iv', bfile.info['iv']
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def add_parser_options(cls, parser):
|
||||
@staticmethod
|
||||
def add_parser_options(parser):
|
||||
parser.add_argument('--openssl-keyfile', help="path to private encryption key file")
|
||||
|
||||
|
||||
|
@ -34,14 +38,18 @@ class TransformDecompress(TransformProcess):
|
|||
def __init__(self, program):
|
||||
self.p = program
|
||||
|
||||
def run(self, bfile, options, **kw):
|
||||
return subprocess.Popen([self.p, '-d'], **kw)
|
||||
def get_cmd(self, bfile, options):
|
||||
return [self.p, '-d']
|
||||
|
||||
|
||||
class TransformBtrfsReceive(TransformProcess):
|
||||
@classmethod
|
||||
def run(cls, bfile, options, **kw):
|
||||
return subprocess.Popen(cls.get_cmd(bfile, options), **kw)
|
||||
|
||||
@staticmethod
|
||||
def run(bfile, options, **kw):
|
||||
return subprocess.Popen(['btrfs', 'receive', options.restore_dir], **kw)
|
||||
def get_cmd(bfile, options):
|
||||
return ['btrfs', 'receive', options.restore_dir]
|
||||
|
||||
|
||||
TRANSFORMERS = (
|
||||
|
@ -96,6 +104,13 @@ class BtrfsPipeline:
|
|||
if msg:
|
||||
logger.error(f"error running {p.args}: {msg}")
|
||||
|
||||
def get_cmd(self, options):
|
||||
command_pipe = [['cat', self.bfile.data_file]]
|
||||
for transformer in self.processors:
|
||||
command_pipe.append(transformer.get_cmd(self.bfile, options))
|
||||
command_pipe.append(TransformBtrfsReceive.get_cmd(self.bfile, options))
|
||||
return ' | '.join(' '.join(x) for x in command_pipe)
|
||||
|
||||
|
||||
class BackupFile:
|
||||
def __init__(self, path):
|
||||
|
@ -132,11 +147,14 @@ class BackupFile:
|
|||
def restore_file(self, options):
|
||||
assert self.info.get('TYPE') == 'raw'
|
||||
assert not self.info.get('INCOMPLETE')
|
||||
logger.info(f"restoring backup {os.path.basename(self.data_file)}")
|
||||
pipeline = BtrfsPipeline(self)
|
||||
for transformer in self.get_transformers():
|
||||
pipeline.append(transformer)
|
||||
pipeline.run(options)
|
||||
if options.dry_run:
|
||||
print(pipeline.get_cmd(options))
|
||||
else:
|
||||
logger.info(f"restoring backup {os.path.basename(self.data_file)}")
|
||||
pipeline.run(options)
|
||||
self.is_restored = True
|
||||
|
||||
|
||||
|
@ -175,13 +193,21 @@ def main():
|
|||
parser = argparse.ArgumentParser(description="restore btrbk raw backup")
|
||||
parser.add_argument('backup', help="backup file to restore; for incremental"
|
||||
" backups the parent files must be in the same directory")
|
||||
parser.add_argument('restore_dir', help="target directory for restored subvolumes (path argument for \"btrfs receive\")")
|
||||
parser.add_argument('--ignore-missing', action='store_true', help="do not fail on missing parent snapshots")
|
||||
parser.add_argument('restore_dir', help="target directory for restored subvolumes"
|
||||
" (path argument for \"btrfs receive\")")
|
||||
parser.add_argument('--ignore-missing', action='store_true',
|
||||
help="do not fail on missing parent snapshots")
|
||||
parser.add_argument('--dry-run', '-n', action='store_true',
|
||||
help="print commmands that would be exectuted")
|
||||
|
||||
for transformer in TRANSFORMERS:
|
||||
transformer.add_parser_options(parser)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.dry_run:
|
||||
logger.setLevel('ERROR')
|
||||
|
||||
restore_from_path(args.backup, args)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue