Skip to content

Commit

Permalink
Ensure consistent load order of domains and networks.
Browse files Browse the repository at this point in the history
By processing JSON or YAML files via Ordered dicts.,
we ensure that domains are processed in the order they are specified
in the relevant configuration files.
  • Loading branch information
Yaniv Kaul committed Oct 26, 2016
1 parent 48ec964 commit 7c88ae8
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 11 deletions.
2 changes: 1 addition & 1 deletion lago/prefix.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ def _ova_to_spec(self, filename):
"template_type": "qcow2",
"format": "qcow2",
"dev": "vda",
"name": "root",
# "name": "root",
"name": os.path.basename(image_file),
"path": ova_extracted_dir +
"/images/" + image_file,
Expand Down
18 changes: 17 additions & 1 deletion lago/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,10 @@ def deepcopy(original_obj):
"""
if isinstance(original_obj, list):
return list(deepcopy(item) for item in original_obj)
elif isinstance(original_obj, collections.OrderedDict):
return collections.OrderedDict(
(key, deepcopy(val)) for key, val in original_obj.items()
)
elif isinstance(original_obj, dict):
return dict((key, deepcopy(val)) for key, val in original_obj.items())
else:
Expand All @@ -439,9 +443,21 @@ def load_virt_stream(virt_fd):
dict: Loaded virt config
"""
try:
virt_conf = json.load(virt_fd)
virt_conf = json.load(
virt_fd, object_pairs_hook=collections.OrderedDict
)
except ValueError:
virt_fd.seek(0)

# Ensure ordered dict loading from YAML. Based on
# http://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts
_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG

def dict_constructor(loader, node):
return collections.OrderedDict(loader.construct_pairs(node))

yaml.add_constructor(_mapping_tag, dict_constructor)

virt_conf = yaml.load(virt_fd)

return deepcopy(virt_conf)
Expand Down
19 changes: 12 additions & 7 deletions lago/virt.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#
# Refer to the README and COPYING files for full details of the license
#
import collections
import functools
import hashlib
import json
Expand Down Expand Up @@ -79,11 +80,11 @@ def __init__(self, prefix, vm_specs, net_specs):
with open(self.prefix.paths.uuid(), 'r') as uuid_fd:
self.uuid = uuid_fd.read().strip()

self._nets = {}
self._nets = collections.OrderedDict()
for name, spec in net_specs.items():
self._nets[name] = self._create_net(spec)

self._vms = {}
self._vms = collections.OrderedDict()
for name, spec in vm_specs.items():
self._vms[name] = self._create_vm(spec)

Expand Down Expand Up @@ -233,17 +234,21 @@ def from_prefix(cls, prefix):
virt_path = functools.partial(prefix.paths.prefixed, 'virt')

with open(virt_path('env'), 'r') as f:
env_dom = json.load(f)
env_dom = json.load(f, object_pairs_hook=collections.OrderedDict)

net_specs = {}
net_specs = collections.OrderedDict()
for name in env_dom['nets']:
with open(virt_path('net-%s' % name), 'r') as f:
net_specs[name] = json.load(f)
net_specs[name] = json.load(
f, object_pairs_hook=collections.OrderedDict
)

vm_specs = {}
vm_specs = collections.OrderedDict()
for name in env_dom['vms']:
with open(virt_path('vm-%s' % name), 'r') as f:
vm_specs[name] = json.load(f)
vm_specs[name] = json.load(
f, object_pairs_hook=collections.OrderedDict
)

return cls(prefix, vm_specs, net_specs)

Expand Down
6 changes: 4 additions & 2 deletions tests/functional/fixtures/status/prefix_skel/expected.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ Prefix:
eth1: {ip: !!python/unicode '192.168.202.2', network: !!python/unicode 'n1'}
VNC port: null
distro: !!python/unicode 'cirros'
metadata: {}
metadata: !!python/object/apply:collections.OrderedDict
- []
root password: !!python/unicode '123456'
snapshots: ''
status: down
Expand All @@ -23,7 +24,8 @@ Prefix:
eth1: {ip: !!python/unicode '192.168.202.3', network: !!python/unicode 'n1'}
VNC port: null
distro: !!python/unicode 'cirros'
metadata: {}
metadata: !!python/object/apply:collections.OrderedDict
- []
root password: !!python/unicode 'cubswin:)'
snapshots: ''
status: down

0 comments on commit 7c88ae8

Please sign in to comment.