From e8805d3fdc09a858ff300e76867837b3f9fc3b77 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Fri, 26 Jun 2015 14:41:58 +0200 Subject: [PATCH] When a qemu VM crash send the log to the client. Fix #243 --- docs/general.rst | 12 ++++++++++ gns3server/modules/qemu/qemu_vm.py | 3 +++ tests/modules/qemu/test_qemu_vm.py | 37 ++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/docs/general.rst b/docs/general.rst index 9f4bc91c..97fef935 100644 --- a/docs/general.rst +++ b/docs/general.rst @@ -199,3 +199,15 @@ to the nature of the multiple supported VM it's easy for an user to upload and run code on your machine. +Notifications +============= + +You can receive notification from the server if you listen the HTTP stream /notifications. + +The available notification are: +* ping +* vm.created +* vm.started +* vm.stopped +* log.error + diff --git a/gns3server/modules/qemu/qemu_vm.py b/gns3server/modules/qemu/qemu_vm.py index 145a0e29..01dc5de5 100644 --- a/gns3server/modules/qemu/qemu_vm.py +++ b/gns3server/modules/qemu/qemu_vm.py @@ -704,6 +704,7 @@ class QemuVM(BaseVM): self._stdout_file = os.path.join(self.working_dir, "qemu.log") log.info("logging to {}".format(self._stdout_file)) with open(self._stdout_file, "w", encoding="utf-8") as fd: + fd.write("Start QEMU with {}\n\nExecution log:\n".format(command_string)) self._process = yield from asyncio.create_subprocess_exec(*self._command, stdout=fd, stderr=subprocess.STDOUT, @@ -732,6 +733,8 @@ class QemuVM(BaseVM): log.info("QEMU process has stopped, return code: %d", returncode) self.status = "stopped" self._process = None + if returncode != 0: + self.project.emit("log.error", "QEMU process has stopped, return code: {}\n{}".format(returncode, self.read_stdout())) @asyncio.coroutine def stop(self): diff --git a/tests/modules/qemu/test_qemu_vm.py b/tests/modules/qemu/test_qemu_vm.py index 8daaa1a0..55700f22 100644 --- a/tests/modules/qemu/test_qemu_vm.py +++ b/tests/modules/qemu/test_qemu_vm.py @@ -114,6 +114,43 @@ def test_stop(loop, vm, running_subprocess_mock): process.terminate.assert_called_with() +def test_termination_callback(vm): + + vm.status = "started" + queue = vm.project.get_listen_queue() + + vm._termination_callback(0) + assert vm.status == "stopped" + + (action, event) = queue.get_nowait() + assert action == "vm.stopped" + assert event == vm + + with pytest.raises(asyncio.queues.QueueEmpty): + queue.get_nowait() + + +def test_termination_callback_error(vm, tmpdir): + + with open(str(tmpdir / "qemu.log"), "w+") as f: + f.write("BOOMM") + + vm.status = "started" + vm._stdout_file = str(tmpdir / "qemu.log") + queue = vm.project.get_listen_queue() + + vm._termination_callback(1) + assert vm.status == "stopped" + + (action, event) = queue.get_nowait() + assert action == "vm.stopped" + assert event == vm + + (action, event) = queue.get_nowait() + assert action == "log.error" + assert event == "QEMU process has stopped, return code: 1\nBOOMM" + + def test_reload(loop, vm): with asyncio_patch("gns3server.modules.qemu.QemuVM._control_vm") as mock: