feat: tag repos

This commit is contained in:
Divyansh Singh 2023-03-23 01:01:26 +05:30
parent f9ef52f9a5
commit 8a63c49498
5 changed files with 69 additions and 35 deletions

View File

@ -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,

View File

@ -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(

View File

@ -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

View File

@ -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: |

View File

@ -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)
)
)