Merge branch 'master' into 1.5

This commit is contained in:
Julien Duponchelle committed 2016-02-01 15:47:46 +01:00
commit 03414993dc
12 files changed
+143 -68

No files matched your search

+18 -2
View File
@@ -19,6 +19,7 @@ import aiohttp
import asyncio
import json
import os
import psutil
from ...web.route import Route
from ...schemas.project import PROJECT_OBJECT_SCHEMA, PROJECT_CREATE_SCHEMA, PROJECT_UPDATE_SCHEMA, PROJECT_FILE_LIST_SCHEMA, PROJECT_LIST_SCHEMA
@@ -205,7 +206,7 @@ class ProjectHandler:
queue = project.get_listen_queue()
ProjectHandler._notifications_listening.setdefault(project.id, 0)
ProjectHandler._notifications_listening[project.id] += 1
response.write("{\"action\": \"ping\"}\n".encode("utf-8"))
response.write("{}\n".format(json.dumps(ProjectHandler._getPingMessage())).encode("utf-8"))
while True:
try:
(action, msg) = yield from asyncio.wait_for(queue.get(), 5)
@@ -218,11 +219,26 @@ class ProjectHandler:
except asyncio.futures.CancelledError as e:
break
except asyncio.futures.TimeoutError:
response.write("{\"action\": \"ping\"}\n".encode("utf-8"))
response.write("{}\n".format(json.dumps(ProjectHandler._getPingMessage())).encode("utf-8"))
project.stop_listen_queue(queue)
if project.id in ProjectHandler._notifications_listening:
ProjectHandler._notifications_listening[project.id] -= 1
@classmethod
def _getPingMessage(cls):
"""
The ping message is regulary send to the client to
keep the connection open. We send with it some informations
about server load.
:returns: hash
"""
stats = {}
# Non blocking call in order to get cpu usage. First call will return 0
stats["cpu_usage_percent"] = psutil.cpu_percent(interval=None)
stats["memory_usage_percent"] = psutil.virtual_memory().percent
return {"action": "ping", "event": stats}
@classmethod
@Route.get(
r"/projects/{project_id}/files",
+3 -2
View File
@@ -458,9 +458,10 @@ class Dynamips(BaseManager):
nio = NIOLinuxEthernet(node.hypervisor, ethernet_device)
elif nio_settings["type"] == "nio_tap":
tap_device = nio_settings["tap_device"]
if not is_interface_up(tap_device):
raise aiohttp.web.HTTPConflict(text="TAP interface {} is down".format(tap_device))
nio = NIOTAP(node.hypervisor, tap_device)
if not is_interface_up(tap_device):
# test after the TAP interface has been created (if it doesn't exist yet)
raise aiohttp.web.HTTPConflict(text="TAP interface {} is down".format(tap_device))
elif nio_settings["type"] == "nio_unix":
local_file = nio_settings["local_file"]
remote_file = nio_settings["remote_file"]
+9 -13
View File
@@ -49,21 +49,17 @@ class Qemu(BaseManager):
"""
kvm = []
try:
process = yield from asyncio.create_subprocess_exec("kvm-ok")
yield from process.wait()
except OSError:
if not os.path.exists("/dev/kvm"):
return kvm
if process.returncode == 0:
arch = platform.machine()
if arch == "x86_64":
kvm.append("x86_64")
kvm.append("i386")
elif arch == "i386":
kvm.append("i386")
else:
kvm.append(platform.machine())
arch = platform.machine()
if arch == "x86_64":
kvm.append("x86_64")
kvm.append("i386")
elif arch == "i386":
kvm.append("i386")
else:
kvm.append(platform.machine())
return kvm
@staticmethod
+5 -2
View File
@@ -80,10 +80,12 @@ class QemuVM(BaseVM):
try:
self.qemu_path = qemu_path
except QemuError as e:
# If the binary is not found for topologies 1.4 and later
# search via the platform otherwise use the binary name
if platform:
self.platform = platform
else:
raise e
self.qemu_path = os.path.basename(qemu_path)
else:
self.platform = platform
@@ -694,6 +696,8 @@ class QemuVM(BaseVM):
log.info('QEMU VM "{name}" [{id}] has set the QEMU initrd path to {initrd}'.format(name=self._name,
id=self._id,
initrd=initrd))
if "asa" in initrd:
self.project.emit("log.warning", {"message": "Warning ASA 8 is not officialy supported by GNS3 and Cisco, we recommend to use ASAv. Depending of your hardware this could not work or you could be limited to one instance."})
self._initrd = initrd
@property
@@ -1498,7 +1502,6 @@ class QemuVM(BaseVM):
answer[field] = getattr(self, field)
except AttributeError:
pass
answer["hda_disk_image"] = self.manager.get_relative_image_path(self._hda_disk_image)
answer["hda_disk_image_md5sum"] = md5sum(self._hda_disk_image)
answer["hdb_disk_image"] = self.manager.get_relative_image_path(self._hdb_disk_image)
+37 -1
View File
@@ -48,6 +48,7 @@ class VMware(BaseManager):
super().__init__()
self._execute_lock = asyncio.Lock()
self._vmware_inventory_lock = asyncio.Lock()
self._vmrun_path = None
self._vmnets = []
self._vmnet_start_range = 2
@@ -191,9 +192,11 @@ class VMware(BaseManager):
if int(version) < 6:
raise VMwareError("Using VMware Player requires version 6 or above")
if version is None:
log.warning("Could not find VMware version")
log.warning("Could not find VMware version. Output of VMware: {}".format(output))
raise VMwareError("Could not find VMware version. Output of VMware: {}".format(output))
except (OSError, subprocess.SubprocessError) as e:
log.error("Error while looking for the VMware version: {}".format(e))
raise VMwareError("Error while looking for the VMware version: {}".format(e))
@staticmethod
def _get_vmnet_interfaces_registry():
@@ -355,6 +358,39 @@ class VMware(BaseManager):
return stdout_data.decode("utf-8", errors="ignore").splitlines()
@asyncio.coroutine
def remove_from_vmware_inventory(self, vmx_path):
"""
Removes a linked clone from the VMware inventory file.
:param vmx_path: path of the linked clone VMX file
"""
with (yield from self._vmware_inventory_lock):
inventory_path = self.get_vmware_inventory_path()
if os.path.exists(inventory_path):
try:
inventory_pairs = self.parse_vmware_file(inventory_path)
except OSError as e:
log.warning('Could not read VMware inventory file "{}": {}'.format(inventory_path, e))
return
vmlist_entry = None
for name, value in inventory_pairs.items():
if value == vmx_path:
vmlist_entry = name.split(".", 1)[0]
break
if vmlist_entry is not None:
for name in inventory_pairs.keys():
if name.startswith(vmlist_entry):
del inventory_pairs[name]
try:
self.write_vmware_file(inventory_path, inventory_pairs)
except OSError as e:
raise VMwareError('Could not write VMware inventory file "{}": {}'.format(inventory_path, e))
@staticmethod
def parse_vmware_file(path):
"""
+5 -25
View File
@@ -375,6 +375,8 @@ class VMwareVM(BaseVM):
vnet = "ethernet{}.vnet".format(adapter_number)
if vnet not in self._vmx_pairs:
raise VMwareError("vnet {} not in VMX file".format(vnet))
if not self._ubridge_hypervisor:
raise VMwareError("Cannot start the packet capture: uBridge is not running")
yield from self._ubridge_hypervisor.send('bridge start_capture {name} "{output_file}"'.format(name=vnet,
output_file=output_file))
@@ -389,6 +391,8 @@ class VMwareVM(BaseVM):
vnet = "ethernet{}.vnet".format(adapter_number)
if vnet not in self._vmx_pairs:
raise VMwareError("vnet {} not in VMX file".format(vnet))
if not self._ubridge_hypervisor:
raise VMwareError("Cannot stop the packet capture: uBridge is not running")
yield from self._ubridge_hypervisor.send("bridge stop_capture {name}".format(name=vnet))
def check_hw_virtualization(self):
@@ -560,31 +564,7 @@ class VMwareVM(BaseVM):
pass
if self._linked_clone:
# clean the VMware inventory path from this linked clone
inventory_path = self.manager.get_vmware_inventory_path()
inventory_pairs = {}
if os.path.exists(inventory_path):
try:
inventory_pairs = self.manager.parse_vmware_file(inventory_path)
except OSError as e:
log.warning('Could not read VMware inventory file "{}": {}'.format(inventory_path, e))
return
vmlist_entry = None
for name, value in inventory_pairs.items():
if value == self._vmx_path:
vmlist_entry = name.split(".", 1)[0]
break
if vmlist_entry is not None:
for name in inventory_pairs.keys():
if name.startswith(vmlist_entry):
del inventory_pairs[name]
try:
self.manager.write_vmware_file(inventory_path, inventory_pairs)
except OSError as e:
raise VMwareError('Could not write VMware inventory file "{}": {}'.format(inventory_path, e))
yield from self.manager.remove_from_vmware_inventory(self._vmx_path)
log.info("VirtualBox VM '{name}' [{id}] closed".format(name=self.name, id=self.id))
self._closed = True