Fixes #1260 - Add enforced versioning to configuration files.

pull/1536/head
Kieran R. Prasch 2019-12-13 18:27:00 -08:00
parent abb462f69a
commit 20146e152b
2 changed files with 19 additions and 4 deletions

View File

@ -2,6 +2,10 @@ import json
import os
from abc import ABC, abstractmethod
from constant_sorrow.constants import (
UNKNOWN_VERSION
)
from nucypher.config import constants
@ -70,6 +74,8 @@ class BaseConfiguration(ABC):
INDENTATION = 2
DEFAULT_CONFIG_ROOT = constants.DEFAULT_CONFIG_ROOT
VERSION = NotImplemented
class ConfigurationError(RuntimeError):
pass
@ -79,6 +85,9 @@ class BaseConfiguration(ABC):
class NoConfigurationRoot(InvalidConfiguration):
pass
class OldVersion(InvalidConfiguration):
pass
def __init__(self,
config_root: str = None,
filepath: str = None,
@ -220,11 +229,17 @@ class BaseConfiguration(ABC):
def serialize(self, serializer=json.dumps) -> str:
"""Returns the JSON serialized output of `static_payload`"""
serialized_payload = serializer(self.static_payload(), indent=self.INDENTATION)
payload = self.static_payload()
payload['version'] = self.VERSION
serialized_payload = serializer(payload, indent=self.INDENTATION)
return serialized_payload
@classmethod
def deserialize(cls, payload: str, deserializer=json.loads) -> dict:
"""Returns the JSON deserialized content of `payload`"""
deserialized_payload = deserializer(payload)
version = deserialized_payload.pop('version', UNKNOWN_VERSION)
if version != cls.VERSION:
raise cls.OldVersion(f"Configuration file is the wrong version "
f"Expected version {cls.VERSION}; Got version {version}")
return deserialized_payload

View File

@ -45,6 +45,8 @@ class CharacterConfiguration(BaseConfiguration):
'Sideways Engagement' of Character classes; a reflection of input parameters.
"""
VERSION = 1 # bump when static payload scheme changes
CHARACTER_CLASS = NotImplemented
DEFAULT_CONTROLLER_PORT = NotImplemented
DEFAULT_DOMAIN = 'goerli'
@ -284,7 +286,6 @@ class CharacterConfiguration(BaseConfiguration):
"""
Warning: This method allows mutation and may result in an inconsistent configuration.
"""
payload = cls._read_configuration_file(filepath=filepath)
node_storage = cls.load_node_storage(storage_payload=payload['node_storage'],
federated_only=payload['federated_only'])
@ -310,8 +311,7 @@ class CharacterConfiguration(BaseConfiguration):
try:
node_configuration = cls(filepath=filepath, provider_process=provider_process, **assembled_params)
except TypeError as e:
# TODO: Trigger configuration migration?
raise cls.ConfigurationError(f"Your configuration file may be out of date: {e}")
raise cls.ConfigurationError(e)
return node_configuration
def validate(self) -> bool: