diff --git a/gns3server/controller/vm.py b/gns3server/controller/vm.py index c16254d3..80eab9b6 100644 --- a/gns3server/controller/vm.py +++ b/gns3server/controller/vm.py @@ -93,6 +93,7 @@ class VM: Create the VM on the compute Node """ data = self._vm_data() + data["vm_id"] = self._id response = yield from self._compute.post("/projects/{}/{}/vms".format(self._project.id, self._vm_type), data=data) self._parse_vm_response(response) @@ -109,13 +110,17 @@ class VM: :param properties: Emulator specific properties of the VM """ - self._name = name - self._console = console - self._console_type = console_type - self._properties = properties + if name: + self._name = name + if console: + self._console = console + if console_type: + self._console_type = console_type + if properties != {}: + self._properties = properties data = self._vm_data() - response = yield from self._compute.put("/projects/{}/{}/vms".format(self._project.id, self._vm_type), data=data) + response = yield from self.put(None, data=data) self._parse_vm_response(response) def _parse_vm_response(self, response): @@ -125,7 +130,7 @@ class VM: for key, value in response.json.items(): if key == "console": self._console = value - elif key in ["console_type", "name", "vm_id"]: + elif key in ["console_type", "name", "vm_id", "project_id", "vm_directory", "command_line", "status"]: pass else: self._properties[key] = value @@ -135,7 +140,6 @@ class VM: Prepare VM data to send to the remote controller """ data = copy.copy(self._properties) - data["vm_id"] = self._id data["name"] = self._name data["console"] = self._console data["console_type"] = self._console_type @@ -193,17 +197,24 @@ class VM: """ HTTP post on the VM """ - if data: - return (yield from self._compute.put("/projects/{}/{}/vms/{}{}".format(self._project.id, self._vm_type, self._id, path), data=data)) + if path is None: + path = "/projects/{}/{}/vms/{}".format(self._project.id, self._vm_type, self._id) else: - return (yield from self._compute.put("/projects/{}/{}/vms/{}{}".format(self._project.id, self._vm_type, self._id, path))) + path = "/projects/{}/{}/vms/{}{}".format(self._project.id, self._vm_type, self._id, path) + if data: + return (yield from self._compute.put(path, data=data)) + else: + return (yield from self._compute.put(path)) @asyncio.coroutine def delete(self, path=None): """ HTTP post on the VM """ - return (yield from self._compute.delete("/projects/{}/{}/vms/{}{}".format(self._project.id, self._vm_type, self._id, path))) + if path is None: + return (yield from self._compute.delete("/projects/{}/{}/vms/{}".format(self._project.id, self._vm_type, self._id))) + else: + return (yield from self._compute.delete("/projects/{}/{}/vms/{}{}".format(self._project.id, self._vm_type, self._id, path))) def __json__(self): return { diff --git a/gns3server/handlers/api/controller/vm_handler.py b/gns3server/handlers/api/controller/vm_handler.py index c8cdd885..7674a8c3 100644 --- a/gns3server/handlers/api/controller/vm_handler.py +++ b/gns3server/handlers/api/controller/vm_handler.py @@ -16,7 +16,7 @@ # along with this program. If not, see . from ....web.route import Route -from ....schemas.vm import VM_OBJECT_SCHEMA +from ....schemas.vm import VM_OBJECT_SCHEMA, VM_UPDATE_SCHEMA from ....controller.project import Project from ....controller import Controller @@ -56,7 +56,7 @@ class VMHandler: 400: "Invalid request" }, description="Update a VM instance", - input=VM_OBJECT_SCHEMA, + input=VM_UPDATE_SCHEMA, output=VM_OBJECT_SCHEMA) def update(request, response): project = Controller.instance().getProject(request.match_info["project_id"]) diff --git a/gns3server/schemas/vm.py b/gns3server/schemas/vm.py index 89c9c8b5..34f84283 100644 --- a/gns3server/schemas/vm.py +++ b/gns3server/schemas/vm.py @@ -111,3 +111,6 @@ VM_OBJECT_SCHEMA = { "additionalProperties": False, "required": ["name", "vm_type", "compute_id"] } + +VM_UPDATE_SCHEMA = VM_OBJECT_SCHEMA +del VM_UPDATE_SCHEMA["required"] diff --git a/gns3server/schemas/vpcs.py b/gns3server/schemas/vpcs.py index 90008f35..86cc0204 100644 --- a/gns3server/schemas/vpcs.py +++ b/gns3server/schemas/vpcs.py @@ -79,6 +79,10 @@ VPCS_UPDATE_SCHEMA = { "description": "Content of the VPCS startup script", "type": ["string", "null"] }, + "startup_script_path": { + "description": "Path of the VPCS startup script relative to project directory (IGNORED)", + "type": ["string", "null"] + } }, "additionalProperties": False, } diff --git a/tests/controller/test_vm.py b/tests/controller/test_vm.py index 2bf39865..61149057 100644 --- a/tests/controller/test_vm.py +++ b/tests/controller/test_vm.py @@ -91,15 +91,14 @@ def test_update(vm, compute, project, async_run): response.json = {"console": 2048} compute.put = AsyncioMagicMock(return_value=response) - async_run(vm.update(console=2048, console_type="vnc", properties={"startup_script" :"echo test"}, name="demo")) + async_run(vm.update(console=2048, console_type="vnc", properties={"startup_script": "echo test"}, name="demo")) data = { "console": 2048, "console_type": "vnc", - "vm_id": vm.id, "startup_script": "echo test", "name": "demo" } - compute.put.assert_called_with("/projects/{}/vpcs/vms".format(vm.project.id), data=data) + compute.put.assert_called_with("/projects/{}/vpcs/vms/{}".format(vm.project.id, vm.id), data=data) assert vm._console == 2048 assert vm._properties == {"startup_script": "echo test"}