diff --git a/lago/prefix.py b/lago/prefix.py index 3bcf3f2e..bfe35ff6 100644 --- a/lago/prefix.py +++ b/lago/prefix.py @@ -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, diff --git a/lago/utils.py b/lago/utils.py index b885eefe..f0acb288 100644 --- a/lago/utils.py +++ b/lago/utils.py @@ -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: @@ -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) diff --git a/lago/virt.py b/lago/virt.py index 9b610fb6..089553a6 100644 --- a/lago/virt.py +++ b/lago/virt.py @@ -23,6 +23,7 @@ import logging import os import uuid +import collections import lxml.etree @@ -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) @@ -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) diff --git a/tests/functional/fixtures/status/prefix_skel/expected.yaml b/tests/functional/fixtures/status/prefix_skel/expected.yaml index fb4cfd7b..75b71823 100644 --- a/tests/functional/fixtures/status/prefix_skel/expected.yaml +++ b/tests/functional/fixtures/status/prefix_skel/expected.yaml @@ -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 @@ -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