mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-24 15:36:27 +00:00
Fix serialization of exceptions
This commit is contained in:
parent
056d279b65
commit
2b6fefd789
7 changed files with 56 additions and 29 deletions
|
@ -136,3 +136,10 @@ class Manifest(object):
|
||||||
return {'__class__': 'bootstrapvz.base.manifest.Manifest',
|
return {'__class__': 'bootstrapvz.base.manifest.Manifest',
|
||||||
'path': self.path,
|
'path': self.path,
|
||||||
'data': self.data}
|
'data': self.data}
|
||||||
|
|
||||||
|
def __setstate__(self, state):
|
||||||
|
self.path = state['path']
|
||||||
|
self.load(state['data'])
|
||||||
|
self.initialize()
|
||||||
|
self.validate()
|
||||||
|
self.parse()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
class ManifestError(Exception):
|
class ManifestError(Exception):
|
||||||
def __init__(self, message, manifest_path, data_path=None):
|
def __init__(self, message, manifest_path, data_path=None):
|
||||||
|
super(ManifestError, self).__init__(message)
|
||||||
self.message = message
|
self.message = message
|
||||||
self.manifest_path = manifest_path
|
self.manifest_path = manifest_path
|
||||||
self.data_path = data_path
|
self.data_path = data_path
|
||||||
|
@ -16,6 +17,7 @@ class ManifestError(Exception):
|
||||||
|
|
||||||
class TaskListError(Exception):
|
class TaskListError(Exception):
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
|
super(TaskListError, self).__init__(message)
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -1,22 +1,31 @@
|
||||||
"""Remote module containing methods to bootstrap remotely
|
"""Remote module containing methods to bootstrap remotely
|
||||||
"""
|
"""
|
||||||
|
import bootstrapvz.common.exceptions
|
||||||
|
|
||||||
|
|
||||||
def register_deserialization_handlers():
|
def register_deserialization_handlers():
|
||||||
from Pyro4.util import SerializerBase
|
from Pyro4.util import SerializerBase
|
||||||
SerializerBase.register_dict_to_class('bootstrapvz.base.manifest.Manifest', deserialize_manifest)
|
SerializerBase.register_dict_to_class('bootstrapvz.base.manifest.Manifest', deserialize_manifest)
|
||||||
SerializerBase.register_dict_to_class('bootstrapvz.base.bootstrapinfo.BootstrapInformation', deserialize_bootstrapinfo)
|
SerializerBase.register_dict_to_class('bootstrapvz.base.bootstrapinfo.BootstrapInformation', deserialize_bootstrapinfo)
|
||||||
|
SerializerBase.register_dict_to_class('bootstrapvz.common.exceptions.ManifestError', 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():
|
||||||
from Pyro4.util import SerializerBase
|
from Pyro4.util import SerializerBase
|
||||||
SerializerBase.unregister_dict_to_class('bootstrapvz.base.manifest.Manifest')
|
SerializerBase.unregister_dict_to_class('bootstrapvz.base.manifest.Manifest')
|
||||||
SerializerBase.unregister_dict_to_class('bootstrapvz.base.bootstrapinfo.BootstrapInformation')
|
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_manifest(classname, state):
|
||||||
from bootstrapvz.base.manifest import Manifest
|
from bootstrapvz.base.manifest import Manifest
|
||||||
return Manifest(path=state['path'], data=state['data'])
|
manifest = Manifest.__new__(Manifest)
|
||||||
|
manifest.__setstate__(state)
|
||||||
|
return manifest
|
||||||
|
|
||||||
|
|
||||||
def deserialize_bootstrapinfo(classname, state):
|
def deserialize_bootstrapinfo(classname, state):
|
||||||
|
@ -24,3 +33,13 @@ def deserialize_bootstrapinfo(classname, state):
|
||||||
bootstrap_info = BootstrapInformation.__new__(BootstrapInformation)
|
bootstrap_info = BootstrapInformation.__new__(BootstrapInformation)
|
||||||
bootstrap_info.__setstate__(state)
|
bootstrap_info.__setstate__(state)
|
||||||
return bootstrap_info
|
return bootstrap_info
|
||||||
|
|
||||||
|
deserialize_map = {'bootstrapvz.common.exceptions.ManifestError': bootstrapvz.common.exceptions.ManifestError,
|
||||||
|
'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)
|
||||||
|
|
|
@ -1,20 +1,19 @@
|
||||||
|
import Pyro4
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
Pyro4.config.REQUIRE_EXPOSE = True
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class CallbackServer(object):
|
class CallbackServer(object):
|
||||||
|
|
||||||
def __init__(self, listen_port, remote_port):
|
def __init__(self, listen_port, remote_port):
|
||||||
self.listen_port = listen_port
|
self.daemon = Pyro4.Daemon(host='localhost', port=listen_port,
|
||||||
self.remote_port = remote_port
|
nathost='localhost', natport=remote_port,
|
||||||
|
|
||||||
def start(self, log_server):
|
|
||||||
import Pyro4
|
|
||||||
self.daemon = Pyro4.Daemon(host='localhost', port=self.listen_port,
|
|
||||||
nathost='localhost', natport=self.remote_port,
|
|
||||||
unixsocket=None)
|
unixsocket=None)
|
||||||
self.daemon.register(log_server)
|
self.daemon.register(self)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
def serve():
|
def serve():
|
||||||
self.daemon.requestLoop()
|
self.daemon.requestLoop()
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
@ -27,3 +26,13 @@ class CallbackServer(object):
|
||||||
self.daemon.shutdown()
|
self.daemon.shutdown()
|
||||||
if hasattr(self, 'thread'):
|
if hasattr(self, 'thread'):
|
||||||
self.thread.join()
|
self.thread.join()
|
||||||
|
|
||||||
|
@Pyro4.expose
|
||||||
|
def handle_log(self, pickled_record):
|
||||||
|
import pickle
|
||||||
|
record = pickle.loads(pickled_record)
|
||||||
|
log = logging.getLogger()
|
||||||
|
record.extra = getattr(record, 'extra', {})
|
||||||
|
record.extra['source'] = 'remote'
|
||||||
|
log.handle(record)
|
||||||
|
|
||||||
|
|
|
@ -15,18 +15,9 @@ class LogForwarder(logging.Handler):
|
||||||
if record.exc_info is not None:
|
if record.exc_info is not None:
|
||||||
import traceback
|
import traceback
|
||||||
exc_type, exc_value, exc_traceback = record.exc_info
|
exc_type, exc_value, exc_traceback = record.exc_info
|
||||||
record.exc_info = traceback.print_exception(exc_type, exc_value, exc_traceback)
|
record.extra = getattr(record, 'extra', {})
|
||||||
|
record.extra['traceback'] = traceback.format_exception(exc_type, exc_value, exc_traceback)
|
||||||
|
record.exc_info = None
|
||||||
# TODO: Use serpent instead
|
# TODO: Use serpent instead
|
||||||
import pickle
|
import pickle
|
||||||
self.server.handle(pickle.dumps(record))
|
self.server.handle_log(pickle.dumps(record))
|
||||||
|
|
||||||
|
|
||||||
class LogServer(object):
|
|
||||||
|
|
||||||
def handle(self, pickled_record):
|
|
||||||
import pickle
|
|
||||||
record = pickle.loads(pickled_record)
|
|
||||||
log = logging.getLogger()
|
|
||||||
record.extra = getattr(record, 'extra', {})
|
|
||||||
record.extra['source'] = 'remote'
|
|
||||||
log.handle(record)
|
|
||||||
|
|
|
@ -82,13 +82,11 @@ def run(manifest, build_server, debug=False, dry_run=False):
|
||||||
from callback import CallbackServer
|
from callback import CallbackServer
|
||||||
callback_server = CallbackServer(listen_port=build_server.local_callback_port,
|
callback_server = CallbackServer(listen_port=build_server.local_callback_port,
|
||||||
remote_port=build_server.remote_callback_port)
|
remote_port=build_server.remote_callback_port)
|
||||||
from log import LogServer
|
|
||||||
log_server = LogServer()
|
|
||||||
try:
|
try:
|
||||||
# Start the callback server (in a background thread)
|
# Start the callback server (in a background thread)
|
||||||
callback_server.start(log_server)
|
callback_server.start()
|
||||||
# Tell the RPC daemon about the callback server
|
# Tell the RPC daemon about the callback server
|
||||||
connection.set_log_server(log_server)
|
connection.set_callback_server(callback_server)
|
||||||
|
|
||||||
# Everything has been set up, begin the bootstrapping process
|
# Everything has been set up, begin the bootstrapping process
|
||||||
bootstrap_info = connection.run(manifest,
|
bootstrap_info = connection.run(manifest,
|
||||||
|
|
|
@ -56,9 +56,10 @@ class Server(object):
|
||||||
return run(*args, **kwargs)
|
return run(*args, **kwargs)
|
||||||
|
|
||||||
@Pyro4.expose
|
@Pyro4.expose
|
||||||
def set_log_server(self, server):
|
def set_callback_server(self, server):
|
||||||
self.log_forwarder.set_server(server)
|
self.callback_server = server
|
||||||
log.debug('Successfully set the log forwarding server')
|
self.log_forwarder.set_server(self.callback_server)
|
||||||
|
log.debug('Forwarding logs to the callback server now')
|
||||||
|
|
||||||
@Pyro4.expose
|
@Pyro4.expose
|
||||||
def ping(self):
|
def ping(self):
|
||||||
|
|
Loading…
Add table
Reference in a new issue