diff --git a/gns3server/config.py b/gns3server/config.py
index 494ac743..cf6062d8 100644
--- a/gns3server/config.py
+++ b/gns3server/config.py
@@ -98,28 +98,15 @@ class Config(object):
self.read_config()
self._cloud_config = configparser.ConfigParser()
self.read_cloud_config()
- self._watch_config_file()
- def _watch_config_file(self):
- asyncio.get_event_loop().call_later(1, self._check_config_file_change)
-
- def _check_config_file_change(self):
+ def reload(self):
"""
- Check if configuration file has changed on the disk
+ Reload configuration
"""
- changed = False
- for file in self._watched_files:
- try:
- if os.stat(file).st_mtime != self._watched_files[file]:
- changed = True
- except OSError:
- continue
- if changed:
- self.read_config()
+ self.read_config()
for section in self._override_config:
self.set_section_config(section, self._override_config[section])
- self._watch_config_file()
def list_cloud_config_file(self):
return self._cloud_file
diff --git a/gns3server/handlers/__init__.py b/gns3server/handlers/__init__.py
index 3db429a1..325e8ba4 100644
--- a/gns3server/handlers/__init__.py
+++ b/gns3server/handlers/__init__.py
@@ -25,6 +25,7 @@ from gns3server.handlers.api.dynamips_vm_handler import DynamipsVMHandler
from gns3server.handlers.api.qemu_handler import QEMUHandler
from gns3server.handlers.api.virtualbox_handler import VirtualBoxHandler
from gns3server.handlers.api.vpcs_handler import VPCSHandler
+from gns3server.handlers.api.config_handler import ConfigHandler
from gns3server.handlers.upload_handler import UploadHandler
if sys.platform.startswith("linux") or hasattr(sys, "_called_from_test"):
diff --git a/gns3server/handlers/api/config_handler.py b/gns3server/handlers/api/config_handler.py
new file mode 100644
index 00000000..0025731e
--- /dev/null
+++ b/gns3server/handlers/api/config_handler.py
@@ -0,0 +1,41 @@
+# -*- 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 .
+
+from ...web.route import Route
+from ...config import Config
+from aiohttp.web import HTTPForbidden
+
+import asyncio
+
+
+class ConfigHandler:
+
+ @classmethod
+ @Route.post(
+ r"/config/reload",
+ description="Check if version is the same as the server",
+ status_codes={
+ 201: "Config reload",
+ 403: "Config reload refused"
+ })
+ def reload(request, response):
+
+ config = Config.instance()
+ if config.get_section_config("Server").getboolean("local", False) is False:
+ raise HTTPForbidden(text="You can only reload the configuration for a local server")
+ config.reload()
+ response.set_status(201)
diff --git a/tests/handlers/api/test_config.py b/tests/handlers/api/test_config.py
new file mode 100644
index 00000000..b081ca13
--- /dev/null
+++ b/tests/handlers/api/test_config.py
@@ -0,0 +1,48 @@
+# -*- 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 .
+
+from configparser import ConfigParser
+from unittest.mock import patch, MagicMock
+
+
+def test_reload_accepted(server):
+
+ gns_config = MagicMock()
+ config = ConfigParser()
+ config.add_section("Server")
+ config.set("Server", "local", "true")
+ gns_config.get_section_config.return_value = config["Server"]
+
+ with patch("gns3server.config.Config.instance", return_value=gns_config):
+ response = server.post('/config/reload', example=True)
+
+ assert response.status == 201
+ assert gns_config.reload.called
+
+
+def test_reload_forbidden(server):
+
+ gns_config = MagicMock()
+ config = ConfigParser()
+ config.add_section("Server")
+ config.set("Server", "local", "false")
+ gns_config.get_section_config.return_value = config["Server"]
+
+ with patch("gns3server.config.Config.instance", return_value=gns_config):
+ response = server.post('/config/reload')
+
+ assert response.status == 403
diff --git a/tests/test_config.py b/tests/test_config.py
index d12683b1..3f119619 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -77,7 +77,7 @@ def test_set_section_config(tmpdir):
assert dict(config.get_section_config("Server")) == {"host": "192.168.1.1"}
-def test_check_config_file_change(tmpdir):
+def test_reload(tmpdir):
config = load_config(tmpdir, {
"Server": {
@@ -91,13 +91,12 @@ def test_check_config_file_change(tmpdir):
"host": "192.168.1.1"
}
})
- os.utime(path, (time.time() + 1, time.time() + 1))
- config._check_config_file_change()
+ config.reload()
assert dict(config.get_section_config("Server")) == {"host": "192.168.1.1"}
-def test_check_config_file_change_override_cmdline(tmpdir):
+def test_reload(tmpdir):
config = load_config(tmpdir, {
"Server": {
@@ -114,7 +113,6 @@ def test_check_config_file_change_override_cmdline(tmpdir):
"host": "192.168.1.2"
}
})
- os.utime(path, (time.time() + 1, time.time() + 1))
- config._check_config_file_change()
+ config.reload()
assert dict(config.get_section_config("Server")) == {"host": "192.168.1.1"}