SettingsPlugins may now track configuration versions

OctoPrint will take care of calling a migration function on the plugin if the plugin demands a newer configuration version than currently stored in config.yaml.
This commit is contained in:
Gina Häußge 2015-06-19 11:10:07 +02:00
parent e55677da22
commit d5af7b9b48
3 changed files with 51 additions and 0 deletions

View file

@ -281,6 +281,7 @@ class PluginSettings(object):
defaults = dict()
self.defaults = dict(plugins=dict())
self.defaults["plugins"][plugin_key] = defaults
self.defaults["plugins"][plugin_key]["_config_version"] = None
if get_preprocessors is None:
get_preprocessors = dict()

View file

@ -830,6 +830,41 @@ class SettingsPlugin(OctoPrintPlugin):
"""
return dict(), dict()
def get_settings_version(self):
"""
Retrieves the settings format version of the plugin.
Use this to have OctoPrint trigger your migration function if it detects an outdated settings version in
config.yaml.
Returns:
int or None: an int signifying the current settings format, should be incremented by plugins whenever there
are backwards incompatible changes. Returning None here disables the version tracking for the
plugin's configuration.
"""
return None
def on_settings_migrate(self, target, current):
"""
Called by OctoPrint if it detects that the installed version of the plugin necessitates a higher settings version
than the one currently stored in _config.yaml. Will also be called if the settings data stored in config.yaml
doesn't have version information, in which case the ``current`` parameter will be None.
Your plugin's implementation should take care of migrating any data by utilizing self._settings. OctoPrint
will take care of saving any changes to disk by calling `self._settings.save()` after returning from this method.
This method will be called before your plugin's :func:`initialize` method, but with all injections already
having taken place. You can therefore depend on the configuration having been migrated by the time :func:`initialize`
is called.
Arguments:
target (int): The settings format version the plugin requires, this should always be the same value as
returned by :func:`get_settings_version`.
current (int or None): The settings format version as currently stored in config.yaml. May be None if
no version information can be found.
"""
pass
class EventHandlerPlugin(OctoPrintPlugin):
"""

View file

@ -210,7 +210,22 @@ class Server():
set_preprocessors=set_preprocessors)
return dict(settings=plugin_settings)
def settings_plugin_pre_init(name, implementation):
if not isinstance(implementation, octoprint.plugin.SettingsPlugin):
return
settings_version = implementation.get_settings_version()
settings_migrator = implementation.on_settings_migrate
if settings_version is not None and settings_migrator is not None:
stored_version = implementation._settings.get_int(["_config_version"])
if stored_version is None or stored_version < settings_version:
settings_migrator(settings_version, stored_version)
implementation._settings.set_int(["_config_version"], settings_version)
implementation._settings.save()
pluginManager.implementation_inject_factories=[octoprint_plugin_inject_factory, settings_plugin_inject_factory]
pluginManager.implementation_pre_inits=[settings_plugin_pre_init]
pluginManager.initialize_implementations()
pluginManager.log_all_plugins()