config/ext: Automatically disable extensions with bad config
Ensures config errors on extensions don't block mopidy startup. Also improves
error messages for config problems.
(cherry picked from commit 684bfcf301)
This commit is contained in:
parent
e255afb97f
commit
01bef27a4e
@ -74,20 +74,28 @@ def main():
|
||||
|
||||
log.setup_logging(config, verbosity_level, args.save_debug_log)
|
||||
|
||||
enabled_extensions = []
|
||||
extensions = {
|
||||
'validate': [], 'config': [], 'disabled': [], 'enabled': []}
|
||||
for extension in installed_extensions:
|
||||
if not ext.validate_extension(extension):
|
||||
config[extension.ext_name] = {'enabled': False}
|
||||
config_errors[extension.ext_name] = {
|
||||
'enabled': 'extension disabled by self check.'}
|
||||
extensions['validate'].append(extension)
|
||||
elif not config[extension.ext_name]['enabled']:
|
||||
config[extension.ext_name] = {'enabled': False}
|
||||
config_errors[extension.ext_name] = {
|
||||
'enabled': 'extension disabled by user config.'}
|
||||
extensions['disabled'].append(extension)
|
||||
elif config_errors.get(extension.ext_name):
|
||||
config[extension.ext_name]['enabled'] = False
|
||||
config_errors[extension.ext_name]['enabled'] = (
|
||||
'extension disabled due to config errors.')
|
||||
extensions['config'].append(extension)
|
||||
else:
|
||||
enabled_extensions.append(extension)
|
||||
extensions['enabled'].append(extension)
|
||||
|
||||
log_extension_info(installed_extensions, enabled_extensions)
|
||||
log_extension_info(installed_extensions, extensions['enabled'])
|
||||
|
||||
# Config and deps commands are simply special cased for now.
|
||||
if args.command == config_cmd:
|
||||
@ -96,22 +104,22 @@ def main():
|
||||
elif args.command == deps_cmd:
|
||||
return args.command.run()
|
||||
|
||||
# Remove errors for extensions that are not enabled:
|
||||
for extension in installed_extensions:
|
||||
if extension not in enabled_extensions:
|
||||
config_errors.pop(extension.ext_name, None)
|
||||
check_config_errors(config_errors)
|
||||
check_config_errors(config, config_errors, extensions)
|
||||
|
||||
if not extensions['enabled']:
|
||||
logger.error('No extension enabled, exiting...')
|
||||
sys.exit(1)
|
||||
|
||||
# Read-only config from here on, please.
|
||||
proxied_config = config_lib.Proxy(config)
|
||||
|
||||
if args.extension and args.extension not in enabled_extensions:
|
||||
if args.extension and args.extension not in extensions['enabled']:
|
||||
logger.error(
|
||||
'Unable to run command provided by disabled extension %s',
|
||||
args.extension.ext_name)
|
||||
return 1
|
||||
|
||||
for extension in enabled_extensions:
|
||||
for extension in extensions['enabled']:
|
||||
extension.setup(registry)
|
||||
|
||||
# Anything that wants to exit after this point must use
|
||||
@ -173,13 +181,39 @@ def log_extension_info(all_extensions, enabled_extensions):
|
||||
'Disabled extensions: %s', ', '.join(disabled_names) or 'none')
|
||||
|
||||
|
||||
def check_config_errors(errors):
|
||||
if not errors:
|
||||
return
|
||||
for section in errors:
|
||||
for key, msg in errors[section].items():
|
||||
logger.error('Config value %s/%s %s', section, key, msg)
|
||||
sys.exit(1)
|
||||
def check_config_errors(config, errors, extensions):
|
||||
fatal_errors = []
|
||||
extension_names = {}
|
||||
all_extension_names = set()
|
||||
|
||||
for state in extensions:
|
||||
extension_names[state] = set(e.ext_name for e in extensions[state])
|
||||
all_extension_names.update(extension_names[state])
|
||||
|
||||
for section in sorted(errors):
|
||||
if not errors[section]:
|
||||
continue
|
||||
|
||||
if section not in all_extension_names:
|
||||
logger.warning('Found fatal %s configuration errors:', section)
|
||||
fatal_errors.append(section)
|
||||
elif section in extension_names['config']:
|
||||
del errors[section]['enabled']
|
||||
logger.warning('Found %s configuration errors, the extension '
|
||||
'has been automatically disabled:', section)
|
||||
else:
|
||||
continue
|
||||
|
||||
for field, msg in errors[section].items():
|
||||
logger.warning(' %s/%s %s', section, field, msg)
|
||||
|
||||
if extensions['config']:
|
||||
logger.warning('Please fix the extension configuration errors or '
|
||||
'disable the extensions to silence these messages.')
|
||||
|
||||
if fatal_errors:
|
||||
logger.error('Please fix fatal configuration errors, exiting...')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Loading…
Reference in New Issue
Block a user