mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-24 17:28:08 +00:00
Server handler to shutdown a local server.
This commit is contained in:
parent
6d901e8295
commit
03796ca729
@ -157,7 +157,7 @@ class Config(object):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def instance(files=None):
|
def instance(files=None):
|
||||||
"""
|
"""
|
||||||
Singleton to return only on instance of Config.
|
Singleton to return only one instance of Config.
|
||||||
|
|
||||||
:params files: Array of configuration files (optional)
|
:params files: Array of configuration files (optional)
|
||||||
:returns: instance of Config
|
:returns: instance of Config
|
||||||
|
@ -26,6 +26,7 @@ from gns3server.handlers.api.qemu_handler import QEMUHandler
|
|||||||
from gns3server.handlers.api.virtualbox_handler import VirtualBoxHandler
|
from gns3server.handlers.api.virtualbox_handler import VirtualBoxHandler
|
||||||
from gns3server.handlers.api.vpcs_handler import VPCSHandler
|
from gns3server.handlers.api.vpcs_handler import VPCSHandler
|
||||||
from gns3server.handlers.api.config_handler import ConfigHandler
|
from gns3server.handlers.api.config_handler import ConfigHandler
|
||||||
|
from gns3server.handlers.api.server_handler import ServerHandler
|
||||||
from gns3server.handlers.upload_handler import UploadHandler
|
from gns3server.handlers.upload_handler import UploadHandler
|
||||||
|
|
||||||
if sys.platform.startswith("linux") or hasattr(sys, "_called_from_test"):
|
if sys.platform.startswith("linux") or hasattr(sys, "_called_from_test"):
|
||||||
|
42
gns3server/handlers/api/server_handler.py
Normal file
42
gns3server/handlers/api/server_handler.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 GNS3 Technologies Inc.
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from ...web.route import Route
|
||||||
|
from ...config import Config
|
||||||
|
from aiohttp.web import HTTPForbidden
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
class ServerHandler:
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@Route.post(
|
||||||
|
r"/server/shutdown",
|
||||||
|
description="Shutdown the local server",
|
||||||
|
status_codes={
|
||||||
|
201: "Server is shutting down",
|
||||||
|
403: "Server shutdown refused"
|
||||||
|
})
|
||||||
|
def shutdown(request, response):
|
||||||
|
|
||||||
|
config = Config.instance()
|
||||||
|
if config.get_section_config("Server").getboolean("local", False) is False:
|
||||||
|
raise HTTPForbidden(text="You can only stop a local server")
|
||||||
|
|
||||||
|
from gns3server.server import Server
|
||||||
|
server = Server.instance()
|
||||||
|
asyncio.async(server.shutdown_server())
|
||||||
|
response.set_status(201)
|
@ -173,7 +173,7 @@ def main():
|
|||||||
CrashReport.instance()
|
CrashReport.instance()
|
||||||
host = server_config["host"]
|
host = server_config["host"]
|
||||||
port = int(server_config["port"])
|
port = int(server_config["port"])
|
||||||
server = Server(host, port)
|
server = Server.instance(host, port)
|
||||||
try:
|
try:
|
||||||
server.run()
|
server.run()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -48,9 +48,22 @@ class Server:
|
|||||||
self._host = host
|
self._host = host
|
||||||
self._port = port
|
self._port = port
|
||||||
self._loop = None
|
self._loop = None
|
||||||
|
self._handler = None
|
||||||
self._start_time = time.time()
|
self._start_time = time.time()
|
||||||
self._port_manager = PortManager(host)
|
self._port_manager = PortManager(host)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def instance(host=None, port=None):
|
||||||
|
"""
|
||||||
|
Singleton to return only one instance of Server.
|
||||||
|
|
||||||
|
:returns: instance of Server
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not hasattr(Server, "_instance") or Server._instance is None:
|
||||||
|
Server._instance = Server(host, port)
|
||||||
|
return Server._instance
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def _run_application(self, handler, ssl_context=None):
|
def _run_application(self, handler, ssl_context=None):
|
||||||
|
|
||||||
@ -63,11 +76,14 @@ class Server:
|
|||||||
return server
|
return server
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def _stop_application(self):
|
def shutdown_server(self):
|
||||||
"""
|
"""
|
||||||
Cleanup the modules (shutdown running emulators etc.)
|
Cleanly shutdown the server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if self._handler:
|
||||||
|
yield from self._handler.finish_connections()
|
||||||
|
|
||||||
for module in MODULES:
|
for module in MODULES:
|
||||||
log.debug("Unloading module {}".format(module.__name__))
|
log.debug("Unloading module {}".format(module.__name__))
|
||||||
m = module.instance()
|
m = module.instance()
|
||||||
@ -81,13 +97,12 @@ class Server:
|
|||||||
|
|
||||||
self._loop.stop()
|
self._loop.stop()
|
||||||
|
|
||||||
def _signal_handling(self, handler):
|
def _signal_handling(self):
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def signal_handler(signame):
|
def signal_handler(signame):
|
||||||
log.warning("Server has got signal {}, exiting...".format(signame))
|
log.warning("Server has got signal {}, exiting...".format(signame))
|
||||||
yield from handler.finish_connections()
|
yield from self.shutdown_server()
|
||||||
yield from self._stop_application()
|
|
||||||
|
|
||||||
signals = ["SIGTERM", "SIGINT"]
|
signals = ["SIGTERM", "SIGINT"]
|
||||||
if sys.platform.startswith("win"):
|
if sys.platform.startswith("win"):
|
||||||
@ -103,14 +118,13 @@ class Server:
|
|||||||
else:
|
else:
|
||||||
self._loop.add_signal_handler(getattr(signal, signal_name), callback)
|
self._loop.add_signal_handler(getattr(signal, signal_name), callback)
|
||||||
|
|
||||||
def _reload_hook(self, handler):
|
def _reload_hook(self):
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def reload():
|
def reload():
|
||||||
|
|
||||||
log.info("Reloading")
|
log.info("Reloading")
|
||||||
yield from handler.finish_connections()
|
yield from self.shutdown_server()
|
||||||
yield from self._stop_application()
|
|
||||||
os.execv(sys.executable, [sys.executable] + sys.argv)
|
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||||
|
|
||||||
# code extracted from tornado
|
# code extracted from tornado
|
||||||
@ -130,7 +144,7 @@ class Server:
|
|||||||
if modified > self._start_time:
|
if modified > self._start_time:
|
||||||
log.debug("File {} has been modified".format(path))
|
log.debug("File {} has been modified".format(path))
|
||||||
asyncio.async(reload())
|
asyncio.async(reload())
|
||||||
self._loop.call_later(1, self._reload_hook, handler)
|
self._loop.call_later(1, self._reload_hook)
|
||||||
|
|
||||||
def _create_ssl_context(self, server_config):
|
def _create_ssl_context(self, server_config):
|
||||||
|
|
||||||
@ -196,13 +210,13 @@ class Server:
|
|||||||
m.port_manager = self._port_manager
|
m.port_manager = self._port_manager
|
||||||
|
|
||||||
log.info("Starting server on {}:{}".format(self._host, self._port))
|
log.info("Starting server on {}:{}".format(self._host, self._port))
|
||||||
handler = app.make_handler(handler=RequestHandler)
|
self._handler = app.make_handler(handler=RequestHandler)
|
||||||
self._loop.run_until_complete(self._run_application(handler, ssl_context))
|
self._loop.run_until_complete(self._run_application(self._handler, ssl_context))
|
||||||
self._signal_handling(handler)
|
self._signal_handling()
|
||||||
|
|
||||||
if server_config.getboolean("live"):
|
if server_config.getboolean("live"):
|
||||||
log.info("Code live reload is enabled, watching for file changes")
|
log.info("Code live reload is enabled, watching for file changes")
|
||||||
self._loop.call_later(1, self._reload_hook, handler)
|
self._loop.call_later(1, self._reload_hook)
|
||||||
|
|
||||||
if server_config.getboolean("shell"):
|
if server_config.getboolean("shell"):
|
||||||
asyncio.async(self.start_shell())
|
asyncio.async(self.start_shell())
|
||||||
|
Loading…
Reference in New Issue
Block a user