From 13f469f9d615f04efe693207c284f45fbad1945f Mon Sep 17 00:00:00 2001 From: grossmj Date: Thu, 8 May 2014 14:20:12 -0600 Subject: [PATCH] Handle local base config path. --- gns3server/builtins/interfaces.py | 1 + gns3server/modules/dynamips/__init__.py | 54 ++++++++++++++++++---- gns3server/modules/dynamips/backends/vm.py | 31 +++++++++---- gns3server/modules/iou/__init__.py | 20 ++++++-- 4 files changed, 84 insertions(+), 22 deletions(-) diff --git a/gns3server/builtins/interfaces.py b/gns3server/builtins/interfaces.py index df270e4a..c84ddadf 100644 --- a/gns3server/builtins/interfaces.py +++ b/gns3server/builtins/interfaces.py @@ -47,6 +47,7 @@ def _get_windows_interfaces(): "description": adapter.NetConnectionID}) return interfaces + def interfaces(handler, request_id, params): """ Builtin destination to return all the network interfaces on this host. diff --git a/gns3server/modules/dynamips/__init__.py b/gns3server/modules/dynamips/__init__.py index 9ed97363..4a8224ef 100644 --- a/gns3server/modules/dynamips/__init__.py +++ b/gns3server/modules/dynamips/__init__.py @@ -430,28 +430,62 @@ class Dynamips(IModule): router.ghost_status = 2 router.ghost_file = ghost_instance - def save_base64config(self, config_base64, router, config_filename): + def create_config_from_file(self, local_base_config, router, destination_config_path): """ - Saves a base64 encoded config (decoded) to a file. + Creates a config file from a local base config - :param config_base64: base64 encoded config + :param local_base_config: path the a local base config :param router: router instance - :param config_filename: file name to save the config + :param destination_config_path: path to the destination config file - :returns: relative path to the config file + :returns: relative path to the created config file """ - config = base64.decodestring(config_base64.encode("utf-8")).decode("utf-8") - config = "!\n" + config.replace("\r", "") - config = config.replace('%h', router.name) - config_dir = os.path.join(router.hypervisor.working_dir, "configs") + log.info("creating config file {} from {}".format(destination_config_path, local_base_config)) + config_path = destination_config_path + config_dir = os.path.dirname(destination_config_path) try: os.makedirs(config_dir) except FileExistsError: pass except OSError as e: raise DynamipsError("Could not create configs directory: {}".format(e)) - config_path = os.path.join(config_dir, config_filename) + + try: + with open(local_base_config, "r") as f: + config = f.read() + with open(config_path, "w") as f: + config = "!\n" + config.replace("\r", "") + config = config.replace('%h', router.name) + f.write(config) + except OSError as e: + raise DynamipsError("Could not save the configuration from {} to {}: {}".format(local_base_config, config_path, e)) + return "configs" + os.sep + os.path.basename(config_path) + + def create_config_from_base64(self, config_base64, router, destination_config_path): + """ + Creates a config file from a base64 encoded config. + + :param config_base64: base64 encoded config + :param router: router instance + :param destination_config_path: path to the destination config file + + :returns: relative path to the created config file + """ + + log.info("creating config file {} from base64".format(destination_config_path)) + config = base64.decodestring(config_base64.encode("utf-8")).decode("utf-8") + config = "!\n" + config.replace("\r", "") + config = config.replace('%h', router.name) + config_dir = os.path.dirname(destination_config_path) + try: + os.makedirs(config_dir) + except FileExistsError: + pass + except OSError as e: + raise DynamipsError("Could not create configs directory: {}".format(e)) + + config_path = destination_config_path try: with open(config_path, "w") as f: log.info("saving startup-config to {}".format(config_path)) diff --git a/gns3server/modules/dynamips/backends/vm.py b/gns3server/modules/dynamips/backends/vm.py index 9059fd20..9b6055ee 100644 --- a/gns3server/modules/dynamips/backends/vm.py +++ b/gns3server/modules/dynamips/backends/vm.py @@ -390,23 +390,36 @@ class VM(object): response = {} try: + startup_config_path = os.path.join(router.hypervisor.working_dir, "configs", "{}.cfg".format(router.name)) + private_config_path = os.path.join(router.hypervisor.working_dir, "configs", "{}-private.cfg".format(router.name)) + # a new startup-config has been pushed if "startup_config_base64" in request: - config_filename = "{}.cfg".format(router.name) # update the request with the new local startup-config path - request["startup_config"] = self.save_base64config(request["startup_config_base64"], router, config_filename) - if "startup_config" in request: - router.set_config(request["startup_config"]) - response["startup_config"] = request["startup_config"] + request["startup_config"] = self.create_config_from_base64(request["startup_config_base64"], router, startup_config_path) # a new private-config has been pushed if "private_config_base64" in request: - config_filename = "{}-private.cfg".format(router.name) # update the request with the new local private-config path - request["private_config"] = self.save_base64config(request["private_config_base64"], router, config_filename) + request["private_config"] = self.create_config_from_base64(request["private_config_base64"], router, private_config_path) + + if "startup_config" in request: + if os.path.isfile(request["startup_config"]) and request["startup_config"] != startup_config_path: + # this is a local file set in the GUI + request["startup_config"] = self.create_config_from_file(request["startup_config"], router, startup_config_path) + router.set_config(request["startup_config"]) + else: + router.set_config(request["startup_config"]) + response["startup_config"] = request["startup_config"] + if "private_config" in request: - router.set_config(router.startup_config, request["private_config"]) - response["private_config"] = request["private_config"] + if os.path.isfile(request["private_config"]) and request["private_config"] != private_config_path: + # this is a local file set in the GUI + request["private_config"] = self.create_config_from_file(request["private_config"], router, private_config_path) + router.set_config(router.startup_config, request["private_config"]) + else: + router.set_config(router.startup_config, request["private_config"]) + response["private_config"] = request["private_config"] except DynamipsError as e: self.send_custom_error(str(e)) diff --git a/gns3server/modules/iou/__init__.py b/gns3server/modules/iou/__init__.py index bc7678d2..334ba4a9 100644 --- a/gns3server/modules/iou/__init__.py +++ b/gns3server/modules/iou/__init__.py @@ -398,13 +398,13 @@ class IOU(IModule): return response = {} + config_path = os.path.join(iou_instance.working_dir, "startup-config") try: - # a new startup-config has been pushed if "startup_config_base64" in request: + # a new startup-config has been pushed config = base64.decodestring(request["startup_config_base64"].encode("utf-8")).decode("utf-8") config = "!\n" + config.replace("\r", "") config = config.replace('%h', iou_instance.name) - config_path = os.path.join(iou_instance.working_dir, "startup-config") try: with open(config_path, "w") as f: log.info("saving startup-config to {}".format(config_path)) @@ -413,7 +413,21 @@ class IOU(IModule): raise IOUError("Could not save the configuration {}: {}".format(config_path, e)) # update the request with the new local startup-config path request["startup_config"] = os.path.basename(config_path) - + elif "startup_config" in request: + if os.path.isfile(request["startup_config"]) and request["startup_config"] != config_path: + # this is a local file set in the GUI + try: + with open(request["startup_config"], "r") as f: + config = f.read() + with open(config_path, "w") as f: + config = "!\n" + config.replace("\r", "") + config = config.replace('%h', iou_instance.name) + f.write(config) + request["startup_config"] = os.path.basename(config_path) + except OSError as e: + raise IOUError("Could not save the configuration from {} to {}: {}".format(request["startup_config"], config_path, e)) + else: + raise IOUError("Startup-config {} could not be found on this server".format(request["startup_config"])) except IOUError as e: self.send_custom_error(str(e)) return