mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-24 15:36:27 +00:00
Make serialization a lot more easy to handle
This commit is contained in:
parent
e2cddbca4c
commit
e9137ac172
8 changed files with 109 additions and 38 deletions
|
@ -130,10 +130,10 @@ class BootstrapInformation(object):
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
state = self.__dict__.copy()
|
state = self.__dict__.copy()
|
||||||
exclude_keys = ['volume', 'source_lists', 'preference_lists', 'packages']
|
exclude_keys = ['source_lists', 'preference_lists', 'packages']
|
||||||
for key in exclude_keys:
|
for key in exclude_keys:
|
||||||
del state[key]
|
del state[key]
|
||||||
state['__class__'] = 'bootstrapvz.base.bootstrapinfo.BootstrapInformation'
|
state['__class__'] = self.__module__ + '.' + self.__class__.__name__
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
|
|
|
@ -32,3 +32,12 @@ class NoPartitions(object):
|
||||||
:rtype: Bytes
|
:rtype: Bytes
|
||||||
"""
|
"""
|
||||||
return self.root.get_end()
|
return self.root.get_end()
|
||||||
|
|
||||||
|
def __getstate__(self):
|
||||||
|
state = self.__dict__.copy()
|
||||||
|
state['__class__'] = self.__module__ + '.' + self.__class__.__name__
|
||||||
|
return state
|
||||||
|
|
||||||
|
def __setstate__(self, state):
|
||||||
|
for key in state:
|
||||||
|
self.__dict__[key] = state[key]
|
||||||
|
|
|
@ -133,7 +133,7 @@ class Manifest(object):
|
||||||
raise ManifestError(message, self.path, data_path)
|
raise ManifestError(message, self.path, data_path)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
return {'__class__': 'bootstrapvz.base.manifest.Manifest',
|
return {'__class__': self.__module__ + '.' + self.__class__.__name__,
|
||||||
'path': self.path,
|
'path': self.path,
|
||||||
'data': self.data}
|
'data': self.data}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,14 @@ class Bytes(object):
|
||||||
self.qty %= other
|
self.qty %= other
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def __getstate__(self):
|
||||||
|
return {'__class__': self.__module__ + '.' + self.__class__.__name__,
|
||||||
|
'qty': self.qty,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __setstate__(self, state):
|
||||||
|
self.qty = state['qty']
|
||||||
|
|
||||||
|
|
||||||
class UnitError(Exception):
|
class UnitError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -77,3 +77,7 @@ class QEMUVolume(LoopbackVolume):
|
||||||
if not self._is_nbd_used(device_name):
|
if not self._is_nbd_used(device_name):
|
||||||
return os.path.join('/dev', device_name)
|
return os.path.join('/dev', device_name)
|
||||||
raise VolumeError('Unable to find free nbd device.')
|
raise VolumeError('Unable to find free nbd device.')
|
||||||
|
|
||||||
|
def __setstate__(self, state):
|
||||||
|
for key in state:
|
||||||
|
self.__dict__[key] = state[key]
|
||||||
|
|
|
@ -43,6 +43,19 @@ class FSMProxy(object):
|
||||||
if not hasattr(self, event):
|
if not hasattr(self, event):
|
||||||
setattr(self, event, make_proxy(fsm, event))
|
setattr(self, event, make_proxy(fsm, event))
|
||||||
|
|
||||||
|
def __getstate__(self):
|
||||||
|
state = {}
|
||||||
|
for key, value in self.__dict__.iteritems():
|
||||||
|
if callable(value) or key == 'fsm':
|
||||||
|
continue
|
||||||
|
state[key] = value
|
||||||
|
state['__class__'] = self.__module__ + '.' + self.__class__.__name__
|
||||||
|
return state
|
||||||
|
|
||||||
|
def __setstate__(self, state):
|
||||||
|
for key in state:
|
||||||
|
self.__dict__[key] = state[key]
|
||||||
|
|
||||||
|
|
||||||
class FSMProxyError(Exception):
|
class FSMProxyError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,45 +1,83 @@
|
||||||
"""Remote module containing methods to bootstrap remotely
|
"""Remote module containing methods to bootstrap remotely
|
||||||
"""
|
"""
|
||||||
import bootstrapvz.common.exceptions
|
from Pyro4.util import SerializerBase
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
supported_classes = ['bootstrapvz.base.manifest.Manifest',
|
||||||
|
'bootstrapvz.base.bootstrapinfo.BootstrapInformation',
|
||||||
|
'bootstrapvz.common.fs.loopbackvolume.LoopbackVolume',
|
||||||
|
'bootstrapvz.common.fs.qemuvolume.QEMUVolume',
|
||||||
|
'bootstrapvz.common.fs.virtualdiskimage.VirtualDiskImage',
|
||||||
|
'bootstrapvz.common.fs.virtualmachinedisk.VirtualMachineDisk',
|
||||||
|
'bootstrapvz.base.fs.partitionmaps.gpt.GPTPartitionMap',
|
||||||
|
'bootstrapvz.base.fs.partitionmaps.msdos.MSDOSPartitionMap',
|
||||||
|
'bootstrapvz.base.fs.partitionmaps.none.NoPartitions',
|
||||||
|
'bootstrapvz.base.fs.partitions.gpt.GPTPartition',
|
||||||
|
'bootstrapvz.base.fs.partitions.gpt_swap.GPTSwapPartition',
|
||||||
|
'bootstrapvz.base.fs.partitions.msdos.MSDOSPartition',
|
||||||
|
'bootstrapvz.base.fs.partitions.msdos_swap.MSDOSSwapPartition',
|
||||||
|
'bootstrapvz.base.fs.partitions.single.SinglePartition',
|
||||||
|
'bootstrapvz.base.fs.partitions.unformatted.UnformattedPartition',
|
||||||
|
'bootstrapvz.common.bytes.Bytes',
|
||||||
|
]
|
||||||
|
|
||||||
|
supported_exceptions = ['bootstrapvz.common.exceptions.ManifestError',
|
||||||
|
'bootstrapvz.common.exceptions.TaskListError',
|
||||||
|
'bootstrapvz.common.exceptions.TaskError',
|
||||||
|
'bootstrapvz.base.fs.exceptions.VolumeError',
|
||||||
|
'bootstrapvz.base.fs.exceptions.PartitionError',
|
||||||
|
'bootstrapvz.base.pkg.exceptions.PackageError',
|
||||||
|
'bootstrapvz.base.pkg.exceptions.SourceError',
|
||||||
|
'bootstrapvz.common.bytes.UnitError',
|
||||||
|
'bootstrapvz.common.fsm_proxy.FSMProxyError',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def register_deserialization_handlers():
|
def register_deserialization_handlers():
|
||||||
from Pyro4.util import SerializerBase
|
for supported_class in supported_classes:
|
||||||
SerializerBase.register_dict_to_class('bootstrapvz.base.manifest.Manifest', deserialize_manifest)
|
SerializerBase.register_dict_to_class(supported_class, deserialize)
|
||||||
SerializerBase.register_dict_to_class('bootstrapvz.base.bootstrapinfo.BootstrapInformation', deserialize_bootstrapinfo)
|
for supported_exc in supported_exceptions:
|
||||||
SerializerBase.register_dict_to_class('bootstrapvz.common.exceptions.ManifestError', deserialize_exception)
|
SerializerBase.register_dict_to_class(supported_exc, deserialize_exception)
|
||||||
SerializerBase.register_dict_to_class('bootstrapvz.common.exceptions.TaskListError', deserialize_exception)
|
|
||||||
SerializerBase.register_dict_to_class('bootstrapvz.common.exceptions.TaskError', deserialize_exception)
|
|
||||||
|
|
||||||
|
|
||||||
def unregister_deserialization_handlers():
|
def unregister_deserialization_handlers():
|
||||||
|
for supported_class in supported_classes:
|
||||||
|
SerializerBase.unregister_dict_to_class(supported_class, deserialize)
|
||||||
|
for supported_exc in supported_exceptions:
|
||||||
|
SerializerBase.unregister_dict_to_class(supported_exc, deserialize_exception)
|
||||||
|
|
||||||
|
|
||||||
|
def deserialize_exception(fq_classname, data):
|
||||||
|
class_object = get_class_object(fq_classname)
|
||||||
from Pyro4.util import SerializerBase
|
from Pyro4.util import SerializerBase
|
||||||
SerializerBase.unregister_dict_to_class('bootstrapvz.base.manifest.Manifest')
|
return SerializerBase.make_exception(class_object, data)
|
||||||
SerializerBase.unregister_dict_to_class('bootstrapvz.base.bootstrapinfo.BootstrapInformation')
|
|
||||||
SerializerBase.unregister_dict_to_class('bootstrapvz.common.exceptions.ManifestError')
|
|
||||||
SerializerBase.unregister_dict_to_class('bootstrapvz.common.exceptions.TaskListError')
|
|
||||||
SerializerBase.unregister_dict_to_class('bootstrapvz.common.exceptions.TaskError')
|
|
||||||
|
|
||||||
|
|
||||||
def deserialize_manifest(classname, state):
|
def deserialize(fq_classname, data):
|
||||||
from bootstrapvz.base.manifest import Manifest
|
class_object = get_class_object(fq_classname)
|
||||||
manifest = Manifest.__new__(Manifest)
|
from Pyro4.util import SerpentSerializer
|
||||||
manifest.__setstate__(state)
|
from Pyro4.errors import SecurityError
|
||||||
return manifest
|
ser = SerpentSerializer()
|
||||||
|
state = {}
|
||||||
|
for key, value in data.items():
|
||||||
|
try:
|
||||||
|
state[key] = ser.recreate_classes(value)
|
||||||
|
except SecurityError as e:
|
||||||
|
msg = 'Unable to deserialize key `{key}\' on {class_name}'.format(key=key, class_name=fq_classname)
|
||||||
|
import pprint
|
||||||
|
msg += pprint.pformat(data)
|
||||||
|
raise Exception(msg, e)
|
||||||
|
|
||||||
|
instance = class_object.__new__(class_object)
|
||||||
|
instance.__setstate__(state)
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
def deserialize_bootstrapinfo(classname, state):
|
def get_class_object(fq_classname):
|
||||||
from bootstrapvz.base.bootstrapinfo import BootstrapInformation
|
parts = fq_classname.split('.')
|
||||||
bootstrap_info = BootstrapInformation.__new__(BootstrapInformation)
|
module_name = '.'.join(parts[:-1])
|
||||||
bootstrap_info.__setstate__(state)
|
class_name = parts[-1]
|
||||||
return bootstrap_info
|
import importlib
|
||||||
|
imported_module = importlib.import_module(module_name)
|
||||||
deserialize_map = {'bootstrapvz.common.exceptions.ManifestError': bootstrapvz.common.exceptions.ManifestError,
|
return getattr(imported_module, class_name)
|
||||||
'bootstrapvz.common.exceptions.TaskListError': bootstrapvz.common.exceptions.TaskListError,
|
|
||||||
'bootstrapvz.common.exceptions.TaskError': bootstrapvz.common.exceptions.TaskError,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def deserialize_exception(classname, data):
|
|
||||||
from Pyro4.util import SerializerBase
|
|
||||||
return SerializerBase.make_exception(deserialize_map[classname], data)
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ volume:
|
||||||
os.close(handle)
|
os.close(handle)
|
||||||
build_server.download(bootstrap_info.volume.image_path, image_path)
|
build_server.download(bootstrap_info.volume.image_path, image_path)
|
||||||
build_server.delete(bootstrap_info.volume.image_path)
|
build_server.delete(bootstrap_info.volume.image_path)
|
||||||
|
# image_path = '/Users/anders/Workspace/cloud/images/debian-wheezy-amd64-141130.vmdk'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
image = tools.images.VirtualBoxImage(manifest, image_path)
|
image = tools.images.VirtualBoxImage(manifest, image_path)
|
||||||
|
@ -46,11 +47,9 @@ volume:
|
||||||
instance.create()
|
instance.create()
|
||||||
try:
|
try:
|
||||||
instance.boot()
|
instance.boot()
|
||||||
|
# tools.reachable_with_ssh(instance)
|
||||||
finally:
|
finally:
|
||||||
instance.shutdown()
|
instance.shutdown()
|
||||||
|
|
||||||
# tools.test(instance)
|
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
if 'instance' in locals():
|
if 'instance' in locals():
|
||||||
instance.destroy()
|
instance.destroy()
|
||||||
|
|
Loading…
Add table
Reference in a new issue