1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-11-24 17:28:08 +00:00

Lock VMware by VM instead of globally

Ref https://github.com/GNS3/gns3-gui/issues/1632
This commit is contained in:
Julien Duponchelle 2016-11-04 19:39:17 +01:00
parent 7255754fef
commit 0c87d8e1bd
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8
2 changed files with 42 additions and 45 deletions

View File

@ -47,7 +47,6 @@ class VMware(BaseManager):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._execute_lock = asyncio.Lock()
self._vmware_inventory_lock = asyncio.Lock() self._vmware_inventory_lock = asyncio.Lock()
self._vmrun_path = None self._vmrun_path = None
self._host_type = None self._host_type = None
@ -371,34 +370,33 @@ class VMware(BaseManager):
@asyncio.coroutine @asyncio.coroutine
def _execute(self, subcommand, args, timeout=120): def _execute(self, subcommand, args, timeout=120):
with (yield from self._execute_lock): if self.host_type is None:
if self.host_type is None: yield from self.check_vmware_version()
yield from self.check_vmware_version()
vmrun_path = self.vmrun_path vmrun_path = self.vmrun_path
if not vmrun_path: if not vmrun_path:
vmrun_path = self.find_vmrun() vmrun_path = self.find_vmrun()
command = [vmrun_path, "-T", self.host_type, subcommand] command = [vmrun_path, "-T", self.host_type, subcommand]
command.extend(args) command.extend(args)
command_string = " ".join(command) command_string = " ".join(command)
log.info("Executing vmrun with command: {}".format(command_string)) log.info("Executing vmrun with command: {}".format(command_string))
try: try:
process = yield from asyncio.create_subprocess_exec(*command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) process = yield from asyncio.create_subprocess_exec(*command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
except (OSError, subprocess.SubprocessError) as e: except (OSError, subprocess.SubprocessError) as e:
raise VMwareError("Could not execute vmrun: {}".format(e)) raise VMwareError("Could not execute vmrun: {}".format(e))
try: try:
stdout_data, _ = yield from asyncio.wait_for(process.communicate(), timeout=timeout) stdout_data, _ = yield from asyncio.wait_for(process.communicate(), timeout=timeout)
except asyncio.TimeoutError: except asyncio.TimeoutError:
raise VMwareError("vmrun has timed out after {} seconds!\nTry to run {} in a terminal to see more informations.".format(timeout, command_string)) raise VMwareError("vmrun has timed out after {} seconds!\nTry to run {} in a terminal to see more informations.".format(timeout, command_string))
if process.returncode: if process.returncode:
# vmrun print errors on stdout # vmrun print errors on stdout
vmrun_error = stdout_data.decode("utf-8", errors="ignore") vmrun_error = stdout_data.decode("utf-8", errors="ignore")
raise VMwareError("vmrun has returned an error: {}\nTry to run {} in a terminal to see more informations.".format(vmrun_error, command_string)) raise VMwareError("vmrun has returned an error: {}\nTry to run {} in a terminal to see more informations.".format(vmrun_error, command_string))
return stdout_data.decode("utf-8", errors="ignore").splitlines() return stdout_data.decode("utf-8", errors="ignore").splitlines()
@asyncio.coroutine @asyncio.coroutine
def check_vmrun_version(self, minimum_required_version="1.13.0"): def check_vmrun_version(self, minimum_required_version="1.13.0"):
@ -413,26 +411,25 @@ class VMware(BaseManager):
:param required_version: required vmrun version number :param required_version: required vmrun version number
""" """
with (yield from self._execute_lock): vmrun_path = self.vmrun_path
vmrun_path = self.vmrun_path if not vmrun_path:
if not vmrun_path: vmrun_path = self.find_vmrun()
vmrun_path = self.find_vmrun()
try: try:
output = yield from subprocess_check_output(vmrun_path) output = yield from subprocess_check_output(vmrun_path)
match = re.search("vmrun version ([0-9\.]+)", output) match = re.search("vmrun version ([0-9\.]+)", output)
version = None version = None
if match: if match:
version = match.group(1) version = match.group(1)
log.debug("VMware vmrun version {} detected, minimum required: {}".format(version, minimum_required_version)) log.debug("VMware vmrun version {} detected, minimum required: {}".format(version, minimum_required_version))
if parse_version(version) < parse_version(minimum_required_version): if parse_version(version) < parse_version(minimum_required_version):
raise VMwareError("VMware vmrun executable version must be >= version {}".format(minimum_required_version)) raise VMwareError("VMware vmrun executable version must be >= version {}".format(minimum_required_version))
if version is None: if version is None:
log.warning("Could not find VMware vmrun version. Output: {}".format(output)) log.warning("Could not find VMware vmrun version. Output: {}".format(output))
raise VMwareError("Could not find VMware vmrun version. Output: {}".format(output)) raise VMwareError("Could not find VMware vmrun version. Output: {}".format(output))
except (OSError, subprocess.SubprocessError) as e: except (OSError, subprocess.SubprocessError) as e:
log.error("Error while looking for the VMware vmrun version: {}".format(e)) log.error("Error while looking for the VMware vmrun version: {}".format(e))
raise VMwareError("Error while looking for the VMware vmrun version: {}".format(e)) raise VMwareError("Error while looking for the VMware vmrun version: {}".format(e))
@asyncio.coroutine @asyncio.coroutine
def remove_from_vmware_inventory(self, vmx_path): def remove_from_vmware_inventory(self, vmx_path):

View File

@ -27,7 +27,7 @@ import tempfile
from gns3server.utils.telnet_server import TelnetServer from gns3server.utils.telnet_server import TelnetServer
from gns3server.utils.interfaces import interfaces from gns3server.utils.interfaces import interfaces
from gns3server.utils.asyncio import wait_for_file_creation, wait_for_named_pipe_creation from gns3server.utils.asyncio import wait_for_file_creation, wait_for_named_pipe_creation, locked_coroutine
from collections import OrderedDict from collections import OrderedDict
from .vmware_error import VMwareError from .vmware_error import VMwareError
from ..nios.nio_udp import NIOUDP from ..nios.nio_udp import NIOUDP
@ -99,7 +99,7 @@ class VMwareVM(BaseNode):
return self._vmnets return self._vmnets
@asyncio.coroutine @locked_coroutine
def _control_vm(self, subcommand, *additional_args): def _control_vm(self, subcommand, *additional_args):
args = [self._vmx_path] args = [self._vmx_path]