mirror of
https://github.com/GNS3/gns3-server
synced 2024-12-24 15:58:08 +00:00
Merge branch 'master' into unstable
This commit is contained in:
commit
5e3ce48a52
@ -16,6 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import base64
|
||||
|
||||
from ...web.route import Route
|
||||
@ -320,6 +321,14 @@ class DynamipsVMHandler:
|
||||
slot_number = int(request.match_info["adapter_number"])
|
||||
port_number = int(request.match_info["port_number"])
|
||||
pcap_file_path = os.path.join(vm.project.capture_working_directory(), request.json["capture_file_name"])
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
#FIXME: Dynamips (Cygwin actually) doesn't like non ascii paths on Windows
|
||||
try:
|
||||
pcap_file_path.encode('ascii')
|
||||
except UnicodeEncodeError:
|
||||
raise DynamipsError('The capture file path "{}" must only contain ASCII (English) characters'.format(pcap_file_path))
|
||||
|
||||
yield from vm.start_capture(slot_number, port_number, pcap_file_path, request.json["data_link_type"])
|
||||
response.json({"pcap_file_path": pcap_file_path})
|
||||
|
||||
|
@ -240,7 +240,7 @@ class BaseManager:
|
||||
@asyncio.coroutine
|
||||
def close_vm(self, vm_id):
|
||||
"""
|
||||
Delete a VM
|
||||
Close a VM
|
||||
|
||||
:param vm_id: VM identifier
|
||||
|
||||
@ -308,6 +308,7 @@ class BaseManager:
|
||||
|
||||
vm = yield from self.close_vm(vm_id)
|
||||
vm.project.mark_vm_for_destruction(vm)
|
||||
if vm.id in self._vms:
|
||||
del self._vms[vm.id]
|
||||
return vm
|
||||
|
||||
|
@ -357,6 +357,17 @@ class Dynamips(BaseManager):
|
||||
|
||||
return hypervisor
|
||||
|
||||
@asyncio.coroutine
|
||||
def ghost_ios_support(self, vm):
|
||||
|
||||
ghost_ios_support = self.config.get_section_config("Dynamips").getboolean("ghost_ios_support", True)
|
||||
if ghost_ios_support:
|
||||
with (yield from Dynamips._ghost_ios_lock):
|
||||
try:
|
||||
yield from self._set_ghost_ios(vm)
|
||||
except GeneratorExit:
|
||||
log.warning("Could not create ghost IOS image {} (GeneratorExit)".format(vm.name))
|
||||
|
||||
@asyncio.coroutine
|
||||
def create_nio(self, node, nio_settings):
|
||||
"""
|
||||
|
@ -97,7 +97,7 @@ class Qemu(BaseManager):
|
||||
os.access(os.path.join(path, f), os.X_OK) and \
|
||||
os.path.isfile(os.path.join(path, f)):
|
||||
qemu_path = os.path.join(path, f)
|
||||
version = yield from Qemu._get_qemu_version(qemu_path)
|
||||
version = yield from Qemu.get_qemu_version(qemu_path)
|
||||
qemus.append({"path": qemu_path, "version": version})
|
||||
except OSError:
|
||||
continue
|
||||
@ -128,7 +128,7 @@ class Qemu(BaseManager):
|
||||
|
||||
@staticmethod
|
||||
@asyncio.coroutine
|
||||
def _get_qemu_version(qemu_path):
|
||||
def get_qemu_version(qemu_path):
|
||||
"""
|
||||
Gets the Qemu version.
|
||||
|
||||
@ -136,7 +136,20 @@ class Qemu(BaseManager):
|
||||
"""
|
||||
|
||||
if sys.platform.startswith("win"):
|
||||
# Qemu on Windows doesn't return anything with parameter -version
|
||||
# look for a version number in version.txt file in the same directory instead
|
||||
version_file = os.path.join(os.path.dirname(qemu_path), "version.txt")
|
||||
if os.path.isfile(version_file):
|
||||
try:
|
||||
with open(version_file, "rb") as file:
|
||||
version = file.read().decode("utf-8").strip()
|
||||
match = re.search("[0-9\.]+", version)
|
||||
if match:
|
||||
return version
|
||||
except (UnicodeDecodeError, OSError) as e:
|
||||
log.warn("could not read {}: {}".format(version_file, e))
|
||||
return ""
|
||||
else:
|
||||
try:
|
||||
output = yield from subprocess_check_output(qemu_path, "-version")
|
||||
match = re.search("version\s+([0-9a-z\-\.]+)", output)
|
||||
|
@ -30,6 +30,7 @@ import asyncio
|
||||
import socket
|
||||
import gns3server
|
||||
|
||||
from pkg_resources import parse_version
|
||||
from .qemu_error import QemuError
|
||||
from ..adapters.ethernet_adapter import EthernetAdapter
|
||||
from ..nios.nio_udp import NIOUDP
|
||||
@ -1317,10 +1318,19 @@ class QemuVM(BaseVM):
|
||||
|
||||
return options
|
||||
|
||||
@asyncio.coroutine
|
||||
def _network_options(self):
|
||||
|
||||
network_options = []
|
||||
network_options.extend(["-net", "none"]) # we do not want any user networking back-end if no adapter is connected.
|
||||
|
||||
patched_qemu = False
|
||||
if self._legacy_networking:
|
||||
version = yield from self.manager.get_qemu_version(self.qemu_path)
|
||||
if version and parse_version(version) < parse_version("1.1.0"):
|
||||
# this is a patched Qemu if version is below 1.1.0
|
||||
patched_qemu = True
|
||||
|
||||
for adapter_number, adapter in enumerate(self._ethernet_adapters):
|
||||
mac = "%s%02x" % (self._mac_address[:-2], (int(self._mac_address[-2:]) + adapter_number) % 255)
|
||||
nio = adapter.get_nio(0)
|
||||
@ -1329,11 +1339,21 @@ class QemuVM(BaseVM):
|
||||
if nio:
|
||||
network_options.extend(["-net", "nic,vlan={},macaddr={},model={}".format(adapter_number, mac, self._adapter_type)])
|
||||
if isinstance(nio, NIOUDP):
|
||||
if patched_qemu:
|
||||
# use patched Qemu syntax
|
||||
network_options.extend(["-net", "udp,vlan={},name=gns3-{},sport={},dport={},daddr={}".format(adapter_number,
|
||||
adapter_number,
|
||||
nio.lport,
|
||||
nio.rport,
|
||||
nio.rhost)])
|
||||
else:
|
||||
# use UDP tunnel support added in Qemu 1.1.0
|
||||
network_options.extend(["-net", "socket,vlan={},name=gns3-{},udp={}:{},localaddr={}:{}".format(adapter_number,
|
||||
adapter_number,
|
||||
nio.rhost,
|
||||
nio.rport,
|
||||
self._host,
|
||||
nio.lport)])
|
||||
elif isinstance(nio, NIOTAP):
|
||||
network_options.extend(["-net", "tap,name=gns3-{},ifname={}".format(adapter_number, nio.tap_device)])
|
||||
elif isinstance(nio, NIONAT):
|
||||
@ -1407,9 +1427,9 @@ class QemuVM(BaseVM):
|
||||
command.extend(["-enable-kvm"])
|
||||
command.extend(["-boot", "order={}".format(self._boot_priority)])
|
||||
disk_options = yield from self._disk_options()
|
||||
command.extend(disk_options)
|
||||
cdrom_option = self._cdrom_option()
|
||||
command.extend(cdrom_option)
|
||||
command.extend((yield from self._disk_options()))
|
||||
command.extend(self._linux_boot_options())
|
||||
if self._console_type == "telnet":
|
||||
command.extend(self._serial_options())
|
||||
|
@ -308,7 +308,7 @@ class VirtualBoxVM(BaseVM):
|
||||
try:
|
||||
with open(hdd_info_file, "r", encoding="utf-8") as f:
|
||||
hdd_table = json.load(f)
|
||||
except OSError as e:
|
||||
except (ValueError, OSError) as e:
|
||||
raise VirtualBoxError("Could not read HDD info file: {}".format(e))
|
||||
|
||||
for hdd_info in hdd_table:
|
||||
|
@ -40,7 +40,7 @@ def fake_qemu_img_binary(tmpdir):
|
||||
def test_get_qemu_version(loop):
|
||||
|
||||
with asyncio_patch("gns3server.modules.qemu.subprocess_check_output", return_value="QEMU emulator version 2.2.0, Copyright (c) 2003-2008 Fabrice Bellard") as mock:
|
||||
version = loop.run_until_complete(asyncio.async(Qemu._get_qemu_version("/tmp/qemu-test")))
|
||||
version = loop.run_until_complete(asyncio.async(Qemu.get_qemu_version("/tmp/qemu-test")))
|
||||
if sys.platform.startswith("win"):
|
||||
assert version == ""
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user