1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-24 17:28:08 +00:00

Graceful shutdown for modules and locale check for the server.

This commit is contained in:
grossmj 2014-04-24 15:59:34 -06:00
parent 9be5625c38
commit 7ebd451dda
4 changed files with 52 additions and 6 deletions

View File

@ -20,10 +20,14 @@ import os
import datetime import datetime
import sys import sys
import multiprocessing import multiprocessing
import locale
import tornado.options import tornado.options
from gns3server.server import Server from gns3server.server import Server
from gns3server.version import __version__ from gns3server.version import __version__
import logging
log = logging.getLogger(__name__)
# command line options # command line options
from tornado.options import define from tornado.options import define
define("host", default="0.0.0.0", help="run on the given host/IP address", type=str) define("host", default="0.0.0.0", help="run on the given host/IP address", type=str)
@ -31,13 +35,48 @@ define("port", default=8000, help="run on the given port", type=int)
define("ipc", default=False, help="use IPC for module communication", type=bool) define("ipc", default=False, help="use IPC for module communication", type=bool)
def locale_check():
"""
Checks if this application runs with a correct locale (i.e. supports UTF-8 encoding) and attempt to fix
if this is not the case.
This is to prevent UnicodeEncodeError with unicode paths when using standard library I/O operation
methods (e.g. os.stat() or os.path.*) which rely on the system or user locale.
"""
# no need to check on Windows
if sys.platform.startswith("win"):
return
language = encoding = None
try:
language, encoding = locale.getlocale()
except ValueError as e:
log.error("could not determine the current locale: {}".format(e))
if not language and not encoding:
try:
log.warn("could not find a default locale, switching to C.UTF-8...")
locale.setlocale(locale.LC_ALL, ("C", "UTF-8"))
except locale.Error as e:
log.error("could not switch to the C.UTF-8 locale: {}".format(e))
raise SystemExit
elif encoding != "UTF-8":
log.warn("your locale {}.{} encoding is not UTF-8, switching to the UTF-8 version...".format(language, encoding))
try:
locale.setlocale(locale.LC_ALL, (language, "UTF-8"))
except locale.Error as e:
log.error("could not set an UTF-8 encoding for the {} locale: {}".format(language, e))
else:
log.info("current locale is {}.{}".format(language, encoding))
def main(): def main():
""" """
Entry point for GNS3 server Entry point for GNS3 server
""" """
if sys.platform.startswith("win"): if sys.platform.startswith("win"):
# necessary on Windows to use freezing software # necessary on Windows to freeze the application
multiprocessing.freeze_support() multiprocessing.freeze_support()
current_year = datetime.date.today().year current_year = datetime.date.today().year
@ -59,6 +98,8 @@ def main():
tornado.options.print_help() tornado.options.print_help()
raise SystemExit raise SystemExit
locale_check()
from tornado.options import options from tornado.options import options
server = Server(options.host, server = Server(options.host,
options.port, options.port,

View File

@ -54,6 +54,7 @@ class IModule(multiprocessing.Process):
self._current_session = None self._current_session = None
self._current_destination = None self._current_destination = None
self._current_call_id = None self._current_call_id = None
self._stopping = False
def _setup(self): def _setup(self):
""" """
@ -128,13 +129,16 @@ class IModule(multiprocessing.Process):
except KeyboardInterrupt: except KeyboardInterrupt:
return return
log.info("{} module has stopped".format(self.name))
def stop(self): def stop(self):
""" """
Stops the event loop. Stops the event loop.
""" """
if self._ioloop: if not self._stopping:
self._ioloop.stop() self._stopping = True
self._ioloop.add_callback_from_signal(self._ioloop.stop)
def send_response(self, results): def send_response(self, results):
""" """

View File

@ -442,8 +442,8 @@ class IOUDevice(object):
self._started = True self._started = True
except OSError as e: except OSError as e:
iou_stdout = self.read_iou_stdout() iou_stdout = self.read_iou_stdout()
log.error("could not start IOU: {}\n{}".format(e, iou_stdout)) log.error("could not start IOU {}: {}\n{}".format(self._path, e, iou_stdout))
raise IOUError("could not start IOU: {}\n{}".format(e, iou_stdout)) raise IOUError("could not start IOU {}: {}\n{}".format(self._path, e, iou_stdout))
# start console support # start console support
self._start_ioucon() self._start_ioucon()

View File

@ -224,7 +224,8 @@ class Server(object):
# terminate all modules # terminate all modules
for module in self._modules: for module in self._modules:
#module.join(timeout=1) # if not sys.platform.startswith("win"):
# module.join(timeout=0.5)
if module.is_alive(): if module.is_alive():
log.info("terminating {}".format(module.name)) log.info("terminating {}".format(module.name))
module.terminate() module.terminate()