3
3
from juju.errors import IncompatibleVersion
4
from juju.lib import serializer
6
6
# The protocol version, which is stored in the /topology node under
7
7
# the "version" key. The protocol version should *only* be updated
59
59
This string may be provided to the :method:`parse` to
60
60
reestablish the same topology state back.
62
return yaml.safe_dump(self._state)
62
return serializer.dump(self._state)
64
64
def parse(self, data):
65
65
"""Parse the dumped data provided and restore internal state.
67
67
The provided data must necessarily have been retrieved by
68
68
calling the :method:`dump`.
70
parsed = yaml.load(data)
70
parsed = serializer.load(data)
71
71
self._state = parsed
72
72
version = self.get_version()
73
73
if version != VERSION:
74
# This will raise if it cannot update the topology.
75
migrate_topology(self)
74
raise IncompatibleVersion(version, VERSION)
77
76
def get_version(self):
78
77
return self._state.get("version", 0)
574
573
return relation_id
578
def _migrate_version_1(topology):
579
"""Migrate topology version 1 to version 2.
581
This change includes the transition from::
586
- service-0000000000: {name: db, role: client}
587
service-0000000001: {name: server, role: server}
596
service-00000001: {name: name, role: role}
597
service-00000002: {name: name, role: role}
602
version = topology.get_version()
606
raise IncompatibleVersion(version, VERSION)
608
relations = topology._state.get("relations")
611
for relation, relation_data in relations.items():
612
new_relations[relation] = {}
613
relation_type, relation_services = relation_data
614
new_relations["interface"] = relation_type
615
new_relations["scope"] = "global"
616
new_relations["services"] = relation_services
618
topology._state["relations"] = new_relations
620
topology._state["version"] = 2
624
# A dict of version migration plans for VERSION n (where n is the key)
625
# to version n + 1. migrate_version will be called until the topology
626
# version is equal to VERSION. If no migration plan exists FAIL
627
_VERSION_MIGRATION = {
629
# DISABLED: We can't migrate the topology till we can migrate older
630
# code currently running in the env that depends on a previous format.
631
# 1: _migrate_version_1
635
def migrate_topology(topology):
636
"""Migrate topology version to current.
638
Does an in-place (destructive) stepwise modification of topology
639
state from its current version to the VERSION represented in this
642
version = topology.get_version()
643
if version == VERSION:
646
current_version = version
647
while current_version < VERSION:
648
if current_version not in _VERSION_MIGRATION:
649
raise IncompatibleVersion(version, VERSION)
650
_VERSION_MIGRATION[current_version](topology)
651
current_version = topology.get_version()