mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-24 17:28:08 +00:00
Prevent parallel execution of VBox commands
In theory it should not be a problem. But It's create issues like this one: Fix: https://github.com/GNS3/gns3-gui/issues/261
This commit is contained in:
parent
6ec081c774
commit
e51a129216
@ -41,6 +41,7 @@ class VirtualBox(BaseManager):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._vboxmanage_path = None
|
self._vboxmanage_path = None
|
||||||
|
self._execute_lock = asyncio.Lock()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def vboxmanage_path(self):
|
def vboxmanage_path(self):
|
||||||
@ -82,34 +83,38 @@ class VirtualBox(BaseManager):
|
|||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def execute(self, subcommand, args, timeout=60):
|
def execute(self, subcommand, args, timeout=60):
|
||||||
|
|
||||||
vboxmanage_path = self.vboxmanage_path
|
# We use a lock prevent parallel execution due to strange errors
|
||||||
if not vboxmanage_path:
|
# reported by a user and reproduced by us.
|
||||||
vboxmanage_path = self.find_vboxmanage()
|
# https://github.com/GNS3/gns3-gui/issues/261
|
||||||
command = [vboxmanage_path, "--nologo", subcommand]
|
with (yield from self._execute_lock):
|
||||||
command.extend(args)
|
vboxmanage_path = self.vboxmanage_path
|
||||||
log.debug("Executing VBoxManage with command: {}".format(command))
|
if not vboxmanage_path:
|
||||||
try:
|
vboxmanage_path = self.find_vboxmanage()
|
||||||
vbox_user = self.config.get_section_config("VirtualBox").get("vbox_user")
|
command = [vboxmanage_path, "--nologo", subcommand]
|
||||||
if vbox_user:
|
command.extend(args)
|
||||||
# TODO: test & review this part
|
log.debug("Executing VBoxManage with command: {}".format(command))
|
||||||
sudo_command = "sudo -i -u {}".format(vbox_user) + " ".join(command)
|
try:
|
||||||
process = yield from asyncio.create_subprocess_shell(sudo_command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
vbox_user = self.config.get_section_config("VirtualBox").get("vbox_user")
|
||||||
else:
|
if vbox_user:
|
||||||
process = yield from asyncio.create_subprocess_exec(*command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
# TODO: test & review this part
|
||||||
except (OSError, subprocess.SubprocessError) as e:
|
sudo_command = "sudo -i -u {}".format(vbox_user) + " ".join(command)
|
||||||
raise VirtualBoxError("Could not execute VBoxManage: {}".format(e))
|
process = yield from asyncio.create_subprocess_shell(sudo_command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
||||||
|
else:
|
||||||
|
process = yield from asyncio.create_subprocess_exec(*command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
|
||||||
|
except (OSError, subprocess.SubprocessError) as e:
|
||||||
|
raise VirtualBoxError("Could not execute VBoxManage: {}".format(e))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
stdout_data, stderr_data = yield from asyncio.wait_for(process.communicate(), timeout=timeout)
|
stdout_data, stderr_data = yield from asyncio.wait_for(process.communicate(), timeout=timeout)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
raise VirtualBoxError("VBoxManage has timed out after {} seconds!".format(timeout))
|
raise VirtualBoxError("VBoxManage has timed out after {} seconds!".format(timeout))
|
||||||
|
|
||||||
if process.returncode:
|
if process.returncode:
|
||||||
# only the first line of the output is useful
|
# only the first line of the output is useful
|
||||||
vboxmanage_error = stderr_data.decode("utf-8", errors="ignore")
|
vboxmanage_error = stderr_data.decode("utf-8", errors="ignore")
|
||||||
raise VirtualBoxError("VirtualBox has returned an error: {}".format(vboxmanage_error))
|
raise VirtualBoxError("VirtualBox has returned an error: {}".format(vboxmanage_error))
|
||||||
|
|
||||||
return stdout_data.decode("utf-8", errors="ignore").splitlines()
|
return stdout_data.decode("utf-8", errors="ignore").splitlines()
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def get_list(self):
|
def get_list(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user