95 lines
3.7 KiB
Python
95 lines
3.7 KiB
Python
import os
|
|
|
|
from ruamel import yaml
|
|
|
|
from borgmatic.config import generate
|
|
|
|
|
|
def _convert_section(source_section_config, section_schema):
|
|
'''
|
|
Given a legacy Parsed_config instance for a single section, convert it to its corresponding
|
|
yaml.comments.CommentedMap representation in preparation for actual serialization to YAML.
|
|
|
|
Where integer types exist in the given section schema, convert their values to integers.
|
|
'''
|
|
destination_section_config = yaml.comments.CommentedMap(
|
|
[
|
|
(
|
|
option_name,
|
|
int(option_value)
|
|
if section_schema['properties'].get(option_name, {}).get('type') == 'integer'
|
|
else option_value,
|
|
)
|
|
for option_name, option_value in source_section_config.items()
|
|
]
|
|
)
|
|
|
|
return destination_section_config
|
|
|
|
|
|
def convert_legacy_parsed_config(source_config, source_excludes, schema):
|
|
'''
|
|
Given a legacy Parsed_config instance loaded from an INI-style config file and a list of exclude
|
|
patterns, convert them to a corresponding yaml.comments.CommentedMap representation in
|
|
preparation for serialization to a single YAML config file.
|
|
|
|
Additionally, use the given schema as a source of helpful comments to include within the
|
|
returned CommentedMap.
|
|
'''
|
|
destination_config = yaml.comments.CommentedMap(
|
|
[
|
|
(section_name, _convert_section(section_config, schema['properties'][section_name]))
|
|
for section_name, section_config in source_config._asdict().items()
|
|
]
|
|
)
|
|
|
|
# Split space-seperated values into actual lists, make "repository" into a list, and merge in
|
|
# excludes.
|
|
location = destination_config['location']
|
|
location['source_directories'] = source_config.location['source_directories'].split(' ')
|
|
location['repositories'] = [location.pop('repository')]
|
|
location['exclude_patterns'] = source_excludes
|
|
|
|
if source_config.consistency.get('checks'):
|
|
destination_config['consistency']['checks'] = source_config.consistency['checks'].split(' ')
|
|
|
|
# Add comments to each section, and then add comments to the fields in each section.
|
|
generate.add_comments_to_configuration_object(destination_config, schema)
|
|
|
|
for section_name, section_config in destination_config.items():
|
|
generate.add_comments_to_configuration_object(
|
|
section_config, schema['properties'][section_name], indent=generate.INDENT
|
|
)
|
|
|
|
return destination_config
|
|
|
|
|
|
class Legacy_configuration_not_upgraded(FileNotFoundError):
|
|
def __init__(self):
|
|
super(Legacy_configuration_not_upgraded, self).__init__(
|
|
'''borgmatic changed its configuration file format in version 1.1.0 from INI-style
|
|
to YAML. This better supports validation, and has a more natural way to express
|
|
lists of values. To upgrade your existing configuration, run:
|
|
|
|
sudo upgrade-borgmatic-config
|
|
|
|
That will generate a new YAML configuration file at /etc/borgmatic/config.yaml
|
|
(by default) using the values from both your existing configuration and excludes
|
|
files. The new version of borgmatic will consume the YAML configuration file
|
|
instead of the old one.'''
|
|
)
|
|
|
|
|
|
def guard_configuration_upgraded(source_config_filename, destination_config_filenames):
|
|
'''
|
|
If legacy source configuration exists but no destination upgraded configs do, raise
|
|
Legacy_configuration_not_upgraded.
|
|
|
|
The idea is that we want to alert the user about upgrading their config if they haven't already.
|
|
'''
|
|
destination_config_exists = any(
|
|
os.path.exists(filename) for filename in destination_config_filenames
|
|
)
|
|
|
|
if os.path.exists(source_config_filename) and not destination_config_exists:
|
|
raise Legacy_configuration_not_upgraded()
|