diff --git a/gns3server/modules/dynamips/__init__.py b/gns3server/modules/dynamips/__init__.py index 8bced160..8a834771 100644 --- a/gns3server/modules/dynamips/__init__.py +++ b/gns3server/modules/dynamips/__init__.py @@ -23,6 +23,7 @@ import sys import os import base64 import tempfile +import shutil from gns3server.modules import IModule import gns3server.jsonrpc as jsonrpc @@ -105,13 +106,12 @@ class Dynamips(IModule): self._hypervisor_manager = None self._hypervisor_manager_settings = {} - self._remote_server = False self._routers = {} self._ethernet_switches = {} self._frame_relay_switches = {} self._atm_switches = {} self._ethernet_hubs = {} - self._projects_dir = os.path.join(kwargs["projects_dir"], "dynamips") + self._projects_dir = kwargs["projects_dir"] self._tempdir = kwargs["temp_dir"] self._working_dir = self._projects_dir self._dynamips = "" @@ -189,7 +189,6 @@ class Dynamips(IModule): self._atm_switches.clear() self._hypervisor_manager = None - self._remote_server = False log.info("dynamips module has been reset") def start_hypervisor_manager(self): @@ -206,18 +205,19 @@ class Dynamips(IModule): raise DynamipsError("Dynamips {} is not executable".format(self._dynamips)) try: - os.makedirs(self._working_dir) + workdir = os.path.join(self._working_dir, "dynamips") + os.makedirs(workdir) except FileExistsError: pass except OSError as e: raise DynamipsError("Could not create working directory {}".format(e)) # 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)) + if not os.access(workdir, os.W_OK): + raise DynamipsError("Cannot write to working directory {}".format(workdir)) - 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, self._host) + log.info("starting the hypervisor manager with Dynamips working directory set to '{}'".format(workdir)) + self._hypervisor_manager = HypervisorManager(self._dynamips, workdir, self._host) for name, value in self._hypervisor_manager_settings.items(): if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value: @@ -244,22 +244,39 @@ class Dynamips(IModule): log.debug("received request {}".format(request)) #TODO: JSON schema validation - # starts the hypervisor manager if it hasn't been started yet if not self._hypervisor_manager: self._dynamips = request.pop("path") if "working_dir" in request: - self._working_dir = os.path.join(request.pop("working_dir"), "dynamips") + self._working_dir = request.pop("working_dir") log.info("this server is local") else: - self._remote_server = True - log.info("this server is remote") self._working_dir = os.path.join(self._projects_dir, request["project_name"]) log.info("this server is remote with working directory path to {}".format(self._working_dir)) self._hypervisor_manager_settings = request else: + if "project_name" in request: + new_working_dir = os.path.join(self._projects_dir, request["project_name"]) + if self._projects_dir != self._working_dir != new_working_dir: + + # trick to avoid file locks by Dynamips on Windows + if sys.platform.startswith("win"): + self._hypervisor_manager.working_dir = tempfile.gettempdir() + + if not os.path.isdir(new_working_dir): + try: + shutil.move(self._working_dir, new_working_dir) + except OSError as e: + log.error("could not move working directory from {} to {}: {}".format(self._working_dir, + new_working_dir, + e)) + return + + self._hypervisor_manager.working_dir = os.path.join(new_working_dir, "dynamips") + self._working_dir = new_working_dir + # apply settings to the hypervisor manager for name, value in request.items(): if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value: diff --git a/gns3server/modules/iou/__init__.py b/gns3server/modules/iou/__init__.py index c67a9ff3..30a0e521 100644 --- a/gns3server/modules/iou/__init__.py +++ b/gns3server/modules/iou/__init__.py @@ -26,6 +26,7 @@ import tempfile import fcntl import struct import socket +import shutil from gns3server.modules import IModule from gns3server.config import Config from .iou_device import IOUDevice @@ -75,7 +76,6 @@ class IOU(IModule): # a new process start when calling IModule IModule.__init__(self, name, *args, **kwargs) - self._remote_server = False self._iou_instances = {} self._console_start_port_range = 4001 self._console_end_port_range = 4512 @@ -84,7 +84,7 @@ class IOU(IModule): self._udp_end_port_range = 40001 self._current_udp_port = self._udp_start_port_range self._host = kwargs["host"] - self._projects_dir = os.path.join(kwargs["projects_dir"], "iou") + self._projects_dir = kwargs["projects_dir"] self._tempdir = kwargs["temp_dir"] self._working_dir = self._projects_dir self._iourc = "" @@ -202,16 +202,26 @@ class IOU(IModule): if "working_dir" in request: new_working_dir = os.path.join(request["working_dir"], "iou") - if self._working_dir != new_working_dir: - self._working_dir = new_working_dir - log.info("this server is local with working directory path to {}".format(self._working_dir)) - for iou_id in self._iou_instances: - iou_instance = self._iou_instances[iou_id] - iou_instance.working_dir = self._working_dir + log.info("this server is local with working directory path to {}".format(new_working_dir)) else: - self._remote_server = True - self._working_dir = os.path.join(self._projects_dir, request["project_name"]) - log.info("this server is remote with working directory path to {}".format(self._working_dir)) + new_working_dir = os.path.join(self._projects_dir, request["project_name"]) + log.info("this server is remote with working directory path to {}".format(new_working_dir)) + if self._projects_dir != self._working_dir != new_working_dir: + if not os.path.isdir(new_working_dir): + try: + shutil.move(self._working_dir, new_working_dir) + except OSError as e: + log.error("could not move working directory from {} to {}: {}".format(self._working_dir, + new_working_dir, + e)) + return + + # update the working directory if it has changed + if self._working_dir != new_working_dir: + self._working_dir = new_working_dir + for iou_id in self._iou_instances: + iou_instance = self._iou_instances[iou_id] + iou_instance.working_dir = self._working_dir if "console_start_port_range" in request and "console_end_port_range" in request: self._console_start_port_range = request["console_start_port_range"] diff --git a/gns3server/modules/iou/iou_device.py b/gns3server/modules/iou/iou_device.py index 0df1e3d3..c96953a7 100644 --- a/gns3server/modules/iou/iou_device.py +++ b/gns3server/modules/iou/iou_device.py @@ -245,7 +245,7 @@ class IOUDevice(object): """ # create our own working directory - working_dir = os.path.join(working_dir, "device-{}".format(self._id)) + working_dir = os.path.join(working_dir, "iou", "device-{}".format(self._id)) try: os.makedirs(working_dir) except FileExistsError: diff --git a/setup.py b/setup.py index 0bb95ed1..45772e4e 100644 --- a/setup.py +++ b/setup.py @@ -45,8 +45,8 @@ setup( description="GNS3 server to asynchronously manage emulators", long_description=open("README.rst", "r").read(), install_requires=[ - "tornado >= 2.0", - "pyzmq", + "tornado >= 3.1", + "pyzmq == 14.0.1", ], entry_points={ "console_scripts": [