feat: tag repos
This commit is contained in:
parent
f9ef52f9a5
commit
8a63c49498
5 changed files with 69 additions and 35 deletions
|
@ -42,11 +42,11 @@ def run_create(
|
|||
global_arguments.dry_run,
|
||||
**hook_context,
|
||||
)
|
||||
logger.info('{}: Creating archive{}'.format(repository, dry_run_label))
|
||||
logger.info('{}: Creating archive{}'.format(repository['path'], dry_run_label))
|
||||
borgmatic.hooks.dispatch.call_hooks_even_if_unconfigured(
|
||||
'remove_database_dumps',
|
||||
hooks,
|
||||
repository,
|
||||
repository['path'],
|
||||
borgmatic.hooks.dump.DATABASE_HOOK_NAMES,
|
||||
location,
|
||||
global_arguments.dry_run,
|
||||
|
@ -54,7 +54,7 @@ def run_create(
|
|||
active_dumps = borgmatic.hooks.dispatch.call_hooks(
|
||||
'dump_databases',
|
||||
hooks,
|
||||
repository,
|
||||
repository['path'],
|
||||
borgmatic.hooks.dump.DATABASE_HOOK_NAMES,
|
||||
location,
|
||||
global_arguments.dry_run,
|
||||
|
@ -63,7 +63,7 @@ def run_create(
|
|||
|
||||
json_output = borgmatic.borg.create.create_archive(
|
||||
global_arguments.dry_run,
|
||||
repository,
|
||||
repository['path'],
|
||||
location,
|
||||
storage,
|
||||
local_borg_version,
|
||||
|
|
|
@ -108,7 +108,7 @@ def run_configuration(config_filename, config, arguments):
|
|||
repo_queue.put((repo, 0),)
|
||||
|
||||
while not repo_queue.empty():
|
||||
repository_path, retry_num = repo_queue.get()
|
||||
repository, retry_num = repo_queue.get()
|
||||
timeout = retry_num * retry_wait
|
||||
if timeout:
|
||||
logger.warning(f'{config_filename}: Sleeping {timeout}s before next retry')
|
||||
|
@ -125,14 +125,14 @@ def run_configuration(config_filename, config, arguments):
|
|||
local_path=local_path,
|
||||
remote_path=remote_path,
|
||||
local_borg_version=local_borg_version,
|
||||
repository_path=repository_path,
|
||||
repository=repository,
|
||||
)
|
||||
except (OSError, CalledProcessError, ValueError) as error:
|
||||
if retry_num < retries:
|
||||
repo_queue.put((repository_path, retry_num + 1),)
|
||||
repo_queue.put((repository, retry_num + 1),)
|
||||
tuple( # Consume the generator so as to trigger logging.
|
||||
log_error_records(
|
||||
'{}: Error running actions for repository'.format(repository_path),
|
||||
'{}: Error running actions for repository'.format(repository['path']),
|
||||
error,
|
||||
levelno=logging.WARNING,
|
||||
log_command_error_output=True,
|
||||
|
@ -147,10 +147,10 @@ def run_configuration(config_filename, config, arguments):
|
|||
return
|
||||
|
||||
yield from log_error_records(
|
||||
'{}: Error running actions for repository'.format(repository_path), error
|
||||
'{}: Error running actions for repository'.format(repository['path']), error
|
||||
)
|
||||
encountered_error = error
|
||||
error_repository = repository_path
|
||||
error_repository = repository['path']
|
||||
|
||||
try:
|
||||
if using_primary_action:
|
||||
|
@ -248,7 +248,7 @@ def run_actions(
|
|||
local_path,
|
||||
remote_path,
|
||||
local_borg_version,
|
||||
repository_path,
|
||||
repository,
|
||||
):
|
||||
'''
|
||||
Given parsed command-line arguments as an argparse.ArgumentParser instance, the configuration
|
||||
|
@ -263,13 +263,13 @@ def run_actions(
|
|||
invalid.
|
||||
'''
|
||||
add_custom_log_levels()
|
||||
repository = os.path.expanduser(repository_path)
|
||||
repository_path = os.path.expanduser(repository['path'])
|
||||
global_arguments = arguments['global']
|
||||
dry_run_label = ' (dry run; not making any changes)' if global_arguments.dry_run else ''
|
||||
hook_context = {
|
||||
'repository': repository_path,
|
||||
# Deprecated: For backwards compatibility with borgmatic < 1.6.0.
|
||||
'repositories': ','.join(location['repositories']),
|
||||
'repositories': ','.join([repo['path'] for repo in location['repositories']]),
|
||||
}
|
||||
|
||||
command.execute_hook(
|
||||
|
|
|
@ -56,9 +56,13 @@ def normalize(config_filename, config):
|
|||
|
||||
# Upgrade remote repositories to ssh:// syntax, required in Borg 2.
|
||||
repositories = location.get('repositories')
|
||||
if isinstance(repositories[0], str):
|
||||
config['location']['repositories'] = [{'path': repository} for repository in repositories]
|
||||
repositories = config['location']['repositories']
|
||||
if repositories:
|
||||
config['location']['repositories'] = []
|
||||
for repository in repositories:
|
||||
for repository_dict in repositories:
|
||||
repository = repository_dict['path']
|
||||
if '~' in repository:
|
||||
logs.append(
|
||||
logging.makeLogRecord(
|
||||
|
@ -71,11 +75,19 @@ def normalize(config_filename, config):
|
|||
)
|
||||
if ':' in repository:
|
||||
if repository.startswith('file://'):
|
||||
updated_repository_path = os.path.abspath(repository.partition('file://')[-1])
|
||||
|
||||
config['location']['repositories'].append(
|
||||
os.path.abspath(repository.partition('file://')[-1])
|
||||
{
|
||||
'path': updated_repository_path,
|
||||
'label': repository_dict.get('label', None),
|
||||
}
|
||||
)
|
||||
elif repository.startswith('ssh://'):
|
||||
config['location']['repositories'].append(repository)
|
||||
config['location']['repositories'].append({
|
||||
'path': repository,
|
||||
'label': repository_dict.get('label', None),
|
||||
})
|
||||
else:
|
||||
rewritten_repository = f"ssh://{repository.replace(':~', '/~').replace(':/', '/').replace(':', '/./')}"
|
||||
logs.append(
|
||||
|
@ -87,8 +99,16 @@ def normalize(config_filename, config):
|
|||
)
|
||||
)
|
||||
)
|
||||
config['location']['repositories'].append(rewritten_repository)
|
||||
config['location']['repositories'].append({
|
||||
'path': rewritten_repository,
|
||||
'label': repository_dict.get('label', None),
|
||||
})
|
||||
else:
|
||||
config['location']['repositories'].append(repository)
|
||||
config['location']['repositories'].append(
|
||||
{
|
||||
'path': repository,
|
||||
'label': repository_dict.get('label', None),
|
||||
}
|
||||
)
|
||||
|
||||
return logs
|
||||
|
|
|
@ -29,19 +29,30 @@ properties:
|
|||
repositories:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: |
|
||||
Paths to local or remote repositories (required). Tildes are
|
||||
expanded. Multiple repositories are backed up to in
|
||||
sequence. Borg placeholders can be used. See the output of
|
||||
"borg help placeholders" for details. See ssh_command for
|
||||
SSH options like identity file or port. If systemd service
|
||||
is used, then add local repository paths in the systemd
|
||||
service file to the ReadWritePaths list.
|
||||
example:
|
||||
- ssh://user@backupserver/./sourcehostname.borg
|
||||
- ssh://user@backupserver/./{fqdn}
|
||||
- /var/local/backups/local.borg
|
||||
type: object
|
||||
required:
|
||||
- path
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
description: |
|
||||
Path to local or remote repository (required).
|
||||
are expanded. Multiple repositories are backed up to
|
||||
in sequence. Borg placeholders can be used. See the
|
||||
output of "borg help placeholders" for details. See
|
||||
ssh_command for SSH options like identity file or
|
||||
port. If systemd service is used, then add local
|
||||
repository paths in the systemd service file to the
|
||||
ReadWritePaths list.
|
||||
example:
|
||||
- ssh://user@backupserver/./sourcehostname.borg
|
||||
- ssh://user@backupserver/./{fqdn}
|
||||
- /var/local/backups/local.borg
|
||||
label:
|
||||
type: string
|
||||
description: |
|
||||
Optional label for the repository.
|
||||
example: backupserver
|
||||
working_directory:
|
||||
type: string
|
||||
description: |
|
||||
|
|
|
@ -138,10 +138,13 @@ def normalize_repository_path(repository):
|
|||
|
||||
def repositories_match(first, second):
|
||||
'''
|
||||
Given two repository paths (relative and/or absolute), return whether they match.
|
||||
Given two repository dicts with keys 'path' (relative and/or absolute),
|
||||
and 'label', return whether they match.
|
||||
'''
|
||||
return normalize_repository_path(first) == normalize_repository_path(second)
|
||||
|
||||
if isinstance(first,str) and isinstance(second,str):
|
||||
return normalize_repository_path(first) == normalize_repository_path(second)
|
||||
elif isinstance(first,dict) and isinstance(second,str):
|
||||
return (second == first.get('label')) or (normalize_repository_path(second) == normalize_repository_path(first.get('path')))
|
||||
|
||||
def guard_configuration_contains_repository(repository, configurations):
|
||||
'''
|
||||
|
@ -160,7 +163,7 @@ def guard_configuration_contains_repository(repository, configurations):
|
|||
config_repository
|
||||
for config in configurations.values()
|
||||
for config_repository in config['location']['repositories']
|
||||
if repositories_match(repository, config_repository)
|
||||
if repositories_match(config_repository, repository)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue