~hazmat/pyjuju/rapi-delta

« back to all changes in this revision

Viewing changes to juju/state/topology.py

  • Committer: Kapil Thangavelu
  • Date: 2012-09-19 20:38:44 UTC
  • mfrom: (573.1.6 rest-context)
  • Revision ID: kapil@canonical.com-20120919203844-dc2pf82ttm7xj3xs
Merged rest-context into rapi-delta.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import yaml
 
1
 
2
2
 
3
3
from juju.errors import IncompatibleVersion
4
 
 
 
4
from juju.lib import serializer
5
5
 
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.
61
61
        """
62
 
        return yaml.safe_dump(self._state)
 
62
        return serializer.dump(self._state)
63
63
 
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`.
69
69
        """
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)
76
75
 
77
76
    def get_version(self):
78
77
        return self._state.get("version", 0)
573
572
            else:
574
573
                return relation_id
575
574
        return None
576
 
 
577
 
 
578
 
def _migrate_version_1(topology):
579
 
    """Migrate topology version 1 to version 2.
580
 
 
581
 
    This change includes the transition from::
582
 
 
583
 
          relations:
584
 
            relation-0000000000:
585
 
            - mysql
586
 
            - service-0000000000: {name: db, role: client}
587
 
              service-0000000001: {name: server, role: server}
588
 
 
589
 
    to::
590
 
 
591
 
          relations
592
 
              relation-00000001:
593
 
                  interface: name
594
 
                  scope: name
595
 
                  services:
596
 
                    service-00000001: {name: name, role: role}
597
 
                    service-00000002: {name: name, role: role}
598
 
 
599
 
    for all relations.
600
 
 
601
 
    """
602
 
    version = topology.get_version()
603
 
    if version > 1:
604
 
        return topology
605
 
    elif version != 1:
606
 
        raise IncompatibleVersion(version, VERSION)
607
 
 
608
 
    relations = topology._state.get("relations")
609
 
    if relations:
610
 
        new_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
617
 
 
618
 
        topology._state["relations"] = new_relations
619
 
 
620
 
    topology._state["version"] = 2
621
 
    return topology
622
 
 
623
 
 
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 = {
628
 
 
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
632
 
}
633
 
 
634
 
 
635
 
def migrate_topology(topology):
636
 
    """Migrate topology version to current.
637
 
 
638
 
    Does an in-place (destructive) stepwise modification of topology
639
 
    state from its current version to the VERSION represented in this
640
 
    module.
641
 
    """
642
 
    version = topology.get_version()
643
 
    if version == VERSION:
644
 
        return topology
645
 
 
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()