From c8c991af788cd2397ea36c27f3ab7b27b5595dde Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Mon, 19 Jun 2017 08:47:50 +0200 Subject: [PATCH] Fix the error about appliance ID not found (#1075) * Fix the error about appliance ID not found * Copy appliance data before editing it --- gns3server/controller/__init__.py | 55 ++++++++++----------- gns3server/controller/appliance.py | 6 ++- gns3server/controller/appliance_template.py | 6 ++- tests/controller/test_controller.py | 13 +++++ 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index fede7a3a..f12ad2bc 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -67,61 +67,60 @@ class Controller: def load_appliances(self): self._appliance_templates = {} for file in os.listdir(get_resource('appliances')): - with open(os.path.join(get_resource('appliances'), file), 'r', encoding='utf-8') as f: - appliance = ApplianceTemplate(None, json.load(f)) + path = os.path.join(get_resource('appliances'), file) + appliance_id = uuid.uuid3(uuid.NAMESPACE_URL, path) # Generate the UUID from path to avoid change between reboots + with open(path, 'r', encoding='utf-8') as f: + appliance = ApplianceTemplate(appliance_id, json.load(f)) if appliance.status != 'broken': self._appliance_templates[appliance.id] = appliance self._appliances = {} + vms = [] for vm in self._settings.get("Qemu", {}).get("vms", []): vm["node_type"] = "qemu" - appliance = Appliance(None, vm) - self._appliances[appliance.id] = appliance + vms.append(vm) for vm in self._settings.get("IOU", {}).get("devices", []): vm["node_type"] = "iou" - appliance = Appliance(None, vm) - self._appliances[appliance.id] = appliance + vms.append(vm) for vm in self._settings.get("Docker", {}).get("containers", []): vm["node_type"] = "docker" - appliance = Appliance(None, vm) - self._appliances[appliance.id] = appliance + vms.append(vm) for vm in self._settings.get("Builtin", {}).get("cloud_nodes", []): vm["node_type"] = "cloud" - appliance = Appliance(None, vm) - self._appliances[appliance.id] = appliance + vms.append(vm) for vm in self._settings.get("Builtin", {}).get("ethernet_switches", []): vm["node_type"] = "ethernet_switch" - appliance = Appliance(None, vm) - self._appliances[appliance.id] = appliance + vms.append(vm) for vm in self._settings.get("Builtin", {}).get("ethernet_hubs", []): vm["node_type"] = "ethernet_hub" - appliance = Appliance(None, vm) - self._appliances[appliance.id] = appliance + vms.append(vm) for vm in self._settings.get("Dynamips", {}).get("routers", []): vm["node_type"] = "dynamips" - appliance = Appliance(None, vm) - self._appliances[appliance.id] = appliance + vms.append(vm) for vm in self._settings.get("VMware", {}).get("vms", []): vm["node_type"] = "vmware" - appliance = Appliance(None, vm) - self._appliances[appliance.id] = appliance + vms.append(vm) for vm in self._settings.get("VirtualBox", {}).get("vms", []): vm["node_type"] = "virtualbox" - appliance = Appliance(None, vm) - self._appliances[appliance.id] = appliance + vms.append(vm) for vm in self._settings.get("VPCS", {}).get("nodes", []): vm["node_type"] = "vpcs" - appliance = Appliance(None, vm) + vms.append(vm) + + for vm in vms: + vm.setdefault("appliance_id", str(uuid.uuid4())) + appliance = Appliance(vm["appliance_id"], vm) self._appliances[appliance.id] = appliance + # Add builtins builtins = [] - builtins.append(Appliance(None, {"node_type": "cloud", "name": "Cloud", "category": 2, "symbol": ":/symbols/cloud.svg"}, builtin=True)) - builtins.append(Appliance(None, {"node_type": "nat", "name": "NAT", "category": 2, "symbol": ":/symbols/cloud.svg"}, builtin=True)) - builtins.append(Appliance(None, {"node_type": "vpcs", "name": "VPCS", "category": 2, "symbol": ":/symbols/vpcs_guest.svg"}, builtin=True)) - builtins.append(Appliance(None, {"node_type": "ethernet_switch", "name": "Ethernet switch", "category": 1, "symbol": ":/symbols/ethernet_switch.svg"}, builtin=True)) - builtins.append(Appliance(None, {"node_type": "ethernet_hub", "name": "Ethernet hub", "category": 1, "symbol": ":/symbols/hub.svg"}, builtin=True)) - builtins.append(Appliance(None, {"node_type": "frame_relay_switch", "name": "Frame Relay switch", "category": 1, "symbol": ":/symbols/frame_relay_switch.svg"}, builtin=True)) - builtins.append(Appliance(None, {"node_type": "atm_switch", "name": "ATM switch", "category": 1, "symbol": ":/symbols/atm_switch.svg"}, builtin=True)) + builtins.append(Appliance(uuid.uuid3(uuid.NAMESPACE_DNS, "cloud"), {"node_type": "cloud", "name": "Cloud", "category": 2, "symbol": ":/symbols/cloud.svg"}, builtin=True)) + builtins.append(Appliance(uuid.uuid3(uuid.NAMESPACE_DNS, "nat"), {"node_type": "nat", "name": "NAT", "category": 2, "symbol": ":/symbols/cloud.svg"}, builtin=True)) + builtins.append(Appliance(uuid.uuid3(uuid.NAMESPACE_DNS, "vpcs"), {"node_type": "vpcs", "name": "VPCS", "category": 2, "symbol": ":/symbols/vpcs_guest.svg"}, builtin=True)) + builtins.append(Appliance(uuid.uuid3(uuid.NAMESPACE_DNS, "ethernet_switch"), {"node_type": "ethernet_switch", "name": "Ethernet switch", "category": 1, "symbol": ":/symbols/ethernet_switch.svg"}, builtin=True)) + builtins.append(Appliance(uuid.uuid3(uuid.NAMESPACE_DNS, "ethernet_hub"), {"node_type": "ethernet_hub", "name": "Ethernet hub", "category": 1, "symbol": ":/symbols/hub.svg"}, builtin=True)) + builtins.append(Appliance(uuid.uuid3(uuid.NAMESPACE_DNS, "frame_relay_switch"), {"node_type": "frame_relay_switch", "name": "Frame Relay switch", "category": 1, "symbol": ":/symbols/frame_relay_switch.svg"}, builtin=True)) + builtins.append(Appliance(uuid.uuid3(uuid.NAMESPACE_DNS, "atm_switch"), {"node_type": "atm_switch", "name": "ATM switch", "category": 1, "symbol": ":/symbols/atm_switch.svg"}, builtin=True)) for b in builtins: self._appliances[b.id] = b diff --git a/gns3server/controller/appliance.py b/gns3server/controller/appliance.py index 9e5f1ba2..8960233b 100644 --- a/gns3server/controller/appliance.py +++ b/gns3server/controller/appliance.py @@ -32,9 +32,13 @@ class Appliance: def __init__(self, appliance_id, data, builtin=False): if appliance_id is None: self._id = str(uuid.uuid4()) + elif isinstance(appliance_id, uuid.UUID): + self._id = str(appliance_id) else: self._id = appliance_id - self._data = data + self._data = data.copy() + if "appliance_id" in self._data: + del self._data["appliance_id"] # Version of the gui before 2.1 use linked_base # and the server linked_clone diff --git a/gns3server/controller/appliance_template.py b/gns3server/controller/appliance_template.py index acf66975..8b9a3909 100644 --- a/gns3server/controller/appliance_template.py +++ b/gns3server/controller/appliance_template.py @@ -23,9 +23,13 @@ class ApplianceTemplate: def __init__(self, appliance_id, data): if appliance_id is None: self._id = str(uuid.uuid4()) + elif isinstance(appliance_id, uuid.UUID): + self._id = str(appliance_id) else: self._id = appliance_id - self._data = data + self._data = data.copy() + if "appliance_id" in self._data: + del self._data["appliance_id"] @property def id(self): diff --git a/tests/controller/test_controller.py b/tests/controller/test_controller.py index 7c43c9c0..5f907cdd 100644 --- a/tests/controller/test_controller.py +++ b/tests/controller/test_controller.py @@ -488,3 +488,16 @@ def test_load_appliances(controller): controller.load_appliances() assert "Test" in [appliance.name for appliance in controller.appliances.values()] assert "Cloud" in [appliance.name for appliance in controller.appliances.values()] + + # UUID should not change when you run again the function + for appliance in controller.appliances.values(): + if appliance.name == "Test": + qemu_uuid = appliance.id + elif appliance.name == "Cloud": + cloud_uuid = appliance.id + controller.load_appliances() + for appliance in controller.appliances.values(): + if appliance.name == "Test": + assert qemu_uuid == appliance.id + elif appliance.name == "Cloud": + assert cloud_uuid == appliance.id