borgmatic/borgmatic/borg/create.py

97 lines
3.3 KiB
Python
Raw Normal View History

from datetime import datetime
import glob
import itertools
import os
import platform
import subprocess
import tempfile
from borgmatic.verbosity import VERBOSITY_SOME, VERBOSITY_LOTS
def initialize(storage_config):
passphrase = storage_config.get('encryption_passphrase')
if passphrase:
os.environ['BORG_PASSPHRASE'] = passphrase
def _write_exclude_file(exclude_patterns=None):
'''
Given a sequence of exclude patterns, write them to a named temporary file and return it. Return
None if no patterns are provided.
'''
if not exclude_patterns:
return None
exclude_file = tempfile.NamedTemporaryFile('w')
exclude_file.write('\n'.join(exclude_patterns))
exclude_file.flush()
return exclude_file
def _make_exclude_flags(location_config, exclude_patterns_filename=None):
'''
Given a location config dict with various exclude options, and a filename containing any exclude
patterns, return the corresponding Borg flags as a tuple.
'''
exclude_filenames = tuple(location_config.get('exclude_from', ())) + (
(exclude_patterns_filename,) if exclude_patterns_filename else ()
)
exclude_from_flags = tuple(
itertools.chain.from_iterable(
('--exclude-from', exclude_filename)
for exclude_filename in exclude_filenames
)
)
caches_flag = ('--exclude-caches',) if location_config.get('exclude_caches') else ()
if_present = location_config.get('exclude_if_present')
if_present_flags = ('--exclude-if-present', if_present) if if_present else ()
return exclude_from_flags + caches_flag + if_present_flags
def create_archive(
verbosity, repository, location_config, storage_config,
):
'''
Given a vebosity flag, a local or remote repository path, a location config dict, and a storage
config dict, create a Borg archive.
'''
sources = tuple(
itertools.chain.from_iterable(
glob.glob(directory) or [directory]
for directory in location_config['source_directories']
)
)
exclude_patterns_file = _write_exclude_file(location_config.get('exclude_patterns'))
exclude_flags = _make_exclude_flags(
location_config,
exclude_patterns_file.name if exclude_patterns_file else None,
)
compression = storage_config.get('compression', None)
compression_flags = ('--compression', compression) if compression else ()
umask = storage_config.get('umask', None)
umask_flags = ('--umask', str(umask)) if umask else ()
one_file_system_flags = ('--one-file-system',) if location_config.get('one_file_system') else ()
remote_path = location_config.get('remote_path')
remote_path_flags = ('--remote-path', remote_path) if remote_path else ()
verbosity_flags = {
VERBOSITY_SOME: ('--info', '--stats',),
VERBOSITY_LOTS: ('--debug', '--list', '--stats'),
}.get(verbosity, ())
full_command = (
'borg', 'create',
'{repository}::{hostname}-{timestamp}'.format(
repository=repository,
hostname=platform.node(),
timestamp=datetime.now().isoformat(),
),
) + sources + exclude_flags + compression_flags + one_file_system_flags + \
remote_path_flags + umask_flags + verbosity_flags
subprocess.check_call(full_command)