mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-25 01:38:08 +00:00
Replace iouyap by ubridge to handle IOU connections. Fixes #614.
This commit is contained in:
parent
c271ef8c6a
commit
183f602fc0
@ -21,7 +21,6 @@ order to run an IOU VM.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import signal
|
|
||||||
import socket
|
import socket
|
||||||
import re
|
import re
|
||||||
import asyncio
|
import asyncio
|
||||||
@ -40,12 +39,11 @@ from .iou_error import IOUError
|
|||||||
from ..adapters.ethernet_adapter import EthernetAdapter
|
from ..adapters.ethernet_adapter import EthernetAdapter
|
||||||
from ..adapters.serial_adapter import SerialAdapter
|
from ..adapters.serial_adapter import SerialAdapter
|
||||||
from ..nios.nio_udp import NIOUDP
|
from ..nios.nio_udp import NIOUDP
|
||||||
from ..nios.nio_tap import NIOTAP
|
|
||||||
from ..nios.nio_ethernet import NIOEthernet
|
|
||||||
from ..base_node import BaseNode
|
from ..base_node import BaseNode
|
||||||
from .utils.iou_import import nvram_import
|
from .utils.iou_import import nvram_import
|
||||||
from .utils.iou_export import nvram_export
|
from .utils.iou_export import nvram_export
|
||||||
from .ioucon import start_ioucon
|
from .ioucon import start_ioucon
|
||||||
|
from gns3server.ubridge.ubridge_error import UbridgeError
|
||||||
from gns3server.utils.file_watcher import FileWatcher
|
from gns3server.utils.file_watcher import FileWatcher
|
||||||
import gns3server.utils.asyncio
|
import gns3server.utils.asyncio
|
||||||
import gns3server.utils.images
|
import gns3server.utils.images
|
||||||
@ -72,12 +70,12 @@ class IOUVM(BaseNode):
|
|||||||
|
|
||||||
super().__init__(name, node_id, project, manager, console=console)
|
super().__init__(name, node_id, project, manager, console=console)
|
||||||
|
|
||||||
self._iouyap_process = None
|
|
||||||
self._iou_process = None
|
self._iou_process = None
|
||||||
self._iou_stdout_file = ""
|
self._iou_stdout_file = ""
|
||||||
self._started = False
|
self._started = False
|
||||||
self._path = None
|
self._path = None
|
||||||
self._ioucon_thread = None
|
self._ioucon_thread = None
|
||||||
|
self._nvram_watcher = None
|
||||||
|
|
||||||
# IOU settings
|
# IOU settings
|
||||||
self._ethernet_adapters = []
|
self._ethernet_adapters = []
|
||||||
@ -91,8 +89,6 @@ class IOUVM(BaseNode):
|
|||||||
self._ram = 256 # Megabytes
|
self._ram = 256 # Megabytes
|
||||||
self._l1_keepalives = False # used to overcome the always-up Ethernet interfaces (not supported by all IOSes).
|
self._l1_keepalives = False # used to overcome the always-up Ethernet interfaces (not supported by all IOSes).
|
||||||
|
|
||||||
self._nvram_watcher = None
|
|
||||||
|
|
||||||
def _config(self):
|
def _config(self):
|
||||||
return self._manager.config.get_section_config("IOU")
|
return self._manager.config.get_section_config("IOU")
|
||||||
|
|
||||||
@ -166,7 +162,7 @@ class IOUVM(BaseNode):
|
|||||||
|
|
||||||
def _check_requirements(self):
|
def _check_requirements(self):
|
||||||
"""
|
"""
|
||||||
Checks if IOUYAP executable is available and if image is accessible.
|
Checks the IOU image.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not self._path:
|
if not self._path:
|
||||||
@ -192,16 +188,6 @@ class IOUVM(BaseNode):
|
|||||||
if not os.access(self._path, os.X_OK):
|
if not os.access(self._path, os.X_OK):
|
||||||
raise IOUError("IOU image '{}' is not executable".format(self._path))
|
raise IOUError("IOU image '{}' is not executable".format(self._path))
|
||||||
|
|
||||||
path = self.iouyap_path
|
|
||||||
if not path:
|
|
||||||
raise IOUError("No path to iouyap program has been set")
|
|
||||||
|
|
||||||
if not os.path.isfile(path):
|
|
||||||
raise IOUError("iouyap program '{}' is not accessible".format(path))
|
|
||||||
|
|
||||||
if not os.access(path, os.X_OK):
|
|
||||||
raise IOUError("iouyap program '{}' is not executable".format(path))
|
|
||||||
|
|
||||||
def __json__(self):
|
def __json__(self):
|
||||||
|
|
||||||
iou_vm_info = {"name": self.name,
|
iou_vm_info = {"name": self.name,
|
||||||
@ -227,21 +213,6 @@ class IOUVM(BaseNode):
|
|||||||
iou_vm_info["path"] = self.manager.get_relative_image_path(self.path)
|
iou_vm_info["path"] = self.manager.get_relative_image_path(self.path)
|
||||||
return iou_vm_info
|
return iou_vm_info
|
||||||
|
|
||||||
@property
|
|
||||||
def iouyap_path(self):
|
|
||||||
"""
|
|
||||||
Returns the IOUYAP executable path.
|
|
||||||
|
|
||||||
:returns: path to IOUYAP
|
|
||||||
"""
|
|
||||||
|
|
||||||
search_path = self._config().get("iouyap_path", "iouyap")
|
|
||||||
path = shutil.which(search_path)
|
|
||||||
# shutil.which return None if the path doesn't exists
|
|
||||||
if not path:
|
|
||||||
return search_path
|
|
||||||
return path
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def iourc_path(self):
|
def iourc_path(self):
|
||||||
"""
|
"""
|
||||||
@ -496,9 +467,7 @@ class IOUVM(BaseNode):
|
|||||||
raise IOUError("The iourc path '{}' is not a regular file".format(iourc_path))
|
raise IOUError("The iourc path '{}' is not a regular file".format(iourc_path))
|
||||||
|
|
||||||
yield from self._check_iou_licence()
|
yield from self._check_iou_licence()
|
||||||
iouyap_path = self.iouyap_path
|
yield from self._start_ubridge()
|
||||||
if not iouyap_path or not os.path.isfile(iouyap_path):
|
|
||||||
raise IOUError("iouyap is necessary to start IOU")
|
|
||||||
|
|
||||||
self._create_netmap_config()
|
self._create_netmap_config()
|
||||||
self._push_configs_to_nvram()
|
self._push_configs_to_nvram()
|
||||||
@ -539,8 +508,46 @@ class IOUVM(BaseNode):
|
|||||||
|
|
||||||
# start console support
|
# start console support
|
||||||
self._start_ioucon()
|
self._start_ioucon()
|
||||||
# connections support
|
|
||||||
yield from self._start_iouyap()
|
# configure networking support
|
||||||
|
yield from self._networking()
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def _networking(self):
|
||||||
|
"""
|
||||||
|
Configures the IOL bridge in uBridge.
|
||||||
|
"""
|
||||||
|
|
||||||
|
bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512)
|
||||||
|
try:
|
||||||
|
# delete any previous bridge if it exists
|
||||||
|
yield from self._ubridge_send("iol_bridge delete {name}".format(name=bridge_name))
|
||||||
|
except UbridgeError:
|
||||||
|
pass
|
||||||
|
yield from self._ubridge_send("iol_bridge create {name} {bridge_id}".format(name=bridge_name, bridge_id=self.application_id + 512))
|
||||||
|
|
||||||
|
bay_id = 0
|
||||||
|
for adapter in self._adapters:
|
||||||
|
unit_id = 0
|
||||||
|
for unit in adapter.ports.keys():
|
||||||
|
nio = adapter.get_nio(unit)
|
||||||
|
if nio and isinstance(nio, NIOUDP):
|
||||||
|
yield from self._ubridge_send("iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(name=bridge_name,
|
||||||
|
iol_id=self.application_id,
|
||||||
|
bay=bay_id,
|
||||||
|
unit=unit_id,
|
||||||
|
lport=nio.lport,
|
||||||
|
rhost=nio.rhost,
|
||||||
|
rport=nio.rport))
|
||||||
|
if nio.capturing:
|
||||||
|
yield from self._ubridge_send('iol_bridge start_capture {name} "{output_file}" {data_link_type}'.format(name=bridge_name,
|
||||||
|
output_file=nio.pcap_output_file,
|
||||||
|
data_link_type=nio.pcap_data_link_type))
|
||||||
|
|
||||||
|
unit_id += 1
|
||||||
|
bay_id += 1
|
||||||
|
|
||||||
|
yield from self._ubridge_send("iol_bridge start {name}".format(name=bridge_name))
|
||||||
|
|
||||||
def _termination_callback(self, process_name, returncode):
|
def _termination_callback(self, process_name, returncode):
|
||||||
"""
|
"""
|
||||||
@ -550,12 +557,9 @@ class IOUVM(BaseNode):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
self._terminate_process_iou()
|
self._terminate_process_iou()
|
||||||
self._terminate_process_iouyap()
|
|
||||||
self._ioucon_thread_stop_event.set()
|
self._ioucon_thread_stop_event.set()
|
||||||
|
|
||||||
if returncode != 0:
|
if returncode != 0:
|
||||||
log.info("{} process has stopped, return code: {}".format(process_name, returncode))
|
|
||||||
else:
|
|
||||||
if returncode == 11:
|
if returncode == 11:
|
||||||
message = "{} process has stopped, return code: {}. This could be an issue with the image using a different image can fix the issue.\n{}".format(process_name, returncode, self.read_iou_stdout())
|
message = "{} process has stopped, return code: {}. This could be an issue with the image using a different image can fix the issue.\n{}".format(process_name, returncode, self.read_iou_stdout())
|
||||||
else:
|
else:
|
||||||
@ -575,99 +579,13 @@ class IOUVM(BaseNode):
|
|||||||
for file_path in glob.glob(os.path.join(glob.escape(self.working_dir), "vlan.dat-*")):
|
for file_path in glob.glob(os.path.join(glob.escape(self.working_dir), "vlan.dat-*")):
|
||||||
shutil.move(file_path, destination)
|
shutil.move(file_path, destination)
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def _start_iouyap(self):
|
|
||||||
"""
|
|
||||||
Starts iouyap (handles connections to and from this IOU VM).
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._update_iouyap_config()
|
|
||||||
command = [self.iouyap_path, "-q", str(self.application_id + 512)] # iouyap has always IOU ID + 512
|
|
||||||
log.info("starting iouyap: {}".format(command))
|
|
||||||
self._iouyap_stdout_file = os.path.join(self.working_dir, "iouyap.log")
|
|
||||||
log.info("logging to {}".format(self._iouyap_stdout_file))
|
|
||||||
with open(self._iouyap_stdout_file, "w", encoding="utf-8") as fd:
|
|
||||||
self._iouyap_process = yield from asyncio.create_subprocess_exec(*command,
|
|
||||||
stdout=fd,
|
|
||||||
stderr=subprocess.STDOUT,
|
|
||||||
cwd=self.working_dir)
|
|
||||||
|
|
||||||
callback = functools.partial(self._termination_callback, "iouyap")
|
|
||||||
gns3server.utils.asyncio.monitor_process(self._iouyap_process, callback)
|
|
||||||
log.info("iouyap started PID={}".format(self._iouyap_process.pid))
|
|
||||||
except (OSError, subprocess.SubprocessError) as e:
|
|
||||||
iouyap_stdout = self.read_iouyap_stdout()
|
|
||||||
log.error("Could not start iouyap: {}\n{}".format(e, iouyap_stdout))
|
|
||||||
raise IOUError("Could not start iouyap: {}\n{}".format(e, iouyap_stdout))
|
|
||||||
|
|
||||||
def _update_iouyap_config(self):
|
|
||||||
"""
|
|
||||||
Updates the iouyap.ini file.
|
|
||||||
"""
|
|
||||||
|
|
||||||
iouyap_ini = os.path.join(self.working_dir, "iouyap.ini")
|
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
config["default"] = {"netmap": "NETMAP",
|
|
||||||
"base_port": "49000"}
|
|
||||||
|
|
||||||
bay_id = 0
|
|
||||||
for adapter in self._adapters:
|
|
||||||
unit_id = 0
|
|
||||||
for unit in adapter.ports.keys():
|
|
||||||
nio = adapter.get_nio(unit)
|
|
||||||
if nio:
|
|
||||||
connection = None
|
|
||||||
if isinstance(nio, NIOUDP):
|
|
||||||
# UDP tunnel
|
|
||||||
connection = {"tunnel_udp": "{lport}:{rhost}:{rport}".format(lport=nio.lport,
|
|
||||||
rhost=nio.rhost,
|
|
||||||
rport=nio.rport)}
|
|
||||||
elif isinstance(nio, NIOTAP):
|
|
||||||
# TAP interface
|
|
||||||
connection = {"tap_dev": "{tap_device}".format(tap_device=nio.tap_device)}
|
|
||||||
|
|
||||||
elif isinstance(nio, NIOEthernet):
|
|
||||||
# Ethernet interface
|
|
||||||
connection = {"eth_dev": "{ethernet_device}".format(ethernet_device=nio.ethernet_device)}
|
|
||||||
|
|
||||||
if connection:
|
|
||||||
interface = "{iouyap_id}:{bay}/{unit}".format(iouyap_id=str(self.application_id + 512), bay=bay_id, unit=unit_id)
|
|
||||||
config[interface] = connection
|
|
||||||
|
|
||||||
if nio.capturing:
|
|
||||||
pcap_data_link_type = nio.pcap_data_link_type.upper()
|
|
||||||
if pcap_data_link_type == "DLT_PPP_SERIAL":
|
|
||||||
pcap_protocol = "ppp"
|
|
||||||
elif pcap_data_link_type == "DLT_C_HDLC":
|
|
||||||
pcap_protocol = "hdlc"
|
|
||||||
elif pcap_data_link_type == "DLT_FRELAY":
|
|
||||||
pcap_protocol = "fr"
|
|
||||||
else:
|
|
||||||
pcap_protocol = "ethernet"
|
|
||||||
capture_info = {"pcap_file": "{pcap_file}".format(pcap_file=nio.pcap_output_file),
|
|
||||||
"pcap_protocol": pcap_protocol,
|
|
||||||
"pcap_overwrite": "y"}
|
|
||||||
config[interface].update(capture_info)
|
|
||||||
|
|
||||||
unit_id += 1
|
|
||||||
bay_id += 1
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(iouyap_ini, "w", encoding="utf-8") as config_file:
|
|
||||||
config.write(config_file)
|
|
||||||
log.info("IOU {name} [id={id}]: iouyap.ini updated".format(name=self._name,
|
|
||||||
id=self._id))
|
|
||||||
except OSError as e:
|
|
||||||
raise IOUError("Could not create {}: {}".format(iouyap_ini, e))
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
Stops the IOU process.
|
Stops the IOU process.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
yield from self._stop_ubridge()
|
||||||
if self._nvram_watcher:
|
if self._nvram_watcher:
|
||||||
self._nvram_watcher.close()
|
self._nvram_watcher.close()
|
||||||
self._nvram_watcher = None
|
self._nvram_watcher = None
|
||||||
@ -693,35 +611,9 @@ class IOUVM(BaseNode):
|
|||||||
pass
|
pass
|
||||||
self._iou_process = None
|
self._iou_process = None
|
||||||
|
|
||||||
if self.is_iouyap_running():
|
|
||||||
self._terminate_process_iouyap()
|
|
||||||
try:
|
|
||||||
yield from gns3server.utils.asyncio.wait_for_process_termination(self._iouyap_process, timeout=3)
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
if self._iouyap_process.returncode is None:
|
|
||||||
log.warn("IOUYAP process {} is still running... killing it".format(self._iouyap_process.pid))
|
|
||||||
try:
|
|
||||||
self._iouyap_process.kill()
|
|
||||||
except ProcessLookupError:
|
|
||||||
pass
|
|
||||||
self._iouyap_process = None
|
|
||||||
|
|
||||||
self._started = False
|
self._started = False
|
||||||
self.save_configs()
|
self.save_configs()
|
||||||
|
|
||||||
def _terminate_process_iouyap(self):
|
|
||||||
"""
|
|
||||||
Terminate the IOUYAP process if running.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if self._iouyap_process:
|
|
||||||
log.info('Stopping IOUYAP process for IOU VM "{}" PID={}'.format(self.name, self._iouyap_process.pid))
|
|
||||||
try:
|
|
||||||
self._iouyap_process.terminate()
|
|
||||||
# Sometime the process can already be dead when we garbage collect
|
|
||||||
except ProcessLookupError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _terminate_process_iou(self):
|
def _terminate_process_iou(self):
|
||||||
"""
|
"""
|
||||||
Terminate the IOU process if running
|
Terminate the IOU process if running
|
||||||
@ -757,17 +649,6 @@ class IOUVM(BaseNode):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_iouyap_running(self):
|
|
||||||
"""
|
|
||||||
Checks if the IOUYAP process is running
|
|
||||||
|
|
||||||
:returns: True or False
|
|
||||||
"""
|
|
||||||
|
|
||||||
if self._iouyap_process and self._iouyap_process.returncode is None:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _create_netmap_config(self):
|
def _create_netmap_config(self):
|
||||||
"""
|
"""
|
||||||
Creates the NETMAP file.
|
Creates the NETMAP file.
|
||||||
@ -778,10 +659,10 @@ class IOUVM(BaseNode):
|
|||||||
with open(netmap_path, "w", encoding="utf-8") as f:
|
with open(netmap_path, "w", encoding="utf-8") as f:
|
||||||
for bay in range(0, 16):
|
for bay in range(0, 16):
|
||||||
for unit in range(0, 4):
|
for unit in range(0, 4):
|
||||||
f.write("{iouyap_id}:{bay}/{unit}{iou_id:>5d}:{bay}/{unit}\n".format(iouyap_id=str(self.application_id + 512),
|
f.write("{ubridge_id}:{bay}/{unit}{iou_id:>5d}:{bay}/{unit}\n".format(ubridge_id=str(self.application_id + 512),
|
||||||
bay=bay,
|
bay=bay,
|
||||||
unit=unit,
|
unit=unit,
|
||||||
iou_id=self.application_id))
|
iou_id=self.application_id))
|
||||||
log.info("IOU {name} [id={id}]: NETMAP file created".format(name=self._name,
|
log.info("IOU {name} [id={id}]: NETMAP file created".format(name=self._name,
|
||||||
id=self._id))
|
id=self._id))
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
@ -853,21 +734,6 @@ class IOUVM(BaseNode):
|
|||||||
log.warn("could not read {}: {}".format(self._iou_stdout_file, e))
|
log.warn("could not read {}: {}".format(self._iou_stdout_file, e))
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def read_iouyap_stdout(self):
|
|
||||||
"""
|
|
||||||
Reads the standard output of the iouyap process.
|
|
||||||
Only use when the process has been stopped or has crashed.
|
|
||||||
"""
|
|
||||||
|
|
||||||
output = ""
|
|
||||||
if self._iouyap_stdout_file:
|
|
||||||
try:
|
|
||||||
with open(self._iouyap_stdout_file, "rb") as file:
|
|
||||||
output = file.read().decode("utf-8", errors="replace")
|
|
||||||
except OSError as e:
|
|
||||||
log.warn("could not read {}: {}".format(self._iouyap_stdout_file, e))
|
|
||||||
return output
|
|
||||||
|
|
||||||
def _start_ioucon(self):
|
def _start_ioucon(self):
|
||||||
"""
|
"""
|
||||||
Starts ioucon thread (for console connections).
|
Starts ioucon thread (for console connections).
|
||||||
@ -963,12 +829,16 @@ class IOUVM(BaseNode):
|
|||||||
nio=nio,
|
nio=nio,
|
||||||
adapter_number=adapter_number,
|
adapter_number=adapter_number,
|
||||||
port_number=port_number))
|
port_number=port_number))
|
||||||
if self.is_iouyap_running():
|
|
||||||
self._update_iouyap_config()
|
if self.ubridge and self.ubridge.is_running():
|
||||||
try:
|
bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512)
|
||||||
os.kill(self._iouyap_process.pid, signal.SIGHUP)
|
yield from self._ubridge_send("iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format(name=bridge_name,
|
||||||
except ProcessLookupError:
|
iol_id=self.application_id,
|
||||||
log.error("Could not update iouyap configuration: process (PID={}) not found".format(self._iouyap_process.pid))
|
bay=adapter_number,
|
||||||
|
unit=port_number,
|
||||||
|
lport=nio.lport,
|
||||||
|
rhost=nio.rhost,
|
||||||
|
rport=nio.rport))
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def adapter_remove_nio_binding(self, adapter_number, port_number):
|
def adapter_remove_nio_binding(self, adapter_number, port_number):
|
||||||
@ -999,12 +869,13 @@ class IOUVM(BaseNode):
|
|||||||
nio=nio,
|
nio=nio,
|
||||||
adapter_number=adapter_number,
|
adapter_number=adapter_number,
|
||||||
port_number=port_number))
|
port_number=port_number))
|
||||||
if self.is_iouyap_running():
|
|
||||||
self._update_iouyap_config()
|
if self.ubridge and self.ubridge.is_running():
|
||||||
try:
|
bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512)
|
||||||
os.kill(self._iouyap_process.pid, signal.SIGHUP)
|
yield from self._ubridge_send("iol_bridge delete_nio_udp {name} {bay} {unit}".format(name=bridge_name,
|
||||||
except ProcessLookupError:
|
bay=adapter_number,
|
||||||
log.error("Could not update iouyap configuration: process (PID={}) not found".format(self._iouyap_process.pid))
|
unit=port_number))
|
||||||
|
|
||||||
return nio
|
return nio
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -1292,12 +1163,13 @@ class IOUVM(BaseNode):
|
|||||||
port_number=port_number,
|
port_number=port_number,
|
||||||
output_file=output_file))
|
output_file=output_file))
|
||||||
|
|
||||||
if self.is_iouyap_running():
|
if self.ubridge and self.ubridge.is_running():
|
||||||
self._update_iouyap_config()
|
bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512)
|
||||||
try:
|
yield from self._ubridge_send('iol_bridge start_capture {name} {bay} {unit} "{output_file}" {data_link_type}'.format(name=bridge_name,
|
||||||
os.kill(self._iouyap_process.pid, signal.SIGHUP)
|
bay=adapter_number,
|
||||||
except ProcessLookupError:
|
unit=port_number,
|
||||||
log.error("Could not update iouyap configuration: process (PID={}) not found".format(self._iouyap_process.pid))
|
output_file=output_file,
|
||||||
|
data_link_type=data_link_type))
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def stop_capture(self, adapter_number, port_number):
|
def stop_capture(self, adapter_number, port_number):
|
||||||
@ -1328,9 +1200,8 @@ class IOUVM(BaseNode):
|
|||||||
id=self._id,
|
id=self._id,
|
||||||
adapter_number=adapter_number,
|
adapter_number=adapter_number,
|
||||||
port_number=port_number))
|
port_number=port_number))
|
||||||
if self.is_iouyap_running():
|
if self.ubridge and self.ubridge.is_running():
|
||||||
self._update_iouyap_config()
|
bridge_name = "IOL-BRIDGE-{}".format(self.application_id + 512)
|
||||||
try:
|
yield from self._ubridge_send('iol_bridge stop_capture {name} {bay} {unit}'.format(name=bridge_name,
|
||||||
os.kill(self._iouyap_process.pid, signal.SIGHUP)
|
bay=adapter_number,
|
||||||
except ProcessLookupError:
|
unit=port_number))
|
||||||
log.error("Could not update iouyap configuration: process (PID={}) not found".format(self._iouyap_process.pid))
|
|
||||||
|
@ -76,6 +76,7 @@ class Hypervisor(UBridgeHypervisor):
|
|||||||
self._process = None
|
self._process = None
|
||||||
self._stdout_file = ""
|
self._stdout_file = ""
|
||||||
self._started = False
|
self._started = False
|
||||||
|
self._version = ""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def process(self):
|
def process(self):
|
||||||
@ -117,6 +118,16 @@ class Hypervisor(UBridgeHypervisor):
|
|||||||
|
|
||||||
self._path = path
|
self._path = path
|
||||||
|
|
||||||
|
@property
|
||||||
|
def version(self):
|
||||||
|
"""
|
||||||
|
Returns the uBridge version.
|
||||||
|
|
||||||
|
:returns: string
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self._version
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def _check_ubridge_version(self):
|
def _check_ubridge_version(self):
|
||||||
"""
|
"""
|
||||||
@ -126,9 +137,9 @@ class Hypervisor(UBridgeHypervisor):
|
|||||||
output = yield from subprocess_check_output(self._path, "-v", cwd=self._working_dir)
|
output = yield from subprocess_check_output(self._path, "-v", cwd=self._working_dir)
|
||||||
match = re.search("ubridge version ([0-9a-z\.]+)", output)
|
match = re.search("ubridge version ([0-9a-z\.]+)", output)
|
||||||
if match:
|
if match:
|
||||||
version = match.group(1)
|
self._version = match.group(1)
|
||||||
if parse_version(version) < parse_version("0.9.5"):
|
if parse_version(self._version) < parse_version("0.9.6"):
|
||||||
raise UbridgeError("uBridge executable version must be >= 0.9.5")
|
raise UbridgeError("uBridge executable version must be >= 0.9.6")
|
||||||
else:
|
else:
|
||||||
raise UbridgeError("Could not determine uBridge version for {}".format(self._path))
|
raise UbridgeError("Could not determine uBridge version for {}".format(self._path))
|
||||||
except (OSError, subprocess.SubprocessError) as e:
|
except (OSError, subprocess.SubprocessError) as e:
|
||||||
|
Loading…
Reference in New Issue
Block a user