2022-08-17 17:13:11 +00:00
import logging
2023-03-19 21:13:23 +00:00
import os
2022-08-17 17:13:11 +00:00
def normalize ( config_filename , config ) :
2020-01-23 21:41:37 +00:00
'''
2022-08-17 17:13:11 +00:00
Given a configuration filename and a configuration dict of its loaded contents , apply particular
hard - coded rules to normalize the configuration to adhere to the current schema . Return any log
message warnings produced based on the normalization performed .
2020-01-23 21:41:37 +00:00
'''
2022-08-17 17:13:11 +00:00
logs = [ ]
2022-10-23 20:56:03 +00:00
location = config . get ( ' location ' ) or { }
storage = config . get ( ' storage ' ) or { }
consistency = config . get ( ' consistency ' ) or { }
hooks = config . get ( ' hooks ' ) or { }
2022-08-17 17:13:11 +00:00
2022-05-24 03:02:10 +00:00
# Upgrade exclude_if_present from a string to a list.
2022-10-23 20:56:03 +00:00
exclude_if_present = location . get ( ' exclude_if_present ' )
2020-01-23 21:41:37 +00:00
if isinstance ( exclude_if_present , str ) :
config [ ' location ' ] [ ' exclude_if_present ' ] = [ exclude_if_present ]
2022-05-24 03:02:10 +00:00
# Upgrade various monitoring hooks from a string to a dict.
2022-10-23 20:56:03 +00:00
healthchecks = hooks . get ( ' healthchecks ' )
2022-05-24 03:02:10 +00:00
if isinstance ( healthchecks , str ) :
config [ ' hooks ' ] [ ' healthchecks ' ] = { ' ping_url ' : healthchecks }
2022-10-23 20:56:03 +00:00
cronitor = hooks . get ( ' cronitor ' )
2022-05-24 03:02:10 +00:00
if isinstance ( cronitor , str ) :
config [ ' hooks ' ] [ ' cronitor ' ] = { ' ping_url ' : cronitor }
2022-10-23 20:56:03 +00:00
pagerduty = hooks . get ( ' pagerduty ' )
2022-05-24 03:02:10 +00:00
if isinstance ( pagerduty , str ) :
config [ ' hooks ' ] [ ' pagerduty ' ] = { ' integration_key ' : pagerduty }
2022-10-23 20:56:03 +00:00
cronhub = hooks . get ( ' cronhub ' )
2022-05-24 03:02:10 +00:00
if isinstance ( cronhub , str ) :
config [ ' hooks ' ] [ ' cronhub ' ] = { ' ping_url ' : cronhub }
2022-05-28 21:42:19 +00:00
# Upgrade consistency checks from a list of strings to a list of dicts.
2022-10-23 20:56:03 +00:00
checks = consistency . get ( ' checks ' )
2022-05-28 21:42:19 +00:00
if isinstance ( checks , list ) and len ( checks ) and isinstance ( checks [ 0 ] , str ) :
config [ ' consistency ' ] [ ' checks ' ] = [ { ' name ' : check_type } for check_type in checks ]
2022-08-17 17:13:11 +00:00
2022-08-18 04:14:58 +00:00
# Rename various configuration options.
2022-10-23 20:56:03 +00:00
numeric_owner = location . pop ( ' numeric_owner ' , None )
2022-08-18 04:14:58 +00:00
if numeric_owner is not None :
config [ ' location ' ] [ ' numeric_ids ' ] = numeric_owner
2022-10-23 20:56:03 +00:00
bsd_flags = location . pop ( ' bsd_flags ' , None )
2022-08-18 04:14:58 +00:00
if bsd_flags is not None :
config [ ' location ' ] [ ' flags ' ] = bsd_flags
2022-10-23 20:56:03 +00:00
remote_rate_limit = storage . pop ( ' remote_rate_limit ' , None )
2022-08-18 04:14:58 +00:00
if remote_rate_limit is not None :
config [ ' storage ' ] [ ' upload_rate_limit ' ] = remote_rate_limit
2022-08-17 17:13:11 +00:00
# Upgrade remote repositories to ssh:// syntax, required in Borg 2.
2022-10-23 20:56:03 +00:00
repositories = location . get ( ' repositories ' )
2022-08-17 17:13:11 +00:00
if repositories :
2023-03-24 19:34:57 +00:00
if isinstance ( repositories [ 0 ] , str ) :
config [ ' location ' ] [ ' repositories ' ] = [
{ ' path ' : repository } for repository in repositories
]
repositories = config [ ' location ' ] [ ' repositories ' ]
2022-08-17 17:13:11 +00:00
config [ ' location ' ] [ ' repositories ' ] = [ ]
2023-03-22 19:31:26 +00:00
for repository_dict in repositories :
2023-03-24 19:34:57 +00:00
repository_path = repository_dict [ ' path ' ]
if ' ~ ' in repository_path :
2022-08-17 17:13:11 +00:00
logs . append (
logging . makeLogRecord (
dict (
levelno = logging . WARNING ,
levelname = ' WARNING ' ,
2022-08-18 04:54:00 +00:00
msg = f ' { config_filename } : Repository paths containing " ~ " are deprecated in borgmatic and no longer work in Borg 2.x+. ' ,
2022-08-17 17:13:11 +00:00
)
)
)
2023-03-24 19:34:57 +00:00
if ' : ' in repository_path :
if repository_path . startswith ( ' file:// ' ) :
updated_repository_path = os . path . abspath (
repository_path . partition ( ' file:// ' ) [ - 1 ]
)
2023-03-21 11:36:03 +00:00
config [ ' location ' ] [ ' repositories ' ] . append (
2023-04-15 02:35:24 +00:00
dict (
repository_dict ,
path = updated_repository_path ,
)
2023-03-21 11:36:03 +00:00
)
2023-03-24 19:34:57 +00:00
elif repository_path . startswith ( ' ssh:// ' ) :
2023-03-26 11:29:29 +00:00
config [ ' location ' ] [ ' repositories ' ] . append ( repository_dict )
2023-03-19 21:13:23 +00:00
else :
2023-03-24 19:34:57 +00:00
rewritten_repository_path = f " ssh:// { repository_path . replace ( ' :~ ' , ' /~ ' ) . replace ( ' :/ ' , ' / ' ) . replace ( ' : ' , ' /./ ' ) } "
2023-03-19 21:13:23 +00:00
logs . append (
logging . makeLogRecord (
dict (
levelno = logging . WARNING ,
levelname = ' WARNING ' ,
2023-03-24 19:34:57 +00:00
msg = f ' { config_filename } : Remote repository paths without ssh:// syntax are deprecated. Interpreting " { repository_path } " as " { rewritten_repository_path } " ' ,
2023-03-19 21:13:23 +00:00
)
2022-08-17 17:13:11 +00:00
)
)
2023-03-22 19:38:30 +00:00
config [ ' location ' ] [ ' repositories ' ] . append (
2023-04-15 02:35:24 +00:00
dict (
repository_dict ,
path = rewritten_repository_path ,
)
2023-03-22 19:38:30 +00:00
)
2022-08-17 17:13:11 +00:00
else :
2023-03-26 11:29:29 +00:00
config [ ' location ' ] [ ' repositories ' ] . append ( repository_dict )
2022-08-17 17:13:11 +00:00
return logs