diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py index c5f60cfd..850ccec5 100644 --- a/gns3server/compute/base_node.py +++ b/gns3server/compute/base_node.py @@ -105,7 +105,9 @@ class BaseNode: def status(self, status): self._node_status = status - self._project.emit("node.updated", self) + if status in ("started", "stopped", "suspended"): + self.project.emit("node.{status}".format(status=status), {"node_id": self.id}) + self.project.emit("node.updated", self) # FIXME: should we send this when we just start/stop/suspend a node? @property def command_line(self): diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index 5e69abfb..19685cbf 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -505,11 +505,12 @@ class DockerVM(BaseNode): # t=5 number of seconds to wait before killing the container try: yield from self.manager.query("POST", "containers/{}/stop".format(self._cid), params={"t": 5}) - log.info("Docker container '{name}' [{image}] stopped".format( - name=self._name, image=self._image)) + log.info("Docker container '{name}' [{image}] stopped".format(name=self._name, image=self._image)) except DockerHttp304Error: # Container is already stopped pass + finally: + self.status = "stopped" # Ignore runtime error because when closing the server except RuntimeError as e: log.debug("Docker runtime error when closing: {}".format(str(e))) @@ -519,17 +520,15 @@ class DockerVM(BaseNode): def pause(self): """Pauses this Docker container.""" yield from self.manager.query("POST", "containers/{}/pause".format(self._cid)) - log.info("Docker container '{name}' [{image}] paused".format( - name=self._name, image=self._image)) - self.status = "paused" + self.status = "suspended" + log.info("Docker container '{name}' [{image}] paused".format(name=self._name, image=self._image)) @asyncio.coroutine def unpause(self): """Unpauses this Docker container.""" yield from self.manager.query("POST", "containers/{}/unpause".format(self._cid)) - log.info("Docker container '{name}' [{image}] unpaused".format( - name=self._name, image=self._image)) self.status = "started" + log.info("Docker container '{name}' [{image}] unpaused".format(name=self._name, image=self._image)) @asyncio.coroutine def close(self): diff --git a/gns3server/compute/dynamips/nodes/router.py b/gns3server/compute/dynamips/nodes/router.py index e7537dd9..6220e9ac 100644 --- a/gns3server/compute/dynamips/nodes/router.py +++ b/gns3server/compute/dynamips/nodes/router.py @@ -294,6 +294,7 @@ class Router(BaseNode): status = yield from self.get_status() if status == "running": yield from self._hypervisor.send('vm suspend "{name}"'.format(name=self._name)) + self.status = "suspended" log.info('Router "{name}" [{id}] has been suspended'.format(name=self._name, id=self._id)) @asyncio.coroutine diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index 81f85e0c..820a9824 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -1036,6 +1036,7 @@ class QemuVM(BaseNode): raise QemuError("Suspending a QEMU VM is not supported") elif vm_status == "running": yield from self._control_vm("stop") + self.status = "suspended" log.debug("QEMU VM has been suspended") else: log.info("QEMU VM is not running to be suspended, current status is {}".format(vm_status)) diff --git a/gns3server/compute/virtualbox/virtualbox_vm.py b/gns3server/compute/virtualbox/virtualbox_vm.py index b35b3f9f..26fe0c83 100644 --- a/gns3server/compute/virtualbox/virtualbox_vm.py +++ b/gns3server/compute/virtualbox/virtualbox_vm.py @@ -208,6 +208,7 @@ class VirtualBoxVM(BaseNode): if self._headless: args.extend(["--type", "headless"]) result = yield from self.manager.execute("startvm", args) + self.status = "started" log.info("VirtualBox VM '{name}' [{id}] started".format(name=self.name, id=self.id)) log.debug("Start result: {}".format(result)) @@ -243,10 +244,12 @@ class VirtualBoxVM(BaseNode): if self.acpi_shutdown: # use ACPI to shutdown the VM result = yield from self._control_vm("acpipowerbutton") + self.status = "stopped" log.debug("ACPI shutdown result: {}".format(result)) else: # power off the VM result = yield from self._control_vm("poweroff") + self.status = "stopped" log.debug("Stop result: {}".format(result)) log.info("VirtualBox VM '{name}' [{id}] stopped".format(name=self.name, id=self.id)) @@ -273,6 +276,7 @@ class VirtualBoxVM(BaseNode): vm_state = yield from self._get_vm_state() if vm_state == "running": yield from self._control_vm("pause") + self.status = "suspended" log.info("VirtualBox VM '{name}' [{id}] suspended".format(name=self.name, id=self.id)) else: log.warn("VirtualBox VM '{name}' [{id}] cannot be suspended, current state: {state}".format(name=self.name, @@ -286,6 +290,7 @@ class VirtualBoxVM(BaseNode): """ yield from self._control_vm("resume") + self.status = "started" log.info("VirtualBox VM '{name}' [{id}] resumed".format(name=self.name, id=self.id)) @asyncio.coroutine diff --git a/gns3server/compute/vmware/vmware_vm.py b/gns3server/compute/vmware/vmware_vm.py index 63e9e9a5..4c3b5bc9 100644 --- a/gns3server/compute/vmware/vmware_vm.py +++ b/gns3server/compute/vmware/vmware_vm.py @@ -480,6 +480,7 @@ class VMwareVM(BaseNode): self._hw_virtualization = True self._started = True + self.status = "started" log.info("VMware VM '{name}' [{id}] started".format(name=self.name, id=self.id)) @asyncio.coroutine @@ -502,6 +503,7 @@ class VMwareVM(BaseNode): yield from self._control_vm("stop") finally: self._started = False + self.status = "stopped" self._read_vmx_file() if self._use_ubridge: @@ -538,6 +540,7 @@ class VMwareVM(BaseNode): if self.manager.host_type != "ws": raise VMwareError("Pausing a VM is only supported by VMware Workstation") yield from self._control_vm("pause") + self.status = "suspended" log.info("VMware VM '{name}' [{id}] paused".format(name=self.name, id=self.id)) @asyncio.coroutine @@ -549,6 +552,7 @@ class VMwareVM(BaseNode): if self.manager.host_type != "ws": raise VMwareError("Unpausing a VM is only supported by VMware Workstation") yield from self._control_vm("unpause") + self.status = "started" log.info("VMware VM '{name}' [{id}] resumed".format(name=self.name, id=self.id)) @asyncio.coroutine