Merge branch '2.1' into 2.2

# Conflicts:
#	gns3server/compute/builtin/nodes/cloud.py
#	gns3server/compute/docker/docker_vm.py
#	gns3server/compute/dynamips/nodes/ethernet_switch.py
#	gns3server/compute/iou/iou_vm.py
#	gns3server/compute/qemu/qemu_vm.py
#	gns3server/compute/virtualbox/virtualbox_vm.py
#	gns3server/compute/vmware/vmware_vm.py
#	gns3server/controller/__init__.py
#	gns3server/version.py
#	gns3server/web/web_server.py
This commit is contained in:
grossmj committed 2018-10-04 15:44:13 +02:00
commit 9de13c570c
36 files changed
+316 -93

No files matched your search

+1 -1
View File
@@ -259,7 +259,7 @@ class Cloud(BaseNode):
try:
output = yield from gns3server.utils.asyncio.subprocess_check_output("networksetup", "-listallhardwareports")
except (FileNotFoundError, subprocess.SubprocessError) as e:
except (OSError, subprocess.SubprocessError) as e:
log.warning("Could not execute networksetup: {}".format(e))
return False
+66 -29
View File
@@ -30,6 +30,7 @@ from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
from gns3server.utils.asyncio.raw_command_server import AsyncioRawCommandServer
from gns3server.utils.asyncio import wait_for_file_creation
from gns3server.utils.asyncio import asyncio_ensure_future
from gns3server.utils.asyncio import monitor_process
from gns3server.utils.get_resource import get_resource
from gns3server.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError
@@ -231,7 +232,10 @@ class DockerVM(BaseNode):
binds = ["{}:/gns3:ro".format(resources)]
# We mount our own etc/network
network_config = self._create_network_config()
try:
network_config = self._create_network_config()
except OSError as e:
raise DockerError("Could not create network config in the container: {}".format(e))
binds.append("{}:/gns3volumes/etc/network:rw".format(network_config))
self._volumes = ["/etc/network"]
@@ -290,11 +294,12 @@ class DockerVM(BaseNode):
try:
image_infos = yield from self._get_image_information()
except DockerHttp404Error:
log.info("Image %s is missing pulling it from docker hub", self._image)
log.info("Image '{}' is missing, pulling it from Docker hub...".format(self._image))
yield from self.pull_image(self._image)
image_infos = yield from self._get_image_information()
if image_infos is None:
raise DockerError("Can't get image informations, please try again.")
if image_infos is None:
raise DockerError("Cannot get information for image '{}', please try again.".format(self._image))
params = {
"Hostname": self._name,
@@ -318,7 +323,10 @@ class DockerVM(BaseNode):
if params["Entrypoint"] is None:
params["Entrypoint"] = []
if self._start_command:
params["Cmd"] = shlex.split(self._start_command)
try:
params["Cmd"] = shlex.split(self._start_command)
except ValueError as e:
raise DockerError("Invalid start command '{}': {}".format(self._start_command, e))
if len(params["Cmd"]) == 0:
params["Cmd"] = image_infos.get("Config", {"Cmd": []})["Cmd"]
if params["Cmd"] is None:
@@ -360,8 +368,7 @@ class DockerVM(BaseNode):
result = yield from self.manager.query("POST", "containers/create", data=params)
self._cid = result['Id']
log.info("Docker container '{name}' [{id}] created".format(
name=self._name, id=self._id))
log.info("Docker container '{name}' [{id}] created".format(name=self._name, id=self._id))
return True
def _format_env(self, variables, env):
@@ -457,16 +464,19 @@ class DockerVM(BaseNode):
@asyncio.coroutine
def _start_aux(self):
"""
Starts an auxiliary console
Start an auxiliary console
"""
# We can not use the API because docker doesn't expose a websocket api for exec
# https://github.com/GNS3/gns3-gui/issues/1039
process = yield from asyncio.subprocess.create_subprocess_exec(
"docker", "exec", "-i", self._cid, "/gns3/bin/busybox", "script", "-qfc", "while true; do TERM=vt100 /gns3/bin/busybox sh; done", "/dev/null",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT,
stdin=asyncio.subprocess.PIPE)
try:
process = yield from asyncio.subprocess.create_subprocess_exec(
"docker", "exec", "-i", self._cid, "/gns3/bin/busybox", "script", "-qfc", "while true; do TERM=vt100 /gns3/bin/busybox sh; done", "/dev/null",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT,
stdin=asyncio.subprocess.PIPE)
except OSError as e:
raise DockerError("Could not start auxiliary console process: {}".format(e))
server = AsyncioTelnetServer(reader=process.stdout, writer=process.stdin, binary=True, echo=True)
try:
self._telnet_servers.append((yield from asyncio.start_server(server.run, self._manager.port_manager.console_host, self.aux)))
@@ -489,21 +499,25 @@ class DockerVM(BaseNode):
for volume in self._volumes:
log.debug("Docker container '{name}' [{image}] fix ownership on {path}".format(
name=self._name, image=self._image, path=volume))
process = yield from asyncio.subprocess.create_subprocess_exec(
"docker",
"exec",
self._cid,
"/gns3/bin/busybox",
"sh",
"-c",
"("
"/gns3/bin/busybox find \"{path}\" -depth -print0"
" | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c '%a:%u:%g:%n' > \"{path}/.gns3_perms\""
")"
" && /gns3/bin/busybox chmod -R u+rX \"{path}\""
" && /gns3/bin/busybox chown {uid}:{gid} -R \"{path}\""
.format(uid=os.getuid(), gid=os.getgid(), path=volume),
)
try:
process = yield from asyncio.subprocess.create_subprocess_exec(
"docker",
"exec",
self._cid,
"/gns3/bin/busybox",
"sh",
"-c",
"("
"/gns3/bin/busybox find \"{path}\" -depth -print0"
" | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c '%a:%u:%g:%n' > \"{path}/.gns3_perms\""
")"
" && /gns3/bin/busybox chmod -R u+rX \"{path}\""
" && /gns3/bin/busybox chown {uid}:{gid} -R \"{path}\""
.format(uid=os.getuid(), gid=os.getgid(), path=volume),
)
except OSError as e:
raise DockerError("Could not fix permissions for {}: {}".format(volume, e))
yield from process.wait()
@asyncio.coroutine
@@ -514,7 +528,7 @@ class DockerVM(BaseNode):
self._display = self._get_free_display_port()
if shutil.which("Xvfb") is None or shutil.which("x11vnc") is None:
raise DockerError("Please install Xvfb and x11vnc before using the VNC support")
raise DockerError("Please install Xvfb and x11vnc before using VNC support")
self._xvfb_process = yield from asyncio.create_subprocess_exec("Xvfb", "-nolisten", "tcp", ":{}".format(self._display), "-screen", "0", self._console_resolution + "x16")
# We pass a port for TCPV6 due to a crash in X11VNC if not here: https://github.com/GNS3/gns3-server/issues/569
self._x11vnc_process = yield from asyncio.create_subprocess_exec("x11vnc", "-forever", "-nopw", "-shared", "-geometry", self._console_resolution, "-display", "WAIT:{}".format(self._display), "-rfbport", str(self.console), "-rfbportv6", str(self.console), "-noncache", "-listen", self._manager.port_manager.console_host)
@@ -522,6 +536,29 @@ class DockerVM(BaseNode):
x11_socket = os.path.join("/tmp/.X11-unix/", "X{}".format(self._display))
yield from wait_for_file_creation(x11_socket)
#monitor_process(self._xvfb_process, self._xvfb_callback)
#monitor_process(self._x11vnc_process, self._x11vnc_callback)
def _xvfb_callback(self, returncode):
"""
Called when the process has stopped.
:param returncode: Process returncode
"""
if returncode != 0:
self.project.emit("log.error", {"message": "The Xvfb process has stopped, return code: {}.".format(returncode)})
def _x11vnc_callback(self, returncode):
"""
Called when the process has stopped.
:param returncode: Process returncode
"""
if returncode != 0:
self.project.emit("log.error", {"message": "The x11vnc process has stopped, return code: {}.".format(returncode)})
@asyncio.coroutine
def _start_http(self):
"""
@@ -87,6 +87,7 @@ class EthernetSwitch(Device):
self._mappings = {}
self._telnet_console = None
self._telnet_shell = None
self._telnet_server = None
self._console = console
self._console_type = console_type
@@ -233,8 +234,9 @@ class EthernetSwitch(Device):
"""
yield from self._telnet.close()
self._telnet_server.close()
if self._telnet_server:
self._telnet_server.close()
for nio in self._nios.values():
if nio:
yield from nio.close()
+2 -2
View File
@@ -369,7 +369,7 @@ class IOUVM(BaseNode):
try:
output = yield from gns3server.utils.asyncio.subprocess_check_output("ldd", self._path)
except (FileNotFoundError, subprocess.SubprocessError) as e:
except (OSError, subprocess.SubprocessError) as e:
log.warning("Could not determine the shared library dependencies for {}: {}".format(self._path, e))
return
@@ -422,7 +422,7 @@ class IOUVM(BaseNode):
hostid = (yield from gns3server.utils.asyncio.subprocess_check_output("hostid")).strip()
except FileNotFoundError as e:
raise IOUError("Could not find hostid: {}".format(e))
except subprocess.SubprocessError as e:
except (OSError, subprocess.SubprocessError) as e:
raise IOUError("Could not execute hostid: {}".format(e))
try:
+1 -1
View File
@@ -23,7 +23,7 @@ import logging
log = logging.getLogger(__name__)
# This ports are disallowed by Chrome and Firefox to avoid issues, we skip them as well
# These ports are disallowed by Chrome and Firefox to avoid issues, we skip them as well
BANNED_PORTS = set((1, 7, 9, 11, 13, 15, 17, 19, 20, 21, 22, 23, 25, 37, 42, 43, 53, 77, 79, 87, 95, 101, 102, 103,
104, 109, 110, 111, 113, 115, 117, 119, 123, 135, 139, 143, 179, 389, 465, 512, 513, 514, 515, 526,
530, 531, 532, 540, 556, 563, 587, 601, 636, 993, 995, 2049, 3659, 4045, 6000, 6665, 6666, 6667,
+2 -2
View File
@@ -194,7 +194,7 @@ class Qemu(BaseManager):
return version
else:
raise QemuError("Could not determine the Qemu version for {}".format(qemu_path))
except subprocess.SubprocessError as e:
except (OSError, subprocess.SubprocessError) as e:
raise QemuError("Error while looking for the Qemu version: {}".format(e))
@staticmethod
@@ -214,7 +214,7 @@ class Qemu(BaseManager):
return version
else:
raise QemuError("Could not determine the Qemu-img version for {}".format(qemu_img_path))
except subprocess.SubprocessError as e:
except (OSError, subprocess.SubprocessError) as e:
raise QemuError("Error while looking for the Qemu-img version: {}".format(e))
@staticmethod
+1 -1
View File
@@ -1101,7 +1101,7 @@ class QemuVM(BaseNode):
if expect in line:
result = line.decode("utf-8").strip()
break
except EOFError as e:
except (ConnectionError, EOFError) as e:
log.warning("Could not read from QEMU monitor: {}".format(e))
writer.close()
return result
@@ -217,6 +217,8 @@ class VirtualBoxVM(BaseNode):
except ET.ParseError:
raise VirtualBoxError("Cannot modify VirtualBox linked nodes file. "
"File {} is corrupted.".format(self._linked_vbox_file()))
except OSError as e:
raise VirtualBoxError("Cannot modify VirtualBox linked nodes file '{}': {}".format(self._linked_vbox_file(), e))
machine = tree.getroot().find("{http://www.virtualbox.org/}Machine")
if machine is not None and machine.get("uuid") != "{" + self.id + "}":
@@ -245,6 +247,7 @@ class VirtualBoxVM(BaseNode):
return True
return False
@locking
@asyncio.coroutine
def start(self):
"""
@@ -949,7 +952,11 @@ class VirtualBoxVM(BaseNode):
"""
if self.console and self.console_type == "telnet":
self._remote_pipe = yield from asyncio_open_serial(self._get_pipe_name())
pipe_name = self._get_pipe_name()
try:
self._remote_pipe = yield from asyncio_open_serial(pipe_name)
except OSError as e:
raise VirtualBoxError("Could not open serial pipe '{}': {}".format(pipe_name, e))
server = AsyncioTelnetServer(reader=self._remote_pipe,
writer=self._remote_pipe,
binary=True,
+6
View File
@@ -150,6 +150,7 @@ class VMware(BaseManager):
VIX 1.13 was the release for Player 6.
VIX 1.14 was the release for Player 7.
VIX 1.15 was the release for Workstation Player 12.
VIX 1.17 was the release for Workstation Player 14.
:param player_version: VMware Player major version.
"""
@@ -163,6 +164,8 @@ class VMware(BaseManager):
yield from self.check_vmrun_version(minimum_required_version="1.14.0")
elif player_version >= 12:
yield from self.check_vmrun_version(minimum_required_version="1.15.0")
elif player_version >= 14:
yield from self.check_vmrun_version(minimum_required_version="1.17.0")
self._host_type = "player"
@asyncio.coroutine
@@ -173,6 +176,7 @@ class VMware(BaseManager):
VIX 1.13 was the release for Workstation 10.
VIX 1.14 was the release for Workstation 11.
VIX 1.15 was the release for Workstation Pro 12.
VIX 1.17 was the release for Workstation Pro 14.
:param ws_version: VMware Workstation major version.
"""
@@ -186,6 +190,8 @@ class VMware(BaseManager):
yield from self.check_vmrun_version(minimum_required_version="1.14.0")
elif ws_version >= 12:
yield from self.check_vmrun_version(minimum_required_version="1.15.0")
elif ws_version >= 14:
yield from self.check_vmrun_version(minimum_required_version="1.17.0")
self._host_type = "ws"
@asyncio.coroutine
+5 -1
View File
@@ -849,7 +849,11 @@ class VMwareVM(BaseNode):
"""
if self.console and self.console_type == "telnet":
self._remote_pipe = yield from asyncio_open_serial(self._get_pipe_name())
pipe_name = self._get_pipe_name()
try:
self._remote_pipe = yield from asyncio_open_serial(self._get_pipe_name())
except OSError as e:
raise VMwareError("Could not open serial pipe '{}': {}".format(pipe_name, e))
server = AsyncioTelnetServer(reader=self._remote_pipe,
writer=self._remote_pipe,
binary=True,
+1 -1
View File
@@ -316,7 +316,7 @@ class VPCSVM(BaseNode):
if sys.platform.startswith("win32"):
try:
self._process.send_signal(signal.CTRL_BREAK_EVENT)
except OSError:
except (SystemError, OSError):
pass
else:
try: