diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py
index 69399a8a..1934b2ff 100644
--- a/gns3server/controller/__init__.py
+++ b/gns3server/controller/__init__.py
@@ -116,7 +116,7 @@ class Controller:
builtins = []
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, "vpcs"), {"node_type": "vpcs", "name": "VPCS", "category": 2, "symbol": ":/symbols/vpcs_guest.svg", "properties": {"base_script_file": "vpcs_base_config.txt"}}, 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))
diff --git a/gns3server/controller/appliance.py b/gns3server/controller/appliance.py
index 9cfb00f0..356ae10e 100644
--- a/gns3server/controller/appliance.py
+++ b/gns3server/controller/appliance.py
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+import copy
import uuid
@@ -54,7 +55,7 @@ class Appliance:
@property
def data(self):
- return self._data
+ return copy.deepcopy(self._data)
@property
def name(self):
diff --git a/gns3server/controller/appliance_template.py b/gns3server/controller/appliance_template.py
index 8b9a3909..de7e98c6 100644
--- a/gns3server/controller/appliance_template.py
+++ b/gns3server/controller/appliance_template.py
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+import copy
import uuid
@@ -43,4 +44,4 @@ class ApplianceTemplate:
"""
Appliance data (a hash)
"""
- return self._data
+ return copy.deepcopy(self._data)
diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py
index d1d8935f..d2b9d7bc 100644
--- a/gns3server/controller/project.py
+++ b/gns3server/controller/project.py
@@ -325,11 +325,12 @@ class Project:
Create a node from an appliance
"""
try:
- template = copy.copy(self.controller.appliances[appliance_id].data)
+ template = self.controller.appliances[appliance_id].data
except KeyError:
msg = "Appliance {} doesn't exist".format(appliance_id)
log.error(msg)
raise aiohttp.web.HTTPNotFound(text=msg)
+ print(template)
template["x"] = x
template["y"] = y
node_type = template.pop("node_type")
diff --git a/tests/controller/test_controller.py b/tests/controller/test_controller.py
index 9eed972b..fcae102f 100644
--- a/tests/controller/test_controller.py
+++ b/tests/controller/test_controller.py
@@ -483,6 +483,7 @@ def test_load_base_files(controller, config, tmpdir):
def test_appliance_templates(controller, async_run):
controller.load_appliances()
assert len(controller.appliance_templates) > 0
+ assert "Alpine Linux" in [c.__json__()["name"] for c in controller.appliance_templates.values()]
def test_load_appliances(controller):
@@ -498,6 +499,11 @@ 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()]
+ assert "VPCS" in [appliance.name for appliance in controller.appliances.values()]
+
+ for appliance in controller.appliances.values():
+ if appliance.name == "VPCS":
+ assert appliance._data["properties"] == {"base_script_file": "vpcs_base_config.txt"}
# UUID should not change when you run again the function
for appliance in controller.appliances.values():
diff --git a/tests/controller/test_project.py b/tests/controller/test_project.py
index c09a9e55..cbafaa51 100644
--- a/tests/controller/test_project.py
+++ b/tests/controller/test_project.py
@@ -193,7 +193,10 @@ def test_add_node_from_appliance(async_run, controller):
"server": "local",
"name": "Test",
"default_name_format": "{name}-{0}",
- "node_type": "vpcs"
+ "node_type": "vpcs",
+ "properties": {
+ "a": 1
+ }
})
controller._computes["local"] = compute
@@ -211,11 +214,22 @@ def test_add_node_from_appliance(async_run, controller):
})
compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
data={'node_id': node.id,
- 'name': 'Test-1'},
+ 'name': 'Test-1',
+ 'a': 1,
+ },
timeout=120)
assert compute in project._project_created_on_compute
controller.notification.emit.assert_any_call("node.created", node.__json__())
+ # Make sure we can call twice the node creation
+ node = async_run(project.add_node_from_appliance("fakeid", x=13, y=12))
+ compute.post.assert_any_call('/projects/{}/vpcs/nodes'.format(project.id),
+ data={'node_id': node.id,
+ 'name': 'Test-2',
+ 'a': 1
+ },
+ timeout=120)
+
def test_delete_node(async_run, controller):
"""