mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-12-22 06:07:51 +00:00
Monitor IOU nvram for change
With the save as you go we need to save the startup config when a change appear instead of the old commit system.
This commit is contained in:
parent
182a979e71
commit
69334665d2
@ -72,23 +72,6 @@ class IOU(BaseManager):
|
|||||||
yield from super().close_node(node_id, *args, **kwargs)
|
yield from super().close_node(node_id, *args, **kwargs)
|
||||||
return node
|
return node
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def project_committed(self, project):
|
|
||||||
"""
|
|
||||||
Called when a project has been committed.
|
|
||||||
|
|
||||||
:param project: Project instance
|
|
||||||
"""
|
|
||||||
|
|
||||||
# save the configs when the project is committed
|
|
||||||
for node in self._nodes.copy().values():
|
|
||||||
if node.project.id == project.id:
|
|
||||||
try:
|
|
||||||
node.save_configs()
|
|
||||||
except IOUError as e:
|
|
||||||
log.warning(e)
|
|
||||||
continue
|
|
||||||
|
|
||||||
def get_application_id(self, node_id):
|
def get_application_id(self, node_id):
|
||||||
"""
|
"""
|
||||||
Get an unique application identifier for IOU.
|
Get an unique application identifier for IOU.
|
||||||
|
@ -46,10 +46,10 @@ from ..base_node import BaseNode
|
|||||||
from .utils.iou_import import nvram_import
|
from .utils.iou_import import nvram_import
|
||||||
from .utils.iou_export import nvram_export
|
from .utils.iou_export import nvram_export
|
||||||
from .ioucon import start_ioucon
|
from .ioucon import start_ioucon
|
||||||
|
from gns3server.utils.file_watcher import FileWatcher
|
||||||
import gns3server.utils.asyncio
|
import gns3server.utils.asyncio
|
||||||
import gns3server.utils.images
|
import gns3server.utils.images
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -91,9 +91,17 @@ class IOUVM(BaseNode):
|
|||||||
self._ram = 256 # Megabytes
|
self._ram = 256 # Megabytes
|
||||||
self._l1_keepalives = False # used to overcome the always-up Ethernet interfaces (not supported by all IOSes).
|
self._l1_keepalives = False # used to overcome the always-up Ethernet interfaces (not supported by all IOSes).
|
||||||
|
|
||||||
|
self._nvram_watcher = None
|
||||||
|
|
||||||
def _config(self):
|
def _config(self):
|
||||||
return self._manager.config.get_section_config("IOU")
|
return self._manager.config.get_section_config("IOU")
|
||||||
|
|
||||||
|
def _nvram_changed(self, path):
|
||||||
|
"""
|
||||||
|
Called when the NVRAM file as changed
|
||||||
|
"""
|
||||||
|
self.save_configs()
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def close(self):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
@ -424,6 +432,12 @@ class IOUVM(BaseNode):
|
|||||||
self.iourc_path,
|
self.iourc_path,
|
||||||
hostname))
|
hostname))
|
||||||
|
|
||||||
|
def _nvram_file(self):
|
||||||
|
"""
|
||||||
|
Path to the nvram file
|
||||||
|
"""
|
||||||
|
return os.path.join(self.working_dir, "nvram_{:05d}".format(self.application_id))
|
||||||
|
|
||||||
def _push_configs_to_nvram(self):
|
def _push_configs_to_nvram(self):
|
||||||
"""
|
"""
|
||||||
Push the startup-config and private-config content to the NVRAM.
|
Push the startup-config and private-config content to the NVRAM.
|
||||||
@ -431,7 +445,7 @@ class IOUVM(BaseNode):
|
|||||||
|
|
||||||
startup_config_content = self.startup_config_content
|
startup_config_content = self.startup_config_content
|
||||||
if startup_config_content:
|
if startup_config_content:
|
||||||
nvram_file = os.path.join(self.working_dir, "nvram_{:05d}".format(self.application_id))
|
nvram_file = self._nvram_file()
|
||||||
try:
|
try:
|
||||||
if not os.path.exists(nvram_file):
|
if not os.path.exists(nvram_file):
|
||||||
open(nvram_file, "a").close()
|
open(nvram_file, "a").close()
|
||||||
@ -489,6 +503,8 @@ class IOUVM(BaseNode):
|
|||||||
# check if there is enough RAM to run
|
# check if there is enough RAM to run
|
||||||
self.check_available_ram(self.ram)
|
self.check_available_ram(self.ram)
|
||||||
|
|
||||||
|
self._nvram_watcher = FileWatcher(self._nvram_file(), self._nvram_changed)
|
||||||
|
|
||||||
# created a environment variable pointing to the iourc file.
|
# created a environment variable pointing to the iourc file.
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
|
|
||||||
@ -544,7 +560,7 @@ class IOUVM(BaseNode):
|
|||||||
Before starting the VM, rename the nvram and vlan.dat files with the correct IOU application identifier.
|
Before starting the VM, rename the nvram and vlan.dat files with the correct IOU application identifier.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
destination = os.path.join(self.working_dir, "nvram_{:05d}".format(self.application_id))
|
destination = self._nvram_file()
|
||||||
for file_path in glob.glob(os.path.join(glob.escape(self.working_dir), "nvram_*")):
|
for file_path in glob.glob(os.path.join(glob.escape(self.working_dir), "nvram_*")):
|
||||||
shutil.move(file_path, destination)
|
shutil.move(file_path, destination)
|
||||||
destination = os.path.join(self.working_dir, "vlan.dat-{:05d}".format(self.application_id))
|
destination = os.path.join(self.working_dir, "vlan.dat-{:05d}".format(self.application_id))
|
||||||
@ -644,6 +660,10 @@ class IOUVM(BaseNode):
|
|||||||
Stops the IOU process.
|
Stops the IOU process.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if self._nvram_watcher:
|
||||||
|
self._nvram_watcher.close()
|
||||||
|
self._nvram_watcher = None
|
||||||
|
|
||||||
if self.is_running():
|
if self.is_running():
|
||||||
# stop console support
|
# stop console support
|
||||||
if self._ioucon_thread:
|
if self._ioucon_thread:
|
||||||
|
@ -23,6 +23,7 @@ class FileWatcher:
|
|||||||
"""
|
"""
|
||||||
Watch for file change and call the callback when something happen
|
Watch for file change and call the callback when something happen
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, path, callback, delay=1):
|
def __init__(self, path, callback, delay=1):
|
||||||
if not isinstance(path, str):
|
if not isinstance(path, str):
|
||||||
path = str(path)
|
path = str(path)
|
||||||
@ -32,7 +33,7 @@ class FileWatcher:
|
|||||||
self._closed = False
|
self._closed = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._mtime = os.stat(path).st_mtime
|
self._mtime = os.stat(path).st_mtime_ns
|
||||||
except OSError:
|
except OSError:
|
||||||
self._mtime = None
|
self._mtime = None
|
||||||
asyncio.get_event_loop().call_later(self._delay, self._check_config_file_change)
|
asyncio.get_event_loop().call_later(self._delay, self._check_config_file_change)
|
||||||
@ -48,9 +49,10 @@ class FileWatcher:
|
|||||||
return
|
return
|
||||||
changed = False
|
changed = False
|
||||||
try:
|
try:
|
||||||
if os.stat(self._path).st_mtime != self._mtime:
|
mtime = os.stat(self._path).st_mtime_ns
|
||||||
|
if mtime != self._mtime:
|
||||||
changed = True
|
changed = True
|
||||||
self._mtime = os.stat(self._path).st_mtime
|
self._mtime = mtime
|
||||||
except OSError:
|
except OSError:
|
||||||
self._mtime = None
|
self._mtime = None
|
||||||
if changed:
|
if changed:
|
||||||
@ -64,5 +66,3 @@ class FileWatcher:
|
|||||||
@callback.setter
|
@callback.setter
|
||||||
def callback(self, val):
|
def callback(self, val):
|
||||||
self._callback = val
|
self._callback = val
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,4 +43,3 @@ def test_file_watcher_not_existing(async_run, tmpdir):
|
|||||||
file.write("b")
|
file.write("b")
|
||||||
async_run(asyncio.sleep(1.5))
|
async_run(asyncio.sleep(1.5))
|
||||||
callback.assert_called_with(str(file))
|
callback.assert_called_with(str(file))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user