mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-24 09:18:08 +00:00
Windows support (freezing).
Client notification support. Hypervisor manager changes. IOU reload support. Switch to non-dynamic module loading because of a multiprocessing problem on Windows.
This commit is contained in:
parent
3df5cdb76f
commit
41a1d16e92
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import sys
|
import sys
|
||||||
|
import multiprocessing
|
||||||
import logging
|
import logging
|
||||||
import tornado.options
|
import tornado.options
|
||||||
import gns3server
|
import gns3server
|
||||||
@ -34,6 +35,10 @@ def main():
|
|||||||
Entry point for GNS3 server
|
Entry point for GNS3 server
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if sys.platform.startswith("win"):
|
||||||
|
# necessary on Windows to use freezing software
|
||||||
|
multiprocessing.freeze_support()
|
||||||
|
|
||||||
current_year = datetime.date.today().year
|
current_year = datetime.date.today().year
|
||||||
print("GNS3 server version {}".format(gns3server.__version__))
|
print("GNS3 server version {}".format(gns3server.__version__))
|
||||||
print("Copyright (c) 2007-{} GNS3 Technologies Inc.".format(current_year))
|
print("Copyright (c) 2007-{} GNS3 Technologies Inc.".format(current_year))
|
||||||
|
@ -15,4 +15,13 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import sys
|
||||||
from .base import IModule
|
from .base import IModule
|
||||||
|
from .dynamips import Dynamips
|
||||||
|
from .iou import IOU
|
||||||
|
|
||||||
|
MODULES = [Dynamips]
|
||||||
|
|
||||||
|
if sys.platform.startswith("linux"):
|
||||||
|
# IOU runs only on Linux
|
||||||
|
MODULES.append(IOU)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
Base class (interface) for modules
|
Base class (interface) for modules
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
import gns3server.jsonrpc as jsonrpc
|
import gns3server.jsonrpc as jsonrpc
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import zmq
|
import zmq
|
||||||
@ -109,7 +110,10 @@ class IModule(multiprocessing.Process):
|
|||||||
log.warning("Module {} got signal {}, exiting...".format(self.name, signum))
|
log.warning("Module {} got signal {}, exiting...".format(self.name, signum))
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]:
|
signals = [signal.SIGTERM, signal.SIGINT]
|
||||||
|
if not sys.platform.startswith("win"):
|
||||||
|
signals.extend([signal.SIGHUP, signal.SIGQUIT])
|
||||||
|
for sig in signals:
|
||||||
signal.signal(sig, signal_handler)
|
signal.signal(sig, signal_handler)
|
||||||
|
|
||||||
log.info("{} module running with PID {}".format(self.name, self.pid))
|
log.info("{} module running with PID {}".format(self.name, self.pid))
|
||||||
@ -179,6 +183,20 @@ class IModule(multiprocessing.Process):
|
|||||||
self._current_call_id))
|
self._current_call_id))
|
||||||
self._stream.send_json(response)
|
self._stream.send_json(response)
|
||||||
|
|
||||||
|
def send_notification(self, results):
|
||||||
|
"""
|
||||||
|
Sends a notification
|
||||||
|
|
||||||
|
:param results: JSON results to the ZeroMQ server
|
||||||
|
"""
|
||||||
|
|
||||||
|
jsonrpc_response = jsonrpc.JSONRPCNotification(results)()
|
||||||
|
|
||||||
|
# add session to the response
|
||||||
|
response = [self._current_session, jsonrpc_response]
|
||||||
|
log.debug("ZeroMQ client ({}) sending: {}".format(self.name, response))
|
||||||
|
self._stream.send_json(response)
|
||||||
|
|
||||||
def _decode_request(self, request):
|
def _decode_request(self, request):
|
||||||
"""
|
"""
|
||||||
Decodes the request to JSON.
|
Decodes the request to JSON.
|
||||||
|
@ -102,6 +102,7 @@ class Dynamips(IModule):
|
|||||||
IModule.__init__(self, name, *args, **kwargs)
|
IModule.__init__(self, name, *args, **kwargs)
|
||||||
|
|
||||||
self._hypervisor_manager = None
|
self._hypervisor_manager = None
|
||||||
|
self._hypervisor_manager_settings = {}
|
||||||
self._remote_server = False
|
self._remote_server = False
|
||||||
self._routers = {}
|
self._routers = {}
|
||||||
self._ethernet_switches = {}
|
self._ethernet_switches = {}
|
||||||
@ -110,6 +111,8 @@ class Dynamips(IModule):
|
|||||||
self._ethernet_hubs = {}
|
self._ethernet_hubs = {}
|
||||||
self._projects_dir = kwargs["projects_dir"]
|
self._projects_dir = kwargs["projects_dir"]
|
||||||
self._tempdir = kwargs["temp_dir"]
|
self._tempdir = kwargs["temp_dir"]
|
||||||
|
self._working_dir = self._projects_dir
|
||||||
|
self._dynamips = ""
|
||||||
|
|
||||||
#self._callback = self.add_periodic_callback(self.test, 1000)
|
#self._callback = self.add_periodic_callback(self.test, 1000)
|
||||||
#self._callback.start()
|
#self._callback.start()
|
||||||
@ -161,6 +164,34 @@ class Dynamips(IModule):
|
|||||||
self._remote_server = False
|
self._remote_server = False
|
||||||
log.info("dynamips module has been reset")
|
log.info("dynamips module has been reset")
|
||||||
|
|
||||||
|
def start_hypervisor_manager(self):
|
||||||
|
"""
|
||||||
|
Starts the hypervisor manager.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# check if Dynamips path exists
|
||||||
|
if not os.path.exists(self._dynamips):
|
||||||
|
raise DynamipsError("Dynamips executable {} doesn't exist".format(self._dynamips))
|
||||||
|
|
||||||
|
# check if Dynamips is executable
|
||||||
|
if not os.access(self._dynamips, os.X_OK):
|
||||||
|
raise DynamipsError("Dynamips {} is not executable".format(self._dynamips))
|
||||||
|
|
||||||
|
# check if the working directory exists
|
||||||
|
if not os.path.exists(self._working_dir):
|
||||||
|
raise DynamipsError("Working directory {} doesn't exist".format(self._working_dir))
|
||||||
|
|
||||||
|
# check if the working directory is writable
|
||||||
|
if not os.access(self._working_dir, os.W_OK):
|
||||||
|
raise DynamipsError("Cannot write to working directory {}".format(self._working_dir))
|
||||||
|
|
||||||
|
log.info("starting the hypervisor manager with Dynamips working directory set to '{}'".format(self._working_dir))
|
||||||
|
self._hypervisor_manager = HypervisorManager(self._dynamips, self._working_dir)
|
||||||
|
|
||||||
|
for name, value in self._hypervisor_manager_settings.items():
|
||||||
|
if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value:
|
||||||
|
setattr(self._hypervisor_manager, name, value)
|
||||||
|
|
||||||
@IModule.route("dynamips.settings")
|
@IModule.route("dynamips.settings")
|
||||||
def settings(self, request):
|
def settings(self, request):
|
||||||
"""
|
"""
|
||||||
@ -184,27 +215,19 @@ class Dynamips(IModule):
|
|||||||
#TODO: JSON schema validation
|
#TODO: JSON schema validation
|
||||||
# starts the hypervisor manager if it hasn't been started yet
|
# starts the hypervisor manager if it hasn't been started yet
|
||||||
if not self._hypervisor_manager:
|
if not self._hypervisor_manager:
|
||||||
dynamips_path = request["path"]
|
self._dynamips = request.pop("path")
|
||||||
|
|
||||||
if "working_dir" in request:
|
if "working_dir" in request:
|
||||||
working_dir = request["working_dir"]
|
self._working_dir = request.pop("working_dir")
|
||||||
log.info("this server is local")
|
log.info("this server is local")
|
||||||
else:
|
else:
|
||||||
self._remote_server = True
|
self._remote_server = True
|
||||||
log.info("this server is remote")
|
log.info("this server is remote")
|
||||||
working_dir = self._projects_dir
|
self._working_dir = self._projects_dir
|
||||||
|
|
||||||
#TODO: check if executable
|
self._hypervisor_manager_settings = request
|
||||||
if not os.path.exists(dynamips_path):
|
|
||||||
raise DynamipsError("Dynamips executable {} doesn't exist".format(working_dir))
|
|
||||||
|
|
||||||
#TODO: check if writable
|
|
||||||
if not os.path.exists(working_dir):
|
|
||||||
raise DynamipsError("Working directory {} doesn't exist".format(working_dir))
|
|
||||||
|
|
||||||
log.info("starting the hypervisor manager with Dynamips working directory set to '{}'".format(working_dir))
|
|
||||||
self._hypervisor_manager = HypervisorManager(dynamips_path, working_dir)
|
|
||||||
|
|
||||||
|
else:
|
||||||
# apply settings to the hypervisor manager
|
# apply settings to the hypervisor manager
|
||||||
for name, value in request.items():
|
for name, value in request.items():
|
||||||
if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value:
|
if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value:
|
||||||
|
@ -47,6 +47,9 @@ class ATMSW(object):
|
|||||||
name = request["name"]
|
name = request["name"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if not self._hypervisor_manager:
|
||||||
|
self.start_hypervisor_manager()
|
||||||
|
|
||||||
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_simulated_device()
|
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_simulated_device()
|
||||||
atmsw = ATMSwitch(hypervisor, name)
|
atmsw = ATMSwitch(hypervisor, name)
|
||||||
except DynamipsError as e:
|
except DynamipsError as e:
|
||||||
|
@ -46,6 +46,9 @@ class ETHHUB(object):
|
|||||||
name = request["name"]
|
name = request["name"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if not self._hypervisor_manager:
|
||||||
|
self.start_hypervisor_manager()
|
||||||
|
|
||||||
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_simulated_device()
|
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_simulated_device()
|
||||||
ethhub = Hub(hypervisor, name)
|
ethhub = Hub(hypervisor, name)
|
||||||
except DynamipsError as e:
|
except DynamipsError as e:
|
||||||
|
@ -46,6 +46,9 @@ class ETHSW(object):
|
|||||||
name = request["name"]
|
name = request["name"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if not self._hypervisor_manager:
|
||||||
|
self.start_hypervisor_manager()
|
||||||
|
|
||||||
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_simulated_device()
|
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_simulated_device()
|
||||||
ethsw = EthernetSwitch(hypervisor, name)
|
ethsw = EthernetSwitch(hypervisor, name)
|
||||||
except DynamipsError as e:
|
except DynamipsError as e:
|
||||||
|
@ -46,6 +46,9 @@ class FRSW(object):
|
|||||||
name = request["name"]
|
name = request["name"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if not self._hypervisor_manager:
|
||||||
|
self.start_hypervisor_manager()
|
||||||
|
|
||||||
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_simulated_device()
|
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_simulated_device()
|
||||||
frsw = FrameRelaySwitch(hypervisor, name)
|
frsw = FrameRelaySwitch(hypervisor, name)
|
||||||
except DynamipsError as e:
|
except DynamipsError as e:
|
||||||
|
@ -127,7 +127,7 @@ class VM(object):
|
|||||||
try:
|
try:
|
||||||
|
|
||||||
if not self._hypervisor_manager:
|
if not self._hypervisor_manager:
|
||||||
raise DynamipsError("Dynamips manager is not started")
|
self.start_hypervisor_manager()
|
||||||
|
|
||||||
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram)
|
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram)
|
||||||
|
|
||||||
|
@ -67,9 +67,9 @@ class C7200(Router):
|
|||||||
|
|
||||||
# first slot is a mandatory Input/Output controller (based on NPE type)
|
# first slot is a mandatory Input/Output controller (based on NPE type)
|
||||||
if npe == "npe-g2":
|
if npe == "npe-g2":
|
||||||
self._slots[0] = C7200_IO_GE_E()
|
self.slot_add_binding(0, C7200_IO_GE_E())
|
||||||
else:
|
else:
|
||||||
self._slots[0] = C7200_IO_2FE()
|
self.slot_add_binding(0, C7200_IO_2FE())
|
||||||
|
|
||||||
def defaults(self):
|
def defaults(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1205,7 +1205,8 @@ class Router(object):
|
|||||||
slot_id=slot_id))
|
slot_id=slot_id))
|
||||||
|
|
||||||
if adapter == None:
|
if adapter == None:
|
||||||
return
|
raise DynamipsError("No adapter in slot {slot_id} on router {name}".format(name=self._name,
|
||||||
|
slot_id=slot_id))
|
||||||
|
|
||||||
#FIXME: check if adapter can be removed!
|
#FIXME: check if adapter can be removed!
|
||||||
|
|
||||||
|
@ -45,9 +45,6 @@ class IOU(IModule):
|
|||||||
|
|
||||||
def __init__(self, name, *args, **kwargs):
|
def __init__(self, name, *args, **kwargs):
|
||||||
|
|
||||||
if not sys.platform.startswith("linux"):
|
|
||||||
raise IOUError("Sorry the IOU module only works on Linux")
|
|
||||||
|
|
||||||
# get the iouyap location
|
# get the iouyap location
|
||||||
config = Config.instance()
|
config = Config.instance()
|
||||||
iou_config = config.get_section_config(name.upper())
|
iou_config = config.get_section_config(name.upper())
|
||||||
@ -80,8 +77,8 @@ class IOU(IModule):
|
|||||||
self._working_dir = self._projects_dir
|
self._working_dir = self._projects_dir
|
||||||
self._iourc = ""
|
self._iourc = ""
|
||||||
|
|
||||||
#self._callback = self.add_periodic_callback(self.test, 1000)
|
self._iou_callback = self.add_periodic_callback(self._check_iou, 5000)
|
||||||
#self._callback.start()
|
self._iou_callback.start()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
@ -95,6 +92,17 @@ class IOU(IModule):
|
|||||||
|
|
||||||
IModule.stop(self) # this will stop the I/O loop
|
IModule.stop(self) # this will stop the I/O loop
|
||||||
|
|
||||||
|
def _check_iou(self):
|
||||||
|
|
||||||
|
for iou_id in self._iou_instances:
|
||||||
|
iou_instance = self._iou_instances[iou_id]
|
||||||
|
if iou_instance.started and not iou_instance.is_running():
|
||||||
|
self.send_notification({"module": self.name,
|
||||||
|
"id": iou_id,
|
||||||
|
"name": iou_instance.name,
|
||||||
|
"message": "IOU is not running"})
|
||||||
|
iou_instance.stop()
|
||||||
|
|
||||||
@IModule.route("iou.reset")
|
@IModule.route("iou.reset")
|
||||||
def reset(self, request):
|
def reset(self, request):
|
||||||
"""
|
"""
|
||||||
@ -115,6 +123,13 @@ class IOU(IModule):
|
|||||||
self._remote_server = False
|
self._remote_server = False
|
||||||
self._current_console_port = self._console_start_port_range
|
self._current_console_port = self._console_start_port_range
|
||||||
self._current_udp_port = self._udp_start_port_range
|
self._current_udp_port = self._udp_start_port_range
|
||||||
|
|
||||||
|
if self._iourc and os.path.exists(self._iourc):
|
||||||
|
try:
|
||||||
|
os.remove(self._iourc)
|
||||||
|
except EnvironmentError as e:
|
||||||
|
log.warn("could not delete iourc file {}: {}".format(self._iourc, e))
|
||||||
|
|
||||||
log.info("IOU module has been reset")
|
log.info("IOU module has been reset")
|
||||||
|
|
||||||
@IModule.route("iou.settings")
|
@IModule.route("iou.settings")
|
||||||
@ -360,6 +375,37 @@ class IOU(IModule):
|
|||||||
return
|
return
|
||||||
self.send_response(request)
|
self.send_response(request)
|
||||||
|
|
||||||
|
@IModule.route("iou.reload")
|
||||||
|
def vm_reload(self, request):
|
||||||
|
"""
|
||||||
|
Reloads an IOU instance.
|
||||||
|
|
||||||
|
Mandatory request parameters:
|
||||||
|
- id (IOU identifier)
|
||||||
|
|
||||||
|
Response parameters:
|
||||||
|
- same as original request
|
||||||
|
|
||||||
|
:param request: JSON request
|
||||||
|
"""
|
||||||
|
|
||||||
|
if request == None:
|
||||||
|
self.send_param_error()
|
||||||
|
return
|
||||||
|
|
||||||
|
#TODO: JSON schema validation for the request
|
||||||
|
log.debug("received request {}".format(request))
|
||||||
|
iou_id = request["id"]
|
||||||
|
iou_instance = self._iou_instances[iou_id]
|
||||||
|
try:
|
||||||
|
if iou_instance.is_running():
|
||||||
|
iou_instance.stop()
|
||||||
|
iou_instance.start()
|
||||||
|
except IOUError as e:
|
||||||
|
self.send_custom_error(str(e))
|
||||||
|
return
|
||||||
|
self.send_response(request)
|
||||||
|
|
||||||
@IModule.route("iou.allocate_udp_port")
|
@IModule.route("iou.allocate_udp_port")
|
||||||
def allocate_udp_port(self, request):
|
def allocate_udp_port(self, request):
|
||||||
"""
|
"""
|
||||||
|
@ -79,6 +79,7 @@ class IOUDevice(object):
|
|||||||
self._ioucon_thead = None
|
self._ioucon_thead = None
|
||||||
self._ioucon_thread_stop_event = None
|
self._ioucon_thread_stop_event = None
|
||||||
self._host = host
|
self._host = host
|
||||||
|
self._started = False
|
||||||
|
|
||||||
# IOU settings
|
# IOU settings
|
||||||
self._ethernet_adapters = [EthernetAdapter(), EthernetAdapter()] # one adapter = 4 interfaces
|
self._ethernet_adapters = [EthernetAdapter(), EthernetAdapter()] # one adapter = 4 interfaces
|
||||||
@ -295,6 +296,16 @@ class IOUDevice(object):
|
|||||||
log.info("IOU device {name} [id={id}] has been deleted".format(name=self._name,
|
log.info("IOU device {name} [id={id}] has been deleted".format(name=self._name,
|
||||||
id=self._id))
|
id=self._id))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def started(self):
|
||||||
|
"""
|
||||||
|
Returns either this IOU device has been started or not.
|
||||||
|
|
||||||
|
:returns: boolean
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self._started
|
||||||
|
|
||||||
def _update_iouyap_config(self):
|
def _update_iouyap_config(self):
|
||||||
"""
|
"""
|
||||||
Updates the iouyap.ini file.
|
Updates the iouyap.ini file.
|
||||||
@ -411,6 +422,7 @@ class IOUDevice(object):
|
|||||||
cwd=self._working_dir,
|
cwd=self._working_dir,
|
||||||
env=env)
|
env=env)
|
||||||
log.info("IOU instance {} started PID={}".format(self._id, self._process.pid))
|
log.info("IOU instance {} started PID={}".format(self._id, self._process.pid))
|
||||||
|
self._started = True
|
||||||
except EnvironmentError as e:
|
except EnvironmentError as e:
|
||||||
log.error("could not start IOU: {}".format(e))
|
log.error("could not start IOU: {}".format(e))
|
||||||
raise IOUError("could not start IOU: {}".format(e))
|
raise IOUError("could not start IOU: {}".format(e))
|
||||||
@ -437,6 +449,7 @@ class IOUDevice(object):
|
|||||||
log.warn("IOU instance {} PID={} is still running".format(self._id,
|
log.warn("IOU instance {} PID={} is still running".format(self._id,
|
||||||
self._process.pid))
|
self._process.pid))
|
||||||
self._process = None
|
self._process = None
|
||||||
|
self._started = False
|
||||||
|
|
||||||
# stop console support
|
# stop console support
|
||||||
if self._ioucon_thead:
|
if self._ioucon_thead:
|
||||||
|
@ -23,6 +23,7 @@ import zmq
|
|||||||
from zmq.eventloop import ioloop, zmqstream
|
from zmq.eventloop import ioloop, zmqstream
|
||||||
ioloop.install()
|
ioloop.install()
|
||||||
|
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
import signal
|
import signal
|
||||||
@ -37,6 +38,7 @@ from .handlers.jsonrpc_websocket import JSONRPCWebSocket
|
|||||||
from .handlers.version_handler import VersionHandler
|
from .handlers.version_handler import VersionHandler
|
||||||
from .handlers.file_upload_handler import FileUploadHandler
|
from .handlers.file_upload_handler import FileUploadHandler
|
||||||
from .module_manager import ModuleManager
|
from .module_manager import ModuleManager
|
||||||
|
from .modules import MODULES
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -85,23 +87,38 @@ class Server(object):
|
|||||||
Loads the modules.
|
Loads the modules.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cwd = os.path.dirname(os.path.abspath(__file__))
|
#=======================================================================
|
||||||
module_path = os.path.join(cwd, 'modules')
|
# cwd = os.path.dirname(os.path.abspath(__file__))
|
||||||
log.info("loading modules from {}".format(module_path))
|
# module_path = os.path.join(cwd, 'modules')
|
||||||
module_manager = ModuleManager([module_path])
|
# log.info("loading modules from {}".format(module_path))
|
||||||
module_manager.load_modules()
|
# module_manager = ModuleManager([module_path])
|
||||||
for module in module_manager.get_all_modules():
|
# module_manager.load_modules()
|
||||||
instance = module_manager.activate_module(module,
|
# for module in module_manager.get_all_modules():
|
||||||
|
# instance = module_manager.activate_module(module,
|
||||||
|
# "127.0.0.1", # ZeroMQ server address
|
||||||
|
# self._zmq_port, # ZeroMQ server port
|
||||||
|
# projects_dir=self._projects_dir,
|
||||||
|
# temp_dir=self._temp_dir)
|
||||||
|
# if not instance:
|
||||||
|
# continue
|
||||||
|
# self._modules.append(instance)
|
||||||
|
# destinations = instance.destinations()
|
||||||
|
# for destination in destinations:
|
||||||
|
# JSONRPCWebSocket.register_destination(destination, module.name)
|
||||||
|
# instance.start() # starts the new process
|
||||||
|
#=======================================================================
|
||||||
|
|
||||||
|
for module in MODULES:
|
||||||
|
instance = module(module.__name__.lower(),
|
||||||
"127.0.0.1", # ZeroMQ server address
|
"127.0.0.1", # ZeroMQ server address
|
||||||
self._zmq_port, # ZeroMQ server port
|
self._zmq_port, # ZeroMQ server port
|
||||||
projects_dir=self._projects_dir,
|
projects_dir=self._projects_dir,
|
||||||
temp_dir=self._temp_dir)
|
temp_dir=self._temp_dir)
|
||||||
if not instance:
|
|
||||||
continue
|
|
||||||
self._modules.append(instance)
|
self._modules.append(instance)
|
||||||
destinations = instance.destinations()
|
destinations = instance.destinations()
|
||||||
for destination in destinations:
|
for destination in destinations:
|
||||||
JSONRPCWebSocket.register_destination(destination, module.name)
|
JSONRPCWebSocket.register_destination(destination, instance.name)
|
||||||
instance.start() # starts the new process
|
instance.start() # starts the new process
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
@ -130,7 +147,10 @@ class Server(object):
|
|||||||
log.warning("Server got signal {}, exiting...".format(signum))
|
log.warning("Server got signal {}, exiting...".format(signum))
|
||||||
self._cleanup()
|
self._cleanup()
|
||||||
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGHUP, signal.SIGQUIT]:
|
signals = [signal.SIGTERM, signal.SIGINT]
|
||||||
|
if not sys.platform.startswith("win"):
|
||||||
|
signals.extend([signal.SIGHUP, signal.SIGQUIT])
|
||||||
|
for sig in signals:
|
||||||
signal.signal(sig, signal_handler)
|
signal.signal(sig, signal_handler)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -23,5 +23,5 @@
|
|||||||
# or negative for a release candidate or beta (after the base version
|
# or negative for a release candidate or beta (after the base version
|
||||||
# number has been incremented)
|
# number has been incremented)
|
||||||
|
|
||||||
__version__ = "0.1.dev"
|
__version__ = "0.9.dev"
|
||||||
__version_info__ = (0, 1, 0, -99)
|
__version_info__ = (0, 9, 0, -99)
|
||||||
|
Loading…
Reference in New Issue
Block a user