mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-07 03:00:30 +03:00
Merge pull request #2942 from markparonyan/ruff/pr03-fstrings
refactor: use f-strings
This commit is contained in:
commit
65c858d455
@ -166,11 +166,7 @@ class BaseNode:
|
||||
if self._wrap_aux:
|
||||
self._internal_aux_port = self._manager.port_manager.get_free_tcp_port(self._project)
|
||||
|
||||
log.debug(
|
||||
"{module}: {name} [{id}] initialized. Console port {console}".format(
|
||||
module=self.manager.module_name, name=self.name, id=self.id, console=self._console
|
||||
)
|
||||
)
|
||||
log.debug(f"{self.manager.module_name}: {self.name} [{self.id}] initialized. Console port {self._console}")
|
||||
|
||||
def __del__(self):
|
||||
|
||||
@ -255,11 +251,7 @@ class BaseNode:
|
||||
:param new_name: name
|
||||
"""
|
||||
|
||||
log.info(
|
||||
"{module}: {name} [{id}] renamed to {new_name}".format(
|
||||
module=self.manager.module_name, name=self.name, id=self.id, new_name=new_name
|
||||
)
|
||||
)
|
||||
log.info(f"{self.manager.module_name}: {self.name} [{self.id}] renamed to {new_name}")
|
||||
self._name = new_name
|
||||
|
||||
@property
|
||||
@ -332,7 +324,7 @@ class BaseNode:
|
||||
Creates the node.
|
||||
"""
|
||||
|
||||
log.debug("{module}: {name} [{id}] created".format(module=self.manager.module_name, name=self.name, id=self.id))
|
||||
log.debug(f"{self.manager.module_name}: {self.name} [{self.id}] created")
|
||||
|
||||
async def delete(self):
|
||||
"""
|
||||
@ -410,9 +402,7 @@ class BaseNode:
|
||||
if self._closed:
|
||||
return False
|
||||
|
||||
log.debug(
|
||||
"{module}: '{name}' [{id}]: is closing".format(module=self.manager.module_name, name=self.name, id=self.id)
|
||||
)
|
||||
log.debug(f"{self.manager.module_name}: '{self.name}' [{self.id}]: is closing")
|
||||
|
||||
if self._console:
|
||||
self._manager.port_manager.release_tcp_port(self._console, self._project)
|
||||
@ -823,11 +813,7 @@ class BaseNode:
|
||||
else:
|
||||
self._aux = self._manager.port_manager.reserve_tcp_port(aux, self._project)
|
||||
|
||||
log.info(
|
||||
"{module}: '{name}' [{id}]: auxiliary console port set to {port}".format(
|
||||
module=self.manager.module_name, name=self.name, id=self.id, port=aux
|
||||
)
|
||||
)
|
||||
log.info(f"{self.manager.module_name}: '{self.name}' [{self.id}]: auxiliary console port set to {aux}")
|
||||
|
||||
@property
|
||||
def console(self):
|
||||
@ -868,11 +854,7 @@ class BaseNode:
|
||||
else:
|
||||
self._console = self._manager.port_manager.reserve_tcp_port(console, self._project)
|
||||
|
||||
log.info(
|
||||
"{module}: '{name}' [{id}]: console port set to {port}".format(
|
||||
module=self.manager.module_name, name=self.name, id=self.id, port=console
|
||||
)
|
||||
)
|
||||
log.info(f"{self.manager.module_name}: '{self.name}' [{self.id}]: console port set to {console}")
|
||||
|
||||
@property
|
||||
def console_type(self):
|
||||
@ -909,13 +891,7 @@ class BaseNode:
|
||||
|
||||
self._console_type = console_type
|
||||
log.info(
|
||||
"{module}: '{name}' [{id}]: console type set to {console_type} (console port is {console})".format(
|
||||
module=self.manager.module_name,
|
||||
name=self.name,
|
||||
id=self.id,
|
||||
console_type=console_type,
|
||||
console=self.console,
|
||||
)
|
||||
f"{self.manager.module_name}: '{self.name}' [{self.id}]: console type set to {console_type} (console port is {self.console})"
|
||||
)
|
||||
|
||||
@property
|
||||
@ -951,9 +927,7 @@ class BaseNode:
|
||||
|
||||
self._aux_type = aux_type
|
||||
log.info(
|
||||
"{module}: '{name}' [{id}]: console type set to {aux_type} (auxiliary console port is {aux})".format(
|
||||
module=self.manager.module_name, name=self.name, id=self.id, aux_type=aux_type, aux=self.aux
|
||||
)
|
||||
f"{self.manager.module_name}: '{self.name}' [{self.id}]: console type set to {aux_type} (auxiliary console port is {self.aux})"
|
||||
)
|
||||
|
||||
@property
|
||||
@ -1107,23 +1081,15 @@ class BaseNode:
|
||||
raise NodeError("Destination NIO is not UDP")
|
||||
|
||||
await self._ubridge_send(
|
||||
"bridge add_nio_udp {name} {lport} {rhost} {rport}".format(
|
||||
name=bridge_name, lport=source_nio.lport, rhost=source_nio.rhost, rport=source_nio.rport
|
||||
)
|
||||
f"bridge add_nio_udp {bridge_name} {source_nio.lport} {source_nio.rhost} {source_nio.rport}"
|
||||
)
|
||||
|
||||
await self._ubridge_send(
|
||||
"bridge add_nio_udp {name} {lport} {rhost} {rport}".format(
|
||||
name=bridge_name, lport=destination_nio.lport, rhost=destination_nio.rhost, rport=destination_nio.rport
|
||||
)
|
||||
f"bridge add_nio_udp {bridge_name} {destination_nio.lport} {destination_nio.rhost} {destination_nio.rport}"
|
||||
)
|
||||
|
||||
if destination_nio.capturing:
|
||||
await self._ubridge_send(
|
||||
'bridge start_capture {name} "{pcap_file}"'.format(
|
||||
name=bridge_name, pcap_file=destination_nio.pcap_output_file
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f'bridge start_capture {bridge_name} "{destination_nio.pcap_output_file}"')
|
||||
|
||||
await self._ubridge_send(f"bridge start {bridge_name}")
|
||||
await self._ubridge_apply_filters(bridge_name, destination_nio.filters)
|
||||
@ -1237,7 +1203,7 @@ class BaseNode:
|
||||
# so allow up to 48 here.
|
||||
if not _MARKER_NAME_RE.match(name) or len(name) > 48:
|
||||
raise UbridgeError(f"Invalid marker name: {name!r}")
|
||||
cmd = 'bridge add_packet_filter {bridge} {name} mark "{bpf}"'.format(bridge=bridge_name, name=name, bpf=bpf)
|
||||
cmd = f'bridge add_packet_filter {bridge_name} {name} mark "{bpf}"'
|
||||
if tag is not None:
|
||||
cmd += f" tag {tag}"
|
||||
# Per-link attribution (contract §3.2): when one ubridge bridge serves
|
||||
@ -1250,7 +1216,7 @@ class BaseNode:
|
||||
linktype = self._marker_linktype(data_link_type)
|
||||
if linktype is not None:
|
||||
cmd += f" linktype {linktype}"
|
||||
cmd += ' pcap "{path}"'.format(path=pcap_path)
|
||||
cmd += f' pcap "{pcap_path}"'
|
||||
# Let BPF compile errors propagate — the marker is the user's intent, so a
|
||||
# bad expression must surface instead of being silently dropped.
|
||||
await self._ubridge_send(cmd)
|
||||
@ -1483,22 +1449,16 @@ class BaseNode:
|
||||
|
||||
if sys.platform.startswith("linux") and block_host_traffic is False:
|
||||
# on Linux we use RAW sockets by default excepting if host traffic must be blocked
|
||||
await self._ubridge_send(
|
||||
'bridge add_nio_linux_raw {name} "{interface}"'.format(name=bridge_name, interface=ethernet_interface)
|
||||
)
|
||||
await self._ubridge_send(f'bridge add_nio_linux_raw {bridge_name} "{ethernet_interface}"')
|
||||
else:
|
||||
# on other platforms we just rely on the pcap library
|
||||
await self._ubridge_send(
|
||||
'bridge add_nio_ethernet {name} "{interface}"'.format(name=bridge_name, interface=ethernet_interface)
|
||||
)
|
||||
await self._ubridge_send(f'bridge add_nio_ethernet {bridge_name} "{ethernet_interface}"')
|
||||
source_mac = None
|
||||
for interface in interfaces():
|
||||
if interface["name"] == ethernet_interface:
|
||||
source_mac = interface["mac_address"]
|
||||
if source_mac:
|
||||
await self._ubridge_send(
|
||||
'bridge set_pcap_filter {name} "not ether src {mac}"'.format(name=bridge_name, mac=source_mac)
|
||||
)
|
||||
await self._ubridge_send(f'bridge set_pcap_filter {bridge_name} "not ether src {source_mac}"')
|
||||
log.info(f"PCAP filter applied on '{ethernet_interface}' for source MAC {source_mac}")
|
||||
|
||||
def _create_local_udp_tunnel(self):
|
||||
@ -1516,9 +1476,7 @@ class BaseNode:
|
||||
source_nio = self.manager.create_nio(source_nio_settings)
|
||||
destination_nio = self.manager.create_nio(destination_nio_settings)
|
||||
log.info(
|
||||
"{module}: '{name}' [{id}]:local UDP tunnel created between port {port1} and {port2}".format(
|
||||
module=self.manager.module_name, name=self.name, id=self.id, port1=lport, port2=rport
|
||||
)
|
||||
f"{self.manager.module_name}: '{self.name}' [{self.id}]:local UDP tunnel created between port {lport} and {rport}"
|
||||
)
|
||||
return source_nio, destination_nio
|
||||
|
||||
@ -1542,9 +1500,7 @@ class BaseNode:
|
||||
available_ram = int(psutil.virtual_memory().available / (1024 * 1024))
|
||||
percentage_left = 100 - psutil.virtual_memory().percent
|
||||
if requested_ram > available_ram:
|
||||
message = '"{}" requires {}MB of RAM to run but there is only {}MB - {}% of RAM left on "{}"'.format(
|
||||
self.name, requested_ram, available_ram, percentage_left, platform.node()
|
||||
)
|
||||
message = f'"{self.name}" requires {requested_ram}MB of RAM to run but there is only {available_ram}MB - {percentage_left}% of RAM left on "{platform.node()}"'
|
||||
self.project.emit("log.warning", {"message": message})
|
||||
|
||||
def _get_custom_adapter_settings(self, adapter_number):
|
||||
|
||||
@ -298,19 +298,13 @@ class Cloud(BaseNode):
|
||||
break
|
||||
|
||||
if not port_info:
|
||||
raise NodeError(
|
||||
"Port {port_number} doesn't exist on cloud '{name}'".format(name=self.name, port_number=port_number)
|
||||
)
|
||||
raise NodeError(f"Port {port_number} doesn't exist on cloud '{self.name}'")
|
||||
|
||||
bridge_name = f"{self._id}-{port_number}"
|
||||
await self._ubridge_send(f"bridge create {bridge_name}")
|
||||
if not isinstance(nio, NIOUDP):
|
||||
raise NodeError("Source NIO is not UDP")
|
||||
await self._ubridge_send(
|
||||
"bridge add_nio_udp {name} {lport} {rhost} {rport}".format(
|
||||
name=bridge_name, lport=nio.lport, rhost=nio.rhost, rport=nio.rport
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f"bridge add_nio_udp {bridge_name} {nio.lport} {nio.rhost} {nio.rport}")
|
||||
|
||||
await self._ubridge_apply_filters(bridge_name, nio.filters)
|
||||
await self._ubridge_apply_markers(bridge_name, nio)
|
||||
@ -347,9 +341,7 @@ class Cloud(BaseNode):
|
||||
)
|
||||
|
||||
if nio.capturing:
|
||||
await self._ubridge_send(
|
||||
'bridge start_capture {name} "{pcap_file}"'.format(name=bridge_name, pcap_file=nio.pcap_output_file)
|
||||
)
|
||||
await self._ubridge_send(f'bridge start_capture {bridge_name} "{nio.pcap_output_file}"')
|
||||
|
||||
await self._ubridge_send(f"bridge start {bridge_name}")
|
||||
|
||||
@ -370,14 +362,10 @@ class Cloud(BaseNode):
|
||||
break
|
||||
i += 1
|
||||
|
||||
await self._ubridge_send(
|
||||
'bridge add_nio_tap "{name}" "{interface}"'.format(name=bridge_name, interface=tap)
|
||||
)
|
||||
await self._ubridge_send('brctl addif "{interface}" "{tap}"'.format(tap=tap, interface=interface))
|
||||
await self._ubridge_send(f'bridge add_nio_tap "{bridge_name}" "{tap}"')
|
||||
await self._ubridge_send(f'brctl addif "{interface}" "{tap}"')
|
||||
else:
|
||||
await self._ubridge_send(
|
||||
'bridge add_nio_linux_raw {name} "{interface}"'.format(name=bridge_name, interface=interface)
|
||||
)
|
||||
await self._ubridge_send(f'bridge add_nio_linux_raw {bridge_name} "{interface}"')
|
||||
|
||||
async def _add_osx_ethernet(self, port_info, bridge_name):
|
||||
"""
|
||||
@ -423,17 +411,13 @@ class Cloud(BaseNode):
|
||||
if port_number in self._nios:
|
||||
raise NodeError(f"Port {port_number} isn't free")
|
||||
|
||||
log.debug(
|
||||
'Cloud "{name}" [{id}]: NIO {nio} bound to port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Cloud "{self._name}" [{self._id}]: NIO {nio} bound to port {port_number}')
|
||||
try:
|
||||
await self.start()
|
||||
await self._add_ubridge_connection(nio, port_number)
|
||||
self._nios[port_number] = nio
|
||||
except (NodeError, UbridgeError) as e:
|
||||
log.error('Cannot add NIO on cloud "{name}": {error}'.format(name=self._name, error=e))
|
||||
log.error(f'Cannot add NIO on cloud "{self._name}": {e}')
|
||||
await self._stop_ubridge()
|
||||
self.status = "stopped"
|
||||
self._nios[port_number] = nio
|
||||
@ -479,11 +463,7 @@ class Cloud(BaseNode):
|
||||
if isinstance(nio, NIOUDP):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
|
||||
log.debug(
|
||||
'Cloud "{name}" [{id}]: NIO {nio} removed from port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Cloud "{self._name}" [{self._id}]: NIO {nio} removed from port {port_number}')
|
||||
|
||||
del self._nios[port_number]
|
||||
if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running():
|
||||
@ -501,9 +481,7 @@ class Cloud(BaseNode):
|
||||
"""
|
||||
|
||||
if not [port["port_number"] for port in self._ports_mapping if port_number == port["port_number"]]:
|
||||
raise NodeError(
|
||||
"Port {port_number} doesn't exist on cloud '{name}'".format(name=self.name, port_number=port_number)
|
||||
)
|
||||
raise NodeError(f"Port {port_number} doesn't exist on cloud '{self.name}'")
|
||||
|
||||
if port_number not in self._nios:
|
||||
raise NodeError(f"Port {port_number} is not connected")
|
||||
@ -526,14 +504,8 @@ class Cloud(BaseNode):
|
||||
raise NodeError(f"Packet capture is already activated on port {port_number}")
|
||||
nio.start_packet_capture(output_file)
|
||||
bridge_name = f"{self._id}-{port_number}"
|
||||
await self._ubridge_send(
|
||||
'bridge start_capture {name} "{output_file}"'.format(name=bridge_name, output_file=output_file)
|
||||
)
|
||||
log.debug(
|
||||
"Cloud '{name}' [{id}]: starting packet capture on port {port_number}".format(
|
||||
name=self.name, id=self.id, port_number=port_number
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f'bridge start_capture {bridge_name} "{output_file}"')
|
||||
log.debug(f"Cloud '{self.name}' [{self.id}]: starting packet capture on port {port_number}")
|
||||
|
||||
async def stop_capture(self, port_number):
|
||||
"""
|
||||
@ -549,8 +521,4 @@ class Cloud(BaseNode):
|
||||
bridge_name = f"{self._id}-{port_number}"
|
||||
await self._ubridge_send(f"bridge stop_capture {bridge_name}")
|
||||
|
||||
log.debug(
|
||||
"Cloud'{name}' [{id}]: stopping packet capture on port {port_number}".format(
|
||||
name=self.name, id=self.id, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f"Cloud'{self.name}' [{self.id}]: stopping packet capture on port {port_number}")
|
||||
|
||||
@ -310,17 +310,13 @@ class EthernetSwitch(BaseNode):
|
||||
if not isinstance(nio, NIOUDP):
|
||||
raise NodeError("Ethernet switch ports only support UDP NIOs")
|
||||
|
||||
log.debug(
|
||||
'Ethernet switch "{name}" [{id}]: NIO {nio} bound to port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Ethernet switch "{self._name}" [{self._id}]: NIO {nio} bound to port {port_number}')
|
||||
try:
|
||||
await self.start()
|
||||
await self._add_ubridge_connection(nio, port_number)
|
||||
self._nios[port_number] = nio
|
||||
except (NodeError, UbridgeError) as e:
|
||||
log.error('Cannot add NIO on Ethernet switch "{name}": {error}'.format(name=self._name, error=e))
|
||||
log.error(f'Cannot add NIO on Ethernet switch "{self._name}": {e}')
|
||||
await self._stop_ubridge()
|
||||
self.status = "stopped"
|
||||
self._nios[port_number] = nio
|
||||
@ -347,19 +343,11 @@ class EthernetSwitch(BaseNode):
|
||||
# VLAN membership for this port's access/trunk/qinq mode
|
||||
await self._apply_port_vlan(port_settings, tap)
|
||||
# GNS3 link endpoint
|
||||
await self._ubridge_send(
|
||||
"bridge add_nio_udp {name} {lport} {rhost} {rport}".format(
|
||||
name=ubridge_bridge, lport=nio.lport, rhost=nio.rhost, rport=nio.rport
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f"bridge add_nio_udp {ubridge_bridge} {nio.lport} {nio.rhost} {nio.rport}")
|
||||
await self._ubridge_apply_filters(ubridge_bridge, nio.filters)
|
||||
await self._ubridge_apply_markers(ubridge_bridge, nio)
|
||||
if nio.capturing:
|
||||
await self._ubridge_send(
|
||||
'bridge start_capture {name} "{output_file}"'.format(
|
||||
name=ubridge_bridge, output_file=nio.pcap_output_file
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f'bridge start_capture {ubridge_bridge} "{nio.pcap_output_file}"')
|
||||
await self._ubridge_send(f"bridge start {ubridge_bridge}")
|
||||
self._tap_by_port[port_number] = tap
|
||||
|
||||
@ -397,11 +385,7 @@ class EthernetSwitch(BaseNode):
|
||||
if isinstance(nio, NIOUDP):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
|
||||
log.debug(
|
||||
'Ethernet switch "{name}" [{id}]: NIO {nio} removed from port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Ethernet switch "{self._name}" [{self._id}]: NIO {nio} removed from port {port_number}')
|
||||
del self._nios[port_number]
|
||||
if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running():
|
||||
await self._delete_ubridge_connection(port_number)
|
||||
@ -512,11 +496,7 @@ class EthernetSwitch(BaseNode):
|
||||
if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running():
|
||||
ubridge_bridge = self._ubridge_bridge_name(port_number)
|
||||
await self._ubridge_send(f'bridge start_capture {ubridge_bridge} "{output_file}"')
|
||||
log.debug(
|
||||
'Ethernet switch "{name}" [{id}]: starting packet capture on port {port}'.format(
|
||||
name=self.name, id=self.id, port=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Ethernet switch "{self.name}" [{self.id}]: starting packet capture on port {port_number}')
|
||||
|
||||
async def stop_capture(self, port_number):
|
||||
"""
|
||||
@ -532,8 +512,4 @@ class EthernetSwitch(BaseNode):
|
||||
if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running():
|
||||
ubridge_bridge = self._ubridge_bridge_name(port_number)
|
||||
await self._ubridge_send(f"bridge stop_capture {ubridge_bridge}")
|
||||
log.debug(
|
||||
'Ethernet switch "{name}" [{id}]: stopping packet capture on port {port}'.format(
|
||||
name=self.name, id=self.id, port=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Ethernet switch "{self.name}" [{self.id}]: stopping packet capture on port {port_number}')
|
||||
|
||||
@ -44,8 +44,8 @@ class Nat(Cloud):
|
||||
nat_interface = "virbr0"
|
||||
if allowed_interfaces and nat_interface not in allowed_interfaces:
|
||||
raise NodeError(
|
||||
"NAT interface {} is not allowed be used on this server. "
|
||||
"Please check the server configuration file.".format(nat_interface)
|
||||
f"NAT interface {nat_interface} is not allowed be used on this server. "
|
||||
"Please check the server configuration file."
|
||||
)
|
||||
if nat_interface not in [interface["name"] for interface in gns3server.utils.interfaces.interfaces()]:
|
||||
raise NodeError(f"NAT interface {nat_interface} is missing, please install libvirt")
|
||||
@ -56,8 +56,8 @@ class Nat(Cloud):
|
||||
nat_interface = "vmnet8"
|
||||
if allowed_interfaces and nat_interface not in allowed_interfaces:
|
||||
raise NodeError(
|
||||
"NAT interface {} is not allowed be used on this server. "
|
||||
"Please check the server configuration file.".format(nat_interface)
|
||||
f"NAT interface {nat_interface} is not allowed be used on this server. "
|
||||
"Please check the server configuration file."
|
||||
)
|
||||
interfaces = list(
|
||||
filter(
|
||||
|
||||
@ -178,9 +178,9 @@ class Docker(BaseManager):
|
||||
else:
|
||||
# use the Min API version supported by the daemon
|
||||
self._api_version = docker_info["MinAPIVersion"]
|
||||
log.warning("Using Docker client with the minimum API version {}".format(self._api_version))
|
||||
log.warning(f"Using Docker client with the minimum API version {self._api_version}")
|
||||
|
||||
log.info("Connected to Docker daemon version {} using API version {}".format(version, self._api_version))
|
||||
log.info(f"Connected to Docker daemon version {version} using API version {self._api_version}")
|
||||
self._check_host_readiness()
|
||||
|
||||
def _check_host_readiness(self):
|
||||
|
||||
@ -177,11 +177,7 @@ class DockerVM(BaseNode):
|
||||
|
||||
self.mac_address = mac_address
|
||||
|
||||
log.debug(
|
||||
"{module}: {name} [{image}] initialized.".format(
|
||||
module=self.manager.module_name, name=self.name, image=self._image
|
||||
)
|
||||
)
|
||||
log.debug(f"{self.manager.module_name}: {self.name} [{self._image}] initialized.")
|
||||
|
||||
def asdict(self):
|
||||
return {
|
||||
@ -251,7 +247,7 @@ class DockerVM(BaseNode):
|
||||
Container name in Docker
|
||||
"""
|
||||
|
||||
return "GNS3.{}.{}".format(self.name, self._project.id)
|
||||
return f"GNS3.{self.name}.{self._project.id}"
|
||||
|
||||
@property
|
||||
def mac_address(self):
|
||||
@ -273,15 +269,11 @@ class DockerVM(BaseNode):
|
||||
|
||||
if not mac_address:
|
||||
# use the node UUID to generate a random MAC address
|
||||
self._mac_address = "02:42:{}:{}:{}:00".format(self.id[2:4], self.id[4:6], self.id[6:8])
|
||||
self._mac_address = f"02:42:{self.id[2:4]}:{self.id[4:6]}:{self.id[6:8]}:00"
|
||||
else:
|
||||
self._mac_address = mac_address
|
||||
|
||||
log.debug(
|
||||
'Docker container "{name}" [{id}]: MAC address changed to {mac_addr}'.format(
|
||||
name=self._name, id=self._id, mac_addr=self._mac_address
|
||||
)
|
||||
)
|
||||
log.debug(f'Docker container "{self._name}" [{self._id}]: MAC address changed to {self._mac_address}')
|
||||
|
||||
@property
|
||||
def start_command(self):
|
||||
@ -468,7 +460,7 @@ class DockerVM(BaseNode):
|
||||
for volume in self._volumes:
|
||||
source = os.path.join(self.working_dir, os.path.relpath(volume, "/"))
|
||||
os.makedirs(source, exist_ok=True)
|
||||
binds.append({"Type": "bind", "Source": source, "Target": "/gns3volumes{}".format(volume)})
|
||||
binds.append({"Type": "bind", "Source": source, "Target": f"/gns3volumes{volume}"})
|
||||
|
||||
# Inject extra config files: write each to the node working directory and
|
||||
# bind-mount it read-only at its target path. Single-file binds are applied
|
||||
@ -536,7 +528,7 @@ class DockerVM(BaseNode):
|
||||
""")
|
||||
for adapter in range(0, self.adapters):
|
||||
f.write(
|
||||
"""
|
||||
f"""
|
||||
# Static config for eth{adapter}
|
||||
#auto eth{adapter}
|
||||
#iface eth{adapter} inet static
|
||||
@ -548,8 +540,8 @@ class DockerVM(BaseNode):
|
||||
# DHCP config for eth{adapter}
|
||||
#auto eth{adapter}
|
||||
#iface eth{adapter} inet dhcp
|
||||
#\thostname {hostname}
|
||||
""".format(adapter=adapter, hostname=self._name)
|
||||
#\thostname {self._name}
|
||||
"""
|
||||
)
|
||||
return path
|
||||
|
||||
@ -734,7 +726,7 @@ class DockerVM(BaseNode):
|
||||
var_value = var.get("value", "")
|
||||
|
||||
formatted = self._format_env(variables, var_value)
|
||||
params["Env"].append("{}={}".format(var_name, formatted))
|
||||
params["Env"].append(f"{var_name}={formatted}")
|
||||
|
||||
if self._environment:
|
||||
for env in self._environment.strip().split("\n"):
|
||||
@ -898,9 +890,7 @@ class DockerVM(BaseNode):
|
||||
state = await self._get_container_state()
|
||||
except DockerHttp404Error:
|
||||
raise DockerError(
|
||||
"Docker container '{name}' with ID {cid} does not exist or is not ready yet. Please try again in a few seconds.".format(
|
||||
name=self.name, cid=self._cid
|
||||
)
|
||||
f"Docker container '{self.name}' with ID {self._cid} does not exist or is not ready yet. Please try again in a few seconds."
|
||||
)
|
||||
if state == "paused":
|
||||
await self.unpause()
|
||||
@ -961,9 +951,7 @@ class DockerVM(BaseNode):
|
||||
self.status = "started"
|
||||
await self._start_interface_monitor()
|
||||
log.debug(
|
||||
"Docker container '{name}' [{image}] started listen for {console_type} on {console}".format(
|
||||
name=self._name, image=self._image, console=self.console, console_type=self.console_type
|
||||
)
|
||||
f"Docker container '{self._name}' [{self._image}] started listen for {self.console_type} on {self.console}"
|
||||
)
|
||||
|
||||
async def _start_console_server(self):
|
||||
@ -1022,11 +1010,7 @@ class DockerVM(BaseNode):
|
||||
await self.manager.query("POST", f"containers/{self._cid}/start")
|
||||
|
||||
for volume in self._volumes:
|
||||
log.debug(
|
||||
"Docker container '{name}' [{image}] fix ownership on {path}".format(
|
||||
name=self._name, image=self._image, path=volume
|
||||
)
|
||||
)
|
||||
log.debug(f"Docker container '{self._name}' [{self._image}] fix ownership on {volume}")
|
||||
|
||||
try:
|
||||
process = await asyncio.subprocess.create_subprocess_exec(
|
||||
@ -1037,13 +1021,11 @@ class DockerVM(BaseNode):
|
||||
"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\""
|
||||
f'/gns3/bin/busybox find "{volume}" -depth -print0'
|
||||
f" | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c '%a:%u:%g:%n' > \"{volume}/.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
|
||||
),
|
||||
f' && /gns3/bin/busybox chmod -R u+rX "{volume}"'
|
||||
f' && /gns3/bin/busybox chown {os.getuid()}:{os.getgid()} -R "{volume}"',
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
except OSError as e:
|
||||
@ -1203,7 +1185,7 @@ class DockerVM(BaseNode):
|
||||
"None",
|
||||
"-desktop",
|
||||
self.name,
|
||||
":{}".format(self._display),
|
||||
f":{self._display}",
|
||||
stdout=fd,
|
||||
stderr=subprocess.STDOUT,
|
||||
)
|
||||
@ -1403,7 +1385,7 @@ class DockerVM(BaseNode):
|
||||
await self._stop_interface_monitor()
|
||||
await self.manager.query("POST", f"containers/{self._cid}/restart")
|
||||
await self._start_interface_monitor()
|
||||
log.debug("Docker container '{name}' [{image}] restarted".format(name=self._name, image=self._image))
|
||||
log.debug(f"Docker container '{self._name}' [{self._image}] restarted")
|
||||
|
||||
def _cleanup_console_resources(self):
|
||||
"""
|
||||
@ -1557,7 +1539,7 @@ class DockerVM(BaseNode):
|
||||
# Container deletion failed - log warning but don't block project close
|
||||
# The stale container will be cleaned up when the project is opened again
|
||||
log.warning(f"Failed to delete Docker container '{self.docker_name}': {e}")
|
||||
log.debug("Docker container '{name}' [{image}] removed".format(name=self._name, image=self._image))
|
||||
log.debug(f"Docker container '{self._name}' [{self._image}] removed")
|
||||
|
||||
if release_nio_udp_ports:
|
||||
for adapter in self._ethernet_adapters:
|
||||
@ -1756,17 +1738,11 @@ class DockerVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise DockerError(
|
||||
"Adapter {adapter_number} doesn't exist on Docker container '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise DockerError(f"Adapter {adapter_number} doesn't exist on Docker container '{self.name}'")
|
||||
|
||||
if port_number and adapter.interfaces == 1:
|
||||
raise DockerError(
|
||||
"Port {port_number} doesn't exist on adapter {adapter_number} of Docker container '{name}'".format(
|
||||
name=self.name, port_number=port_number, adapter_number=adapter_number
|
||||
)
|
||||
f"Port {port_number} doesn't exist on adapter {adapter_number} of Docker container '{self.name}'"
|
||||
)
|
||||
|
||||
for index in range(4096):
|
||||
@ -1775,16 +1751,12 @@ class DockerVM(BaseNode):
|
||||
break
|
||||
if adapter.host_ifc is None:
|
||||
raise DockerError(
|
||||
"Adapter {adapter_number} couldn't allocate interface on Docker container '{name}'. Too many Docker interfaces already exists".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
f"Adapter {adapter_number} couldn't allocate interface on Docker container '{self.name}'. Too many Docker interfaces already exists"
|
||||
)
|
||||
bridge_name = self._bridge_name(adapter_number, port_number)
|
||||
await self._ubridge_send(f"bridge create {bridge_name}")
|
||||
self._bridges.add(bridge_name)
|
||||
await self._ubridge_send(
|
||||
"bridge add_nio_tap {bridge_name} {hostif} off".format(bridge_name=bridge_name, hostif=adapter.host_ifc)
|
||||
)
|
||||
await self._ubridge_send(f"bridge add_nio_tap {bridge_name} {adapter.host_ifc} off")
|
||||
|
||||
mac_address = int_to_macaddress(macaddress_to_int(self._mac_address) + adapter_number)
|
||||
custom_adapter = self._get_custom_adapter_settings(adapter_number)
|
||||
@ -1793,7 +1765,7 @@ class DockerVM(BaseNode):
|
||||
mac_address = custom_mac_address
|
||||
|
||||
try:
|
||||
await self._ubridge_send("docker set_mac_addr {ifc} {mac}".format(ifc=adapter.host_ifc, mac=mac_address))
|
||||
await self._ubridge_send(f"docker set_mac_addr {adapter.host_ifc} {mac_address}")
|
||||
except UbridgeError:
|
||||
log.warning(f"Could not set MAC address {mac_address} on interface {adapter.host_ifc}")
|
||||
|
||||
@ -1825,17 +1797,9 @@ class DockerVM(BaseNode):
|
||||
async def _connect_nio(self, adapter_number, nio, port_number=0):
|
||||
|
||||
bridge_name = self._bridge_name(adapter_number, port_number)
|
||||
await self._ubridge_send(
|
||||
"bridge add_nio_udp {bridge_name} {lport} {rhost} {rport}".format(
|
||||
bridge_name=bridge_name, lport=nio.lport, rhost=nio.rhost, rport=nio.rport
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f"bridge add_nio_udp {bridge_name} {nio.lport} {nio.rhost} {nio.rport}")
|
||||
if nio.capturing:
|
||||
await self._ubridge_send(
|
||||
'bridge start_capture {bridge_name} "{pcap_file}"'.format(
|
||||
bridge_name=bridge_name, pcap_file=nio.pcap_output_file
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f'bridge start_capture {bridge_name} "{nio.pcap_output_file}"')
|
||||
await self._ubridge_send(f"bridge start {bridge_name}")
|
||||
await self._ubridge_apply_filters(bridge_name, nio.filters)
|
||||
await self._ubridge_apply_markers(bridge_name, nio)
|
||||
@ -1852,17 +1816,11 @@ class DockerVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise DockerError(
|
||||
"Adapter {adapter_number} doesn't exist on Docker container '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise DockerError(f"Adapter {adapter_number} doesn't exist on Docker container '{self.name}'")
|
||||
|
||||
if not adapter.port_exists(port_number):
|
||||
raise DockerError(
|
||||
"Port {port_number} doesn't exist on adapter {adapter_number} of Docker container '{name}'".format(
|
||||
name=self.name, port_number=port_number, adapter_number=adapter_number
|
||||
)
|
||||
f"Port {port_number} doesn't exist on adapter {adapter_number} of Docker container '{self.name}'"
|
||||
)
|
||||
|
||||
if self.status == "started" and self.ubridge:
|
||||
@ -1870,11 +1828,7 @@ class DockerVM(BaseNode):
|
||||
await self._set_adapter_carrier(adapter_number, not nio.suspend, port_number)
|
||||
|
||||
adapter.add_nio(port_number, nio)
|
||||
log.debug(
|
||||
"Docker container '{name}' [{id}]: {nio} added to adapter {adapter_number}".format(
|
||||
name=self.name, id=self._id, nio=nio, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.debug(f"Docker container '{self.name}' [{self._id}]: {nio} added to adapter {adapter_number}")
|
||||
|
||||
async def adapter_update_nio_binding(self, adapter_number, nio, port_number=0):
|
||||
"""
|
||||
@ -1906,11 +1860,7 @@ class DockerVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise DockerError(
|
||||
"Adapter {adapter_number} doesn't exist on Docker VM '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise DockerError(f"Adapter {adapter_number} doesn't exist on Docker VM '{self.name}'")
|
||||
|
||||
await self.stop_capture(adapter_number, port_number)
|
||||
if self.ubridge:
|
||||
@ -1919,19 +1869,11 @@ class DockerVM(BaseNode):
|
||||
if self.status == "started":
|
||||
await self._set_adapter_carrier(adapter_number, False, port_number)
|
||||
await self._ubridge_send(f"bridge stop {bridge_name}")
|
||||
await self._ubridge_send(
|
||||
"bridge remove_nio_udp {bridge_name} {lport} {rhost} {rport}".format(
|
||||
bridge_name=bridge_name, lport=nio.lport, rhost=nio.rhost, rport=nio.rport
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f"bridge remove_nio_udp {bridge_name} {nio.lport} {nio.rhost} {nio.rport}")
|
||||
|
||||
adapter.remove_nio(port_number)
|
||||
|
||||
log.debug(
|
||||
"Docker VM '{name}' [{id}]: {nio} removed from adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, nio=adapter.host_ifc, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.debug(f"Docker VM '{self.name}' [{self.id}]: {adapter.host_ifc} removed from adapter {adapter_number}")
|
||||
|
||||
def get_nio(self, adapter_number, port_number=0):
|
||||
"""
|
||||
@ -1946,11 +1888,7 @@ class DockerVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except KeyError:
|
||||
raise DockerError(
|
||||
"Adapter {adapter_number} doesn't exist on Docker VM '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise DockerError(f"Adapter {adapter_number} doesn't exist on Docker VM '{self.name}'")
|
||||
|
||||
nio = adapter.get_nio(port_number)
|
||||
|
||||
@ -1985,11 +1923,7 @@ class DockerVM(BaseNode):
|
||||
for adapter_number in range(0, adapters):
|
||||
self._ethernet_adapters.append(EthernetAdapter())
|
||||
|
||||
log.debug(
|
||||
'Docker container "{name}" [{id}]: number of Ethernet adapters changed to {adapters}'.format(
|
||||
name=self._name, id=self._id, adapters=adapters
|
||||
)
|
||||
)
|
||||
log.debug(f'Docker container "{self._name}" [{self._id}]: number of Ethernet adapters changed to {adapters}')
|
||||
|
||||
async def _start_ubridge_capture(self, adapter_number, output_file, port_number=0):
|
||||
"""
|
||||
@ -2035,11 +1969,7 @@ class DockerVM(BaseNode):
|
||||
if self.status == "started" and self.ubridge:
|
||||
await self._start_ubridge_capture(adapter_number, output_file, port_number)
|
||||
|
||||
log.debug(
|
||||
"Docker VM '{name}' [{id}]: starting packet capture on adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.debug(f"Docker VM '{self.name}' [{self.id}]: starting packet capture on adapter {adapter_number}")
|
||||
|
||||
async def stop_capture(self, adapter_number, port_number=0):
|
||||
"""
|
||||
@ -2056,11 +1986,7 @@ class DockerVM(BaseNode):
|
||||
if self.status == "started" and self.ubridge:
|
||||
await self._stop_ubridge_capture(adapter_number, port_number)
|
||||
|
||||
log.debug(
|
||||
"Docker VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.debug(f"Docker VM '{self.name}' [{self.id}]: stopping packet capture on adapter {adapter_number}")
|
||||
|
||||
async def _get_log(self):
|
||||
"""
|
||||
|
||||
@ -418,11 +418,7 @@ class VendorDockerVM(DockerVM):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise DockerError(
|
||||
"Adapter {adapter_number} doesn't exist on Docker container '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise DockerError(f"Adapter {adapter_number} doesn't exist on Docker container '{self.name}'")
|
||||
|
||||
interface_number = adapter_number * adapter.interfaces + port_number
|
||||
bridge_name = self._bridge_name(adapter_number, port_number)
|
||||
|
||||
@ -284,9 +284,9 @@ class Dynamips(BaseManager):
|
||||
version = match.group(1)
|
||||
return version
|
||||
else:
|
||||
raise DynamipsError("Could not determine the Dynamips version for {}".format(dynamips_path))
|
||||
raise DynamipsError(f"Could not determine the Dynamips version for {dynamips_path}")
|
||||
except (OSError, subprocess.SubprocessError) as e:
|
||||
raise DynamipsError("Error while looking for the Dynamips version: {}".format(e))
|
||||
raise DynamipsError(f"Error while looking for the Dynamips version: {e}")
|
||||
|
||||
async def start_new_hypervisor(self, working_dir=None):
|
||||
"""
|
||||
@ -308,7 +308,7 @@ class Dynamips(BaseManager):
|
||||
|
||||
dynamips_version = await self.dynamips_version(self.dynamips_path)
|
||||
if parse_version(dynamips_version) < parse_version("0.2.11"):
|
||||
raise DynamipsError("Dynamips version must be >= 0.2.11, detected version is {}".format(dynamips_version))
|
||||
raise DynamipsError(f"Dynamips version must be >= 0.2.11, detected version is {dynamips_version}")
|
||||
|
||||
if not sys.platform.startswith("win"):
|
||||
# Hypervisor should always listen to 127.0.0.1
|
||||
|
||||
@ -96,7 +96,7 @@ class DynamipsHypervisor:
|
||||
try:
|
||||
version = await self.send("hypervisor version")
|
||||
self._version = version[0].split("-", 1)[0]
|
||||
log.debug("Dynamips version {} detected".format(self._version))
|
||||
log.debug(f"Dynamips version {self._version} detected")
|
||||
except IndexError:
|
||||
log.warning("Dynamips version could not be detected")
|
||||
self._version = "Unknown"
|
||||
@ -253,9 +253,7 @@ class DynamipsHypervisor:
|
||||
await self._writer.drain()
|
||||
except OSError as e:
|
||||
raise DynamipsError(
|
||||
"Could not send Dynamips command '{command}' to {host}:{port}: {error}, process running: {run}".format(
|
||||
command=command.strip(), host=self._host, port=self._port, error=e, run=self.is_running()
|
||||
)
|
||||
f"Could not send Dynamips command '{command.strip()}' to {self._host}:{self._port}: {e}, process running: {self.is_running()}"
|
||||
)
|
||||
|
||||
# Now retrieve the result
|
||||
@ -281,9 +279,7 @@ class DynamipsHypervisor:
|
||||
if not chunk:
|
||||
if retries > max_retries:
|
||||
raise DynamipsError(
|
||||
"No data returned from {host}:{port}, Dynamips process running: {run}".format(
|
||||
host=self._host, port=self._port, run=self.is_running()
|
||||
)
|
||||
f"No data returned from {self._host}:{self._port}, Dynamips process running: {self.is_running()}"
|
||||
)
|
||||
else:
|
||||
retries += 1
|
||||
@ -293,9 +289,7 @@ class DynamipsHypervisor:
|
||||
buf += chunk.decode("utf-8", errors="ignore")
|
||||
except OSError as e:
|
||||
raise DynamipsError(
|
||||
"Could not read response for '{command}' from {host}:{port}: {error}, process running: {run}".format(
|
||||
command=command.strip(), host=self._host, port=self._port, error=e, run=self.is_running()
|
||||
)
|
||||
f"Could not read response for '{command.strip()}' from {self._host}:{self._port}: {e}, process running: {self.is_running()}"
|
||||
)
|
||||
|
||||
# If the buffer doesn't end in '\n' then we can't be done
|
||||
@ -304,9 +298,7 @@ class DynamipsHypervisor:
|
||||
continue
|
||||
except IndexError:
|
||||
raise DynamipsError(
|
||||
"Could not communicate with {host}:{port}, Dynamips process running: {run}".format(
|
||||
host=self._host, port=self._port, run=self.is_running()
|
||||
)
|
||||
f"Could not communicate with {self._host}:{self._port}, Dynamips process running: {self.is_running()}"
|
||||
)
|
||||
|
||||
data += buf.split("\r\n")
|
||||
|
||||
@ -195,13 +195,13 @@ class Hypervisor(DynamipsHypervisor):
|
||||
|
||||
command = [self._path]
|
||||
command.extend(["-N1"]) # use instance IDs for filenames
|
||||
command.extend(["-l", "dynamips_i{}_log.txt".format(self._id)]) # log file
|
||||
command.extend(["-l", f"dynamips_i{self._id}_log.txt"]) # log file
|
||||
|
||||
if self._bind_console_host:
|
||||
# support was added in Dynamips version 0.2.23
|
||||
command.extend(["-H", "{}:{}".format(self._host, self._port), "--console-binding-addr", self._console_host])
|
||||
command.extend(["-H", f"{self._host}:{self._port}", "--console-binding-addr", self._console_host])
|
||||
elif self._console_host != "0.0.0.0" and self._console_host != "::":
|
||||
command.extend(["-H", "{}:{}".format(self._host, self._port)])
|
||||
command.extend(["-H", f"{self._host}:{self._port}"])
|
||||
else:
|
||||
command.extend(["-H", str(self._port)])
|
||||
|
||||
|
||||
@ -130,11 +130,7 @@ class NIO:
|
||||
raise DynamipsError(f"Unknown direction {direction} to bind filter {filter_name}:")
|
||||
dynamips_direction = self._dynamips_direction[direction]
|
||||
|
||||
await self._hypervisor.send(
|
||||
"nio bind_filter {name} {direction} {filter}".format(
|
||||
name=self._name, direction=dynamips_direction, filter=filter_name
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f"nio bind_filter {self._name} {dynamips_direction} {filter_name}")
|
||||
|
||||
if direction == "in":
|
||||
self._input_filter = filter_name
|
||||
@ -155,9 +151,7 @@ class NIO:
|
||||
raise DynamipsError(f"Unknown direction {direction} to unbind filter:")
|
||||
dynamips_direction = self._dynamips_direction[direction]
|
||||
|
||||
await self._hypervisor.send(
|
||||
"nio unbind_filter {name} {direction}".format(name=self._name, direction=dynamips_direction)
|
||||
)
|
||||
await self._hypervisor.send(f"nio unbind_filter {self._name} {dynamips_direction}")
|
||||
|
||||
if direction == "in":
|
||||
self._input_filter = None
|
||||
@ -190,11 +184,7 @@ class NIO:
|
||||
raise DynamipsError(f"Unknown direction {direction} to setup filter:")
|
||||
dynamips_direction = self._dynamips_direction[direction]
|
||||
|
||||
await self._hypervisor.send(
|
||||
"nio setup_filter {name} {direction} {options}".format(
|
||||
name=self._name, direction=dynamips_direction, options=options
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f"nio setup_filter {self._name} {dynamips_direction} {options}")
|
||||
|
||||
if direction == "in":
|
||||
self._input_filter_options = options
|
||||
|
||||
@ -43,15 +43,9 @@ class NIOGenericEthernet(NIO):
|
||||
|
||||
async def create(self):
|
||||
|
||||
await self._hypervisor.send(
|
||||
"nio create_gen_eth {name} {eth_device}".format(name=self._name, eth_device=self._ethernet_device)
|
||||
)
|
||||
await self._hypervisor.send(f"nio create_gen_eth {self._name} {self._ethernet_device}")
|
||||
|
||||
log.info(
|
||||
"NIO Generic Ethernet {name} created with device {device}".format(
|
||||
name=self._name, device=self._ethernet_device
|
||||
)
|
||||
)
|
||||
log.info(f"NIO Generic Ethernet {self._name} created with device {self._ethernet_device}")
|
||||
|
||||
@property
|
||||
def ethernet_device(self):
|
||||
|
||||
@ -42,15 +42,9 @@ class NIOLinuxEthernet(NIO):
|
||||
|
||||
async def create(self):
|
||||
|
||||
await self._hypervisor.send(
|
||||
"nio create_linux_eth {name} {eth_device}".format(name=self._name, eth_device=self._ethernet_device)
|
||||
)
|
||||
await self._hypervisor.send(f"nio create_linux_eth {self._name} {self._ethernet_device}")
|
||||
|
||||
log.info(
|
||||
"NIO Linux Ethernet {name} created with device {device}".format(
|
||||
name=self._name, device=self._ethernet_device
|
||||
)
|
||||
)
|
||||
log.info(f"NIO Linux Ethernet {self._name} created with device {self._ethernet_device}")
|
||||
|
||||
@property
|
||||
def ethernet_device(self):
|
||||
|
||||
@ -55,11 +55,7 @@ class NIOUDP(NIO):
|
||||
return
|
||||
# Ubridge is not supported
|
||||
if not hasattr(self._node, "add_ubridge_udp_connection"):
|
||||
await self._hypervisor.send(
|
||||
"nio create_udp {name} {lport} {rhost} {rport}".format(
|
||||
name=self._name, lport=self._lport, rhost=self._rhost, rport=self._rport
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f"nio create_udp {self._name} {self._lport} {self._rhost} {self._rport}")
|
||||
return
|
||||
self._local_tunnel_lport = self._node.manager.port_manager.get_free_udp_port(self._node.project)
|
||||
self._local_tunnel_rport = self._node.manager.port_manager.get_free_udp_port(self._node.project)
|
||||
@ -70,11 +66,7 @@ class NIOUDP(NIO):
|
||||
)
|
||||
)
|
||||
|
||||
log.debug(
|
||||
"NIO UDP {name} created with lport={lport}, rhost={rhost}, rport={rport}".format(
|
||||
name=self._name, lport=self._lport, rhost=self._rhost, rport=self._rport
|
||||
)
|
||||
)
|
||||
log.debug(f"NIO UDP {self._name} created with lport={self._lport}, rhost={self._rhost}, rport={self._rport}")
|
||||
|
||||
self._source_nio = nio_udp.NIOUDP(self._local_tunnel_rport, "127.0.0.1", self._local_tunnel_lport)
|
||||
self._destination_nio = nio_udp.NIOUDP(self._lport, self._rhost, self._rport)
|
||||
|
||||
@ -45,16 +45,10 @@ class NIOUNIX(NIO):
|
||||
|
||||
async def create(self):
|
||||
|
||||
await self._hypervisor.send(
|
||||
"nio create_unix {name} {local} {remote}".format(
|
||||
name=self._name, local=self._local_file, remote=self._remote_file
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f"nio create_unix {self._name} {self._local_file} {self._remote_file}")
|
||||
|
||||
log.info(
|
||||
"NIO UNIX {name} created with local file {local} and remote file {remote}".format(
|
||||
name=self._name, local=self._local_file, remote=self._remote_file
|
||||
)
|
||||
f"NIO UNIX {self._name} created with local file {self._local_file} and remote file {self._remote_file}"
|
||||
)
|
||||
|
||||
@property
|
||||
|
||||
@ -45,17 +45,9 @@ class NIOVDE(NIO):
|
||||
|
||||
async def create(self):
|
||||
|
||||
await self._hypervisor.send(
|
||||
"nio create_vde {name} {control} {local}".format(
|
||||
name=self._name, control=self._control_file, local=self._local_file
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f"nio create_vde {self._name} {self._control_file} {self._local_file}")
|
||||
|
||||
log.info(
|
||||
"NIO VDE {name} created with control={control}, local={local}".format(
|
||||
name=self._name, control=self._control_file, local=self._local_file
|
||||
)
|
||||
)
|
||||
log.info(f"NIO VDE {self._name} created with control={self._control_file}, local={self._local_file}")
|
||||
|
||||
@property
|
||||
def control_file(self):
|
||||
|
||||
@ -82,11 +82,7 @@ class ATMSwitch(Device):
|
||||
"""
|
||||
|
||||
await self._hypervisor.send(f'atmsw rename "{self._name}" "{new_name}"')
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: renamed to "{new_name}"'.format(
|
||||
name=self._name, id=self._id, new_name=new_name
|
||||
)
|
||||
)
|
||||
log.info(f'ATM switch "{self._name}" [{self._id}]: renamed to "{new_name}"')
|
||||
self._name = new_name
|
||||
|
||||
@property
|
||||
@ -165,11 +161,7 @@ class ATMSwitch(Device):
|
||||
if port_number in self._nios:
|
||||
raise DynamipsError(f"Port {port_number} isn't free")
|
||||
|
||||
log.info(
|
||||
'ATM switch "{name}" [id={id}]: NIO {nio} bound to port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'ATM switch "{self._name}" [id={self._id}]: NIO {nio} bound to port {port_number}')
|
||||
|
||||
self._nios[port_number] = nio
|
||||
await self.set_mappings(self._mappings)
|
||||
@ -193,16 +185,7 @@ class ATMSwitch(Device):
|
||||
destination_port, destination_vpi, destination_vci = destination
|
||||
if port_number == source_port:
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: unmapping VCC between port {source_port} VPI {source_vpi} VCI {source_vci} and port {destination_port} VPI {destination_vpi} VCI {destination_vci}'.format(
|
||||
name=self._name,
|
||||
id=self._id,
|
||||
source_port=source_port,
|
||||
source_vpi=source_vpi,
|
||||
source_vci=source_vci,
|
||||
destination_port=destination_port,
|
||||
destination_vpi=destination_vpi,
|
||||
destination_vci=destination_vci,
|
||||
)
|
||||
f'ATM switch "{self._name}" [{self._id}]: unmapping VCC between port {source_port} VPI {source_vpi} VCI {source_vci} and port {destination_port} VPI {destination_vpi} VCI {destination_vci}'
|
||||
)
|
||||
await self.unmap_pvc(
|
||||
source_port, source_vpi, source_vci, destination_port, destination_vpi, destination_vci
|
||||
@ -216,14 +199,7 @@ class ATMSwitch(Device):
|
||||
destination_port, destination_vpi = destination
|
||||
if port_number == source_port:
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: unmapping VPC between port {source_port} VPI {source_vpi} and port {destination_port} VPI {destination_vpi}'.format(
|
||||
name=self._name,
|
||||
id=self._id,
|
||||
source_port=source_port,
|
||||
source_vpi=source_vpi,
|
||||
destination_port=destination_port,
|
||||
destination_vpi=destination_vpi,
|
||||
)
|
||||
f'ATM switch "{self._name}" [{self._id}]: unmapping VPC between port {source_port} VPI {source_vpi} and port {destination_port} VPI {destination_vpi}'
|
||||
)
|
||||
await self.unmap_vp(source_port, source_vpi, destination_port, destination_vpi)
|
||||
await self.unmap_vp(destination_port, destination_vpi, source_port, source_vpi)
|
||||
@ -231,11 +207,7 @@ class ATMSwitch(Device):
|
||||
nio = self._nios[port_number]
|
||||
if isinstance(nio, NIOUDP):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: NIO {nio} removed from port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'ATM switch "{self._name}" [{self._id}]: NIO {nio} removed from port {port_number}')
|
||||
|
||||
del self._nios[port_number]
|
||||
return nio
|
||||
@ -283,16 +255,7 @@ class ATMSwitch(Device):
|
||||
destination_vci,
|
||||
) not in self._active_mappings:
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: mapping VCC between port {source_port} VPI {source_vpi} VCI {source_vci} and port {destination_port} VPI {destination_vpi} VCI {destination_vci}'.format(
|
||||
name=self._name,
|
||||
id=self._id,
|
||||
source_port=source_port,
|
||||
source_vpi=source_vpi,
|
||||
source_vci=source_vci,
|
||||
destination_port=destination_port,
|
||||
destination_vpi=destination_vpi,
|
||||
destination_vci=destination_vci,
|
||||
)
|
||||
f'ATM switch "{self._name}" [{self._id}]: mapping VCC between port {source_port} VPI {source_vpi} VCI {source_vci} and port {destination_port} VPI {destination_vpi} VCI {destination_vci}'
|
||||
)
|
||||
await self.map_pvc(
|
||||
source_port, source_vpi, source_vci, destination_port, destination_vpi, destination_vci
|
||||
@ -310,14 +273,7 @@ class ATMSwitch(Device):
|
||||
destination_vpi,
|
||||
) not in self._active_mappings:
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: mapping VPC between port {source_port} VPI {source_vpi} and port {destination_port} VPI {destination_vpi}'.format(
|
||||
name=self._name,
|
||||
id=self._id,
|
||||
source_port=source_port,
|
||||
source_vpi=source_vpi,
|
||||
destination_port=destination_port,
|
||||
destination_vpi=destination_vpi,
|
||||
)
|
||||
f'ATM switch "{self._name}" [{self._id}]: mapping VPC between port {source_port} VPI {source_vpi} and port {destination_port} VPI {destination_vpi}'
|
||||
)
|
||||
await self.map_vp(source_port, source_vpi, destination_port, destination_vpi)
|
||||
await self.map_vp(destination_port, destination_vpi, source_port, source_vpi)
|
||||
@ -341,16 +297,10 @@ class ATMSwitch(Device):
|
||||
nio1 = self._nios[port1]
|
||||
nio2 = self._nios[port2]
|
||||
|
||||
await self._hypervisor.send(
|
||||
'atmsw create_vpc "{name}" {input_nio} {input_vpi} {output_nio} {output_vpi}'.format(
|
||||
name=self._name, input_nio=nio1, input_vpi=vpi1, output_nio=nio2, output_vpi=vpi2
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'atmsw create_vpc "{self._name}" {nio1} {vpi1} {nio2} {vpi2}')
|
||||
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: VPC from port {port1} VPI {vpi1} to port {port2} VPI {vpi2} created'.format(
|
||||
name=self._name, id=self._id, port1=port1, vpi1=vpi1, port2=port2, vpi2=vpi2
|
||||
)
|
||||
f'ATM switch "{self._name}" [{self._id}]: VPC from port {port1} VPI {vpi1} to port {port2} VPI {vpi2} created'
|
||||
)
|
||||
|
||||
self._active_mappings[(port1, vpi1)] = (port2, vpi2)
|
||||
@ -374,16 +324,10 @@ class ATMSwitch(Device):
|
||||
nio1 = self._nios[port1]
|
||||
nio2 = self._nios[port2]
|
||||
|
||||
await self._hypervisor.send(
|
||||
'atmsw delete_vpc "{name}" {input_nio} {input_vpi} {output_nio} {output_vpi}'.format(
|
||||
name=self._name, input_nio=nio1, input_vpi=vpi1, output_nio=nio2, output_vpi=vpi2
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'atmsw delete_vpc "{self._name}" {nio1} {vpi1} {nio2} {vpi2}')
|
||||
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: VPC from port {port1} VPI {vpi1} to port {port2} VPI {vpi2} deleted'.format(
|
||||
name=self._name, id=self._id, port1=port1, vpi1=vpi1, port2=port2, vpi2=vpi2
|
||||
)
|
||||
f'ATM switch "{self._name}" [{self._id}]: VPC from port {port1} VPI {vpi1} to port {port2} VPI {vpi2} deleted'
|
||||
)
|
||||
|
||||
del self._active_mappings[(port1, vpi1)]
|
||||
@ -409,22 +353,10 @@ class ATMSwitch(Device):
|
||||
nio1 = self._nios[port1]
|
||||
nio2 = self._nios[port2]
|
||||
|
||||
await self._hypervisor.send(
|
||||
'atmsw create_vcc "{name}" {input_nio} {input_vpi} {input_vci} {output_nio} {output_vpi} {output_vci}'.format(
|
||||
name=self._name,
|
||||
input_nio=nio1,
|
||||
input_vpi=vpi1,
|
||||
input_vci=vci1,
|
||||
output_nio=nio2,
|
||||
output_vpi=vpi2,
|
||||
output_vci=vci2,
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'atmsw create_vcc "{self._name}" {nio1} {vpi1} {vci1} {nio2} {vpi2} {vci2}')
|
||||
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: VCC from port {port1} VPI {vpi1} VCI {vci1} to port {port2} VPI {vpi2} VCI {vci2} created'.format(
|
||||
name=self._name, id=self._id, port1=port1, vpi1=vpi1, vci1=vci1, port2=port2, vpi2=vpi2, vci2=vci2
|
||||
)
|
||||
f'ATM switch "{self._name}" [{self._id}]: VCC from port {port1} VPI {vpi1} VCI {vci1} to port {port2} VPI {vpi2} VCI {vci2} created'
|
||||
)
|
||||
|
||||
self._active_mappings[(port1, vpi1, vci1)] = (port2, vpi2, vci2)
|
||||
@ -450,22 +382,10 @@ class ATMSwitch(Device):
|
||||
nio1 = self._nios[port1]
|
||||
nio2 = self._nios[port2]
|
||||
|
||||
await self._hypervisor.send(
|
||||
'atmsw delete_vcc "{name}" {input_nio} {input_vpi} {input_vci} {output_nio} {output_vpi} {output_vci}'.format(
|
||||
name=self._name,
|
||||
input_nio=nio1,
|
||||
input_vpi=vpi1,
|
||||
input_vci=vci1,
|
||||
output_nio=nio2,
|
||||
output_vpi=vpi2,
|
||||
output_vci=vci2,
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'atmsw delete_vcc "{self._name}" {nio1} {vpi1} {vci1} {nio2} {vpi2} {vci2}')
|
||||
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: VCC from port {port1} VPI {vpi1} VCI {vci1} to port {port2} VPI {vpi2} VCI {vci2} deleted'.format(
|
||||
name=self._name, id=self._id, port1=port1, vpi1=vpi1, vci1=vci1, port2=port2, vpi2=vpi2, vci2=vci2
|
||||
)
|
||||
f'ATM switch "{self._name}" [{self._id}]: VCC from port {port1} VPI {vpi1} VCI {vci1} to port {port2} VPI {vpi2} VCI {vci2} deleted'
|
||||
)
|
||||
del self._active_mappings[(port1, vpi1, vci1)]
|
||||
|
||||
@ -487,11 +407,7 @@ class ATMSwitch(Device):
|
||||
raise DynamipsError(f"Port {port_number} has already a filter applied")
|
||||
|
||||
await nio.start_packet_capture(output_file, data_link_type)
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: starting packet capture on port {port}'.format(
|
||||
name=self._name, id=self._id, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'ATM switch "{self._name}" [{self._id}]: starting packet capture on port {port_number}')
|
||||
|
||||
async def stop_capture(self, port_number):
|
||||
"""
|
||||
@ -504,8 +420,4 @@ class ATMSwitch(Device):
|
||||
if not nio.capturing:
|
||||
return
|
||||
await nio.stop_packet_capture()
|
||||
log.info(
|
||||
'ATM switch "{name}" [{id}]: stopping packet capture on port {port}'.format(
|
||||
name=self._name, id=self._id, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'ATM switch "{self._name}" [{self._id}]: stopping packet capture on port {port_number}')
|
||||
|
||||
@ -54,9 +54,7 @@ class Bridge(Device):
|
||||
:param new_name: New name for this bridge
|
||||
"""
|
||||
|
||||
await self._hypervisor.send(
|
||||
'nio_bridge rename "{name}" "{new_name}"'.format(name=self._name, new_name=new_name)
|
||||
)
|
||||
await self._hypervisor.send(f'nio_bridge rename "{self._name}" "{new_name}"')
|
||||
|
||||
self._name = new_name
|
||||
|
||||
|
||||
@ -124,9 +124,7 @@ class C1700(Router):
|
||||
|
||||
await self._hypervisor.send(f'c1700 set_chassis "{self._name}" {chassis}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: chassis set to {chassis}'.format(name=self._name, id=self._id, chassis=chassis)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: chassis set to {chassis}')
|
||||
|
||||
self._chassis = chassis
|
||||
self._setup_chassis()
|
||||
@ -150,9 +148,5 @@ class C1700(Router):
|
||||
|
||||
await self._hypervisor.send(f'c1700 set_iomem "{self._name}" {iomem}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: I/O memory updated from {old_iomem}% to {new_iomem}%'.format(
|
||||
name=self._name, id=self._id, old_iomem=self._iomem, new_iomem=iomem
|
||||
)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: I/O memory updated from {self._iomem}% to {iomem}%')
|
||||
self._iomem = iomem
|
||||
|
||||
@ -136,9 +136,7 @@ class C2600(Router):
|
||||
|
||||
await self._hypervisor.send(f'c2600 set_chassis "{self._name}" {chassis}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: chassis set to {chassis}'.format(name=self._name, id=self._id, chassis=chassis)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: chassis set to {chassis}')
|
||||
self._chassis = chassis
|
||||
self._setup_chassis()
|
||||
|
||||
@ -161,9 +159,5 @@ class C2600(Router):
|
||||
|
||||
await self._hypervisor.send(f'c2600 set_iomem "{self._name}" {iomem}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: I/O memory updated from {old_iomem}% to {new_iomem}%'.format(
|
||||
name=self._name, id=self._id, old_iomem=self._iomem, new_iomem=iomem
|
||||
)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: I/O memory updated from {self._iomem}% to {iomem}%')
|
||||
self._iomem = iomem
|
||||
|
||||
@ -102,9 +102,5 @@ class C2691(Router):
|
||||
|
||||
await self._hypervisor.send(f'c2691 set_iomem "{self._name}" {iomem}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: I/O memory updated from {old_iomem}% to {new_iomem}%'.format(
|
||||
name=self._name, id=self._id, old_iomem=self._iomem, new_iomem=iomem
|
||||
)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: I/O memory updated from {self._iomem}% to {iomem}%')
|
||||
self._iomem = iomem
|
||||
|
||||
@ -119,9 +119,7 @@ class C3600(Router):
|
||||
|
||||
await self._hypervisor.send(f'c3600 set_chassis "{self._name}" {chassis}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: chassis set to {chassis}'.format(name=self._name, id=self._id, chassis=chassis)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: chassis set to {chassis}')
|
||||
|
||||
self._chassis = chassis
|
||||
self._setup_chassis()
|
||||
@ -145,9 +143,5 @@ class C3600(Router):
|
||||
|
||||
await self._hypervisor.send(f'c3600 set_iomem "{self._name}" {iomem}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: I/O memory updated from {old_iomem}% to {new_iomem}%'.format(
|
||||
name=self._name, id=self._id, old_iomem=self._iomem, new_iomem=iomem
|
||||
)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: I/O memory updated from {self._iomem}% to {iomem}%')
|
||||
self._iomem = iomem
|
||||
|
||||
@ -102,9 +102,5 @@ class C3725(Router):
|
||||
|
||||
await self._hypervisor.send(f'c3725 set_iomem "{self._name}" {iomem}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: I/O memory updated from {old_iomem}% to {new_iomem}%'.format(
|
||||
name=self._name, id=self._id, old_iomem=self._iomem, new_iomem=iomem
|
||||
)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: I/O memory updated from {self._iomem}% to {iomem}%')
|
||||
self._iomem = iomem
|
||||
|
||||
@ -102,9 +102,5 @@ class C3745(Router):
|
||||
|
||||
await self._hypervisor.send(f'c3745 set_iomem "{self._name}" {iomem}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: I/O memory updated from {old_iomem}% to {new_iomem}%'.format(
|
||||
name=self._name, id=self._id, old_iomem=self._iomem, new_iomem=iomem
|
||||
)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: I/O memory updated from {self._iomem}% to {iomem}%')
|
||||
self._iomem = iomem
|
||||
|
||||
@ -139,11 +139,7 @@ class C7200(Router):
|
||||
|
||||
await self._hypervisor.send(f'c7200 set_npe "{self._name}" {npe}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: NPE updated from {old_npe} to {new_npe}'.format(
|
||||
name=self._name, id=self._id, old_npe=self._npe, new_npe=npe
|
||||
)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: NPE updated from {self._npe} to {npe}')
|
||||
self._npe = npe
|
||||
|
||||
@property
|
||||
@ -165,11 +161,7 @@ class C7200(Router):
|
||||
|
||||
await self._hypervisor.send(f'c7200 set_midplane "{self._name}" {midplane}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: midplane updated from {old_midplane} to {new_midplane}'.format(
|
||||
name=self._name, id=self._id, old_midplane=self._midplane, new_midplane=midplane
|
||||
)
|
||||
)
|
||||
log.info(f'Router "{self._name}" [{self._id}]: midplane updated from {self._midplane} to {midplane}')
|
||||
self._midplane = midplane
|
||||
|
||||
@property
|
||||
@ -196,20 +188,10 @@ class C7200(Router):
|
||||
|
||||
sensor_id = 0
|
||||
for sensor in sensors:
|
||||
await self._hypervisor.send(
|
||||
'c7200 set_temp_sensor "{name}" {sensor_id} {temp}'.format(
|
||||
name=self._name, sensor_id=sensor_id, temp=sensor
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'c7200 set_temp_sensor "{self._name}" {sensor_id} {sensor}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: sensor {sensor_id} temperature updated from {old_temp}C to {new_temp}C'.format(
|
||||
name=self._name,
|
||||
id=self._id,
|
||||
sensor_id=sensor_id,
|
||||
old_temp=self._sensors[sensor_id],
|
||||
new_temp=sensors[sensor_id],
|
||||
)
|
||||
f'Router "{self._name}" [{self._id}]: sensor {sensor_id} temperature updated from {self._sensors[sensor_id]}C to {sensors[sensor_id]}C'
|
||||
)
|
||||
|
||||
sensor_id += 1
|
||||
@ -235,16 +217,10 @@ class C7200(Router):
|
||||
|
||||
power_supply_id = 0
|
||||
for power_supply in power_supplies:
|
||||
await self._hypervisor.send(
|
||||
'c7200 set_power_supply "{name}" {power_supply_id} {powered_on}'.format(
|
||||
name=self._name, power_supply_id=power_supply_id, powered_on=power_supply
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'c7200 set_power_supply "{self._name}" {power_supply_id} {power_supply}')
|
||||
|
||||
log.info(
|
||||
'Router "{name}" [{id}]: power supply {power_supply_id} state updated to {powered_on}'.format(
|
||||
name=self._name, id=self._id, power_supply_id=power_supply_id, powered_on=power_supply
|
||||
)
|
||||
f'Router "{self._name}" [{self._id}]: power supply {power_supply_id} state updated to {power_supply}'
|
||||
)
|
||||
power_supply_id += 1
|
||||
|
||||
|
||||
@ -145,11 +145,7 @@ class EthernetHub(Bridge):
|
||||
|
||||
await Bridge.add_nio(self, nio)
|
||||
|
||||
log.info(
|
||||
'Ethernet hub "{name}" [{id}]: NIO {nio} bound to port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Ethernet hub "{self._name}" [{self._id}]: NIO {nio} bound to port {port_number}')
|
||||
self._mappings[port_number] = nio
|
||||
|
||||
async def remove_nio(self, port_number):
|
||||
@ -170,11 +166,7 @@ class EthernetHub(Bridge):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
await Bridge.remove_nio(self, nio)
|
||||
|
||||
log.info(
|
||||
'Ethernet hub "{name}" [{id}]: NIO {nio} removed from port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Ethernet hub "{self._name}" [{self._id}]: NIO {nio} removed from port {port_number}')
|
||||
|
||||
del self._mappings[port_number]
|
||||
return nio
|
||||
@ -216,11 +208,7 @@ class EthernetHub(Bridge):
|
||||
raise DynamipsError(f"Port {port_number} has already a filter applied")
|
||||
|
||||
await nio.start_packet_capture(output_file, data_link_type)
|
||||
log.info(
|
||||
'Ethernet hub "{name}" [{id}]: starting packet capture on port {port}'.format(
|
||||
name=self._name, id=self._id, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Ethernet hub "{self._name}" [{self._id}]: starting packet capture on port {port_number}')
|
||||
|
||||
async def stop_capture(self, port_number):
|
||||
"""
|
||||
@ -233,8 +221,4 @@ class EthernetHub(Bridge):
|
||||
if not nio.capturing:
|
||||
return
|
||||
await nio.stop_packet_capture()
|
||||
log.info(
|
||||
'Ethernet hub "{name}" [{id}]: stopping packet capture on port {port}'.format(
|
||||
name=self._name, id=self._id, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Ethernet hub "{self._name}" [{self._id}]: stopping packet capture on port {port_number}')
|
||||
|
||||
@ -210,11 +210,7 @@ class EthernetSwitch(Device):
|
||||
"""
|
||||
|
||||
await self._hypervisor.send(f'ethsw rename "{self._name}" "{new_name}"')
|
||||
log.info(
|
||||
'Ethernet switch "{name}" [{id}]: renamed to "{new_name}"'.format(
|
||||
name=self._name, id=self._id, new_name=new_name
|
||||
)
|
||||
)
|
||||
log.info(f'Ethernet switch "{self._name}" [{self._id}]: renamed to "{new_name}"')
|
||||
self._name = new_name
|
||||
|
||||
@property
|
||||
@ -279,11 +275,7 @@ class EthernetSwitch(Device):
|
||||
|
||||
await self._hypervisor.send(f'ethsw add_nio "{self._name}" {nio}')
|
||||
|
||||
log.info(
|
||||
'Ethernet switch "{name}" [{id}]: NIO {nio} bound to port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Ethernet switch "{self._name}" [{self._id}]: NIO {nio} bound to port {port_number}')
|
||||
self._nios[port_number] = nio
|
||||
for port_settings in self._ports:
|
||||
if port_settings["port_number"] == port_number:
|
||||
@ -309,11 +301,7 @@ class EthernetSwitch(Device):
|
||||
if self._hypervisor:
|
||||
await self._hypervisor.send(f'ethsw remove_nio "{self._name}" {nio}')
|
||||
|
||||
log.info(
|
||||
'Ethernet switch "{name}" [{id}]: NIO {nio} removed from port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Ethernet switch "{self._name}" [{self._id}]: NIO {nio} removed from port {port_number}')
|
||||
|
||||
del self._nios[port_number]
|
||||
if port_number in self._mappings:
|
||||
@ -367,14 +355,10 @@ class EthernetSwitch(Device):
|
||||
raise DynamipsError(f"Port {port_number} is not allocated")
|
||||
|
||||
nio = self._nios[port_number]
|
||||
await self._hypervisor.send(
|
||||
'ethsw set_access_port "{name}" {nio} {vlan_id}'.format(name=self._name, nio=nio, vlan_id=vlan_id)
|
||||
)
|
||||
await self._hypervisor.send(f'ethsw set_access_port "{self._name}" {nio} {vlan_id}')
|
||||
|
||||
log.info(
|
||||
'Ethernet switch "{name}" [{id}]: port {port} set as an access port in VLAN {vlan_id}'.format(
|
||||
name=self._name, id=self._id, port=port_number, vlan_id=vlan_id
|
||||
)
|
||||
f'Ethernet switch "{self._name}" [{self._id}]: port {port_number} set as an access port in VLAN {vlan_id}'
|
||||
)
|
||||
self._mappings[port_number] = ("access", vlan_id)
|
||||
|
||||
@ -390,16 +374,10 @@ class EthernetSwitch(Device):
|
||||
raise DynamipsError(f"Port {port_number} is not allocated")
|
||||
|
||||
nio = self._nios[port_number]
|
||||
await self._hypervisor.send(
|
||||
'ethsw set_dot1q_port "{name}" {nio} {native_vlan}'.format(
|
||||
name=self._name, nio=nio, native_vlan=native_vlan
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'ethsw set_dot1q_port "{self._name}" {nio} {native_vlan}')
|
||||
|
||||
log.info(
|
||||
'Ethernet switch "{name}" [{id}]: port {port} set as a 802.1Q port with native VLAN {vlan_id}'.format(
|
||||
name=self._name, id=self._id, port=port_number, vlan_id=native_vlan
|
||||
)
|
||||
f'Ethernet switch "{self._name}" [{self._id}]: port {port_number} set as a 802.1Q port with native VLAN {native_vlan}'
|
||||
)
|
||||
|
||||
self._mappings[port_number] = ("dot1q", native_vlan)
|
||||
@ -428,9 +406,7 @@ class EthernetSwitch(Device):
|
||||
)
|
||||
|
||||
log.info(
|
||||
'Ethernet switch "{name}" [{id}]: port {port} set as a QinQ ({ethertype}) port with outer VLAN {vlan_id}'.format(
|
||||
name=self._name, id=self._id, port=port_number, vlan_id=outer_vlan, ethertype=ethertype
|
||||
)
|
||||
f'Ethernet switch "{self._name}" [{self._id}]: port {port_number} set as a QinQ ({ethertype}) port with outer VLAN {outer_vlan}'
|
||||
)
|
||||
self._mappings[port_number] = ("qinq", outer_vlan, ethertype)
|
||||
|
||||
@ -469,11 +445,7 @@ class EthernetSwitch(Device):
|
||||
raise DynamipsError(f"Port {port_number} has already a filter applied")
|
||||
|
||||
await nio.start_packet_capture(output_file, data_link_type)
|
||||
log.info(
|
||||
'Ethernet switch "{name}" [{id}]: starting packet capture on port {port}'.format(
|
||||
name=self._name, id=self._id, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Ethernet switch "{self._name}" [{self._id}]: starting packet capture on port {port_number}')
|
||||
|
||||
async def stop_capture(self, port_number):
|
||||
"""
|
||||
@ -486,8 +458,4 @@ class EthernetSwitch(Device):
|
||||
if not nio.capturing:
|
||||
return
|
||||
await nio.stop_packet_capture()
|
||||
log.info(
|
||||
'Ethernet switch "{name}" [{id}]: stopping packet capture on port {port}'.format(
|
||||
name=self._name, id=self._id, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Ethernet switch "{self._name}" [{self._id}]: stopping packet capture on port {port_number}')
|
||||
|
||||
@ -81,11 +81,7 @@ class FrameRelaySwitch(Device):
|
||||
"""
|
||||
|
||||
await self._hypervisor.send(f'frsw rename "{self._name}" "{new_name}"')
|
||||
log.info(
|
||||
'Frame Relay switch "{name}" [{id}]: renamed to "{new_name}"'.format(
|
||||
name=self._name, id=self._id, new_name=new_name
|
||||
)
|
||||
)
|
||||
log.info(f'Frame Relay switch "{self._name}" [{self._id}]: renamed to "{new_name}"')
|
||||
self._name = new_name
|
||||
|
||||
@property
|
||||
@ -165,11 +161,7 @@ class FrameRelaySwitch(Device):
|
||||
if port_number in self._nios:
|
||||
raise DynamipsError(f"Port {port_number} isn't free")
|
||||
|
||||
log.info(
|
||||
'Frame Relay switch "{name}" [{id}]: NIO {nio} bound to port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Frame Relay switch "{self._name}" [{self._id}]: NIO {nio} bound to port {port_number}')
|
||||
|
||||
self._nios[port_number] = nio
|
||||
await self.set_mappings(self._mappings)
|
||||
@ -193,14 +185,7 @@ class FrameRelaySwitch(Device):
|
||||
destination_port, destination_dlci = destination
|
||||
if port_number == source_port:
|
||||
log.info(
|
||||
'Frame Relay switch "{name}" [{id}]: unmapping VC between port {source_port} DLCI {source_dlci} and port {destination_port} DLCI {destination_dlci}'.format(
|
||||
name=self._name,
|
||||
id=self._id,
|
||||
source_port=source_port,
|
||||
source_dlci=source_dlci,
|
||||
destination_port=destination_port,
|
||||
destination_dlci=destination_dlci,
|
||||
)
|
||||
f'Frame Relay switch "{self._name}" [{self._id}]: unmapping VC between port {source_port} DLCI {source_dlci} and port {destination_port} DLCI {destination_dlci}'
|
||||
)
|
||||
await self.unmap_vc(source_port, source_dlci, destination_port, destination_dlci)
|
||||
await self.unmap_vc(destination_port, destination_dlci, source_port, source_dlci)
|
||||
@ -209,11 +194,7 @@ class FrameRelaySwitch(Device):
|
||||
if isinstance(nio, NIOUDP):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
|
||||
log.info(
|
||||
'Frame Relay switch "{name}" [{id}]: NIO {nio} removed from port {port}'.format(
|
||||
name=self._name, id=self._id, nio=nio, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Frame Relay switch "{self._name}" [{self._id}]: NIO {nio} removed from port {port_number}')
|
||||
|
||||
del self._nios[port_number]
|
||||
return nio
|
||||
@ -255,14 +236,7 @@ class FrameRelaySwitch(Device):
|
||||
destination_dlci,
|
||||
) not in self._active_mappings:
|
||||
log.info(
|
||||
'Frame Relay switch "{name}" [{id}]: mapping VC between port {source_port} DLCI {source_dlci} and port {destination_port} DLCI {destination_dlci}'.format(
|
||||
name=self._name,
|
||||
id=self._id,
|
||||
source_port=source_port,
|
||||
source_dlci=source_dlci,
|
||||
destination_port=destination_port,
|
||||
destination_dlci=destination_dlci,
|
||||
)
|
||||
f'Frame Relay switch "{self._name}" [{self._id}]: mapping VC between port {source_port} DLCI {source_dlci} and port {destination_port} DLCI {destination_dlci}'
|
||||
)
|
||||
|
||||
await self.map_vc(source_port, source_dlci, destination_port, destination_dlci)
|
||||
@ -287,16 +261,10 @@ class FrameRelaySwitch(Device):
|
||||
nio1 = self._nios[port1]
|
||||
nio2 = self._nios[port2]
|
||||
|
||||
await self._hypervisor.send(
|
||||
'frsw create_vc "{name}" {input_nio} {input_dlci} {output_nio} {output_dlci}'.format(
|
||||
name=self._name, input_nio=nio1, input_dlci=dlci1, output_nio=nio2, output_dlci=dlci2
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'frsw create_vc "{self._name}" {nio1} {dlci1} {nio2} {dlci2}')
|
||||
|
||||
log.info(
|
||||
'Frame Relay switch "{name}" [{id}]: VC from port {port1} DLCI {dlci1} to port {port2} DLCI {dlci2} created'.format(
|
||||
name=self._name, id=self._id, port1=port1, dlci1=dlci1, port2=port2, dlci2=dlci2
|
||||
)
|
||||
f'Frame Relay switch "{self._name}" [{self._id}]: VC from port {port1} DLCI {dlci1} to port {port2} DLCI {dlci2} created'
|
||||
)
|
||||
|
||||
self._active_mappings[(port1, dlci1)] = (port2, dlci2)
|
||||
@ -320,16 +288,10 @@ class FrameRelaySwitch(Device):
|
||||
nio1 = self._nios[port1]
|
||||
nio2 = self._nios[port2]
|
||||
|
||||
await self._hypervisor.send(
|
||||
'frsw delete_vc "{name}" {input_nio} {input_dlci} {output_nio} {output_dlci}'.format(
|
||||
name=self._name, input_nio=nio1, input_dlci=dlci1, output_nio=nio2, output_dlci=dlci2
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'frsw delete_vc "{self._name}" {nio1} {dlci1} {nio2} {dlci2}')
|
||||
|
||||
log.info(
|
||||
'Frame Relay switch "{name}" [{id}]: VC from port {port1} DLCI {dlci1} to port {port2} DLCI {dlci2} deleted'.format(
|
||||
name=self._name, id=self._id, port1=port1, dlci1=dlci1, port2=port2, dlci2=dlci2
|
||||
)
|
||||
f'Frame Relay switch "{self._name}" [{self._id}]: VC from port {port1} DLCI {dlci1} to port {port2} DLCI {dlci2} deleted'
|
||||
)
|
||||
del self._active_mappings[(port1, dlci1)]
|
||||
|
||||
@ -352,11 +314,7 @@ class FrameRelaySwitch(Device):
|
||||
raise DynamipsError(f"Port {port_number} has already a filter applied")
|
||||
|
||||
await nio.start_packet_capture(output_file, data_link_type)
|
||||
log.info(
|
||||
'Frame relay switch "{name}" [{id}]: starting packet capture on port {port}'.format(
|
||||
name=self._name, id=self._id, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Frame relay switch "{self._name}" [{self._id}]: starting packet capture on port {port_number}')
|
||||
|
||||
async def stop_capture(self, port_number):
|
||||
"""
|
||||
@ -369,8 +327,4 @@ class FrameRelaySwitch(Device):
|
||||
if not nio.capturing:
|
||||
return
|
||||
await nio.stop_packet_capture()
|
||||
log.info(
|
||||
'Frame relay switch "{name}" [{id}]: stopping packet capture on port {port}'.format(
|
||||
name=self._name, id=self._id, port=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'Frame relay switch "{self._name}" [{self._id}]: stopping packet capture on port {port_number}')
|
||||
|
||||
@ -242,16 +242,10 @@ class Router(BaseNode):
|
||||
)
|
||||
await self._hypervisor.set_working_dir(self._working_directory)
|
||||
|
||||
await self._hypervisor.send(
|
||||
'vm create "{name}" {id} {platform}'.format(name=self._name, id=self._dynamips_id, platform=self._platform)
|
||||
)
|
||||
await self._hypervisor.send(f'vm create "{self._name}" {self._dynamips_id} {self._platform}')
|
||||
|
||||
if not self._ghost_flag:
|
||||
log.debug(
|
||||
'Router {platform} "{name}" [{id}] has been created'.format(
|
||||
name=self._name, platform=self._platform, id=self._id
|
||||
)
|
||||
)
|
||||
log.debug(f'Router {self._platform} "{self._name}" [{self._id}] has been created')
|
||||
|
||||
if self._console is not None:
|
||||
# For SSH console, tell Dynamips to listen on the internal port so that
|
||||
@ -326,11 +320,7 @@ class Router(BaseNode):
|
||||
# an empty private-config can prevent a router to boot.
|
||||
private_config_path = ""
|
||||
|
||||
await self._hypervisor.send(
|
||||
'vm set_config "{name}" "{startup}" "{private}"'.format(
|
||||
name=self._name, startup=startup_config_path, private=private_config_path
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'vm set_config "{self._name}" "{startup_config_path}" "{private_config_path}"')
|
||||
await self._hypervisor.send(f'vm start "{self._name}"')
|
||||
self.status = "started"
|
||||
log.debug(f'router "{self._name}" [{self._id}] has been started')
|
||||
@ -550,11 +540,7 @@ class Router(BaseNode):
|
||||
|
||||
await self._hypervisor.send(f'vm set_ios "{self._name}" "{image}"')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: has a new IOS image set: "{image}"'.format(
|
||||
name=self._name, id=self._id, image=image
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: has a new IOS image set: "{image}"')
|
||||
|
||||
self._image = image
|
||||
|
||||
@ -579,11 +565,7 @@ class Router(BaseNode):
|
||||
return
|
||||
|
||||
await self._hypervisor.send(f'vm set_ram "{self._name}" {ram}')
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: RAM updated from {old_ram}MB to {new_ram}MB'.format(
|
||||
name=self._name, id=self._id, old_ram=self._ram, new_ram=ram
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: RAM updated from {self._ram}MB to {ram}MB')
|
||||
self._ram = ram
|
||||
|
||||
@property
|
||||
@ -607,11 +589,7 @@ class Router(BaseNode):
|
||||
return
|
||||
|
||||
await self._hypervisor.send(f'vm set_nvram "{self._name}" {nvram}')
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: NVRAM updated from {old_nvram}KB to {new_nvram}KB'.format(
|
||||
name=self._name, id=self._id, old_nvram=self._nvram, new_nvram=nvram
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: NVRAM updated from {self._nvram}KB to {nvram}KB')
|
||||
self._nvram = nvram
|
||||
|
||||
@property
|
||||
@ -694,9 +672,7 @@ class Router(BaseNode):
|
||||
|
||||
await self._hypervisor.send(f'vm set_clock_divisor "{self._name}" {clock_divisor}')
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: clock divisor updated from {old_clock} to {new_clock}'.format(
|
||||
name=self._name, id=self._id, old_clock=self._clock_divisor, new_clock=clock_divisor
|
||||
)
|
||||
f'Router "{self._name}" [{self._id}]: clock divisor updated from {self._clock_divisor} to {clock_divisor}'
|
||||
)
|
||||
self._clock_divisor = clock_divisor
|
||||
|
||||
@ -750,9 +726,7 @@ class Router(BaseNode):
|
||||
begin = time.time()
|
||||
idlepcs = await self._hypervisor.send(f'vm get_idle_pc_prop "{self._name}" 0')
|
||||
log.debug(
|
||||
'Router "{name}" [{id}] has finished calculating Idle-PC values after {time:.4f} seconds'.format(
|
||||
name=self._name, id=self._id, time=time.time() - begin
|
||||
)
|
||||
f'Router "{self._name}" [{self._id}] has finished calculating Idle-PC values after {time.time() - begin:.4f} seconds'
|
||||
)
|
||||
if was_auto_started:
|
||||
await self.stop()
|
||||
@ -794,11 +768,7 @@ class Router(BaseNode):
|
||||
if is_running: # router is running
|
||||
await self._hypervisor.send(f'vm set_idle_max "{self._name}" 0 {idlemax}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: idlemax updated from {old_idlemax} to {new_idlemax}'.format(
|
||||
name=self._name, id=self._id, old_idlemax=self._idlemax, new_idlemax=idlemax
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: idlemax updated from {self._idlemax} to {idlemax}')
|
||||
|
||||
self._idlemax = idlemax
|
||||
|
||||
@ -821,15 +791,9 @@ class Router(BaseNode):
|
||||
|
||||
is_running = await self.is_running()
|
||||
if is_running: # router is running
|
||||
await self._hypervisor.send(
|
||||
'vm set_idle_sleep_time "{name}" 0 {idlesleep}'.format(name=self._name, idlesleep=idlesleep)
|
||||
)
|
||||
await self._hypervisor.send(f'vm set_idle_sleep_time "{self._name}" 0 {idlesleep}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: idlesleep updated from {old_idlesleep} to {new_idlesleep}'.format(
|
||||
name=self._name, id=self._id, old_idlesleep=self._idlesleep, new_idlesleep=idlesleep
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: idlesleep updated from {self._idlesleep} to {idlesleep}')
|
||||
|
||||
self._idlesleep = idlesleep
|
||||
|
||||
@ -850,15 +814,9 @@ class Router(BaseNode):
|
||||
:ghost_file: path to ghost file
|
||||
"""
|
||||
|
||||
await self._hypervisor.send(
|
||||
'vm set_ghost_file "{name}" "{ghost_file}"'.format(name=self._name, ghost_file=ghost_file)
|
||||
)
|
||||
await self._hypervisor.send(f'vm set_ghost_file "{self._name}" "{ghost_file}"')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: ghost file set to "{ghost_file}"'.format(
|
||||
name=self._name, id=self._id, ghost_file=ghost_file
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: ghost file set to "{ghost_file}"')
|
||||
|
||||
self._ghost_file = ghost_file
|
||||
|
||||
@ -893,15 +851,9 @@ class Router(BaseNode):
|
||||
2 => Use an existing ghost instance
|
||||
"""
|
||||
|
||||
await self._hypervisor.send(
|
||||
'vm set_ghost_status "{name}" {ghost_status}'.format(name=self._name, ghost_status=ghost_status)
|
||||
)
|
||||
await self._hypervisor.send(f'vm set_ghost_status "{self._name}" {ghost_status}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: ghost status set to {ghost_status}'.format(
|
||||
name=self._name, id=self._id, ghost_status=ghost_status
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: ghost status set to {ghost_status}')
|
||||
self._ghost_status = ghost_status
|
||||
|
||||
@property
|
||||
@ -924,15 +876,9 @@ class Router(BaseNode):
|
||||
:param exec_area: exec area value (integer)
|
||||
"""
|
||||
|
||||
await self._hypervisor.send(
|
||||
'vm set_exec_area "{name}" {exec_area}'.format(name=self._name, exec_area=exec_area)
|
||||
)
|
||||
await self._hypervisor.send(f'vm set_exec_area "{self._name}" {exec_area}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: exec area updated from {old_exec}MB to {new_exec}MB'.format(
|
||||
name=self._name, id=self._id, old_exec=self._exec_area, new_exec=exec_area
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: exec area updated from {self._exec_area}MB to {exec_area}MB')
|
||||
self._exec_area = exec_area
|
||||
|
||||
@property
|
||||
@ -954,11 +900,7 @@ class Router(BaseNode):
|
||||
|
||||
await self._hypervisor.send(f'vm set_disk0 "{self._name}" {disk0}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: disk0 updated from {old_disk0}MB to {new_disk0}MB'.format(
|
||||
name=self._name, id=self._id, old_disk0=self._disk0, new_disk0=disk0
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: disk0 updated from {self._disk0}MB to {disk0}MB')
|
||||
self._disk0 = disk0
|
||||
|
||||
@property
|
||||
@ -980,11 +922,7 @@ class Router(BaseNode):
|
||||
|
||||
await self._hypervisor.send(f'vm set_disk1 "{self._name}" {disk1}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: disk1 updated from {old_disk1}MB to {new_disk1}MB'.format(
|
||||
name=self._name, id=self._id, old_disk1=self._disk1, new_disk1=disk1
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: disk1 updated from {self._disk1}MB to {disk1}MB')
|
||||
self._disk1 = disk1
|
||||
|
||||
@property
|
||||
@ -1031,11 +969,7 @@ class Router(BaseNode):
|
||||
if self.console_type != console_type:
|
||||
status = await self.get_status()
|
||||
if status == "running":
|
||||
raise DynamipsError(
|
||||
'"{name}" must be stopped to change the console type to {console_type}'.format(
|
||||
name=self._name, console_type=console_type
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f'"{self._name}" must be stopped to change the console type to {console_type}')
|
||||
|
||||
self.console_type = console_type
|
||||
|
||||
@ -1077,9 +1011,7 @@ class Router(BaseNode):
|
||||
status = await self.get_status()
|
||||
if status == "running":
|
||||
raise DynamipsError(
|
||||
'"{name}" must be stopped to change the auxiliary console type to {aux_type}'.format(
|
||||
name=self._name, aux_type=aux_type
|
||||
)
|
||||
f'"{self._name}" must be stopped to change the auxiliary console type to {aux_type}'
|
||||
)
|
||||
|
||||
self.aux_type = aux_type
|
||||
@ -1133,17 +1065,9 @@ class Router(BaseNode):
|
||||
:param mac_addr: a MAC address (hexadecimal format: hh:hh:hh:hh:hh:hh)
|
||||
"""
|
||||
|
||||
await self._hypervisor.send(
|
||||
'{platform} set_mac_addr "{name}" {mac_addr}'.format(
|
||||
platform=self._platform, name=self._name, mac_addr=mac_addr
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'{self._platform} set_mac_addr "{self._name}" {mac_addr}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: MAC address updated from {old_mac} to {new_mac}'.format(
|
||||
name=self._name, id=self._id, old_mac=self._mac_addr, new_mac=mac_addr
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: MAC address updated from {self._mac_addr} to {mac_addr}')
|
||||
self._mac_addr = mac_addr
|
||||
|
||||
@property
|
||||
@ -1163,17 +1087,9 @@ class Router(BaseNode):
|
||||
:param system_id: a system ID (also called board processor ID)
|
||||
"""
|
||||
|
||||
await self._hypervisor.send(
|
||||
'{platform} set_system_id "{name}" {system_id}'.format(
|
||||
platform=self._platform, name=self._name, system_id=system_id
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'{self._platform} set_system_id "{self._name}" {system_id}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: system ID updated from {old_id} to {new_id}'.format(
|
||||
name=self._name, id=self._id, old_id=self._system_id, new_id=system_id
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: system ID updated from {self._system_id} to {system_id}')
|
||||
self._system_id = system_id
|
||||
|
||||
async def get_slot_bindings(self):
|
||||
@ -1202,9 +1118,7 @@ class Router(BaseNode):
|
||||
if slot is not None:
|
||||
current_adapter = slot
|
||||
raise DynamipsError(
|
||||
'Slot {slot_number} is already occupied by adapter {adapter} on router "{name}"'.format(
|
||||
name=self._name, slot_number=slot_number, adapter=current_adapter
|
||||
)
|
||||
f'Slot {slot_number} is already occupied by adapter {current_adapter} on router "{self._name}"'
|
||||
)
|
||||
|
||||
is_running = await self.is_running()
|
||||
@ -1215,37 +1129,19 @@ class Router(BaseNode):
|
||||
and not (self._platform == "c3600" and self.chassis == "3660")
|
||||
and not (self._platform == "c3745" and adapter == "NM-4T")
|
||||
):
|
||||
raise DynamipsError(
|
||||
'Adapter {adapter} cannot be added while router "{name}" is running'.format(
|
||||
adapter=adapter, name=self._name
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f'Adapter {adapter} cannot be added while router "{self._name}" is running')
|
||||
|
||||
await self._hypervisor.send(
|
||||
'vm slot_add_binding "{name}" {slot_number} 0 {adapter}'.format(
|
||||
name=self._name, slot_number=slot_number, adapter=adapter
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_add_binding "{self._name}" {slot_number} 0 {adapter}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: adapter {adapter} inserted into slot {slot_number}'.format(
|
||||
name=self._name, id=self._id, adapter=adapter, slot_number=slot_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: adapter {adapter} inserted into slot {slot_number}')
|
||||
|
||||
self._slots[slot_number] = adapter
|
||||
|
||||
# Generate an OIR event if the router is running
|
||||
if is_running:
|
||||
await self._hypervisor.send(
|
||||
'vm slot_oir_start "{name}" {slot_number} 0'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_oir_start "{self._name}" {slot_number} 0')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: OIR start event sent to slot {slot_number}'.format(
|
||||
name=self._name, id=self._id, slot_number=slot_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: OIR start event sent to slot {slot_number}')
|
||||
|
||||
async def slot_remove_binding(self, slot_number):
|
||||
"""
|
||||
@ -1257,14 +1153,10 @@ class Router(BaseNode):
|
||||
try:
|
||||
adapter = self._slots[slot_number]
|
||||
except IndexError:
|
||||
raise DynamipsError(
|
||||
'Slot {slot_number} does not exist on router "{name}"'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
raise DynamipsError(f'Slot {slot_number} does not exist on router "{self._name}"')
|
||||
|
||||
if adapter is None:
|
||||
raise DynamipsError(
|
||||
'No adapter in slot {slot_number} on router "{name}"'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
raise DynamipsError(f'No adapter in slot {slot_number} on router "{self._name}"')
|
||||
|
||||
is_running = await self.is_running()
|
||||
|
||||
@ -1274,33 +1166,17 @@ class Router(BaseNode):
|
||||
and not (self._platform == "c3600" and self.chassis == "3660")
|
||||
and not (self._platform == "c3745" and adapter == "NM-4T")
|
||||
):
|
||||
raise DynamipsError(
|
||||
'Adapter {adapter} cannot be removed while router "{name}" is running'.format(
|
||||
adapter=adapter, name=self._name
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f'Adapter {adapter} cannot be removed while router "{self._name}" is running')
|
||||
|
||||
# Generate an OIR event if the router is running
|
||||
if is_running:
|
||||
await self._hypervisor.send(
|
||||
'vm slot_oir_stop "{name}" {slot_number} 0'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_oir_stop "{self._name}" {slot_number} 0')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: OIR stop event sent to slot {slot_number}'.format(
|
||||
name=self._name, id=self._id, slot_number=slot_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: OIR stop event sent to slot {slot_number}')
|
||||
|
||||
await self._hypervisor.send(
|
||||
'vm slot_remove_binding "{name}" {slot_number} 0'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_remove_binding "{self._name}" {slot_number} 0')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: adapter {adapter} removed from slot {slot_number}'.format(
|
||||
name=self._name, id=self._id, adapter=adapter, slot_number=slot_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: adapter {adapter} removed from slot {slot_number}')
|
||||
self._slots[slot_number] = None
|
||||
|
||||
async def install_wic(self, wic_slot_number, wic):
|
||||
@ -1325,24 +1201,16 @@ class Router(BaseNode):
|
||||
raise DynamipsError(f"WIC slot {wic_slot_number} is already occupied by another WIC")
|
||||
|
||||
if await self.is_running():
|
||||
raise DynamipsError(
|
||||
'WIC "{wic}" cannot be added while router "{name}" is running'.format(wic=wic, name=self._name)
|
||||
)
|
||||
raise DynamipsError(f'WIC "{wic}" cannot be added while router "{self._name}" is running')
|
||||
|
||||
# Dynamips WICs slot IDs start on a multiple of 16
|
||||
# WIC1 = 16, WIC2 = 32 and WIC3 = 48
|
||||
internal_wic_slot_number = 16 * (wic_slot_number + 1)
|
||||
await self._hypervisor.send(
|
||||
'vm slot_add_binding "{name}" {slot_number} {wic_slot_number} {wic}'.format(
|
||||
name=self._name, slot_number=slot_number, wic_slot_number=internal_wic_slot_number, wic=wic
|
||||
)
|
||||
f'vm slot_add_binding "{self._name}" {slot_number} {internal_wic_slot_number} {wic}'
|
||||
)
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: {wic} inserted into WIC slot {wic_slot_number}'.format(
|
||||
name=self._name, id=self._id, wic=wic, wic_slot_number=wic_slot_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: {wic} inserted into WIC slot {wic_slot_number}')
|
||||
|
||||
adapter.install_wic(wic_slot_number, wic)
|
||||
|
||||
@ -1368,24 +1236,16 @@ class Router(BaseNode):
|
||||
|
||||
if await self.is_running():
|
||||
raise DynamipsError(
|
||||
'WIC cannot be removed from slot {wic_slot_number} while router "{name}" is running'.format(
|
||||
wic_slot_number=wic_slot_number, name=self._name
|
||||
)
|
||||
f'WIC cannot be removed from slot {wic_slot_number} while router "{self._name}" is running'
|
||||
)
|
||||
|
||||
# Dynamips WICs slot IDs start on a multiple of 16
|
||||
# WIC1 = 16, WIC2 = 32 and WIC3 = 48
|
||||
internal_wic_slot_number = 16 * (wic_slot_number + 1)
|
||||
await self._hypervisor.send(
|
||||
'vm slot_remove_binding "{name}" {slot_number} {wic_slot_number}'.format(
|
||||
name=self._name, slot_number=slot_number, wic_slot_number=internal_wic_slot_number
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_remove_binding "{self._name}" {slot_number} {internal_wic_slot_number}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: {wic} removed from WIC slot {wic_slot_number}'.format(
|
||||
name=self._name, id=self._id, wic=adapter.wics[wic_slot_number], wic_slot_number=wic_slot_number
|
||||
)
|
||||
f'Router "{self._name}" [{self._id}]: {adapter.wics[wic_slot_number]} removed from WIC slot {wic_slot_number}'
|
||||
)
|
||||
adapter.uninstall_wic(wic_slot_number)
|
||||
|
||||
@ -1398,9 +1258,7 @@ class Router(BaseNode):
|
||||
:returns: list of NIO bindings
|
||||
"""
|
||||
|
||||
nio_bindings = await self._hypervisor.send(
|
||||
'vm slot_nio_bindings "{name}" {slot_number}'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
nio_bindings = await self._hypervisor.send(f'vm slot_nio_bindings "{self._name}" {slot_number}')
|
||||
return nio_bindings
|
||||
|
||||
async def slot_add_nio_binding(self, slot_number, port_number, nio):
|
||||
@ -1415,44 +1273,22 @@ class Router(BaseNode):
|
||||
try:
|
||||
adapter = self._slots[slot_number]
|
||||
except IndexError:
|
||||
raise DynamipsError(
|
||||
'Slot {slot_number} does not exist on router "{name}"'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
raise DynamipsError(f'Slot {slot_number} does not exist on router "{self._name}"')
|
||||
|
||||
if adapter is None:
|
||||
raise DynamipsError(f"Adapter is missing in slot {slot_number}")
|
||||
|
||||
if not adapter.port_exists(port_number):
|
||||
raise DynamipsError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f"Port {port_number} does not exist on adapter {adapter}")
|
||||
|
||||
try:
|
||||
await self._hypervisor.send(
|
||||
'vm slot_add_nio_binding "{name}" {slot_number} {port_number} {nio}'.format(
|
||||
name=self._name, slot_number=slot_number, port_number=port_number, nio=nio
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_add_nio_binding "{self._name}" {slot_number} {port_number} {nio}')
|
||||
except DynamipsError:
|
||||
# in case of error try to remove and add the nio binding
|
||||
await self._hypervisor.send(
|
||||
'vm slot_remove_nio_binding "{name}" {slot_number} {port_number}'.format(
|
||||
name=self._name, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(
|
||||
'vm slot_add_nio_binding "{name}" {slot_number} {port_number} {nio}'.format(
|
||||
name=self._name, slot_number=slot_number, port_number=port_number, nio=nio
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_remove_nio_binding "{self._name}" {slot_number} {port_number}')
|
||||
await self._hypervisor.send(f'vm slot_add_nio_binding "{self._name}" {slot_number} {port_number} {nio}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: NIO {nio_name} bound to port {slot_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, nio_name=nio.name, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: NIO {nio.name} bound to port {slot_number}/{port_number}')
|
||||
|
||||
await self.slot_enable_nio(slot_number, port_number)
|
||||
adapter.add_nio(port_number, nio)
|
||||
@ -1481,27 +1317,17 @@ class Router(BaseNode):
|
||||
try:
|
||||
adapter = self._slots[slot_number]
|
||||
except IndexError:
|
||||
raise DynamipsError(
|
||||
'Slot {slot_number} does not exist on router "{name}"'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
raise DynamipsError(f'Slot {slot_number} does not exist on router "{self._name}"')
|
||||
|
||||
if adapter is None:
|
||||
raise DynamipsError(f"Adapter is missing in slot {slot_number}")
|
||||
|
||||
if not adapter.port_exists(port_number):
|
||||
raise DynamipsError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f"Port {port_number} does not exist on adapter {adapter}")
|
||||
|
||||
await self.stop_capture(slot_number, port_number)
|
||||
await self.slot_disable_nio(slot_number, port_number)
|
||||
await self._hypervisor.send(
|
||||
'vm slot_remove_nio_binding "{name}" {slot_number} {port_number}'.format(
|
||||
name=self._name, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_remove_nio_binding "{self._name}" {slot_number} {port_number}')
|
||||
|
||||
nio = adapter.get_nio(port_number)
|
||||
if nio is None:
|
||||
@ -1509,11 +1335,7 @@ class Router(BaseNode):
|
||||
await nio.close()
|
||||
adapter.remove_nio(port_number)
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: NIO {nio_name} removed from port {slot_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, nio_name=nio.name, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: NIO {nio.name} removed from port {slot_number}/{port_number}')
|
||||
|
||||
return nio
|
||||
|
||||
@ -1527,17 +1349,9 @@ class Router(BaseNode):
|
||||
|
||||
is_running = await self.is_running()
|
||||
if is_running: # running router
|
||||
await self._hypervisor.send(
|
||||
'vm slot_enable_nio "{name}" {slot_number} {port_number}'.format(
|
||||
name=self._name, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_enable_nio "{self._name}" {slot_number} {port_number}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: NIO enabled on port {slot_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: NIO enabled on port {slot_number}/{port_number}')
|
||||
|
||||
def get_nio(self, slot_number, port_number):
|
||||
"""
|
||||
@ -1552,24 +1366,14 @@ class Router(BaseNode):
|
||||
try:
|
||||
adapter = self._slots[slot_number]
|
||||
except IndexError:
|
||||
raise DynamipsError(
|
||||
'Slot {slot_number} does not exist on router "{name}"'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
raise DynamipsError(f'Slot {slot_number} does not exist on router "{self._name}"')
|
||||
if not adapter.port_exists(port_number):
|
||||
raise DynamipsError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f"Port {port_number} does not exist on adapter {adapter}")
|
||||
|
||||
nio = adapter.get_nio(port_number)
|
||||
|
||||
if not nio:
|
||||
raise DynamipsError(
|
||||
"Port {slot_number}/{port_number} is not connected".format(
|
||||
slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f"Port {slot_number}/{port_number} is not connected")
|
||||
return nio
|
||||
|
||||
async def slot_disable_nio(self, slot_number, port_number):
|
||||
@ -1582,17 +1386,9 @@ class Router(BaseNode):
|
||||
|
||||
is_running = await self.is_running()
|
||||
if is_running: # running router
|
||||
await self._hypervisor.send(
|
||||
'vm slot_disable_nio "{name}" {slot_number} {port_number}'.format(
|
||||
name=self._name, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
await self._hypervisor.send(f'vm slot_disable_nio "{self._name}" {slot_number} {port_number}')
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: NIO disabled on port {slot_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: NIO disabled on port {slot_number}/{port_number}')
|
||||
|
||||
async def start_capture(self, slot_number, port_number, output_file, data_link_type="DLT_EN10MB"):
|
||||
"""
|
||||
@ -1612,15 +1408,9 @@ class Router(BaseNode):
|
||||
try:
|
||||
adapter = self._slots[slot_number]
|
||||
except IndexError:
|
||||
raise DynamipsError(
|
||||
'Slot {slot_number} does not exist on router "{name}"'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
raise DynamipsError(f'Slot {slot_number} does not exist on router "{self._name}"')
|
||||
if not adapter.port_exists(port_number):
|
||||
raise DynamipsError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f"Port {port_number} does not exist on adapter {adapter}")
|
||||
|
||||
data_link_type = data_link_type.lower()
|
||||
if data_link_type.startswith("dlt_"):
|
||||
@ -1629,24 +1419,12 @@ class Router(BaseNode):
|
||||
nio = adapter.get_nio(port_number)
|
||||
|
||||
if not nio:
|
||||
raise DynamipsError(
|
||||
"Port {slot_number}/{port_number} is not connected".format(
|
||||
slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f"Port {slot_number}/{port_number} is not connected")
|
||||
|
||||
if nio.input_filter[0] is not None and nio.output_filter[0] is not None:
|
||||
raise DynamipsError(
|
||||
"Port {port_number} has already a filter applied on {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f"Port {port_number} has already a filter applied on {adapter}")
|
||||
await nio.start_packet_capture(output_file, data_link_type)
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: starting packet capture on port {slot_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: starting packet capture on port {slot_number}/{port_number}')
|
||||
|
||||
async def stop_capture(self, slot_number, port_number):
|
||||
"""
|
||||
@ -1659,34 +1437,20 @@ class Router(BaseNode):
|
||||
try:
|
||||
adapter = self._slots[slot_number]
|
||||
except IndexError:
|
||||
raise DynamipsError(
|
||||
'Slot {slot_number} does not exist on router "{name}"'.format(name=self._name, slot_number=slot_number)
|
||||
)
|
||||
raise DynamipsError(f'Slot {slot_number} does not exist on router "{self._name}"')
|
||||
if not adapter.port_exists(port_number):
|
||||
raise DynamipsError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f"Port {port_number} does not exist on adapter {adapter}")
|
||||
|
||||
nio = adapter.get_nio(port_number)
|
||||
|
||||
if not nio:
|
||||
raise DynamipsError(
|
||||
"Port {slot_number}/{port_number} is not connected".format(
|
||||
slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise DynamipsError(f"Port {slot_number}/{port_number} is not connected")
|
||||
|
||||
if not nio.capturing:
|
||||
return
|
||||
await nio.stop_packet_capture()
|
||||
|
||||
log.debug(
|
||||
'Router "{name}" [{id}]: stopping packet capture on port {slot_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, slot_number=slot_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'Router "{self._name}" [{self._id}]: stopping packet capture on port {slot_number}/{port_number}')
|
||||
|
||||
def _create_slots(self, numslots):
|
||||
"""
|
||||
|
||||
@ -162,11 +162,7 @@ class IOUVM(BaseNode):
|
||||
|
||||
super().__init__(name, node_id, project, manager, console=console, console_type=console_type)
|
||||
|
||||
log.debug(
|
||||
'IOU "{name}" [{id}]: assigned with application ID {application_id}'.format(
|
||||
name=self._name, id=self._id, application_id=application_id
|
||||
)
|
||||
)
|
||||
log.debug(f'IOU "{self._name}" [{self._id}]: assigned with application ID {application_id}')
|
||||
|
||||
self._iou_process = None
|
||||
self._telnet_server = None
|
||||
@ -428,11 +424,7 @@ class IOUVM(BaseNode):
|
||||
if self._ram == ram:
|
||||
return
|
||||
|
||||
log.debug(
|
||||
'IOU "{name}" [{id}]: RAM updated from {old_ram}MB to {new_ram}MB'.format(
|
||||
name=self._name, id=self._id, old_ram=self._ram, new_ram=ram
|
||||
)
|
||||
)
|
||||
log.debug(f'IOU "{self._name}" [{self._id}]: RAM updated from {self._ram}MB to {ram}MB')
|
||||
|
||||
self._ram = ram
|
||||
|
||||
@ -457,11 +449,7 @@ class IOUVM(BaseNode):
|
||||
if self._nvram == nvram:
|
||||
return
|
||||
|
||||
log.debug(
|
||||
'IOU "{name}" [{id}]: NVRAM updated from {old_nvram}KB to {new_nvram}KB'.format(
|
||||
name=self._name, id=self._id, old_nvram=self._nvram, new_nvram=nvram
|
||||
)
|
||||
)
|
||||
log.debug(f'IOU "{self._name}" [{self._id}]: NVRAM updated from {self._nvram}KB to {nvram}KB')
|
||||
self._nvram = nvram
|
||||
|
||||
@property
|
||||
@ -622,9 +610,7 @@ class IOUVM(BaseNode):
|
||||
ioukey = hashlib.md5(pad1 + pad2 + struct.pack("!I", ioukey) + pad1).hexdigest()[:16]
|
||||
if ioukey != user_ioukey:
|
||||
raise IOUError(
|
||||
"Invalid IOU license key {} detected in iourc file {} for host {}".format(
|
||||
user_ioukey, self.iourc_path, hostname
|
||||
)
|
||||
f"Invalid IOU license key {user_ioukey} detected in iourc file {self.iourc_path} for host {hostname}"
|
||||
)
|
||||
|
||||
def _nvram_file(self):
|
||||
@ -780,9 +766,7 @@ class IOUVM(BaseNode):
|
||||
except OSError as e:
|
||||
await self.stop()
|
||||
raise IOUError(
|
||||
"Could not start {} server on socket {}:{}: {}".format(
|
||||
error_prefix, self._manager.port_manager.console_host, self.console, e
|
||||
)
|
||||
f"Could not start {error_prefix} server on socket {self._manager.port_manager.console_host}:{self.console}: {e}"
|
||||
)
|
||||
|
||||
async def reset_console(self):
|
||||
@ -818,15 +802,7 @@ class IOUVM(BaseNode):
|
||||
nio = adapter.get_nio(unit)
|
||||
if nio and isinstance(nio, NIOUDP):
|
||||
await 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,
|
||||
)
|
||||
f"iol_bridge add_nio_udp {bridge_name} {self.application_id} {bay_id} {unit_id} {nio.lport} {nio.rhost} {nio.rport}"
|
||||
)
|
||||
if nio.capturing:
|
||||
await self._ubridge_send(
|
||||
@ -855,9 +831,7 @@ class IOUVM(BaseNode):
|
||||
self._stop_l1_keepalive_responder()
|
||||
if returncode != 0:
|
||||
if returncode == -11:
|
||||
message = 'IOU VM "{}" process has stopped with return code: {} (segfault). This could be an issue with the IOU image, using a different image may fix this.\n{}'.format(
|
||||
self.name, returncode, self.read_iou_stdout()
|
||||
)
|
||||
message = f'IOU VM "{self.name}" process has stopped with return code: {returncode} (segfault). This could be an issue with the IOU image, using a different image may fix this.\n{self.read_iou_stdout()}'
|
||||
else:
|
||||
message = (
|
||||
f'IOU VM "{self.name}" process has stopped with return code: {returncode}\n{self.read_iou_stdout()}'
|
||||
@ -980,15 +954,8 @@ class IOUVM(BaseNode):
|
||||
with open(netmap_path, "w", encoding="utf-8") as f:
|
||||
for bay in range(0, 16):
|
||||
for unit in range(0, 4):
|
||||
f.write(
|
||||
"{ubridge_id}:{bay}/{unit}{iou_id:>5d}:{bay}/{unit}\n".format(
|
||||
ubridge_id=str(self.application_id + 512),
|
||||
bay=bay,
|
||||
unit=unit,
|
||||
iou_id=self.application_id,
|
||||
)
|
||||
)
|
||||
log.debug("IOU {name} [id={id}]: NETMAP file created".format(name=self._name, id=self._id))
|
||||
f.write(f"{self.application_id + 512!s}:{bay}/{unit}{self.application_id:>5d}:{bay}/{unit}\n")
|
||||
log.debug(f"IOU {self._name} [id={self._id}]: NETMAP file created")
|
||||
except OSError as e:
|
||||
raise IOUError(f"Could not create {netmap_path}: {e}")
|
||||
|
||||
@ -1160,9 +1127,7 @@ class IOUVM(BaseNode):
|
||||
self._ethernet_adapters.append(EthernetAdapter(interfaces=4))
|
||||
|
||||
log.debug(
|
||||
'IOU "{name}" [{id}]: number of Ethernet adapters changed to {adapters}'.format(
|
||||
name=self._name, id=self._id, adapters=len(self._ethernet_adapters)
|
||||
)
|
||||
f'IOU "{self._name}" [{self._id}]: number of Ethernet adapters changed to {len(self._ethernet_adapters)}'
|
||||
)
|
||||
|
||||
self._adapters = self._ethernet_adapters + self._serial_adapters
|
||||
@ -1189,11 +1154,7 @@ class IOUVM(BaseNode):
|
||||
for _ in range(0, serial_adapters):
|
||||
self._serial_adapters.append(SerialAdapter(interfaces=4))
|
||||
|
||||
log.debug(
|
||||
'IOU "{name}" [{id}]: number of Serial adapters changed to {adapters}'.format(
|
||||
name=self._name, id=self._id, adapters=len(self._serial_adapters)
|
||||
)
|
||||
)
|
||||
log.debug(f'IOU "{self._name}" [{self._id}]: number of Serial adapters changed to {len(self._serial_adapters)}')
|
||||
|
||||
self._adapters = self._ethernet_adapters + self._serial_adapters
|
||||
|
||||
@ -1209,38 +1170,18 @@ class IOUVM(BaseNode):
|
||||
try:
|
||||
adapter = self._adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise IOUError(
|
||||
'Adapter {adapter_number} does not exist for IOU "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise IOUError(f'Adapter {adapter_number} does not exist for IOU "{self._name}"')
|
||||
|
||||
if not adapter.port_exists(port_number):
|
||||
raise IOUError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise IOUError(f"Port {port_number} does not exist on adapter {adapter}")
|
||||
|
||||
adapter.add_nio(port_number, nio)
|
||||
log.debug(
|
||||
'IOU "{name}" [{id}]: {nio} added to {adapter_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, nio=nio, adapter_number=adapter_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'IOU "{self._name}" [{self._id}]: {nio} added to {adapter_number}/{port_number}')
|
||||
|
||||
if self.ubridge:
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
await 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=adapter_number,
|
||||
unit=port_number,
|
||||
lport=nio.lport,
|
||||
rhost=nio.rhost,
|
||||
rport=nio.rport,
|
||||
)
|
||||
f"iol_bridge add_nio_udp {bridge_name} {self.application_id} {adapter_number} {port_number} {nio.lport} {nio.rhost} {nio.rport}"
|
||||
)
|
||||
await self._ubridge_apply_filters(adapter_number, port_number, nio.filters)
|
||||
await self._ubridge_apply_markers(adapter_number, port_number, nio)
|
||||
@ -1267,10 +1208,10 @@ class IOUVM(BaseNode):
|
||||
:param filters: Array of filter dictionnary
|
||||
"""
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
location = "{bridge_name} {bay} {unit}".format(bridge_name=bridge_name, bay=adapter_number, unit=port_number)
|
||||
location = f"{bridge_name} {adapter_number} {port_number}"
|
||||
await self._ubridge_send("iol_bridge reset_packet_filters " + location)
|
||||
for filter in self._build_filter_list(filters):
|
||||
cmd = "iol_bridge add_packet_filter {} {}".format(location, filter)
|
||||
cmd = f"iol_bridge add_packet_filter {location} {filter}"
|
||||
await self._ubridge_send(cmd)
|
||||
|
||||
async def _ubridge_apply_markers(self, adapter_number, port_number, nio):
|
||||
@ -1294,7 +1235,7 @@ class IOUVM(BaseNode):
|
||||
manager = MarkerManager.instance()
|
||||
markers_dir = self.project.markers_working_directory()
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
location = "{bridge_name} {bay} {unit}".format(bridge_name=bridge_name, bay=adapter_number, unit=port_number)
|
||||
location = f"{bridge_name} {adapter_number} {port_number}"
|
||||
desired = {(name, spec.get("link_id", "")): spec for name, spec in markers.items()}
|
||||
|
||||
# 1. Remove installed markers that are no longer desired.
|
||||
@ -1338,7 +1279,7 @@ class IOUVM(BaseNode):
|
||||
continue
|
||||
pcap_path = os.path.join(markers_dir, f"{self._id}_{link_id}_{name}.pcap")
|
||||
# iol_bridge add_packet_filter {br} {bay} {unit} {name} mark "{bpf}" [tag {id}] pcap "{path}"
|
||||
cmd = 'iol_bridge add_packet_filter {loc} {name} mark "{bpf}"'.format(loc=location, name=name, bpf=bpf)
|
||||
cmd = f'iol_bridge add_packet_filter {location} {name} mark "{bpf}"'
|
||||
if tag is not None:
|
||||
cmd += f" tag {tag}"
|
||||
if link_id:
|
||||
@ -1349,7 +1290,7 @@ class IOUVM(BaseNode):
|
||||
linktype = self._marker_linktype(spec.get("data_link_type"))
|
||||
if linktype is not None:
|
||||
cmd += f" linktype {linktype}"
|
||||
cmd += ' pcap "{path}"'.format(path=pcap_path)
|
||||
cmd += f' pcap "{pcap_path}"'
|
||||
try:
|
||||
await self._ubridge_send(cmd)
|
||||
except UbridgeError as e:
|
||||
@ -1400,36 +1341,20 @@ class IOUVM(BaseNode):
|
||||
try:
|
||||
adapter = self._adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise IOUError(
|
||||
'Adapter {adapter_number} does not exist on IOU "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise IOUError(f'Adapter {adapter_number} does not exist on IOU "{self._name}"')
|
||||
|
||||
if not adapter.port_exists(port_number):
|
||||
raise IOUError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise IOUError(f"Port {port_number} does not exist on adapter {adapter}")
|
||||
|
||||
nio = adapter.get_nio(port_number)
|
||||
if isinstance(nio, NIOUDP):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
adapter.remove_nio(port_number)
|
||||
log.debug(
|
||||
'IOU "{name}" [{id}]: {nio} removed from {adapter_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, nio=nio, adapter_number=adapter_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'IOU "{self._name}" [{self._id}]: {nio} removed from {adapter_number}/{port_number}')
|
||||
|
||||
if self.ubridge:
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
await self._ubridge_send(
|
||||
"iol_bridge delete_nio_udp {name} {bay} {unit}".format(
|
||||
name=bridge_name, bay=adapter_number, unit=port_number
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f"iol_bridge delete_nio_udp {bridge_name} {adapter_number} {port_number}")
|
||||
|
||||
return nio
|
||||
|
||||
@ -1446,25 +1371,15 @@ class IOUVM(BaseNode):
|
||||
try:
|
||||
adapter = self._adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise IOUError(
|
||||
'Adapter {adapter_number} does not exist on IOU "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise IOUError(f'Adapter {adapter_number} does not exist on IOU "{self._name}"')
|
||||
|
||||
if not adapter.port_exists(port_number):
|
||||
raise IOUError(
|
||||
"Port {port_number} does not exist on adapter {adapter}".format(
|
||||
adapter=adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise IOUError(f"Port {port_number} does not exist on adapter {adapter}")
|
||||
|
||||
nio = adapter.get_nio(port_number)
|
||||
|
||||
if not nio:
|
||||
raise IOUError(
|
||||
"NIO {port_number} does not exist on adapter {adapter}".format(adapter=adapter, port_number=port_number)
|
||||
)
|
||||
raise IOUError(f"NIO {port_number} does not exist on adapter {adapter}")
|
||||
return nio
|
||||
|
||||
@property
|
||||
@ -1751,21 +1666,11 @@ class IOUVM(BaseNode):
|
||||
|
||||
nio = self.get_nio(adapter_number, port_number)
|
||||
if nio.capturing:
|
||||
raise IOUError(
|
||||
"Packet capture is already activated on {adapter_number}/{port_number}".format(
|
||||
adapter_number=adapter_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise IOUError(f"Packet capture is already activated on {adapter_number}/{port_number}")
|
||||
|
||||
nio.start_packet_capture(output_file, data_link_type)
|
||||
log.debug(
|
||||
'IOU "{name}" [{id}]: starting packet capture on {adapter_number}/{port_number} to {output_file}'.format(
|
||||
name=self._name,
|
||||
id=self._id,
|
||||
adapter_number=adapter_number,
|
||||
port_number=port_number,
|
||||
output_file=output_file,
|
||||
)
|
||||
f'IOU "{self._name}" [{self._id}]: starting packet capture on {adapter_number}/{port_number} to {output_file}'
|
||||
)
|
||||
|
||||
if self.ubridge:
|
||||
@ -1792,15 +1697,7 @@ class IOUVM(BaseNode):
|
||||
if not nio.capturing:
|
||||
return
|
||||
nio.stop_packet_capture()
|
||||
log.debug(
|
||||
'IOU "{name}" [{id}]: stopping packet capture on {adapter_number}/{port_number}'.format(
|
||||
name=self._name, id=self._id, adapter_number=adapter_number, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.debug(f'IOU "{self._name}" [{self._id}]: stopping packet capture on {adapter_number}/{port_number}')
|
||||
if self.ubridge:
|
||||
bridge_name = f"IOL-BRIDGE-{self.application_id + 512}"
|
||||
await self._ubridge_send(
|
||||
"iol_bridge stop_capture {name} {bay} {unit}".format(
|
||||
name=bridge_name, bay=adapter_number, unit=port_number
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f"iol_bridge stop_capture {bridge_name} {adapter_number} {port_number}")
|
||||
|
||||
@ -91,9 +91,7 @@ class ProjectManager:
|
||||
return
|
||||
# send a warning if used disk space is >= 90%
|
||||
if used_disk_space >= 90:
|
||||
message = 'Only {:.2f}% or less of free disk space detected in "{}" on "{}"'.format(
|
||||
100 - used_disk_space, project.path, platform.node()
|
||||
)
|
||||
message = f'Only {100 - used_disk_space:.2f}% or less of free disk space detected in "{project.path}" on "{platform.node()}"'
|
||||
log.warning(message)
|
||||
project.emit("log.warning", {"message": message})
|
||||
|
||||
|
||||
@ -238,9 +238,9 @@ class Qemu(BaseManager):
|
||||
version = match.group(1)
|
||||
return version
|
||||
else:
|
||||
raise QemuError("Could not determine the swtpm version for '{}'".format(swtpm_path))
|
||||
raise QemuError(f"Could not determine the swtpm version for '{swtpm_path}'")
|
||||
except (OSError, subprocess.SubprocessError) as e:
|
||||
raise QemuError("Error while looking for the swtpm version: {}".format(e))
|
||||
raise QemuError(f"Error while looking for the swtpm version: {e}")
|
||||
|
||||
@staticmethod
|
||||
def get_haxm_windows_version():
|
||||
@ -260,7 +260,7 @@ class Qemu(BaseManager):
|
||||
for index in range(winreg.QueryInfoKey(hkey)[0]):
|
||||
product_id = winreg.EnumKey(hkey, index)
|
||||
try:
|
||||
product_key = winreg.OpenKey(hkey, r"{}\InstallProperties".format(product_id))
|
||||
product_key = winreg.OpenKey(hkey, rf"{product_id}\InstallProperties")
|
||||
try:
|
||||
if winreg.QueryValueEx(product_key, "DisplayName")[0].endswith(
|
||||
"Hardware Accelerated Execution Manager"
|
||||
|
||||
@ -317,11 +317,7 @@ class QemuVM(BaseNode):
|
||||
f"Sorry a node without the linked base setting enabled can only be used once on your server. {value} is already used by {node.name} in project {node.project.name}"
|
||||
)
|
||||
setattr(self, "_" + variable, value)
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU {variable} path to {disk_image}'.format(
|
||||
name=self._name, variable=variable, id=self._id, disk_image=value
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the QEMU {variable} path to {value}')
|
||||
|
||||
@property
|
||||
def hda_disk_image(self):
|
||||
@ -423,9 +419,7 @@ class QemuVM(BaseNode):
|
||||
|
||||
self._hda_disk_interface = hda_disk_interface
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU hda disk interface to {interface}'.format(
|
||||
name=self._name, id=self._id, interface=self._hda_disk_interface
|
||||
)
|
||||
f'QEMU VM "{self._name}" [{self._id}] has set the QEMU hda disk interface to {self._hda_disk_interface}'
|
||||
)
|
||||
|
||||
@property
|
||||
@ -448,9 +442,7 @@ class QemuVM(BaseNode):
|
||||
|
||||
self._hdb_disk_interface = hdb_disk_interface
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU hdb disk interface to {interface}'.format(
|
||||
name=self._name, id=self._id, interface=self._hdb_disk_interface
|
||||
)
|
||||
f'QEMU VM "{self._name}" [{self._id}] has set the QEMU hdb disk interface to {self._hdb_disk_interface}'
|
||||
)
|
||||
|
||||
@property
|
||||
@ -473,9 +465,7 @@ class QemuVM(BaseNode):
|
||||
|
||||
self._hdc_disk_interface = hdc_disk_interface
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU hdc disk interface to {interface}'.format(
|
||||
name=self._name, id=self._id, interface=self._hdc_disk_interface
|
||||
)
|
||||
f'QEMU VM "{self._name}" [{self._id}] has set the QEMU hdc disk interface to {self._hdc_disk_interface}'
|
||||
)
|
||||
|
||||
@property
|
||||
@ -498,9 +488,7 @@ class QemuVM(BaseNode):
|
||||
|
||||
self._hdd_disk_interface = hdd_disk_interface
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU hdd disk interface to {interface}'.format(
|
||||
name=self._name, id=self._id, interface=self._hdd_disk_interface
|
||||
)
|
||||
f'QEMU VM "{self._name}" [{self._id}] has set the QEMU hdd disk interface to {self._hdd_disk_interface}'
|
||||
)
|
||||
|
||||
@property
|
||||
@ -524,11 +512,7 @@ class QemuVM(BaseNode):
|
||||
if cdrom_image:
|
||||
self._cdrom_image = self.manager.get_abs_image_path(cdrom_image, self.working_dir)
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU cdrom image path to {cdrom_image}'.format(
|
||||
name=self._name, id=self._id, cdrom_image=self._cdrom_image
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the QEMU cdrom image path to {self._cdrom_image}')
|
||||
else:
|
||||
self._cdrom_image = ""
|
||||
|
||||
@ -554,9 +538,7 @@ class QemuVM(BaseNode):
|
||||
await self._control_vm("eject -f ide1-cd0")
|
||||
await self._control_vm(f"change ide1-cd0 {self._cdrom_image}")
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has changed the cdrom image path to {cdrom_image}'.format(
|
||||
name=self._name, id=self._id, cdrom_image=self._cdrom_image
|
||||
)
|
||||
f'QEMU VM "{self._name}" [{self._id}] has changed the cdrom image path to {self._cdrom_image}'
|
||||
)
|
||||
else:
|
||||
await self._control_vm("eject -f ide1-cd0")
|
||||
@ -581,11 +563,7 @@ class QemuVM(BaseNode):
|
||||
"""
|
||||
|
||||
self._bios_image = self.manager.get_abs_image_path(bios_image, self.working_dir)
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU bios image path to {bios_image}'.format(
|
||||
name=self._name, id=self._id, bios_image=self._bios_image
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the QEMU bios image path to {self._bios_image}')
|
||||
|
||||
@property
|
||||
def boot_priority(self):
|
||||
@ -606,11 +584,7 @@ class QemuVM(BaseNode):
|
||||
"""
|
||||
|
||||
self._boot_priority = boot_priority
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the boot priority to {boot_priority}'.format(
|
||||
name=self._name, id=self._id, boot_priority=self._boot_priority
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the boot priority to {self._boot_priority}')
|
||||
|
||||
@property
|
||||
def ethernet_adapters(self):
|
||||
@ -641,11 +615,7 @@ class QemuVM(BaseNode):
|
||||
for adapter_number in range(0, adapters):
|
||||
self._ethernet_adapters.append(EthernetAdapter())
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}]: number of Ethernet adapters changed to {adapters}'.format(
|
||||
name=self._name, id=self._id, adapters=adapters
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}]: number of Ethernet adapters changed to {adapters}')
|
||||
|
||||
@property
|
||||
def adapter_type(self):
|
||||
@ -667,11 +637,7 @@ class QemuVM(BaseNode):
|
||||
|
||||
self._adapter_type = adapter_type
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}]: adapter type changed to {adapter_type}'.format(
|
||||
name=self._name, id=self._id, adapter_type=adapter_type
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}]: adapter type changed to {adapter_type}')
|
||||
|
||||
@property
|
||||
def mac_address(self):
|
||||
@ -697,11 +663,7 @@ class QemuVM(BaseNode):
|
||||
else:
|
||||
self._mac_address = mac_address
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}]: MAC address changed to {mac_addr}'.format(
|
||||
name=self._name, id=self._id, mac_addr=self._mac_address
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}]: MAC address changed to {self._mac_address}')
|
||||
|
||||
@property
|
||||
def replicate_network_connection_state(self):
|
||||
@ -790,11 +752,7 @@ class QemuVM(BaseNode):
|
||||
:param cpu_throttling: integer
|
||||
"""
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the percentage of CPU allowed to {cpu}'.format(
|
||||
name=self._name, id=self._id, cpu=cpu_throttling
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the percentage of CPU allowed to {cpu_throttling}')
|
||||
self._cpu_throttling = cpu_throttling
|
||||
self._stop_cpulimit()
|
||||
if cpu_throttling:
|
||||
@ -818,11 +776,7 @@ class QemuVM(BaseNode):
|
||||
:param process_priority: string
|
||||
"""
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the process priority to {priority}'.format(
|
||||
name=self._name, id=self._id, priority=process_priority
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the process priority to {process_priority}')
|
||||
self._process_priority = process_priority
|
||||
|
||||
@property
|
||||
@ -954,11 +908,7 @@ class QemuVM(BaseNode):
|
||||
:param options: QEMU options
|
||||
"""
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU options to {options}'.format(
|
||||
name=self._name, id=self._id, options=options
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the QEMU options to {options}')
|
||||
|
||||
# "-no-kvm" and "-no-hax' are deprecated since Qemu v5.2
|
||||
if "-no-kvm" in options:
|
||||
@ -1002,11 +952,7 @@ class QemuVM(BaseNode):
|
||||
|
||||
initrd = self.manager.get_abs_image_path(initrd, self.working_dir)
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU initrd path to {initrd}'.format(
|
||||
name=self._name, id=self._id, initrd=initrd
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the QEMU initrd path to {initrd}')
|
||||
if "asa" in initrd and self._initrd != initrd:
|
||||
self.project.emit(
|
||||
"log.warning",
|
||||
@ -1035,11 +981,7 @@ class QemuVM(BaseNode):
|
||||
"""
|
||||
|
||||
kernel_image = self.manager.get_abs_image_path(kernel_image, self.working_dir)
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU kernel image path to {kernel_image}'.format(
|
||||
name=self._name, id=self._id, kernel_image=kernel_image
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the QEMU kernel image path to {kernel_image}')
|
||||
self._kernel_image = kernel_image
|
||||
|
||||
@property
|
||||
@ -1060,11 +1002,7 @@ class QemuVM(BaseNode):
|
||||
:param kernel_command_line: QEMU kernel command line
|
||||
"""
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] has set the QEMU kernel command line to {kernel_command_line}'.format(
|
||||
name=self._name, id=self._id, kernel_command_line=kernel_command_line
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}] has set the QEMU kernel command line to {kernel_command_line}')
|
||||
self._kernel_command_line = kernel_command_line
|
||||
|
||||
async def _set_process_priority(self):
|
||||
@ -1121,8 +1059,8 @@ class QemuVM(BaseNode):
|
||||
command = [
|
||||
cpulimit_exec,
|
||||
"--lazy",
|
||||
"--pid={}".format(self._process.pid),
|
||||
"--limit={}".format(self._cpu_throttling),
|
||||
f"--pid={self._process.pid}",
|
||||
f"--limit={self._cpu_throttling}",
|
||||
]
|
||||
self._cpulimit_process = subprocess.Popen(command, cwd=self.working_dir)
|
||||
log.debug(f"CPU throttled to {self._cpu_throttling}%")
|
||||
@ -1265,8 +1203,8 @@ class QemuVM(BaseNode):
|
||||
qemu_stdout += (
|
||||
"\nTPM error: the project directory is not on the same partition as the root directory which can be a problem when using AppArmor.\n"
|
||||
"Please try to execute the following commands on the server:\n\n"
|
||||
"echo 'owner {}/** rwk,' | sudo tee /etc/apparmor.d/local/usr.bin.swtpm > /dev/null\n"
|
||||
"sudo service apparmor restart".format(os.path.dirname(self.project.path))
|
||||
f"echo 'owner {os.path.dirname(self.project.path)}/** rwk,' | sudo tee /etc/apparmor.d/local/usr.bin.swtpm > /dev/null\n"
|
||||
"sudo service apparmor restart"
|
||||
)
|
||||
self.project.emit(
|
||||
"log.error",
|
||||
@ -1344,11 +1282,7 @@ class QemuVM(BaseNode):
|
||||
break
|
||||
|
||||
if not connection_success:
|
||||
log.warning(
|
||||
"Could not connect to QEMU monitor on {}:{}: {}".format(
|
||||
self._monitor_host, self._monitor, last_exception
|
||||
)
|
||||
)
|
||||
log.warning(f"Could not connect to QEMU monitor on {self._monitor_host}:{self._monitor}: {last_exception}")
|
||||
else:
|
||||
log.debug(
|
||||
f"Connected to QEMU monitor on {self._monitor_host}:{self._monitor} after {time.time() - begin:.4f} seconds"
|
||||
@ -1549,11 +1483,7 @@ class QemuVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise QemuError(
|
||||
'Adapter {adapter_number} does not exist on QEMU VM "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise QemuError(f'Adapter {adapter_number} does not exist on QEMU VM "{self._name}"')
|
||||
|
||||
if self.is_running():
|
||||
try:
|
||||
@ -1563,18 +1493,10 @@ class QemuVM(BaseNode):
|
||||
if self._replicate_network_connection_state:
|
||||
await self._control_vm(f"set_link gns3-{adapter_number} on")
|
||||
except (IndexError, KeyError):
|
||||
raise QemuError(
|
||||
'Adapter {adapter_number} does not exist on QEMU VM "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise QemuError(f'Adapter {adapter_number} does not exist on QEMU VM "{self._name}"')
|
||||
|
||||
adapter.add_nio(0, nio)
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}]: {nio} added to adapter {adapter_number}'.format(
|
||||
name=self._name, id=self._id, nio=nio, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}]: {nio} added to adapter {adapter_number}')
|
||||
|
||||
async def adapter_update_nio_binding(self, adapter_number, nio):
|
||||
"""
|
||||
@ -1595,11 +1517,7 @@ class QemuVM(BaseNode):
|
||||
else:
|
||||
await self._control_vm(f"set_link gns3-{adapter_number} on")
|
||||
except IndexError:
|
||||
raise QemuError(
|
||||
'Adapter {adapter_number} does not exist on QEMU VM "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise QemuError(f'Adapter {adapter_number} does not exist on QEMU VM "{self._name}"')
|
||||
|
||||
async def adapter_remove_nio_binding(self, adapter_number):
|
||||
"""
|
||||
@ -1613,11 +1531,7 @@ class QemuVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise QemuError(
|
||||
'Adapter {adapter_number} does not exist on QEMU VM "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise QemuError(f'Adapter {adapter_number} does not exist on QEMU VM "{self._name}"')
|
||||
|
||||
await self.stop_capture(adapter_number)
|
||||
if self.is_running():
|
||||
@ -1630,11 +1544,7 @@ class QemuVM(BaseNode):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
adapter.remove_nio(0)
|
||||
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}]: {nio} removed from adapter {adapter_number}'.format(
|
||||
name=self._name, id=self._id, nio=nio, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.debug(f'QEMU VM "{self._name}" [{self._id}]: {nio} removed from adapter {adapter_number}')
|
||||
return nio
|
||||
|
||||
def get_nio(self, adapter_number):
|
||||
@ -1649,11 +1559,7 @@ class QemuVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise QemuError(
|
||||
'Adapter {adapter_number} does not exist on QEMU VM "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise QemuError(f'Adapter {adapter_number} does not exist on QEMU VM "{self._name}"')
|
||||
|
||||
nio = adapter.get_nio(0)
|
||||
|
||||
@ -1682,11 +1588,7 @@ class QemuVM(BaseNode):
|
||||
)
|
||||
)
|
||||
|
||||
log.debug(
|
||||
"QEMU VM '{name}' [{id}]: starting packet capture on adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.debug(f"QEMU VM '{self.name}' [{self.id}]: starting packet capture on adapter {adapter_number}")
|
||||
|
||||
async def stop_capture(self, adapter_number):
|
||||
"""
|
||||
@ -1703,11 +1605,7 @@ class QemuVM(BaseNode):
|
||||
if self.ubridge:
|
||||
await self._ubridge_send("bridge stop_capture {name}".format(name=f"QEMU-{self._id}-{adapter_number}"))
|
||||
|
||||
log.debug(
|
||||
"QEMU VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.debug(f"QEMU VM '{self.name}' [{self.id}]: stopping packet capture on adapter {adapter_number}")
|
||||
|
||||
async def create_disk_image(self, disk_name, options):
|
||||
"""
|
||||
@ -1912,7 +1810,7 @@ class QemuVM(BaseNode):
|
||||
# FIXME: consider making this more global (not just for Qemu + SPICE)
|
||||
console_host = "::"
|
||||
except OSError as e:
|
||||
raise QemuError("Could not check if IPv6 is enabled: {}".format(e))
|
||||
raise QemuError(f"Could not check if IPv6 is enabled: {e}")
|
||||
return ["-spice", f"addr={console_host},port={port},disable-ticketing", "-vga", "qxl"]
|
||||
else:
|
||||
return []
|
||||
@ -2050,7 +1948,7 @@ class QemuVM(BaseNode):
|
||||
qemu_img_path,
|
||||
"create",
|
||||
"-o",
|
||||
"backing_file={}".format(disk_image),
|
||||
f"backing_file={disk_image}",
|
||||
"-F",
|
||||
backing_file_format,
|
||||
"-f",
|
||||
@ -2062,7 +1960,7 @@ class QemuVM(BaseNode):
|
||||
if retcode:
|
||||
stdout = self.read_qemu_img_stdout()
|
||||
raise QemuError(
|
||||
"Could not create '{}' disk image: qemu-img returned with {}\n{}".format(disk_name, retcode, stdout)
|
||||
f"Could not create '{disk_name}' disk image: qemu-img returned with {retcode}\n{stdout}"
|
||||
)
|
||||
except (OSError, subprocess.SubprocessError) as e:
|
||||
stdout = self.read_qemu_img_stdout()
|
||||
@ -2077,7 +1975,7 @@ class QemuVM(BaseNode):
|
||||
if signature != 0xAA55:
|
||||
raise OSError(f"mcopy failure: {image}: invalid MBR")
|
||||
if part_type not in (1, 4, 6, 11, 12, 14):
|
||||
raise OSError("mcopy failure: {}: invalid partition type {:02X}".format(image, part_type))
|
||||
raise OSError(f"mcopy failure: {image}: invalid partition type {part_type:02X}")
|
||||
part_image = image + f"@@{offset}S"
|
||||
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
@ -2332,7 +2230,7 @@ class QemuVM(BaseNode):
|
||||
|
||||
elif self._uefi:
|
||||
system_ovmf_firmware_dir = Path(self.manager.config.settings.Qemu.ovmf_firmware_dir)
|
||||
log.debug("Using OVMF firmware directory: {}".format(system_ovmf_firmware_dir))
|
||||
log.debug(f"Using OVMF firmware directory: {system_ovmf_firmware_dir}")
|
||||
old_ovmf_vars_path = os.path.join(self.working_dir, "OVMF_VARS.fd")
|
||||
if os.path.exists(old_ovmf_vars_path):
|
||||
# the node has its own UEFI variables store already, we must also use the old UEFI firmware
|
||||
@ -2352,8 +2250,8 @@ class QemuVM(BaseNode):
|
||||
# otherwise, get the UEFI firmware from the images directory
|
||||
ovmf_firmware_path = self.manager.get_abs_image_path("OVMF_CODE_4M.fd")
|
||||
|
||||
log.debug("Configuring UEFI boot mode using OVMF file: '{}'".format(ovmf_firmware_path))
|
||||
options.extend(["-drive", "if=pflash,format=raw,readonly,file={}".format(ovmf_firmware_path)])
|
||||
log.debug(f"Configuring UEFI boot mode using OVMF file: '{ovmf_firmware_path}'")
|
||||
options.extend(["-drive", f"if=pflash,format=raw,readonly,file={ovmf_firmware_path}"])
|
||||
|
||||
# try to use the UEFI variables store from the system first
|
||||
try:
|
||||
@ -2377,8 +2275,8 @@ class QemuVM(BaseNode):
|
||||
try:
|
||||
shutil.copyfile(ovmf_vars_path, ovmf_vars_node_path)
|
||||
except OSError as e:
|
||||
raise QemuError("Cannot copy OVMF_VARS_4M.fd file to the node working directory: {}".format(e))
|
||||
options.extend(["-drive", "if=pflash,format=raw,file={}".format(ovmf_vars_node_path)])
|
||||
raise QemuError(f"Cannot copy OVMF_VARS_4M.fd file to the node working directory: {e}")
|
||||
options.extend(["-drive", f"if=pflash,format=raw,file={ovmf_vars_node_path}"])
|
||||
|
||||
# edk2 firmware requires a Random Number Generator (RNG) device in order to turn network adapters on
|
||||
options.extend(["-object", "rng-random,filename=/dev/urandom,id=rng0"])
|
||||
@ -2426,25 +2324,23 @@ class QemuVM(BaseNode):
|
||||
swtpm_version = await self.manager.get_swtpm_version(swtpm)
|
||||
if swtpm_version and parse_version(swtpm_version) < parse_version("0.8.0"):
|
||||
# swtpm >= version 0.8.0 is required
|
||||
raise QemuError(
|
||||
"swtpm version 0.8.0 or above must be installed (detected version is {})".format(swtpm_version)
|
||||
)
|
||||
raise QemuError(f"swtpm version 0.8.0 or above must be installed (detected version is {swtpm_version})")
|
||||
try:
|
||||
command = [
|
||||
swtpm,
|
||||
"socket",
|
||||
"--tpm2",
|
||||
"--tpmstate",
|
||||
"dir={}".format(tpm_dir),
|
||||
f"dir={tpm_dir}",
|
||||
"--ctrl",
|
||||
"type=unixio,path={},terminate".format(tpm_sock),
|
||||
f"type=unixio,path={tpm_sock},terminate",
|
||||
]
|
||||
command_string = " ".join(shlex.quote(s) for s in command)
|
||||
log.debug("Starting swtpm (TPM emulator) with: {}".format(command_string))
|
||||
log.debug(f"Starting swtpm (TPM emulator) with: {command_string}")
|
||||
self._swtpm_process = subprocess.Popen(command, cwd=self.working_dir)
|
||||
log.debug("swtpm (TPM emulator) has started")
|
||||
except (OSError, subprocess.SubprocessError) as e:
|
||||
raise QemuError("Could not start swtpm (TPM emulator): {}".format(e))
|
||||
raise QemuError(f"Could not start swtpm (TPM emulator): {e}")
|
||||
|
||||
def _stop_swtpm(self):
|
||||
"""
|
||||
@ -2462,10 +2358,10 @@ class QemuVM(BaseNode):
|
||||
|
||||
tpm_sock = os.path.join(self.temporary_directory, "swtpm.sock")
|
||||
if not os.path.exists(tpm_sock):
|
||||
raise QemuError("swtpm socket file '{}' does not exist".format(tpm_sock))
|
||||
raise QemuError(f"swtpm socket file '{tpm_sock}' does not exist")
|
||||
options = [
|
||||
"-chardev",
|
||||
"socket,id=chrtpm,path={}".format(tpm_sock),
|
||||
f"socket,id=chrtpm,path={tpm_sock}",
|
||||
"-tpmdev",
|
||||
"emulator,id=tpm0,chardev=chrtpm",
|
||||
"-device",
|
||||
@ -2504,7 +2400,7 @@ class QemuVM(BaseNode):
|
||||
|
||||
device_string = f"{adapter_type},mac={mac}"
|
||||
if adapter_type == "virtio-net-pci":
|
||||
device_string = "{},speed=10000,duplex=full".format(device_string)
|
||||
device_string = f"{device_string},speed=10000,duplex=full"
|
||||
bridge_id = math.floor(pci_device_id / 32)
|
||||
if bridge_id > 0:
|
||||
if pci_bridges_created < bridge_id:
|
||||
@ -2512,9 +2408,7 @@ class QemuVM(BaseNode):
|
||||
network_options.extend(
|
||||
[
|
||||
"-device",
|
||||
"pci-bridge,id=pci-bridge{bridge_id},bus=dmi_pci_bridge{bridge_id},chassis_nr=0x1,addr=0x{bridge_id},shpc=off".format(
|
||||
bridge_id=bridge_id
|
||||
),
|
||||
f"pci-bridge,id=pci-bridge{bridge_id},bus=dmi_pci_bridge{bridge_id},chassis_nr=0x1,addr=0x{bridge_id},shpc=off",
|
||||
]
|
||||
)
|
||||
pci_bridges_created += 1
|
||||
@ -2661,9 +2555,7 @@ class QemuVM(BaseNode):
|
||||
for snapshot in json_data["snapshots"]:
|
||||
if snapshot["name"] == snapshot_name:
|
||||
log.debug(
|
||||
'QEMU VM "{name}" [{id}] VM saved state detected (snapshot name: {snapshot})'.format(
|
||||
name=self._name, id=self.id, snapshot=snapshot_name
|
||||
)
|
||||
f'QEMU VM "{self._name}" [{self.id}] VM saved state detected (snapshot name: {snapshot_name})'
|
||||
)
|
||||
return ["-loadvm", snapshot_name.replace(",", ",,")]
|
||||
|
||||
@ -2740,7 +2632,7 @@ class QemuVM(BaseNode):
|
||||
if allow_unsafe_options is False:
|
||||
for opt in additional_opt_list:
|
||||
if opt in FORBIDDEN_OPTIONS:
|
||||
raise QemuError("Forbidden additional option: {}".format(opt))
|
||||
raise QemuError(f"Forbidden additional option: {opt}")
|
||||
command.extend(additional_opt_list)
|
||||
|
||||
# avoiding mouse offset (see https://github.com/GNS3/gns3-server/issues/2335)
|
||||
|
||||
@ -52,4 +52,4 @@ def unpack_zip(filename, extract_dir=None):
|
||||
for fname, date_time in reversed(dirs):
|
||||
os.utime(fname, (date_time, date_time))
|
||||
except zipfile.BadZipFile:
|
||||
raise shutil.ReadError("{} is not a zip file".format(filename))
|
||||
raise shutil.ReadError(f"{filename} is not a zip file")
|
||||
|
||||
@ -188,9 +188,7 @@ class UBridgeHypervisor:
|
||||
await self._writer.drain()
|
||||
except OSError as e:
|
||||
raise UbridgeError(
|
||||
"Lost communication with {endpoint} when sending command '{command}': {error}, uBridge process running: {run}".format(
|
||||
endpoint=self.endpoint, command=command, error=e, run=self.is_running()
|
||||
)
|
||||
f"Lost communication with {self.endpoint} when sending command '{command}': {e}, uBridge process running: {self.is_running()}"
|
||||
)
|
||||
|
||||
# Now retrieve the result
|
||||
@ -215,9 +213,7 @@ class UBridgeHypervisor:
|
||||
if not chunk:
|
||||
if retries > max_retries:
|
||||
raise UbridgeError(
|
||||
"No data returned from {endpoint} after sending command '{command}', uBridge process running: {run}".format(
|
||||
endpoint=self.endpoint, command=command, run=self.is_running()
|
||||
)
|
||||
f"No data returned from {self.endpoint} after sending command '{command}', uBridge process running: {self.is_running()}"
|
||||
)
|
||||
else:
|
||||
retries += 1
|
||||
@ -227,9 +223,7 @@ class UBridgeHypervisor:
|
||||
buf += chunk.decode("utf-8")
|
||||
except OSError as e:
|
||||
raise UbridgeError(
|
||||
"Lost communication with {endpoint} after sending command '{command}': {error}, uBridge process running: {run}".format(
|
||||
endpoint=self.endpoint, command=command, error=e, run=self.is_running()
|
||||
)
|
||||
f"Lost communication with {self.endpoint} after sending command '{command}': {e}, uBridge process running: {self.is_running()}"
|
||||
)
|
||||
|
||||
# If the buffer doesn't end in '\n' then we can't be done
|
||||
@ -238,9 +232,7 @@ class UBridgeHypervisor:
|
||||
continue
|
||||
except IndexError:
|
||||
raise UbridgeError(
|
||||
"Could not communicate with {endpoint} after sending command '{command}', uBridge process running: {run}".format(
|
||||
endpoint=self.endpoint, command=command, run=self.is_running()
|
||||
)
|
||||
f"Could not communicate with {self.endpoint} after sending command '{command}', uBridge process running: {self.is_running()}"
|
||||
)
|
||||
|
||||
data += buf.split("\r\n")
|
||||
|
||||
@ -234,7 +234,7 @@ class VirtualBoxVM(BaseNode):
|
||||
|
||||
linked_vbox_file = self._linked_vbox_file()
|
||||
if not os.path.exists(linked_vbox_file):
|
||||
raise VirtualBoxError("Cannot find VirtualBox linked node file: {}".format(linked_vbox_file))
|
||||
raise VirtualBoxError(f"Cannot find VirtualBox linked node file: {linked_vbox_file}")
|
||||
|
||||
try:
|
||||
tree = ET.parse(linked_vbox_file)
|
||||
@ -402,11 +402,7 @@ class VirtualBoxVM(BaseNode):
|
||||
self.status = "suspended"
|
||||
log.info(f"VirtualBox VM '{self.name}' [{self.id}] suspended")
|
||||
else:
|
||||
log.warning(
|
||||
"VirtualBox VM '{name}' [{id}] cannot be suspended, current state: {state}".format(
|
||||
name=self.name, id=self.id, state=vm_state
|
||||
)
|
||||
)
|
||||
log.warning(f"VirtualBox VM '{self.name}' [{self.id}] cannot be suspended, current state: {vm_state}")
|
||||
|
||||
async def resume(self):
|
||||
"""
|
||||
@ -511,9 +507,7 @@ class VirtualBoxVM(BaseNode):
|
||||
os.path.join(self.working_dir, self._vmname, "Snapshots", os.path.basename(value))
|
||||
):
|
||||
log.info(
|
||||
"VirtualBox VM '{name}' [{id}] detaching HDD {controller} {port} {device}".format(
|
||||
name=self.name, id=self.id, controller=controller, port=port, device=device
|
||||
)
|
||||
f"VirtualBox VM '{self.name}' [{self.id}] detaching HDD {controller} {port} {device}"
|
||||
)
|
||||
hdd_table.append(
|
||||
{
|
||||
@ -530,11 +524,7 @@ class VirtualBoxVM(BaseNode):
|
||||
with open(hdd_info_file, "w", encoding="utf-8") as f:
|
||||
json.dump(hdd_table, f, indent=4)
|
||||
except OSError as e:
|
||||
log.warning(
|
||||
"VirtualBox VM '{name}' [{id}] could not write HHD info file: {error}".format(
|
||||
name=self.name, id=self.id, error=e.strerror
|
||||
)
|
||||
)
|
||||
log.warning(f"VirtualBox VM '{self.name}' [{self.id}] could not write HHD info file: {e.strerror}")
|
||||
|
||||
return hdd_table
|
||||
|
||||
@ -739,15 +729,11 @@ class VirtualBoxVM(BaseNode):
|
||||
log.warning(f"Could not find system property '{max_adapter_string}' for chipset {chipset}")
|
||||
|
||||
log.info(
|
||||
"VirtualBox VM '{name}' [{id}] can have a maximum of {max} network adapters for chipset {chipset}".format(
|
||||
name=self.name, id=self.id, max=self._maximum_adapters, chipset=chipset.upper()
|
||||
)
|
||||
f"VirtualBox VM '{self.name}' [{self.id}] can have a maximum of {self._maximum_adapters} network adapters for chipset {chipset.upper()}"
|
||||
)
|
||||
if adapters > self._maximum_adapters:
|
||||
raise VirtualBoxError(
|
||||
"The configured {} chipset limits the VM to {} network adapters. The chipset can be changed outside GNS3 in the VirtualBox VM settings.".format(
|
||||
chipset.upper(), self._maximum_adapters
|
||||
)
|
||||
f"The configured {chipset.upper()} chipset limits the VM to {self._maximum_adapters} network adapters. The chipset can be changed outside GNS3 in the VirtualBox VM settings."
|
||||
)
|
||||
|
||||
self._ethernet_adapters.clear()
|
||||
@ -755,11 +741,7 @@ class VirtualBoxVM(BaseNode):
|
||||
self._ethernet_adapters[adapter_number] = EthernetAdapter()
|
||||
|
||||
self._adapters = len(self._ethernet_adapters)
|
||||
log.info(
|
||||
"VirtualBox VM '{name}' [{id}] has changed the number of Ethernet adapters to {adapters}".format(
|
||||
name=self.name, id=self.id, adapters=adapters
|
||||
)
|
||||
)
|
||||
log.info(f"VirtualBox VM '{self.name}' [{self.id}] has changed the number of Ethernet adapters to {adapters}")
|
||||
|
||||
@property
|
||||
def use_any_adapter(self):
|
||||
@ -804,11 +786,7 @@ class VirtualBoxVM(BaseNode):
|
||||
"""
|
||||
|
||||
self._adapter_type = adapter_type
|
||||
log.info(
|
||||
"VirtualBox VM '{name}' [{id}]: adapter type changed to {adapter_type}".format(
|
||||
name=self.name, id=self.id, adapter_type=adapter_type
|
||||
)
|
||||
)
|
||||
log.info(f"VirtualBox VM '{self.name}' [{self.id}]: adapter type changed to {adapter_type}")
|
||||
|
||||
async def _get_vm_info(self):
|
||||
"""
|
||||
@ -1076,11 +1054,7 @@ class VirtualBoxVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except KeyError:
|
||||
raise VirtualBoxError(
|
||||
"Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise VirtualBoxError(f"Adapter {adapter_number} doesn't exist on VirtualBox VM '{self.name}'")
|
||||
|
||||
# check if trying to connect to a nat, bridged, host-only or any other special adapter
|
||||
nic_attachments = await self._get_nic_attachements(self._maximum_adapters)
|
||||
@ -1088,10 +1062,8 @@ class VirtualBoxVM(BaseNode):
|
||||
if attachment in ("nat", "bridged", "intnet", "hostonly", "natnetwork"):
|
||||
if not self._use_any_adapter:
|
||||
raise VirtualBoxError(
|
||||
"Attachment '{attachment}' is already configured on adapter {adapter_number}. "
|
||||
"Please remove it or allow VirtualBox VM '{name}' to use any adapter.".format(
|
||||
attachment=attachment, adapter_number=adapter_number, name=self.name
|
||||
)
|
||||
f"Attachment '{attachment}' is already configured on adapter {adapter_number}. "
|
||||
f"Please remove it or allow VirtualBox VM '{self.name}' to use any adapter."
|
||||
)
|
||||
elif self.is_running():
|
||||
# dynamically configure an UDP tunnel attachment if the VM is already running
|
||||
@ -1109,19 +1081,11 @@ class VirtualBoxVM(BaseNode):
|
||||
f"VBOX-{self._id}-{adapter_number}", self._local_udp_tunnels[adapter_number][1], nio
|
||||
)
|
||||
except KeyError:
|
||||
raise VirtualBoxError(
|
||||
"Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise VirtualBoxError(f"Adapter {adapter_number} doesn't exist on VirtualBox VM '{self.name}'")
|
||||
await self._control_vm(f"setlinkstate{adapter_number + 1} on")
|
||||
|
||||
adapter.add_nio(0, nio)
|
||||
log.info(
|
||||
"VirtualBox VM '{name}' [{id}]: {nio} added to adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, nio=nio, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.info(f"VirtualBox VM '{self.name}' [{self.id}]: {nio} added to adapter {adapter_number}")
|
||||
|
||||
async def adapter_update_nio_binding(self, adapter_number, nio):
|
||||
"""
|
||||
@ -1141,11 +1105,7 @@ class VirtualBoxVM(BaseNode):
|
||||
else:
|
||||
await self._control_vm(f"setlinkstate{adapter_number + 1} on")
|
||||
except IndexError:
|
||||
raise VirtualBoxError(
|
||||
'Adapter {adapter_number} does not exist on VirtualBox VM "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise VirtualBoxError(f'Adapter {adapter_number} does not exist on VirtualBox VM "{self._name}"')
|
||||
|
||||
async def adapter_remove_nio_binding(self, adapter_number):
|
||||
"""
|
||||
@ -1159,11 +1119,7 @@ class VirtualBoxVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except KeyError:
|
||||
raise VirtualBoxError(
|
||||
"Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise VirtualBoxError(f"Adapter {adapter_number} doesn't exist on VirtualBox VM '{self.name}'")
|
||||
|
||||
await self.stop_capture(adapter_number)
|
||||
if self.is_running():
|
||||
@ -1177,11 +1133,7 @@ class VirtualBoxVM(BaseNode):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
adapter.remove_nio(0)
|
||||
|
||||
log.info(
|
||||
"VirtualBox VM '{name}' [{id}]: {nio} removed from adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, nio=nio, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.info(f"VirtualBox VM '{self.name}' [{self.id}]: {nio} removed from adapter {adapter_number}")
|
||||
return nio
|
||||
|
||||
def get_nio(self, adapter_number):
|
||||
@ -1196,11 +1148,7 @@ class VirtualBoxVM(BaseNode):
|
||||
try:
|
||||
adapter = self.ethernet_adapters[adapter_number]
|
||||
except KeyError:
|
||||
raise VirtualBoxError(
|
||||
"Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise VirtualBoxError(f"Adapter {adapter_number} doesn't exist on VirtualBox VM '{self.name}'")
|
||||
|
||||
nio = adapter.get_nio(0)
|
||||
|
||||
@ -1235,11 +1183,7 @@ class VirtualBoxVM(BaseNode):
|
||||
)
|
||||
)
|
||||
|
||||
log.info(
|
||||
"VirtualBox VM '{name}' [{id}]: starting packet capture on adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.info(f"VirtualBox VM '{self.name}' [{self.id}]: starting packet capture on adapter {adapter_number}")
|
||||
|
||||
async def stop_capture(self, adapter_number):
|
||||
"""
|
||||
@ -1256,8 +1200,4 @@ class VirtualBoxVM(BaseNode):
|
||||
if self.ubridge:
|
||||
await self._ubridge_send("bridge stop_capture {name}".format(name=f"VBOX-{self._id}-{adapter_number}"))
|
||||
|
||||
log.info(
|
||||
"VirtualBox VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.info(f"VirtualBox VM '{self.name}' [{self.id}]: stopping packet capture on adapter {adapter_number}")
|
||||
|
||||
@ -241,12 +241,12 @@ class VMware(BaseManager):
|
||||
for line in f.read().splitlines():
|
||||
match = re.search(r"VNET_([0-9]+)_HOSTONLY_SUBNET\s+(.*)", line)
|
||||
if match:
|
||||
vmnet = "vmnet{}".format(match.group(1))
|
||||
vmnet = f"vmnet{match.group(1)}"
|
||||
if vmnet in vmnet_interfaces.keys():
|
||||
vmnet_interfaces[vmnet]["subnet"] = match.group(2)
|
||||
match = re.search(r"VNET_([0-9]+)_HOSTONLY_NETMASK\s+(.*)", line)
|
||||
if match:
|
||||
vmnet = "vmnet{}".format(match.group(1))
|
||||
vmnet = f"vmnet{match.group(1)}"
|
||||
if vmnet in vmnet_interfaces.keys():
|
||||
vmnet_interfaces[vmnet]["netmask"] = match.group(2)
|
||||
|
||||
@ -305,7 +305,7 @@ class VMware(BaseManager):
|
||||
|
||||
def refresh_vmnet_list(self, ubridge=True):
|
||||
|
||||
log.debug("Refreshing VMnet list with uBridge={}".format(ubridge))
|
||||
log.debug(f"Refreshing VMnet list with uBridge={ubridge}")
|
||||
|
||||
if ubridge:
|
||||
# VMnet host adapters must be present when uBridge is used
|
||||
@ -315,7 +315,7 @@ class VMware(BaseManager):
|
||||
self._vmnets_info = vmnet_interfaces.copy()
|
||||
vmnet_interfaces = list(vmnet_interfaces.keys())
|
||||
|
||||
log.debug("Found {} VMnet interfaces".format(len(vmnet_interfaces)))
|
||||
log.debug(f"Found {len(vmnet_interfaces)} VMnet interfaces")
|
||||
# remove vmnets already in use
|
||||
for vmware_vm in self._nodes.values():
|
||||
for used_vmnet in vmware_vm.vmnets:
|
||||
@ -326,7 +326,7 @@ class VMware(BaseManager):
|
||||
# remove vmnets that are not managed
|
||||
for vmnet in vmnet_interfaces.copy():
|
||||
if vmnet in vmnet_interfaces and self.is_managed_vmnet(vmnet) is False:
|
||||
log.debug("{} is not managed by GNS3".format(vmnet))
|
||||
log.debug(f"{vmnet} is not managed by GNS3")
|
||||
vmnet_interfaces.remove(vmnet)
|
||||
|
||||
self._vmnets = vmnet_interfaces
|
||||
@ -677,9 +677,7 @@ class VMware(BaseManager):
|
||||
default_vm_path = pairs["prefvmx.defaultvmpath"]
|
||||
if not os.path.isdir(default_vm_path):
|
||||
raise VMwareError(
|
||||
'Could not find or access the default VM directory: "{default_vm_path}". Please change "prefvmx.defaultvmpath={default_vm_path}" in "{vmware_preferences_path}"'.format(
|
||||
default_vm_path=default_vm_path, vmware_preferences_path=vmware_preferences_path
|
||||
)
|
||||
f'Could not find or access the default VM directory: "{default_vm_path}". Please change "prefvmx.defaultvmpath={default_vm_path}" in "{vmware_preferences_path}"'
|
||||
)
|
||||
vmware_vms = self._get_vms_from_directory(default_vm_path)
|
||||
|
||||
|
||||
@ -361,18 +361,12 @@ class VMwareVM(BaseNode):
|
||||
await self._add_ubridge_ethernet_connection(vnet, vmnet_interface, block_host_traffic)
|
||||
else:
|
||||
# special case on macOS, we cannot bind VMnet interfaces using the libpcap
|
||||
await self._ubridge_send(
|
||||
'bridge add_nio_fusion_vmnet {name} "{interface}"'.format(name=vnet, interface=vmnet_interface)
|
||||
)
|
||||
await self._ubridge_send(f'bridge add_nio_fusion_vmnet {vnet} "{vmnet_interface}"')
|
||||
else:
|
||||
await self._add_ubridge_ethernet_connection(vnet, vmnet_interface, block_host_traffic)
|
||||
|
||||
if isinstance(nio, NIOUDP):
|
||||
await self._ubridge_send(
|
||||
"bridge add_nio_udp {name} {lport} {rhost} {rport}".format(
|
||||
name=vnet, lport=nio.lport, rhost=nio.rhost, rport=nio.rport
|
||||
)
|
||||
)
|
||||
await self._ubridge_send(f"bridge add_nio_udp {vnet} {nio.lport} {nio.rhost} {nio.rport}")
|
||||
|
||||
if nio.capturing:
|
||||
await self._ubridge_send(f'bridge start_capture {vnet} "{nio.pcap_output_file}"')
|
||||
@ -418,9 +412,7 @@ class VMwareVM(BaseNode):
|
||||
raise VMwareError(f"vnet {vnet} not in VMX file")
|
||||
if not self._ubridge_hypervisor:
|
||||
raise VMwareError("Cannot start the packet capture: uBridge is not running")
|
||||
await self._ubridge_send(
|
||||
'bridge start_capture {name} "{output_file}"'.format(name=vnet, output_file=output_file)
|
||||
)
|
||||
await self._ubridge_send(f'bridge start_capture {vnet} "{output_file}"')
|
||||
|
||||
async def _stop_ubridge_capture(self, adapter_number):
|
||||
"""
|
||||
@ -694,11 +686,7 @@ class VMwareVM(BaseNode):
|
||||
self._ethernet_adapters[adapter_number] = EthernetAdapter()
|
||||
|
||||
self._adapters = len(self._ethernet_adapters)
|
||||
log.info(
|
||||
"VMware VM '{name}' [{id}] has changed the number of Ethernet adapters to {adapters}".format(
|
||||
name=self.name, id=self.id, adapters=adapters
|
||||
)
|
||||
)
|
||||
log.info(f"VMware VM '{self.name}' [{self.id}] has changed the number of Ethernet adapters to {adapters}")
|
||||
|
||||
@property
|
||||
def adapter_type(self):
|
||||
@ -719,11 +707,7 @@ class VMwareVM(BaseNode):
|
||||
"""
|
||||
|
||||
self._adapter_type = adapter_type
|
||||
log.info(
|
||||
"VMware VM '{name}' [{id}]: adapter type changed to {adapter_type}".format(
|
||||
name=self.name, id=self.id, adapter_type=adapter_type
|
||||
)
|
||||
)
|
||||
log.info(f"VMware VM '{self.name}' [{self.id}]: adapter type changed to {adapter_type}")
|
||||
|
||||
@property
|
||||
def use_any_adapter(self):
|
||||
@ -760,11 +744,7 @@ class VMwareVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise VMwareError(
|
||||
"Adapter {adapter_number} doesn't exist on VMware VM '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise VMwareError(f"Adapter {adapter_number} doesn't exist on VMware VM '{self.name}'")
|
||||
|
||||
self._read_vmx_file()
|
||||
# check if trying to connect to a nat, bridged or host-only adapter
|
||||
@ -778,28 +758,20 @@ class VMwareVM(BaseNode):
|
||||
):
|
||||
if await self.is_running():
|
||||
raise VMwareError(
|
||||
"Attachment '{attachment}' is configured on network adapter {adapter_number}. "
|
||||
"Please stop VMware VM '{name}' to link to this adapter and allow GNS3 to change the attachment type.".format(
|
||||
attachment=self._vmx_pairs[connection_type], adapter_number=adapter_number, name=self.name
|
||||
)
|
||||
f"Attachment '{self._vmx_pairs[connection_type]}' is configured on network adapter {adapter_number}. "
|
||||
f"Please stop VMware VM '{self.name}' to link to this adapter and allow GNS3 to change the attachment type."
|
||||
)
|
||||
else:
|
||||
raise VMwareError(
|
||||
"Attachment '{attachment}' is already configured on network adapter {adapter_number}. "
|
||||
"Please remove it or allow VMware VM '{name}' to use any adapter.".format(
|
||||
attachment=self._vmx_pairs[connection_type], adapter_number=adapter_number, name=self.name
|
||||
)
|
||||
f"Attachment '{self._vmx_pairs[connection_type]}' is already configured on network adapter {adapter_number}. "
|
||||
f"Please remove it or allow VMware VM '{self.name}' to use any adapter."
|
||||
)
|
||||
|
||||
adapter.add_nio(0, nio)
|
||||
if self._started and self._ubridge_hypervisor:
|
||||
await self._add_ubridge_connection(nio, adapter_number)
|
||||
|
||||
log.info(
|
||||
"VMware VM '{name}' [{id}]: {nio} added to adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, nio=nio, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.info(f"VMware VM '{self.name}' [{self.id}]: {nio} added to adapter {adapter_number}")
|
||||
|
||||
async def adapter_update_nio_binding(self, adapter_number, nio):
|
||||
"""
|
||||
@ -813,11 +785,7 @@ class VMwareVM(BaseNode):
|
||||
try:
|
||||
await self._update_ubridge_connection(adapter_number, nio)
|
||||
except IndexError:
|
||||
raise VMwareError(
|
||||
'Adapter {adapter_number} does not exist on VMware VM "{name}"'.format(
|
||||
name=self._name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise VMwareError(f'Adapter {adapter_number} does not exist on VMware VM "{self._name}"')
|
||||
|
||||
async def adapter_remove_nio_binding(self, adapter_number):
|
||||
"""
|
||||
@ -831,11 +799,7 @@ class VMwareVM(BaseNode):
|
||||
try:
|
||||
adapter = self._ethernet_adapters[adapter_number]
|
||||
except IndexError:
|
||||
raise VMwareError(
|
||||
"Adapter {adapter_number} doesn't exist on VMware VM '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise VMwareError(f"Adapter {adapter_number} doesn't exist on VMware VM '{self.name}'")
|
||||
|
||||
await self.stop_capture(adapter_number)
|
||||
nio = adapter.get_nio(0)
|
||||
@ -845,11 +809,7 @@ class VMwareVM(BaseNode):
|
||||
if self._started and self._ubridge_hypervisor:
|
||||
await self._delete_ubridge_connection(adapter_number)
|
||||
|
||||
log.info(
|
||||
"VMware VM '{name}' [{id}]: {nio} removed from adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, nio=nio, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.info(f"VMware VM '{self.name}' [{self.id}]: {nio} removed from adapter {adapter_number}")
|
||||
|
||||
return nio
|
||||
|
||||
@ -865,11 +825,7 @@ class VMwareVM(BaseNode):
|
||||
try:
|
||||
adapter = self.ethernet_adapters[adapter_number]
|
||||
except KeyError:
|
||||
raise VMwareError(
|
||||
"Adapter {adapter_number} doesn't exist on VMware VM '{name}'".format(
|
||||
name=self.name, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
raise VMwareError(f"Adapter {adapter_number} doesn't exist on VMware VM '{self.name}'")
|
||||
|
||||
nio = adapter.get_nio(0)
|
||||
if not nio:
|
||||
@ -984,11 +940,7 @@ class VMwareVM(BaseNode):
|
||||
if self._started:
|
||||
await self._start_ubridge_capture(adapter_number, output_file)
|
||||
|
||||
log.info(
|
||||
"VMware VM '{name}' [{id}]: starting packet capture on adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.info(f"VMware VM '{self.name}' [{self.id}]: starting packet capture on adapter {adapter_number}")
|
||||
|
||||
async def stop_capture(self, adapter_number):
|
||||
"""
|
||||
@ -1005,8 +957,4 @@ class VMwareVM(BaseNode):
|
||||
if self._started:
|
||||
await self._stop_ubridge_capture(adapter_number)
|
||||
|
||||
log.info(
|
||||
"VMware VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(
|
||||
name=self.name, id=self.id, adapter_number=adapter_number
|
||||
)
|
||||
)
|
||||
log.info(f"VMware VM '{self.name}' [{self.id}]: stopping packet capture on adapter {adapter_number}")
|
||||
|
||||
@ -384,21 +384,13 @@ class VPCSVM(BaseNode):
|
||||
"""
|
||||
|
||||
if not self._ethernet_adapter.port_exists(port_number):
|
||||
raise VPCSError(
|
||||
"Port {port_number} doesn't exist on adapter {adapter}".format(
|
||||
adapter=self._ethernet_adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise VPCSError(f"Port {port_number} doesn't exist on adapter {self._ethernet_adapter}")
|
||||
|
||||
if self.is_running():
|
||||
await self.add_ubridge_udp_connection(f"VPCS-{self._id}", self._local_udp_tunnel[1], nio)
|
||||
|
||||
self._ethernet_adapter.add_nio(port_number, nio)
|
||||
log.info(
|
||||
'VPCS "{name}" [{id}]: {nio} added to port {port_number}'.format(
|
||||
name=self._name, id=self.id, nio=nio, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'VPCS "{self._name}" [{self.id}]: {nio} added to port {port_number}')
|
||||
|
||||
return nio
|
||||
|
||||
@ -411,11 +403,7 @@ class VPCSVM(BaseNode):
|
||||
"""
|
||||
|
||||
if not self._ethernet_adapter.port_exists(port_number):
|
||||
raise VPCSError(
|
||||
"Port {port_number} doesn't exist on adapter {adapter}".format(
|
||||
adapter=self._ethernet_adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise VPCSError(f"Port {port_number} doesn't exist on adapter {self._ethernet_adapter}")
|
||||
if self.is_running():
|
||||
await self.update_ubridge_udp_connection(f"VPCS-{self._id}", self._local_udp_tunnel[1], nio)
|
||||
|
||||
@ -429,11 +417,7 @@ class VPCSVM(BaseNode):
|
||||
"""
|
||||
|
||||
if not self._ethernet_adapter.port_exists(port_number):
|
||||
raise VPCSError(
|
||||
"Port {port_number} doesn't exist on adapter {adapter}".format(
|
||||
adapter=self._ethernet_adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise VPCSError(f"Port {port_number} doesn't exist on adapter {self._ethernet_adapter}")
|
||||
|
||||
await self.stop_capture(port_number)
|
||||
if self.is_running():
|
||||
@ -444,11 +428,7 @@ class VPCSVM(BaseNode):
|
||||
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
||||
self._ethernet_adapter.remove_nio(port_number)
|
||||
|
||||
log.info(
|
||||
'VPCS "{name}" [{id}]: {nio} removed from port {port_number}'.format(
|
||||
name=self._name, id=self.id, nio=nio, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.info(f'VPCS "{self._name}" [{self.id}]: {nio} removed from port {port_number}')
|
||||
return nio
|
||||
|
||||
def get_nio(self, port_number):
|
||||
@ -461,11 +441,7 @@ class VPCSVM(BaseNode):
|
||||
"""
|
||||
|
||||
if not self._ethernet_adapter.port_exists(port_number):
|
||||
raise VPCSError(
|
||||
"Port {port_number} doesn't exist on adapter {adapter}".format(
|
||||
adapter=self._ethernet_adapter, port_number=port_number
|
||||
)
|
||||
)
|
||||
raise VPCSError(f"Port {port_number} doesn't exist on adapter {self._ethernet_adapter}")
|
||||
nio = self._ethernet_adapter.get_nio(port_number)
|
||||
if not nio:
|
||||
raise VPCSError(f"Port {port_number} is not connected")
|
||||
@ -489,11 +465,7 @@ class VPCSVM(BaseNode):
|
||||
'bridge start_capture {name} "{output_file}"'.format(name=f"VPCS-{self._id}", output_file=output_file)
|
||||
)
|
||||
|
||||
log.info(
|
||||
"VPCS '{name}' [{id}]: starting packet capture on port {port_number}".format(
|
||||
name=self.name, id=self.id, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.info(f"VPCS '{self.name}' [{self.id}]: starting packet capture on port {port_number}")
|
||||
|
||||
async def stop_capture(self, port_number):
|
||||
"""
|
||||
@ -510,11 +482,7 @@ class VPCSVM(BaseNode):
|
||||
if self.ubridge:
|
||||
await self._ubridge_send("bridge stop_capture {name}".format(name=f"VPCS-{self._id}"))
|
||||
|
||||
log.info(
|
||||
"VPCS '{name}' [{id}]: stopping packet capture on port {port_number}".format(
|
||||
name=self.name, id=self.id, port_number=port_number
|
||||
)
|
||||
)
|
||||
log.info(f"VPCS '{self.name}' [{self.id}]: stopping packet capture on port {port_number}")
|
||||
|
||||
def _build_command(self):
|
||||
"""
|
||||
|
||||
@ -362,7 +362,7 @@ class Controller:
|
||||
# install the built-in appliances if needed
|
||||
if Config.instance().settings.Server.install_builtin_appliances:
|
||||
previous_version = controller_vars.get("version")
|
||||
log.info("Comparing controller version {} with config version {}".format(__version__, previous_version))
|
||||
log.info(f"Comparing controller version {__version__} with config version {previous_version}")
|
||||
builtin_appliances_path = self._appliance_manager.builtin_appliances_path()
|
||||
if not previous_version or parse_version(__version__.split("+")[0]) > parse_version(
|
||||
previous_version.split("+")[0]
|
||||
|
||||
@ -72,9 +72,7 @@ class Drawing:
|
||||
return data.decode()
|
||||
except UnicodeError:
|
||||
width, height, filetype = get_size(data)
|
||||
return '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="{height}" width="{width}">\n<image height="{height}" width="{width}" xlink:href="data:image/{filetype};base64,{b64}" />\n</svg>'.format(
|
||||
b64=base64.b64encode(data).decode(), filetype=filetype, width=width, height=height
|
||||
)
|
||||
return f'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="{height}" width="{width}">\n<image height="{height}" width="{width}" xlink:href="data:image/{filetype};base64,{base64.b64encode(data).decode()}" />\n</svg>'
|
||||
except OSError:
|
||||
log.warning("Image file %s missing", filename)
|
||||
return "<svg></svg>"
|
||||
|
||||
@ -175,7 +175,7 @@ def _is_exportable(path, include_snapshots=False):
|
||||
return False
|
||||
|
||||
# do not export directories of snapshots
|
||||
if include_snapshots is False and "{sep}snapshots{sep}".format(sep=os.path.sep) in path:
|
||||
if include_snapshots is False and f"{os.path.sep}snapshots{os.path.sep}" in path:
|
||||
return False
|
||||
|
||||
try:
|
||||
|
||||
@ -60,9 +60,7 @@ class GNS3VM:
|
||||
:returns: Return list of engines supported by GNS3 for the GNS3VM
|
||||
"""
|
||||
|
||||
download_url = "https://github.com/GNS3/gns3-gui/releases/download/v{version}/GNS3.VM.VMware.Workstation.{version}.zip".format(
|
||||
version=__version__
|
||||
)
|
||||
download_url = f"https://github.com/GNS3/gns3-gui/releases/download/v{__version__}/GNS3.VM.VMware.Workstation.{__version__}.zip"
|
||||
vmware_info = {
|
||||
"engine_id": "vmware",
|
||||
"description": f'VMware is the recommended choice for best performances.<br>The GNS3 VM can be <a href="{download_url}">downloaded here</a>.',
|
||||
@ -76,9 +74,7 @@ class GNS3VM:
|
||||
vmware_info["name"] = "VMware Workstation / Player (recommended)"
|
||||
|
||||
download_url = (
|
||||
"https://github.com/GNS3/gns3-gui/releases/download/v{version}/GNS3.VM.Hyper-V.{version}.zip".format(
|
||||
version=__version__
|
||||
)
|
||||
f"https://github.com/GNS3/gns3-gui/releases/download/v{__version__}/GNS3.VM.Hyper-V.{__version__}.zip"
|
||||
)
|
||||
hyperv_info = {
|
||||
"engine_id": "hyper-v",
|
||||
@ -90,9 +86,7 @@ class GNS3VM:
|
||||
}
|
||||
|
||||
download_url = (
|
||||
"https://github.com/GNS3/gns3-gui/releases/download/v{version}/GNS3.VM.VirtualBox.{version}.zip".format(
|
||||
version=__version__
|
||||
)
|
||||
f"https://github.com/GNS3/gns3-gui/releases/download/v{__version__}/GNS3.VM.VirtualBox.{__version__}.zip"
|
||||
)
|
||||
virtualbox_info = {
|
||||
"engine_id": "virtualbox",
|
||||
@ -377,9 +371,7 @@ class GNS3VM:
|
||||
if netmask:
|
||||
compute_network = ipaddress.ip_interface(f"{compute.host_ip}/{netmask}").network
|
||||
if vm_network.compare_networks(compute_network) != 0:
|
||||
msg = "The GNS3 VM (IP={}, NETWORK={}) is not on the same network as the {} server (IP={}, NETWORK={}), please make sure the local server binding is in the same network as the GNS3 VM".format(
|
||||
self.ip_address, vm_network, compute_id, compute.host_ip, compute_network
|
||||
)
|
||||
msg = f"The GNS3 VM (IP={self.ip_address}, NETWORK={vm_network}) is not on the same network as the {compute_id} server (IP={compute.host_ip}, NETWORK={compute_network}), please make sure the local server binding is in the same network as the GNS3 VM"
|
||||
self._controller.notification.controller_emit("log.warning", {"message": msg})
|
||||
except ComputeError as e:
|
||||
log.warning(f"Could not check the VM is in the same subnet as the local server: {e}")
|
||||
|
||||
@ -138,7 +138,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
for info in result.splitlines():
|
||||
if "=" in info:
|
||||
name, value = info.split("=", 1)
|
||||
if name == "{}{}".format(backend_type, interface_number):
|
||||
if name == f"{backend_type}{interface_number}":
|
||||
return value.strip('"')
|
||||
return None
|
||||
|
||||
@ -179,7 +179,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
ip_address = match.group(1)
|
||||
netmask = match.group(2)
|
||||
else:
|
||||
raise GNS3VMError("Could not find IP address and netmask for vboxnet {}".format(vboxnet))
|
||||
raise GNS3VMError(f"Could not find IP address and netmask for vboxnet {vboxnet}")
|
||||
|
||||
try:
|
||||
interface = ipaddress.IPv4Interface(f"{ip_address}/{netmask}")
|
||||
@ -189,17 +189,15 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
lower_ip = str(interface.ip + 2)
|
||||
upper_ip = str(subnet.network_address + subnet.num_addresses - 2)
|
||||
except ValueError:
|
||||
raise GNS3VMError(
|
||||
"Invalid IP address and netmask for vboxnet {}: {}/{}".format(vboxnet, ip_address, netmask)
|
||||
)
|
||||
raise GNS3VMError(f"Invalid IP address and netmask for vboxnet {vboxnet}: {ip_address}/{netmask}")
|
||||
|
||||
dhcp_server_args = [
|
||||
"add",
|
||||
"--network=HostInterfaceNetworking-{}".format(vboxnet),
|
||||
"--server-ip={}".format(dhcp_server_ip),
|
||||
"--netmask={}".format(netmask),
|
||||
"--lower-ip={}".format(lower_ip),
|
||||
"--upper-ip={}".format(upper_ip),
|
||||
f"--network=HostInterfaceNetworking-{vboxnet}",
|
||||
f"--server-ip={dhcp_server_ip}",
|
||||
f"--netmask={netmask}",
|
||||
f"--lower-ip={lower_ip}",
|
||||
f"--upper-ip={upper_ip}",
|
||||
"--enable",
|
||||
]
|
||||
await self._execute("dhcpserver", dhcp_server_args)
|
||||
@ -212,7 +210,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
:returns: boolean
|
||||
"""
|
||||
|
||||
properties = await self._execute("list", ["{}".format(vboxnet_type)])
|
||||
properties = await self._execute("list", [f"{vboxnet_type}"])
|
||||
for prop in properties.splitlines():
|
||||
try:
|
||||
name, value = prop.split(":", 1)
|
||||
@ -287,9 +285,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
interface_number = await self._look_for_interface("hostonlynetwork")
|
||||
if interface_number < 0:
|
||||
raise GNS3VMError(
|
||||
'VM "{}" must have a network adapter attached to a host-only network in order to start'.format(
|
||||
self.vmname
|
||||
)
|
||||
f'VM "{self.vmname}" must have a network adapter attached to a host-only network in order to start'
|
||||
)
|
||||
else:
|
||||
backend_type = "hostonlyadapter"
|
||||
@ -299,17 +295,13 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
|
||||
if interface_number < 0:
|
||||
raise GNS3VMError(
|
||||
'VM "{}" must have a network adapter attached to a {} in order to start'.format(
|
||||
self.vmname, backend_description
|
||||
)
|
||||
f'VM "{self.vmname}" must have a network adapter attached to a {backend_description} in order to start'
|
||||
)
|
||||
|
||||
vboxnet = await self._look_for_vboxnet(backend_type, interface_number)
|
||||
if vboxnet is None:
|
||||
raise GNS3VMError(
|
||||
'A VirtualBox host-only network could not be found on network adapter {} for "{}"'.format(
|
||||
interface_number, self._vmname
|
||||
)
|
||||
f'A VirtualBox host-only network could not be found on network adapter {interface_number} for "{self._vmname}"'
|
||||
)
|
||||
|
||||
if not (await self._check_vboxnet_exists(vboxnet, vboxnet_type)):
|
||||
@ -319,9 +311,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
first_available_vboxnet = await self._find_first_available_vboxnet()
|
||||
if first_available_vboxnet is None:
|
||||
raise GNS3VMError(
|
||||
'Please add a VirtualBox host-only network with DHCP enabled and attached it to network adapter {} for "{}"'.format(
|
||||
interface_number, self._vmname
|
||||
)
|
||||
f'Please add a VirtualBox host-only network with DHCP enabled and attached it to network adapter {interface_number} for "{self._vmname}"'
|
||||
)
|
||||
await self.set_hostonly_network(interface_number, first_available_vboxnet)
|
||||
vboxnet = first_available_vboxnet
|
||||
@ -330,18 +320,14 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
await self._execute("hostonlyif", ["create"])
|
||||
except GNS3VMError:
|
||||
raise GNS3VMError(
|
||||
'VirtualBox host-only network "{}" does not exist and could not be automatically created, please make the sure the network adapter {} configuration is valid for "{}"'.format(
|
||||
vboxnet, interface_number, self._vmname
|
||||
)
|
||||
f'VirtualBox host-only network "{vboxnet}" does not exist and could not be automatically created, please make the sure the network adapter {interface_number} configuration is valid for "{self._vmname}"'
|
||||
)
|
||||
|
||||
if backend_type == "hostonlyadapter" and not (await self._check_dhcp_server(vboxnet)):
|
||||
try:
|
||||
await self._add_dhcp_server(vboxnet)
|
||||
except GNS3VMError as e:
|
||||
raise GNS3VMError(
|
||||
"Could not add DHCP server for vboxnet {}: {}, please configure manually".format(vboxnet, e)
|
||||
)
|
||||
raise GNS3VMError(f"Could not add DHCP server for vboxnet {vboxnet}: {e}, please configure manually")
|
||||
|
||||
vm_state = await self._get_state()
|
||||
log.info(f'"{self._vmname}" state is {vm_state}')
|
||||
@ -372,7 +358,7 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
else:
|
||||
# if we can't get the IP address from the guest property, we try to get it from the GNS3 server (a NAT interface is required)
|
||||
if nat_interface_number < 0:
|
||||
raise GNS3VMError("Could not find guest IP address for {}".format(self.vmname))
|
||||
raise GNS3VMError(f"Could not find guest IP address for {self.vmname}")
|
||||
log.warning("Could not find IP address from guest property, trying to get it from GNS3 server")
|
||||
ip_address = "127.0.0.1"
|
||||
try:
|
||||
@ -382,33 +368,27 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
s.bind((ip_address, 0))
|
||||
api_port = s.getsockname()[1]
|
||||
except OSError as e:
|
||||
raise GNS3VMError("Error while getting random port: {}".format(e))
|
||||
raise GNS3VMError(f"Error while getting random port: {e}")
|
||||
|
||||
if await self._check_vbox_port_forwarding():
|
||||
# delete the GNS3VM NAT port forwarding rule if it exists
|
||||
log.info("Removing GNS3VM NAT port forwarding rule from interface {}".format(nat_interface_number))
|
||||
await self._execute(
|
||||
"controlvm", [self._vmname, "natpf{}".format(nat_interface_number), "delete", "GNS3VM"]
|
||||
)
|
||||
log.info(f"Removing GNS3VM NAT port forwarding rule from interface {nat_interface_number}")
|
||||
await self._execute("controlvm", [self._vmname, f"natpf{nat_interface_number}", "delete", "GNS3VM"])
|
||||
|
||||
# add a GNS3VM NAT port forwarding rule to redirect 127.0.0.1 with random port to the port in the VM
|
||||
log.info(
|
||||
"Adding GNS3VM NAT port forwarding rule with port {} to interface {}".format(
|
||||
api_port, nat_interface_number
|
||||
)
|
||||
)
|
||||
log.info(f"Adding GNS3VM NAT port forwarding rule with port {api_port} to interface {nat_interface_number}")
|
||||
await self._execute(
|
||||
"controlvm",
|
||||
[
|
||||
self._vmname,
|
||||
"natpf{}".format(nat_interface_number),
|
||||
"GNS3VM,tcp,{},{},,{}".format(ip_address, api_port, self.port),
|
||||
f"natpf{nat_interface_number}",
|
||||
f"GNS3VM,tcp,{ip_address},{api_port},,{self.port}",
|
||||
],
|
||||
)
|
||||
|
||||
self.ip_address = await self._get_ip_from_server(interface_number, api_port)
|
||||
|
||||
log.info("GNS3 VM has been started with IP '{}'".format(self.ip_address))
|
||||
log.info(f"GNS3 VM has been started with IP '{self.ip_address}'")
|
||||
self.running = True
|
||||
|
||||
async def _get_ip_from_guest_property(self):
|
||||
@ -446,8 +426,9 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
json_data = await resp.json()
|
||||
if json_data:
|
||||
for interface in json_data:
|
||||
if "name" in interface and interface["name"] == "eth{}".format(
|
||||
hostonly_interface_number - 1
|
||||
if (
|
||||
"name" in interface
|
||||
and interface["name"] == f"eth{hostonly_interface_number - 1}"
|
||||
):
|
||||
if "ip_address" in interface and len(interface["ip_address"]) > 0:
|
||||
return interface["ip_address"]
|
||||
@ -537,7 +518,5 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
"modifyvm", [self._vmname, f"--hostonlyadapter{adapter_number}", hostonly_network_name], timeout=3
|
||||
)
|
||||
log.info(
|
||||
'VirtualBox host-only network "{}" set on network adapter {} for "{}"'.format(
|
||||
hostonly_network_name, adapter_number, self._vmname
|
||||
)
|
||||
f'VirtualBox host-only network "{hostonly_network_name}" set on network adapter {adapter_number} for "{self._vmname}"'
|
||||
)
|
||||
|
||||
@ -388,7 +388,7 @@ async def update_snapshots(snapshots_dir, project_path, project_name, project_id
|
||||
async with aiofiles.open(snapshot_path, "wb+") as f:
|
||||
async for chunk in zstream:
|
||||
await f.write(chunk)
|
||||
log.info("Project '{}': updated and repacked snapshot file '{}'".format(project_name, snapshot))
|
||||
log.info(f"Project '{project_name}': updated and repacked snapshot file '{snapshot}'")
|
||||
except OSError as e:
|
||||
raise ControllerError(
|
||||
f"Cannot update snapshot '{os.path.basename(snapshot)}': the snapshot cannot be recreated: {e}"
|
||||
|
||||
@ -552,14 +552,8 @@ class Link:
|
||||
adapter_number = self.capture_node["adapter_number"]
|
||||
port_number = self.capture_node["port_number"]
|
||||
url = (
|
||||
"/projects/{project_id}/{node_type}/nodes/{node_id}/adapters/{adapter_number}/"
|
||||
"ports/{port_number}/capture/stream".format(
|
||||
project_id=self.project.id,
|
||||
node_type=node_type,
|
||||
node_id=node_id,
|
||||
adapter_number=adapter_number,
|
||||
port_number=port_number,
|
||||
)
|
||||
f"/projects/{self.project.id}/{node_type}/nodes/{node_id}/adapters/{adapter_number}/"
|
||||
f"ports/{port_number}/capture/stream"
|
||||
)
|
||||
|
||||
return compute._getUrl(url)
|
||||
|
||||
@ -1483,7 +1483,7 @@ class Project:
|
||||
try:
|
||||
snapshot = Snapshot(self, filename=snap)
|
||||
except ValueError:
|
||||
log.error("Invalid snapshot file: {}".format(snap))
|
||||
log.error(f"Invalid snapshot file: {snap}")
|
||||
continue
|
||||
self._snapshots[snapshot.id] = snapshot
|
||||
else:
|
||||
@ -1492,13 +1492,13 @@ class Project:
|
||||
try:
|
||||
path = os.path.join(snapshot_dir, snapshot_entry["filename"])
|
||||
if not os.path.isfile(path):
|
||||
log.warning("Snapshot file '{}' does not exist".format(path))
|
||||
log.warning(f"Snapshot file '{path}' does not exist")
|
||||
continue
|
||||
snapshot_entry.pop("project_id")
|
||||
snapshot = Snapshot(self, **snapshot_entry)
|
||||
self._snapshots[snapshot.id] = snapshot
|
||||
except KeyError:
|
||||
log.error("Invalid entry in snapshot config file: {}".format(snapshot_entry))
|
||||
log.error(f"Invalid entry in snapshot config file: {snapshot_entry}")
|
||||
continue
|
||||
|
||||
self._save_snapshot_config()
|
||||
@ -1515,7 +1515,7 @@ class Project:
|
||||
with open(self._snapshot_conf_path, "w+") as f:
|
||||
json.dump(self._snapshot_conf, f, indent=4)
|
||||
except OSError as e:
|
||||
log.error("Cannot write snapshot config '{}': {}".format(self._snapshot_conf_path, e))
|
||||
log.error(f"Cannot write snapshot config '{self._snapshot_conf_path}': {e}")
|
||||
|
||||
@open_required
|
||||
async def snapshot(self, name):
|
||||
@ -2142,7 +2142,7 @@ class Project:
|
||||
# remote replication is not supported with remote computes
|
||||
for compute in self.computes:
|
||||
if compute.id != "local":
|
||||
log.warning("Fast duplication is not supported with remote compute: '{}'".format(compute.id))
|
||||
log.warning(f"Fast duplication is not supported with remote compute: '{compute.id}'")
|
||||
return None
|
||||
# work dir
|
||||
p_work = pathlib.Path(location or self.path).parent.absolute()
|
||||
@ -2156,9 +2156,7 @@ class Project:
|
||||
await wait_run_in_executor(
|
||||
shutil.copytree, self.path, new_project_path.as_posix(), symlinks=True, ignore_dangling_symlinks=True
|
||||
)
|
||||
log.info(
|
||||
"Project content copied from '{}' to '{}' in {}s".format(self.path, new_project_path, time.time() - t0)
|
||||
)
|
||||
log.info(f"Project content copied from '{self.path}' to '{new_project_path}' in {time.time() - t0}s")
|
||||
|
||||
# Read the topology file using the actual filename (self._filename), not self.name
|
||||
# This handles the case where a project has been renamed but we need to read the actual file
|
||||
@ -2177,7 +2175,7 @@ class Project:
|
||||
regenerate_topology_ids(topology, new_project_path, reset_mac_addresses)
|
||||
|
||||
# dump the updated .gns3 project file
|
||||
dot_gns3_path = new_project_path.joinpath("{}.gns3".format(project_name))
|
||||
dot_gns3_path = new_project_path.joinpath(f"{project_name}.gns3")
|
||||
topology["project_id"] = new_project_id
|
||||
with open(dot_gns3_path, "w+") as f:
|
||||
json.dump(topology, f, indent=4, sort_keys=True)
|
||||
@ -2190,7 +2188,7 @@ class Project:
|
||||
# Remove the old .gns3 file (which has the original project name)
|
||||
os.remove(old_gns3_file)
|
||||
project = await self.controller.load_project(dot_gns3_path, load=False)
|
||||
log.info("Project '{}': fast duplicated in {:.4f} seconds".format(project.name, time.time() - t0))
|
||||
log.info(f"Project '{project.name}': fast duplicated in {time.time() - t0:.4f} seconds")
|
||||
return project
|
||||
|
||||
def is_running(self):
|
||||
|
||||
@ -79,7 +79,7 @@ class Snapshot:
|
||||
.replace(tzinfo=None)
|
||||
.strftime(DESCRIPTION_DATETIME_FORMAT)
|
||||
)
|
||||
description = "Snapshot '{}' taken on {}".format(self._name, date)
|
||||
description = f"Snapshot '{self._name}' taken on {date}"
|
||||
|
||||
self._description = description
|
||||
self._filename = filename
|
||||
@ -157,7 +157,7 @@ class Snapshot:
|
||||
auto_open=self._project.auto_open,
|
||||
auto_close=self._project.auto_close,
|
||||
)
|
||||
log.info("Snapshot '{}' restored in {:.4f} seconds".format(self.name, time.time() - begin))
|
||||
log.info(f"Snapshot '{self.name}' restored in {time.time() - begin:.4f} seconds")
|
||||
except (OSError, PermissionError) as e:
|
||||
raise ControllerError(str(e))
|
||||
await project.open()
|
||||
|
||||
@ -77,14 +77,14 @@ class CrashReport:
|
||||
dsn=CrashReport.DSN, release=__version__, default_integrations=False, integrations=[sentry_logging]
|
||||
)
|
||||
except Exception as e:
|
||||
log.error("Crash report could not be sent: {}".format(e))
|
||||
log.error(f"Crash report could not be sent: {e}")
|
||||
return
|
||||
|
||||
tags = {
|
||||
"os:name": platform.system(),
|
||||
"os:release": platform.release(),
|
||||
"os:win_32": " ".join(platform.win32_ver()),
|
||||
"os:mac": "{} {}".format(platform.mac_ver()[0], platform.mac_ver()[2]),
|
||||
"os:mac": f"{platform.mac_ver()[0]} {platform.mac_ver()[2]}",
|
||||
"os:linux": distro.name(pretty=True),
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ class CrashReport:
|
||||
scope.set_tag(key, value)
|
||||
|
||||
extra_context = {
|
||||
"python:version": "{}.{}.{}".format(sys.version_info[0], sys.version_info[1], sys.version_info[2]),
|
||||
"python:version": f"{sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]}",
|
||||
"python:bit": struct.calcsize("P") * 8,
|
||||
"python:encoding": sys.getdefaultencoding(),
|
||||
"python:frozen": "{}".format(hasattr(sys, "frozen")),
|
||||
|
||||
@ -59,10 +59,10 @@ class GUID(TypeDecorator):
|
||||
return str(value)
|
||||
else:
|
||||
if not isinstance(value, uuid.UUID):
|
||||
return "{:032x}".format(uuid.UUID(value).int)
|
||||
return f"{uuid.UUID(value).int:032x}"
|
||||
else:
|
||||
# hexstring
|
||||
return "{:032x}".format(value.int)
|
||||
return f"{value.int:032x}"
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
if value is None:
|
||||
|
||||
@ -260,9 +260,7 @@ class Server:
|
||||
raise SystemExit("Python 3.9 or higher is required")
|
||||
|
||||
log.info(
|
||||
"Running with Python {major}.{minor}.{micro} and has PID {pid}".format(
|
||||
major=sys.version_info[0], minor=sys.version_info[1], micro=sys.version_info[2], pid=os.getpid()
|
||||
)
|
||||
f"Running with Python {sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]} and has PID {os.getpid()}"
|
||||
)
|
||||
|
||||
# check for the correct locale (UNIX/Linux only)
|
||||
|
||||
@ -48,7 +48,7 @@ def int_to_macaddress(integer):
|
||||
"""
|
||||
Convert an integer to a mac address
|
||||
"""
|
||||
return ":".join(textwrap.wrap("{:012x}".format(integer), width=2))
|
||||
return ":".join(textwrap.wrap(f"{integer:012x}", width=2))
|
||||
|
||||
|
||||
def parse_version(version):
|
||||
|
||||
@ -184,7 +184,7 @@ class ZipFile(zipfile.ZipFile):
|
||||
"""
|
||||
|
||||
if not isinstance(comment, bytes):
|
||||
raise TypeError("comment: expected bytes, got {}".format(type(comment)))
|
||||
raise TypeError(f"comment: expected bytes, got {type(comment)}")
|
||||
# check for valid comment length
|
||||
if len(comment) >= zipfile.ZIP_MAX_COMMENT:
|
||||
if self.debug:
|
||||
|
||||
@ -70,7 +70,7 @@ async def list_images(image_type):
|
||||
for root, _, filenames in _os_walk(directory, recurse=recurse):
|
||||
for filename in filenames:
|
||||
if filename in files:
|
||||
log.debug("File {} has already been found, skipping...".format(filename))
|
||||
log.debug(f"File {filename} has already been found, skipping...")
|
||||
continue
|
||||
if filename.endswith(".md5sum") or filename.startswith("."):
|
||||
continue
|
||||
|
||||
@ -66,7 +66,7 @@ def _get_windows_interfaces_from_registry():
|
||||
if ip_address:
|
||||
# get the first IPv4 address only
|
||||
ip_address = ip_address[0]
|
||||
npf_interface = "\\Device\\NPF_{guid}".format(guid=guid)
|
||||
npf_interface = f"\\Device\\NPF_{guid}"
|
||||
interfaces.append(
|
||||
{
|
||||
"id": npf_interface,
|
||||
@ -116,7 +116,7 @@ def get_windows_interfaces():
|
||||
ip_address = network_config.IPAddress[0]
|
||||
netmask = network_config.IPSubnet[0]
|
||||
break
|
||||
npf_interface = "\\Device\\NPF_{guid}".format(guid=adapter.GUID)
|
||||
npf_interface = f"\\Device\\NPF_{adapter.GUID}"
|
||||
interfaces.append(
|
||||
{
|
||||
"id": npf_interface,
|
||||
|
||||
@ -107,7 +107,6 @@ ignore = [
|
||||
"S110", # 23 try-except-pass
|
||||
"UP006", # 270 non-pep585-annotation
|
||||
"UP007", # 81 non-pep604-annotation-union
|
||||
"UP032", # 560 f-string
|
||||
"UP035", # 106 deprecated-import
|
||||
"UP045", # 1100 non-pep604-annotation-optional
|
||||
]
|
||||
|
||||
@ -39,7 +39,7 @@ class Welcome_dialog:
|
||||
if self.gns3_version() is None:
|
||||
self.display.set_background_title("GNS3")
|
||||
else:
|
||||
self.display.set_background_title("GNS3 {}".format(self.gns3_version()))
|
||||
self.display.set_background_title(f"GNS3 {self.gns3_version()}")
|
||||
|
||||
def get_ip(self):
|
||||
"""
|
||||
@ -228,42 +228,36 @@ class Welcome_dialog:
|
||||
if answer != self.display.OK:
|
||||
return
|
||||
if destination == self.get_ip():
|
||||
self.display.msgbox("The destination cannot be the same as this VM IP address ({})".format(destination))
|
||||
self.display.msgbox(f"The destination cannot be the same as this VM IP address ({destination})")
|
||||
return
|
||||
if option == "Send":
|
||||
# first make sure they are no files belonging to root
|
||||
os.system("sudo chown -R gns3:gns3 /opt/gns3")
|
||||
# then rsync the data
|
||||
command = r"rsync -az --progress -e 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /home/gns3/.ssh/gns3-vm-key' /opt/gns3 gns3@{}:/opt".format(
|
||||
destination
|
||||
)
|
||||
ret = os.system('bash -c "{}"'.format(command))
|
||||
command = rf"rsync -az --progress -e 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /home/gns3/.ssh/gns3-vm-key' /opt/gns3 gns3@{destination}:/opt"
|
||||
ret = os.system(f'bash -c "{command}"')
|
||||
time.sleep(10)
|
||||
if ret != 0:
|
||||
self.display.msgbox("Could not send data to the other GNS3 VM located at {}".format(destination))
|
||||
self.display.msgbox(f"Could not send data to the other GNS3 VM located at {destination}")
|
||||
else:
|
||||
self.display.msgbox(
|
||||
"Images and projects have been successfully sent to the other GNS3 VM located at {}".format(
|
||||
destination
|
||||
)
|
||||
f"Images and projects have been successfully sent to the other GNS3 VM located at {destination}"
|
||||
)
|
||||
elif option == "Setup":
|
||||
script = """
|
||||
script = f"""
|
||||
if [ ! -f ~/.ssh/gns3-vm-key ]
|
||||
then
|
||||
ssh-keygen -f ~/.ssh/gns3-vm-key -N '' -C gns3@{}
|
||||
ssh-keygen -f ~/.ssh/gns3-vm-key -N '' -C gns3@{self.get_ip()}
|
||||
fi
|
||||
ssh-copy-id -i ~/.ssh/gns3-vm-key gns3@{}
|
||||
""".format(self.get_ip(), destination)
|
||||
ret = os.system('bash -c "{}"'.format(script))
|
||||
ssh-copy-id -i ~/.ssh/gns3-vm-key gns3@{destination}
|
||||
"""
|
||||
ret = os.system(f'bash -c "{script}"')
|
||||
time.sleep(10)
|
||||
if ret != 0:
|
||||
self.display.msgbox("Error while setting up the migrate feature")
|
||||
else:
|
||||
self.display.msgbox(
|
||||
"Configuration successful, you can now send data to the GNS3 VM located at {} without password".format(
|
||||
destination
|
||||
)
|
||||
f"Configuration successful, you can now send data to the GNS3 VM located at {destination} without password"
|
||||
)
|
||||
|
||||
def shrink_disk(self):
|
||||
@ -300,11 +294,7 @@ class Welcome_dialog:
|
||||
if version is None:
|
||||
content += "GNS3 is not installed please install it with sudo pip3 install gns3-server. Or download a preinstalled VM.\n\n"
|
||||
else:
|
||||
content = (
|
||||
"GNS3 version: {gns3_version}\nVM version: {gns3vm_version}\nKVM support available: {kvm}\n\n".format(
|
||||
gns3vm_version=self.gns3vm_version(), gns3_version=version, kvm=self.kvm_support()
|
||||
)
|
||||
)
|
||||
content = f"GNS3 version: {version}\nVM version: {self.gns3vm_version()}\nKVM support available: {self.kvm_support()}\n\n"
|
||||
|
||||
ip = self.get_ip()
|
||||
|
||||
@ -336,7 +326,7 @@ Images and projects are located in /opt/gns3
|
||||
try:
|
||||
response = urllib.request.urlopen("http://pypi.python.org/", timeout=5)
|
||||
except urllib.request.URLError as err:
|
||||
self.display.infobox("Can't connect to Internet (pypi.python.org): {}".format(str(err)))
|
||||
self.display.infobox(f"Can't connect to Internet (pypi.python.org): {err!s}")
|
||||
time.sleep(15)
|
||||
return
|
||||
self.display.infobox("Connection to Internet: OK")
|
||||
@ -384,7 +374,7 @@ Images and projects are located in /opt/gns3
|
||||
|
||||
major_version = self.gns3_major_version()
|
||||
if major_version == "2.2":
|
||||
os.system("nano ~/.config/GNS3/{}/gns3_server.conf".format(major_version))
|
||||
os.system(f"nano ~/.config/GNS3/{major_version}/gns3_server.conf")
|
||||
else:
|
||||
os.system("nano ~/.config/GNS3/gns3_server.conf")
|
||||
|
||||
@ -474,7 +464,7 @@ Images and projects are located in /opt/gns3
|
||||
try:
|
||||
while True:
|
||||
code, tag = self.display.menu(
|
||||
"GNS3 {}".format(self.gns3_version()),
|
||||
f"GNS3 {self.gns3_version()}",
|
||||
choices=[
|
||||
("Information", "Display VM information"),
|
||||
("Upgrade", "Upgrade GNS3"),
|
||||
|
||||
@ -465,9 +465,7 @@ class TestNodeRoutes:
|
||||
|
||||
compute.http_query.assert_called_with(
|
||||
"GET",
|
||||
"/projects/{project_id}/files/project-files/vpcs/{node_id}/hello".format(
|
||||
project_id=project.id, node_id=node.id
|
||||
),
|
||||
f"/projects/{project.id}/files/project-files/vpcs/{node.id}/hello",
|
||||
timeout=None,
|
||||
stream=True,
|
||||
)
|
||||
@ -491,16 +489,12 @@ class TestNodeRoutes:
|
||||
compute.http_query.assert_called_once()
|
||||
call_args = compute.http_query.call_args
|
||||
assert call_args[0][0] == "POST"
|
||||
assert call_args[0][1] == "/projects/{project_id}/files/project-files/vpcs/{node_id}/hello".format(
|
||||
project_id=project.id, node_id=node.id
|
||||
)
|
||||
assert call_args[0][1] == f"/projects/{project.id}/files/project-files/vpcs/{node.id}/hello"
|
||||
assert call_args[1]["timeout"] is None
|
||||
# data should be an async generator from request.stream()
|
||||
assert hasattr(call_args[1]["data"], "__aiter__")
|
||||
|
||||
response = await client.get(
|
||||
"/projects/{project_id}/nodes/{node_id}/files/../hello".format(project_id=project.id, node_id=node.id)
|
||||
)
|
||||
response = await client.get(f"/projects/{project.id}/nodes/{node.id}/files/../hello")
|
||||
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||
|
||||
# @pytest.mark.asyncio
|
||||
|
||||
@ -244,10 +244,9 @@ class TestControllerProjectRoutes:
|
||||
)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.headers["CONTENT-TYPE"] == "application/gns3project"
|
||||
assert response.headers[
|
||||
"CONTENT-DISPOSITION"
|
||||
] == "attachment; filename=\"{name}.gns3project\"; filename*=UTF-8''{name}.gns3project".format(
|
||||
name=project.name
|
||||
assert (
|
||||
response.headers["CONTENT-DISPOSITION"]
|
||||
== f"attachment; filename=\"{project.name}.gns3project\"; filename*=UTF-8''{project.name}.gns3project"
|
||||
)
|
||||
|
||||
with open(str(tmpdir / "project.zip"), "wb+") as f:
|
||||
@ -283,10 +282,9 @@ class TestControllerProjectRoutes:
|
||||
)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.headers["CONTENT-TYPE"] == "application/gns3project"
|
||||
assert response.headers[
|
||||
"CONTENT-DISPOSITION"
|
||||
] == "attachment; filename=\"{name}.gns3project\"; filename*=UTF-8''{name}.gns3project".format(
|
||||
name=project.name
|
||||
assert (
|
||||
response.headers["CONTENT-DISPOSITION"]
|
||||
== f"attachment; filename=\"{project.name}.gns3project\"; filename*=UTF-8''{project.name}.gns3project"
|
||||
)
|
||||
with open(str(tmpdir / "project.zip"), "wb+") as f:
|
||||
f.write(response.content)
|
||||
@ -343,10 +341,9 @@ class TestControllerProjectRoutes:
|
||||
|
||||
if response.status_code == status.HTTP_200_OK:
|
||||
assert response.headers["CONTENT-TYPE"] == "application/gns3project"
|
||||
assert response.headers[
|
||||
"CONTENT-DISPOSITION"
|
||||
] == "attachment; filename=\"{name}.gns3project\"; filename*=UTF-8''{name}.gns3project".format(
|
||||
name=project.name
|
||||
assert (
|
||||
response.headers["CONTENT-DISPOSITION"]
|
||||
== f"attachment; filename=\"{project.name}.gns3project\"; filename*=UTF-8''{project.name}.gns3project"
|
||||
)
|
||||
with open(str(tmpdir / "project.zip"), "wb+") as f:
|
||||
f.write(response.content)
|
||||
|
||||
@ -42,9 +42,7 @@ class TestVersionRoutes:
|
||||
params = {"version": "0.4.2"}
|
||||
response = await client.post(app.url_path_for("check_version"), json=params)
|
||||
assert response.status_code == status.HTTP_409_CONFLICT
|
||||
assert response.json() == {
|
||||
"message": "Client version 0.4.2 is not the same as server version {}".format(__version__)
|
||||
}
|
||||
assert response.json() == {"message": f"Client version 0.4.2 is not the same as server version {__version__}"}
|
||||
|
||||
async def test_version_invalid_input_schema(self, app: FastAPI, client: AsyncClient) -> None:
|
||||
|
||||
|
||||
@ -189,11 +189,11 @@ async def test_linux_ethernet_raw_add_nio(linux_platform, compute_project, nio):
|
||||
|
||||
ubridge_mock.assert_has_calls(
|
||||
[
|
||||
call("bridge create {}-0".format(cloud._id)),
|
||||
call("bridge add_nio_udp {}-0 4242 127.0.0.1 4343".format(cloud._id)),
|
||||
call("bridge reset_packet_filters {}-0".format(cloud._id)),
|
||||
call('bridge add_nio_linux_raw {}-0 "eth0"'.format(cloud._id)),
|
||||
call("bridge start {}-0".format(cloud._id)),
|
||||
call(f"bridge create {cloud._id}-0"),
|
||||
call(f"bridge add_nio_udp {cloud._id}-0 4242 127.0.0.1 4343"),
|
||||
call(f"bridge reset_packet_filters {cloud._id}-0"),
|
||||
call(f'bridge add_nio_linux_raw {cloud._id}-0 "eth0"'),
|
||||
call(f"bridge start {cloud._id}-0"),
|
||||
]
|
||||
)
|
||||
|
||||
@ -218,11 +218,11 @@ async def test_linux_ethernet_raw_add_nio_bridge(linux_platform, compute_project
|
||||
tap = "gns3tap0-0"
|
||||
ubridge_mock.assert_has_calls(
|
||||
[
|
||||
call("bridge create {}-0".format(cloud._id)),
|
||||
call("bridge add_nio_udp {}-0 4242 127.0.0.1 4343".format(cloud._id)),
|
||||
call("bridge reset_packet_filters {}-0".format(cloud._id)),
|
||||
call('bridge add_nio_tap "{}-0" "{}"'.format(cloud._id, tap)),
|
||||
call('brctl addif "bridge0" "{}"'.format(tap)),
|
||||
call("bridge start {}-0".format(cloud._id)),
|
||||
call(f"bridge create {cloud._id}-0"),
|
||||
call(f"bridge add_nio_udp {cloud._id}-0 4242 127.0.0.1 4343"),
|
||||
call(f"bridge reset_packet_filters {cloud._id}-0"),
|
||||
call(f'bridge add_nio_tap "{cloud._id}-0" "{tap}"'),
|
||||
call(f'brctl addif "bridge0" "{tap}"'),
|
||||
call(f"bridge start {cloud._id}-0"),
|
||||
]
|
||||
)
|
||||
|
||||
@ -51,7 +51,7 @@ async def test_query_success(vm):
|
||||
data = await vm.query("POST", "test", data={"a": True}, params={"b": 1})
|
||||
vm._session.request.assert_called_with(
|
||||
"POST",
|
||||
"http://docker/v{}/test".format(DOCKER_MINIMUM_API_VERSION),
|
||||
f"http://docker/v{DOCKER_MINIMUM_API_VERSION}/test",
|
||||
data='{"a": true}',
|
||||
headers={"content-type": "application/json"},
|
||||
params={"b": 1},
|
||||
@ -76,7 +76,7 @@ async def test_query_error(vm):
|
||||
await vm.query("POST", "test", data={"a": True}, params={"b": 1})
|
||||
vm._session.request.assert_called_with(
|
||||
"POST",
|
||||
"http://docker/v{}/test".format(DOCKER_MINIMUM_API_VERSION),
|
||||
f"http://docker/v{DOCKER_MINIMUM_API_VERSION}/test",
|
||||
data='{"a": true}',
|
||||
headers={"content-type": "application/json"},
|
||||
params={"b": 1},
|
||||
@ -99,7 +99,7 @@ async def test_query_error_json(vm):
|
||||
await vm.query("POST", "test", data={"a": True}, params={"b": 1})
|
||||
vm._session.request.assert_called_with(
|
||||
"POST",
|
||||
"http://docker/v{}/test".format(DOCKER_MINIMUM_API_VERSION),
|
||||
f"http://docker/v{DOCKER_MINIMUM_API_VERSION}/test",
|
||||
data='{"a": true}',
|
||||
headers={"content-type": "application/json"},
|
||||
params={"b": 1},
|
||||
|
||||
@ -103,7 +103,7 @@ async def test_create(compute_project, manager):
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -145,7 +145,7 @@ async def test_create_with_tag(compute_project, manager):
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -192,7 +192,7 @@ async def test_create_vnc(compute_project, manager):
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -423,7 +423,7 @@ async def test_create_start_cmd(compute_project, manager):
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -520,7 +520,7 @@ async def test_create_image_digest_match(compute_project, manager):
|
||||
)
|
||||
await vm.create()
|
||||
# the last query is the container creation: the digest check let it through
|
||||
assert mock.call_args[0] == ("POST", "containers/create?name={}".format(vm.docker_name))
|
||||
assert mock.call_args[0] == ("POST", f"containers/create?name={vm.docker_name}")
|
||||
assert vm._cid == "sha256:" + "a" * 64
|
||||
|
||||
|
||||
@ -554,7 +554,7 @@ async def test_create_with_user(compute_project, manager):
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -647,7 +647,7 @@ async def test_create_with_extra_volumes_duplicate_1_image(compute_project, mana
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -699,7 +699,7 @@ async def test_create_with_extra_volumes_duplicate_2_user(compute_project, manag
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -751,7 +751,7 @@ async def test_create_with_extra_volumes_duplicate_3_subdir(compute_project, man
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -803,7 +803,7 @@ async def test_create_with_extra_volumes_duplicate_4_backslash(compute_project,
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -853,7 +853,7 @@ async def test_create_with_extra_volumes_duplicate_5_subdir_issue_1595(compute_p
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -905,7 +905,7 @@ async def test_create_with_extra_volumes_duplicate_6_subdir_issue_1595(compute_p
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -956,7 +956,7 @@ async def test_create_with_extra_volumes(compute_project, manager):
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -1376,7 +1376,7 @@ async def test_update(vm):
|
||||
mock_query.assert_any_call("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
|
||||
mock_query.assert_any_call(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -1448,7 +1448,7 @@ async def test_update_running(vm):
|
||||
mock_query.assert_any_call("DELETE", "containers/e90e34656842", params={"force": 1, "v": 1})
|
||||
mock_query.assert_any_call(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -1633,7 +1633,7 @@ async def test_add_ubridge_connection_no_free_interface(vm):
|
||||
nio = vm.manager.create_nio(nio)
|
||||
with pytest.raises(DockerError):
|
||||
# We create fake ethernet interfaces for docker
|
||||
interfaces = ["tap-gns3-e{}".format(index) for index in range(4096)]
|
||||
interfaces = [f"tap-gns3-e{index}" for index in range(4096)]
|
||||
|
||||
with patch("psutil.net_if_addrs", return_value=interfaces):
|
||||
await vm._add_ubridge_connection(nio, 0)
|
||||
@ -1821,9 +1821,9 @@ async def test_start_vnc(vm):
|
||||
"None",
|
||||
"-desktop",
|
||||
"test",
|
||||
":{}".format(vm._display),
|
||||
f":{vm._display}",
|
||||
)
|
||||
mock_wait.assert_called_with("/tmp/.X11-unix/X{}".format(vm._display))
|
||||
mock_wait.assert_called_with(f"/tmp/.X11-unix/X{vm._display}")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -1882,9 +1882,7 @@ async def test_fix_permission(vm):
|
||||
"/gns3/bin/busybox",
|
||||
"sh",
|
||||
"-c",
|
||||
'(/gns3/bin/busybox find "/etc" -depth -print0 | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c \'%a:%u:%g:%n\' > "/etc/.gns3_perms") && /gns3/bin/busybox chmod -R u+rX "/etc" && /gns3/bin/busybox chown {}:{} -R "/etc"'.format(
|
||||
os.getuid(), os.getgid()
|
||||
),
|
||||
f'(/gns3/bin/busybox find "/etc" -depth -print0 | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c \'%a:%u:%g:%n\' > "/etc/.gns3_perms") && /gns3/bin/busybox chmod -R u+rX "/etc" && /gns3/bin/busybox chown {os.getuid()}:{os.getgid()} -R "/etc"',
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
assert process.wait.called
|
||||
@ -1907,9 +1905,7 @@ async def test_fix_permission_not_running(vm):
|
||||
"/gns3/bin/busybox",
|
||||
"sh",
|
||||
"-c",
|
||||
'(/gns3/bin/busybox find "/etc" -depth -print0 | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c \'%a:%u:%g:%n\' > "/etc/.gns3_perms") && /gns3/bin/busybox chmod -R u+rX "/etc" && /gns3/bin/busybox chown {}:{} -R "/etc"'.format(
|
||||
os.getuid(), os.getgid()
|
||||
),
|
||||
f'(/gns3/bin/busybox find "/etc" -depth -print0 | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c \'%a:%u:%g:%n\' > "/etc/.gns3_perms") && /gns3/bin/busybox chmod -R u+rX "/etc" && /gns3/bin/busybox chown {os.getuid()}:{os.getgid()} -R "/etc"',
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
assert mock_start.called
|
||||
@ -2080,7 +2076,7 @@ async def test_cpus(compute_project, manager):
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
@ -2122,7 +2118,7 @@ async def test_memory(compute_project, manager):
|
||||
await vm.create()
|
||||
mock.assert_called_with(
|
||||
"POST",
|
||||
"containers/create?name={}".format(vm.docker_name),
|
||||
f"containers/create?name={vm.docker_name}",
|
||||
data={
|
||||
"Tty": True,
|
||||
"OpenStdin": True,
|
||||
|
||||
@ -56,7 +56,7 @@ def iourc_file(tmpdir):
|
||||
path = str(tmpdir / "iourc")
|
||||
with open(path, "w+") as f:
|
||||
hostname = socket.gethostname()
|
||||
f.write("[license]\n{} = aaaaaaaaaaaaaaaa;".format(hostname))
|
||||
f.write(f"[license]\n{hostname} = aaaaaaaaaaaaaaaa;")
|
||||
return path
|
||||
|
||||
|
||||
@ -182,15 +182,15 @@ async def test_rename_nvram_file(vm):
|
||||
It should rename the nvram file to the correct name before launching the VM
|
||||
"""
|
||||
|
||||
with open(os.path.join(vm.working_dir, "nvram_0000{}".format(vm.application_id + 1)), "w+") as f:
|
||||
with open(os.path.join(vm.working_dir, f"nvram_0000{vm.application_id + 1}"), "w+") as f:
|
||||
f.write("1")
|
||||
|
||||
with open(os.path.join(vm.working_dir, "vlan.dat-0000{}".format(vm.application_id + 1)), "w+") as f:
|
||||
with open(os.path.join(vm.working_dir, f"vlan.dat-0000{vm.application_id + 1}"), "w+") as f:
|
||||
f.write("1")
|
||||
|
||||
vm._rename_nvram_file()
|
||||
assert os.path.exists(os.path.join(vm.working_dir, "nvram_0000{}".format(vm.application_id)))
|
||||
assert os.path.exists(os.path.join(vm.working_dir, "vlan.dat-0000{}".format(vm.application_id)))
|
||||
assert os.path.exists(os.path.join(vm.working_dir, f"nvram_0000{vm.application_id}"))
|
||||
assert os.path.exists(os.path.join(vm.working_dir, f"vlan.dat-0000{vm.application_id}"))
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -589,13 +589,13 @@ async def test_invalid_iou_file(vm, iourc_file):
|
||||
# Missing ;
|
||||
with pytest.raises(IOUError):
|
||||
with open(iourc_file, "w+") as f:
|
||||
f.write("[license]\n{} = aaaaaaaaaaaaaaaa".format(hostname))
|
||||
f.write(f"[license]\n{hostname} = aaaaaaaaaaaaaaaa")
|
||||
await vm._check_iou_license()
|
||||
|
||||
# Key too short
|
||||
with pytest.raises(IOUError):
|
||||
with open(iourc_file, "w+") as f:
|
||||
f.write("[license]\n{} = aaaaaaaaaaaaaa;".format(hostname))
|
||||
f.write(f"[license]\n{hostname} = aaaaaaaaaaaaaa;")
|
||||
await vm._check_iou_license()
|
||||
|
||||
# Invalid hostname
|
||||
|
||||
@ -384,7 +384,7 @@ async def test_disk_options(vm, tmpdir, fake_qemu_img_binary):
|
||||
fake_qemu_img_binary,
|
||||
"create",
|
||||
"-o",
|
||||
"backing_file={}".format(vm._hda_disk_image),
|
||||
f"backing_file={vm._hda_disk_image}",
|
||||
"-F",
|
||||
"qcow2",
|
||||
"-f",
|
||||
@ -394,7 +394,7 @@ async def test_disk_options(vm, tmpdir, fake_qemu_img_binary):
|
||||
fake_qemu_img_binary,
|
||||
"create",
|
||||
"-o",
|
||||
"backing_file={}".format(vm._hdb_disk_image),
|
||||
f"backing_file={vm._hdb_disk_image}",
|
||||
"-F",
|
||||
"qcow2",
|
||||
"-f",
|
||||
@ -449,7 +449,7 @@ async def test_uefi_boot_mode_option(vm, tmpdir, images_dir, fake_qemu_img_binar
|
||||
f.write("1")
|
||||
|
||||
options = await vm._build_command()
|
||||
assert " ".join(["-drive", "if=pflash,format=raw,readonly,file={}".format(ovmf_code_path)]) in " ".join(options)
|
||||
assert " ".join(["-drive", f"if=pflash,format=raw,readonly,file={ovmf_code_path}"]) in " ".join(options)
|
||||
assert " ".join(
|
||||
["-drive", "if=pflash,format=raw,file={}".format(os.path.join(vm.working_dir, "OVMF_VARS_4M.fd"))]
|
||||
) in " ".join(options)
|
||||
@ -490,7 +490,7 @@ async def test_tpm_option(vm, tmpdir, fake_qemu_img_binary):
|
||||
tpm_sock = os.path.join(vm.temporary_directory, "swtpm.sock")
|
||||
with patch("os.path.exists", return_value=True) as os_path:
|
||||
options = await vm._build_command()
|
||||
assert "-chardev socket,id=chrtpm,path={}".format(tpm_sock) in " ".join(options)
|
||||
assert f"-chardev socket,id=chrtpm,path={tpm_sock}" in " ".join(options)
|
||||
assert "-tpmdev emulator,id=tpm0,chardev=chrtpm" in " ".join(options)
|
||||
assert "-device tpm-tis,tpmdev=tpm0" in " ".join(options)
|
||||
|
||||
@ -608,7 +608,7 @@ async def test_build_command(vm, fake_qemu_binary):
|
||||
"-uuid",
|
||||
vm.id,
|
||||
"-serial",
|
||||
"telnet:127.0.0.1:{},server,nowait".format(vm._internal_console_port),
|
||||
f"telnet:127.0.0.1:{vm._internal_console_port},server,nowait",
|
||||
"-net",
|
||||
"none",
|
||||
"-device",
|
||||
@ -616,9 +616,9 @@ async def test_build_command(vm, fake_qemu_binary):
|
||||
"-device",
|
||||
"pci-bridge,id=pci-bridge1,bus=dmi_pci_bridge1,chassis_nr=0x1,addr=0x1,shpc=off",
|
||||
"-device",
|
||||
"e1000,mac={},bus=pci-bridge1,addr=0x00,netdev=gns3-0".format(vm._mac_address),
|
||||
f"e1000,mac={vm._mac_address},bus=pci-bridge1,addr=0x00,netdev=gns3-0",
|
||||
"-netdev",
|
||||
"socket,id=gns3-0,udp=127.0.0.1:{},localaddr=127.0.0.1:{}".format(nio.rport, nio.lport),
|
||||
f"socket,id=gns3-0,udp=127.0.0.1:{nio.rport},localaddr=127.0.0.1:{nio.lport}",
|
||||
"-display",
|
||||
"none",
|
||||
]
|
||||
@ -679,7 +679,7 @@ async def test_build_command_kvm_2_4(linux_platform, vm, fake_qemu_binary):
|
||||
"-uuid",
|
||||
vm.id,
|
||||
"-serial",
|
||||
"telnet:127.0.0.1:{},server,nowait".format(vm._internal_console_port),
|
||||
f"telnet:127.0.0.1:{vm._internal_console_port},server,nowait",
|
||||
"-net",
|
||||
"none",
|
||||
"-device",
|
||||
@ -687,9 +687,9 @@ async def test_build_command_kvm_2_4(linux_platform, vm, fake_qemu_binary):
|
||||
"-device",
|
||||
"pci-bridge,id=pci-bridge1,bus=dmi_pci_bridge1,chassis_nr=0x1,addr=0x1,shpc=off",
|
||||
"-device",
|
||||
"e1000,mac={},bus=pci-bridge1,addr=0x00,netdev=gns3-0".format(vm._mac_address),
|
||||
f"e1000,mac={vm._mac_address},bus=pci-bridge1,addr=0x00,netdev=gns3-0",
|
||||
"-netdev",
|
||||
"socket,id=gns3-0,udp=127.0.0.1:{},localaddr=127.0.0.1:{}".format(nio.rport, nio.lport),
|
||||
f"socket,id=gns3-0,udp=127.0.0.1:{nio.rport},localaddr=127.0.0.1:{nio.lport}",
|
||||
"-nographic",
|
||||
]
|
||||
|
||||
@ -727,7 +727,7 @@ async def test_build_command_two_adapters(vm, fake_qemu_binary):
|
||||
"-uuid",
|
||||
vm.id,
|
||||
"-serial",
|
||||
"telnet:127.0.0.1:{},server,nowait".format(vm._internal_console_port),
|
||||
f"telnet:127.0.0.1:{vm._internal_console_port},server,nowait",
|
||||
"-net",
|
||||
"none",
|
||||
"-device",
|
||||
@ -735,15 +735,13 @@ async def test_build_command_two_adapters(vm, fake_qemu_binary):
|
||||
"-device",
|
||||
"pci-bridge,id=pci-bridge1,bus=dmi_pci_bridge1,chassis_nr=0x1,addr=0x1,shpc=off",
|
||||
"-device",
|
||||
"e1000,mac={},bus=pci-bridge1,addr=0x00,netdev=gns3-0".format(vm._mac_address),
|
||||
f"e1000,mac={vm._mac_address},bus=pci-bridge1,addr=0x00,netdev=gns3-0",
|
||||
"-netdev",
|
||||
"socket,id=gns3-0,udp=127.0.0.1:{},localaddr=127.0.0.1:{}".format(nio1.rport, nio1.lport),
|
||||
f"socket,id=gns3-0,udp=127.0.0.1:{nio1.rport},localaddr=127.0.0.1:{nio1.lport}",
|
||||
"-device",
|
||||
"e1000,mac={},bus=pci-bridge1,addr=0x01,netdev=gns3-1".format(
|
||||
int_to_macaddress(macaddress_to_int(vm._mac_address) + 1)
|
||||
),
|
||||
f"e1000,mac={int_to_macaddress(macaddress_to_int(vm._mac_address) + 1)},bus=pci-bridge1,addr=0x01,netdev=gns3-1",
|
||||
"-netdev",
|
||||
"socket,id=gns3-1,udp=127.0.0.1:{},localaddr=127.0.0.1:{}".format(nio2.rport, nio2.lport),
|
||||
f"socket,id=gns3-1,udp=127.0.0.1:{nio2.rport},localaddr=127.0.0.1:{nio2.lport}",
|
||||
"-nographic",
|
||||
]
|
||||
|
||||
@ -761,8 +759,8 @@ async def test_build_command_two_adapters_mac_address(vm):
|
||||
assert mac_0[:8] == "00:00:ab"
|
||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()):
|
||||
cmd = await vm._build_command()
|
||||
assert "e1000,mac={},bus=pci-bridge1,addr=0x00,netdev=gns3-0".format(mac_0) in cmd
|
||||
assert "e1000,mac={},bus=pci-bridge1,addr=0x01,netdev=gns3-1".format(mac_1) in cmd
|
||||
assert f"e1000,mac={mac_0},bus=pci-bridge1,addr=0x00,netdev=gns3-0" in cmd
|
||||
assert f"e1000,mac={mac_1},bus=pci-bridge1,addr=0x01,netdev=gns3-1" in cmd
|
||||
|
||||
vm.mac_address = "00:42:ab:0e:0f:0a"
|
||||
mac_0 = vm._mac_address
|
||||
@ -770,8 +768,8 @@ async def test_build_command_two_adapters_mac_address(vm):
|
||||
assert mac_0[:8] == "00:42:ab"
|
||||
with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()):
|
||||
cmd = await vm._build_command()
|
||||
assert "e1000,mac={},bus=pci-bridge1,addr=0x00,netdev=gns3-0".format(mac_0) in cmd
|
||||
assert "e1000,mac={},bus=pci-bridge1,addr=0x01,netdev=gns3-1".format(mac_1) in cmd
|
||||
assert f"e1000,mac={mac_0},bus=pci-bridge1,addr=0x00,netdev=gns3-0" in cmd
|
||||
assert f"e1000,mac={mac_1},bus=pci-bridge1,addr=0x01,netdev=gns3-1" in cmd
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -793,19 +791,19 @@ async def test_build_command_large_number_of_adapters(vm):
|
||||
assert len([l for l in cmd if "e1000" in l]) == 100
|
||||
assert len(vm._ethernet_adapters) == 100
|
||||
|
||||
assert "e1000,mac={},bus=pci-bridge1,addr=0x00,netdev=gns3-0".format(mac_0) in cmd
|
||||
assert "e1000,mac={},bus=pci-bridge1,addr=0x01,netdev=gns3-1".format(mac_1) in cmd
|
||||
assert f"e1000,mac={mac_0},bus=pci-bridge1,addr=0x00,netdev=gns3-0" in cmd
|
||||
assert f"e1000,mac={mac_1},bus=pci-bridge1,addr=0x01,netdev=gns3-1" in cmd
|
||||
assert "pci-bridge,id=pci-bridge0,bus=dmi_pci_bridge0,chassis_nr=0x1,addr=0x0,shpc=off" not in cmd
|
||||
assert "pci-bridge,id=pci-bridge1,bus=dmi_pci_bridge1,chassis_nr=0x1,addr=0x1,shpc=off" in cmd
|
||||
assert "pci-bridge,id=pci-bridge2,bus=dmi_pci_bridge2,chassis_nr=0x1,addr=0x2,shpc=off" in cmd
|
||||
assert "i82801b11-bridge,id=dmi_pci_bridge1" in cmd
|
||||
|
||||
mac_29 = int_to_macaddress(macaddress_to_int(vm._mac_address) + 29)
|
||||
assert "e1000,mac={},bus=pci-bridge1,addr=0x1d,netdev=gns3-29".format(mac_29) in cmd
|
||||
assert f"e1000,mac={mac_29},bus=pci-bridge1,addr=0x1d,netdev=gns3-29" in cmd
|
||||
mac_30 = int_to_macaddress(macaddress_to_int(vm._mac_address) + 30)
|
||||
assert "e1000,mac={},bus=pci-bridge1,addr=0x1e,netdev=gns3-30".format(mac_30) in cmd
|
||||
assert f"e1000,mac={mac_30},bus=pci-bridge1,addr=0x1e,netdev=gns3-30" in cmd
|
||||
mac_74 = int_to_macaddress(macaddress_to_int(vm._mac_address) + 74)
|
||||
assert "e1000,mac={},bus=pci-bridge3,addr=0x0a,netdev=gns3-74".format(mac_74) in cmd
|
||||
assert f"e1000,mac={mac_74},bus=pci-bridge3,addr=0x0a,netdev=gns3-74" in cmd
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
@ -91,7 +91,7 @@ async def test_list_vms(manager):
|
||||
return ["memory=512"]
|
||||
elif args[0] == "ccd8c50b-c172-457d-99fa-dd69371ede0e":
|
||||
return ["memory=256"]
|
||||
assert False, "Unknow {} {}".format(cmd, args)
|
||||
assert False, f"Unknow {cmd} {args}"
|
||||
|
||||
with asyncio_patch("gns3server.compute.virtualbox.VirtualBox.execute") as mock:
|
||||
mock.side_effect = execute_mock
|
||||
|
||||
@ -74,5 +74,5 @@ async def test_get_mac_id_no_id_available(compute_project, port_manager):
|
||||
with pytest.raises(VPCSError):
|
||||
for i in range(0, 256):
|
||||
node_id = str(uuid.uuid4())
|
||||
await vpcs.create_node("PC {}".format(i), compute_project.id, node_id)
|
||||
await vpcs.create_node(f"PC {i}", compute_project.id, node_id)
|
||||
assert vpcs.get_mac_id(node_id) == i
|
||||
|
||||
@ -298,7 +298,7 @@ def test_update_startup_script_with_escaping_characters_in_name(vm):
|
||||
|
||||
vm.startup_script = "set pcname initial-name\n"
|
||||
vm.name = "test\\"
|
||||
assert vm.startup_script == "set pcname test{}".format(os.linesep)
|
||||
assert vm.startup_script == f"set pcname test{os.linesep}"
|
||||
|
||||
|
||||
def test_get_startup_script(vm):
|
||||
|
||||
@ -400,7 +400,7 @@ async def test_downloadFile(project, compute):
|
||||
with asyncio_patch("aiohttp.ClientSession.request", return_value=response) as mock:
|
||||
await compute.download_file(project, "test/titi")
|
||||
mock.assert_called_with(
|
||||
"GET", "https://example.com:84/v3/compute/projects/{}/files/test/titi".format(project.id), auth=None
|
||||
"GET", f"https://example.com:84/v3/compute/projects/{project.id}/files/test/titi", auth=None
|
||||
)
|
||||
await compute.close()
|
||||
|
||||
@ -492,7 +492,7 @@ async def test_list_files(project, compute):
|
||||
assert await compute.list_files(project) == res
|
||||
mock.assert_any_call(
|
||||
"GET",
|
||||
"https://example.com:84/v3/compute/projects/{}/files".format(project.id),
|
||||
f"https://example.com:84/v3/compute/projects/{project.id}/files",
|
||||
headers={"content-type": "application/json"},
|
||||
data=None,
|
||||
auth=None,
|
||||
|
||||
@ -312,7 +312,7 @@ async def test_create(node, compute):
|
||||
|
||||
assert await node.create() is True
|
||||
data = {"console": 2048, "console_type": "vnc", "node_id": node.id, "startup_script": "echo test", "name": "demo"}
|
||||
compute.post.assert_called_with("/projects/{}/vpcs/nodes".format(node.project.id), data=data, timeout=1200)
|
||||
compute.post.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes", data=data, timeout=1200)
|
||||
assert node._console == 2048
|
||||
assert node._properties == {"startup_script": "echo test"}
|
||||
|
||||
@ -359,7 +359,7 @@ async def test_create_image_missing_kept_in_degraded_state(project, compute, tmp
|
||||
|
||||
async def resp(*args, **kwargs):
|
||||
raise ComputeConflictError(
|
||||
"/projects/{}/qemu/nodes".format(project.id),
|
||||
f"/projects/{project.id}/qemu/nodes",
|
||||
{"message": "The image is missing", "image": "missing.qcow2", "exception": "ImageMissingError"},
|
||||
)
|
||||
|
||||
@ -390,7 +390,7 @@ async def test_create_image_missing_raises_by_default(project, compute, tmpdir,
|
||||
|
||||
async def resp(*args, **kwargs):
|
||||
raise ComputeConflictError(
|
||||
"/projects/{}/qemu/nodes".format(project.id),
|
||||
f"/projects/{project.id}/qemu/nodes",
|
||||
{"message": "The image is missing", "image": "missing.qcow2", "exception": "ImageMissingError"},
|
||||
)
|
||||
|
||||
@ -513,7 +513,7 @@ async def test_create_docker_image_missing_after_failed_pull(project, compute):
|
||||
|
||||
async def resp(*args, **kwargs):
|
||||
raise ComputeConflictError(
|
||||
"/projects/{}/docker/nodes".format(project.id),
|
||||
f"/projects/{project.id}/docker/nodes",
|
||||
{"message": "The image is missing", "image": "ghost:latest", "exception": "ImageMissingError"},
|
||||
)
|
||||
|
||||
@ -544,7 +544,7 @@ async def test_create_docker_image_missing_pull_error_raises_by_default(project,
|
||||
|
||||
async def resp(*args, **kwargs):
|
||||
raise ComputeConflictError(
|
||||
"/projects/{}/docker/nodes".format(project.id),
|
||||
f"/projects/{project.id}/docker/nodes",
|
||||
{"message": "The image is missing", "image": "ghost:latest", "exception": "ImageMissingError"},
|
||||
)
|
||||
|
||||
@ -714,7 +714,7 @@ async def test_create_base_script(node, config, compute, tmpdir):
|
||||
"name": "demo",
|
||||
}
|
||||
|
||||
compute.post.assert_called_with("/projects/{}/vpcs/nodes".format(node.project.id), data=data, timeout=1200)
|
||||
compute.post.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes", data=data, timeout=1200)
|
||||
|
||||
|
||||
def test_symbol(node, symbols_dir):
|
||||
@ -779,7 +779,7 @@ async def test_update(node, compute, project, controller):
|
||||
|
||||
await node.update(x=42, console=2048, console_type="vnc", properties={"startup_script": "echo test"}, name="demo")
|
||||
data = {"console": 2048, "console_type": "vnc", "startup_script": "echo test", "name": "demo"}
|
||||
compute.put.assert_called_with("/projects/{}/vpcs/nodes/{}".format(node.project.id, node.id), data=data)
|
||||
compute.put.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes/{node.id}", data=data)
|
||||
assert node._console == 2048
|
||||
assert node.x == 42
|
||||
assert node._properties == {"startup_script": "echo test"}
|
||||
@ -799,7 +799,7 @@ async def test_update_properties(node, compute, controller):
|
||||
|
||||
await node.update(x=42, console=2048, console_type="vnc", properties={"startup_script": "hello world"}, name="demo")
|
||||
data = {"console": 2048, "console_type": "vnc", "startup_script": "hello world", "name": "demo"}
|
||||
compute.put.assert_called_with("/projects/{}/vpcs/nodes/{}".format(node.project.id, node.id), data=data)
|
||||
compute.put.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes/{node.id}", data=data)
|
||||
assert node._console == 2048
|
||||
assert node.x == 42
|
||||
assert node._properties == {"startup_script": "echo test"}
|
||||
@ -933,7 +933,7 @@ async def test_start(node, compute):
|
||||
compute.post = AsyncioMagicMock()
|
||||
|
||||
await node.start()
|
||||
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/start".format(node.project.id, node.id), timeout=240)
|
||||
compute.post.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes/{node.id}/start", timeout=240)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -949,7 +949,7 @@ async def test_start_iou(compute, project, controller):
|
||||
controller._iou_license_settings = {"license_check": True, "iourc_content": "aa"}
|
||||
await node.start()
|
||||
compute.post.assert_called_with(
|
||||
"/projects/{}/iou/nodes/{}/start".format(node.project.id, node.id),
|
||||
f"/projects/{node.project.id}/iou/nodes/{node.id}/start",
|
||||
timeout=240,
|
||||
data={"license_check": True, "iourc_content": "aa"},
|
||||
)
|
||||
@ -962,7 +962,7 @@ async def test_stop(node, compute):
|
||||
|
||||
await node.stop()
|
||||
compute.post.assert_called_with(
|
||||
"/projects/{}/vpcs/nodes/{}/stop".format(node.project.id, node.id), timeout=240, dont_connect=True
|
||||
f"/projects/{node.project.id}/vpcs/nodes/{node.id}/stop", timeout=240, dont_connect=True
|
||||
)
|
||||
|
||||
|
||||
@ -971,7 +971,7 @@ async def test_suspend(node, compute):
|
||||
|
||||
compute.post = AsyncioMagicMock()
|
||||
await node.suspend()
|
||||
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/suspend".format(node.project.id, node.id), timeout=240)
|
||||
compute.post.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes/{node.id}/suspend", timeout=240)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -979,7 +979,7 @@ async def test_reload(node, compute):
|
||||
|
||||
compute.post = AsyncioMagicMock()
|
||||
await node.reload()
|
||||
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/reload".format(node.project.id, node.id), timeout=240)
|
||||
compute.post.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes/{node.id}/reload", timeout=240)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -994,7 +994,7 @@ async def test_create_without_console(node, compute):
|
||||
|
||||
await node.create()
|
||||
data = {"console_type": "vnc", "node_id": node.id, "startup_script": "echo test", "name": "demo"}
|
||||
compute.post.assert_called_with("/projects/{}/vpcs/nodes".format(node.project.id), data=data, timeout=1200)
|
||||
compute.post.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes", data=data, timeout=1200)
|
||||
assert node._console == 2048
|
||||
assert node._properties == {"test_value": "success", "startup_script": "echo test"}
|
||||
|
||||
@ -1003,21 +1003,21 @@ async def test_create_without_console(node, compute):
|
||||
async def test_delete(node, compute):
|
||||
|
||||
await node.destroy()
|
||||
compute.delete.assert_called_with("/projects/{}/vpcs/nodes/{}".format(node.project.id, node.id))
|
||||
compute.delete.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes/{node.id}")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_post(node, compute):
|
||||
|
||||
await node.post("/test", {"a": "b"})
|
||||
compute.post.assert_called_with("/projects/{}/vpcs/nodes/{}/test".format(node.project.id, node.id), data={"a": "b"})
|
||||
compute.post.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes/{node.id}/test", data={"a": "b"})
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_delete(node, compute):
|
||||
|
||||
await node.delete("/test")
|
||||
compute.delete.assert_called_with("/projects/{}/vpcs/nodes/{}/test".format(node.project.id, node.id))
|
||||
compute.delete.assert_called_with(f"/projects/{node.project.id}/vpcs/nodes/{node.id}/test")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -1028,9 +1028,7 @@ async def test_dynamips_idle_pc(node, compute):
|
||||
response.json = {"idlepc": "0x60606f54"}
|
||||
compute.get = AsyncioMagicMock(return_value=response)
|
||||
await node.dynamips_auto_idlepc()
|
||||
compute.get.assert_called_with(
|
||||
"/projects/{}/dynamips/nodes/{}/auto_idlepc".format(node.project.id, node.id), timeout=240
|
||||
)
|
||||
compute.get.assert_called_with(f"/projects/{node.project.id}/dynamips/nodes/{node.id}/auto_idlepc", timeout=240)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -1042,7 +1040,7 @@ async def test_dynamips_idlepc_proposals(node, compute):
|
||||
compute.get = AsyncioMagicMock(return_value=response)
|
||||
await node.dynamips_idlepc_proposals()
|
||||
compute.get.assert_called_with(
|
||||
"/projects/{}/dynamips/nodes/{}/idlepc_proposals".format(node.project.id, node.id), timeout=240
|
||||
f"/projects/{node.project.id}/dynamips/nodes/{node.id}/idlepc_proposals", timeout=240
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ async def test_update_on_compute(controller):
|
||||
project._project_created_on_compute = [compute]
|
||||
project.emit_notification = MagicMock()
|
||||
await project.update(variables=variables)
|
||||
compute.put.assert_any_call("/projects/{}".format(project.id), {"variables": variables})
|
||||
compute.put.assert_any_call(f"/projects/{project.id}", {"variables": variables})
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -203,7 +203,7 @@ async def test_add_node_local(controller):
|
||||
},
|
||||
)
|
||||
compute.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes".format(project.id),
|
||||
f"/projects/{project.id}/vpcs/nodes",
|
||||
data={"node_id": node.id, "startup_script": "test.cfg", "name": "test"},
|
||||
timeout=1200,
|
||||
)
|
||||
@ -272,7 +272,7 @@ async def test_add_node_non_local(controller):
|
||||
|
||||
compute.post.assert_any_call("/projects", data={"name": project._name, "project_id": project._id})
|
||||
compute.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes".format(project.id),
|
||||
f"/projects/{project.id}/vpcs/nodes",
|
||||
data={"node_id": node.id, "startup_script": "test.cfg", "name": "test"},
|
||||
timeout=1200,
|
||||
)
|
||||
@ -448,7 +448,7 @@ async def test_add_node_iou_no_id_available(controller):
|
||||
with pytest.raises(ControllerError):
|
||||
for i in range(1, 513):
|
||||
prop = {"properties": {"application_id": i}}
|
||||
project._nodes[i] = Node(project, compute, "Node{}".format(i), node_id=i, node_type="iou", **prop)
|
||||
project._nodes[i] = Node(project, compute, f"Node{i}", node_id=i, node_type="iou", **prop)
|
||||
await project.add_node(compute, "test1", None, node_type="iou")
|
||||
|
||||
|
||||
@ -538,7 +538,7 @@ async def test_delete_node(controller):
|
||||
await project.delete_node(node.id)
|
||||
assert node.id not in project._nodes
|
||||
|
||||
compute.delete.assert_any_call("/projects/{}/vpcs/nodes/{}".format(project.id, node.id))
|
||||
compute.delete.assert_any_call(f"/projects/{project.id}/vpcs/nodes/{node.id}")
|
||||
project.emit_notification.assert_any_call("node.deleted", node.asdict())
|
||||
|
||||
|
||||
@ -585,7 +585,7 @@ async def test_delete_node_delete_link(controller):
|
||||
assert node.id not in project._nodes
|
||||
assert link.id not in project._links
|
||||
|
||||
compute.delete.assert_any_call("/projects/{}/vpcs/nodes/{}".format(project.id, node.id))
|
||||
compute.delete.assert_any_call(f"/projects/{project.id}/vpcs/nodes/{node.id}")
|
||||
project.emit_notification.assert_any_call("node.deleted", node.asdict())
|
||||
project.emit_notification.assert_any_call("link.deleted", link.asdict())
|
||||
|
||||
|
||||
@ -74,7 +74,7 @@ async def test_create(project):
|
||||
await link.add_node(node2, 3, 1)
|
||||
|
||||
compute1.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node1.id}/adapters/0/ports/4/nio",
|
||||
data={
|
||||
"lport": 1024,
|
||||
"rhost": "192.168.1.2",
|
||||
@ -88,7 +88,7 @@ async def test_create(project):
|
||||
)
|
||||
|
||||
compute2.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/3/ports/1/nio".format(project.id, node2.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node2.id}/adapters/3/ports/1/nio",
|
||||
data={
|
||||
"lport": 2048,
|
||||
"rhost": "192.168.1.1",
|
||||
@ -152,7 +152,7 @@ async def test_create_one_side_failure(project):
|
||||
await link.add_node(node2, 3, 1)
|
||||
|
||||
compute1.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node1.id}/adapters/0/ports/4/nio",
|
||||
data={
|
||||
"lport": 1024,
|
||||
"rhost": "192.168.1.2",
|
||||
@ -166,7 +166,7 @@ async def test_create_one_side_failure(project):
|
||||
)
|
||||
|
||||
compute2.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/3/ports/1/nio".format(project.id, node2.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node2.id}/adapters/3/ports/1/nio",
|
||||
data={
|
||||
"lport": 2048,
|
||||
"rhost": "192.168.1.1",
|
||||
@ -179,9 +179,7 @@ async def test_create_one_side_failure(project):
|
||||
timeout=120,
|
||||
)
|
||||
# The link creation has failed we rollback the nio
|
||||
compute1.delete.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id), timeout=120
|
||||
)
|
||||
compute1.delete.assert_any_call(f"/projects/{project.id}/vpcs/nodes/{node1.id}/adapters/0/ports/4/nio", timeout=120)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -202,12 +200,8 @@ async def test_delete(project):
|
||||
|
||||
await link.delete()
|
||||
|
||||
compute1.delete.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id), timeout=120
|
||||
)
|
||||
compute2.delete.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/3/ports/1/nio".format(project.id, node2.id), timeout=120
|
||||
)
|
||||
compute1.delete.assert_any_call(f"/projects/{project.id}/vpcs/nodes/{node1.id}/adapters/0/ports/4/nio", timeout=120)
|
||||
compute2.delete.assert_any_call(f"/projects/{project.id}/vpcs/nodes/{node2.id}/adapters/3/ports/1/nio", timeout=120)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -310,7 +304,7 @@ async def test_reset(project):
|
||||
assert link.debug_link_data[1]["lport"] != link.debug_link_data[1]["rport"]
|
||||
# the committed NIO carries the fresh pair, not the released one
|
||||
compute1.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node1.id}/adapters/0/ports/4/nio",
|
||||
data={
|
||||
"lport": 4096,
|
||||
"rhost": "192.168.1.2",
|
||||
@ -401,16 +395,14 @@ async def test_capture(project):
|
||||
assert link.capturing
|
||||
|
||||
compute1.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/capture/start".format(project.id, node_vpcs.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node_vpcs.id}/adapters/0/ports/4/capture/start",
|
||||
data={"capture_file_name": link.default_capture_file_name(), "data_link_type": "DLT_EN10MB"},
|
||||
)
|
||||
|
||||
await link.stop_capture()
|
||||
assert link.capturing is False
|
||||
|
||||
compute1.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/capture/stop".format(project.id, node_vpcs.id)
|
||||
)
|
||||
compute1.post.assert_any_call(f"/projects/{project.id}/vpcs/nodes/{node_vpcs.id}/adapters/0/ports/4/capture/stop")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -483,7 +475,7 @@ async def test_update(project):
|
||||
await link.add_node(node2, 3, 1)
|
||||
|
||||
compute1.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node1.id}/adapters/0/ports/4/nio",
|
||||
data={
|
||||
"lport": 1024,
|
||||
"rhost": "192.168.1.2",
|
||||
@ -497,7 +489,7 @@ async def test_update(project):
|
||||
)
|
||||
|
||||
compute2.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/3/ports/1/nio".format(project.id, node2.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node2.id}/adapters/3/ports/1/nio",
|
||||
data={
|
||||
"lport": 2048,
|
||||
"rhost": "192.168.1.1",
|
||||
@ -513,7 +505,7 @@ async def test_update(project):
|
||||
assert link.created
|
||||
await link.update_filters({"frequency_drop": [5], "bpf": ["icmp[icmptype] == 8"]})
|
||||
compute1.put.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node1.id}/adapters/0/ports/4/nio",
|
||||
data={
|
||||
"lport": 1024,
|
||||
"rhost": "192.168.1.2",
|
||||
@ -563,7 +555,7 @@ async def test_update_ethernet_switch_nio(project):
|
||||
|
||||
await link.update_filters({"delay": [10, 0]})
|
||||
compute1.put.assert_any_call(
|
||||
"/projects/{}/ethernet_switch/nodes/{}/adapters/3/ports/1/nio".format(project.id, node_switch.id),
|
||||
f"/projects/{project.id}/ethernet_switch/nodes/{node_switch.id}/adapters/3/ports/1/nio",
|
||||
data={
|
||||
"lport": 1024,
|
||||
"rhost": "192.168.1.1",
|
||||
@ -625,7 +617,7 @@ async def test_update_suspend(project):
|
||||
await link.add_node(node2, 3, 1)
|
||||
|
||||
compute1.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/0/ports/4/nio".format(project.id, node1.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node1.id}/adapters/0/ports/4/nio",
|
||||
data={
|
||||
"lport": 1024,
|
||||
"rhost": "192.168.1.2",
|
||||
@ -639,7 +631,7 @@ async def test_update_suspend(project):
|
||||
)
|
||||
|
||||
compute2.post.assert_any_call(
|
||||
"/projects/{}/vpcs/nodes/{}/adapters/3/ports/1/nio".format(project.id, node2.id),
|
||||
f"/projects/{project.id}/vpcs/nodes/{node2.id}/adapters/3/ports/1/nio",
|
||||
data={
|
||||
"lport": 2048,
|
||||
"rhost": "192.168.1.1",
|
||||
|
||||
@ -46,15 +46,15 @@ def test_convert(directory, tmpdir):
|
||||
before_directory = os.path.join(topologies_directory, directory, "before")
|
||||
after_directory = os.path.join(topologies_directory, directory, "after")
|
||||
|
||||
assert os.path.exists(before_directory), "No before directory found file for {}".format(directory)
|
||||
assert os.path.exists(after_directory), "No after directory found file for {}".format(directory)
|
||||
assert os.path.exists(before_directory), f"No before directory found file for {directory}"
|
||||
assert os.path.exists(after_directory), f"No after directory found file for {directory}"
|
||||
|
||||
gns3_file = None
|
||||
for file in os.listdir(before_directory):
|
||||
if file.endswith(".gns3"):
|
||||
gns3_file = file
|
||||
|
||||
assert gns3_file, "No .gns3 found file for {}".format(before_directory)
|
||||
assert gns3_file, f"No .gns3 found file for {before_directory}"
|
||||
|
||||
with open(os.path.join(before_directory, gns3_file)) as f:
|
||||
before_topology = json.load(f)
|
||||
@ -76,19 +76,19 @@ def test_convert(directory, tmpdir):
|
||||
for file in files:
|
||||
directory = os.path.relpath(root, after_directory)
|
||||
file_path = os.path.join(work_directory, directory, file)
|
||||
assert os.path.exists(file_path), "{} is missing".format(os.path.join(directory, file))
|
||||
assert os.path.exists(file_path), f"{os.path.join(directory, file)} is missing"
|
||||
|
||||
# For gns3project we check if size are not too much differents
|
||||
if file_path.endswith(".gns3project"):
|
||||
size = os.stat(file_path).st_size
|
||||
other_size = os.stat(os.path.join(os.path.join(root, file))).st_size
|
||||
assert size in range(other_size - 100, other_size + 100), "File {} is different".format(
|
||||
os.path.join(directory, file)
|
||||
assert size in range(other_size - 100, other_size + 100), (
|
||||
f"File {os.path.join(directory, file)} is different"
|
||||
)
|
||||
# For non .gns3 file we check if the file are the same
|
||||
elif not file_path.endswith(".gns3"):
|
||||
assert os.stat(file_path).st_size == os.stat(os.path.join(os.path.join(root, file))).st_size, (
|
||||
"File {} is different".format(os.path.join(directory, file))
|
||||
f"File {os.path.join(directory, file)} is different"
|
||||
)
|
||||
|
||||
# Check if we don't have unexpected file in work directory
|
||||
@ -98,7 +98,7 @@ def test_convert(directory, tmpdir):
|
||||
file_path = os.path.join(after_directory, directory, file)
|
||||
# .backup are created by the conversion process
|
||||
if ".backup" not in file_path:
|
||||
assert os.path.exists(file_path), "{} should not be here".format(os.path.join(directory, file))
|
||||
assert os.path.exists(file_path), f"{os.path.join(directory, file)} should not be here"
|
||||
|
||||
with open(os.path.join(after_directory, gns3_file)) as f:
|
||||
after_topology = json.load(f)
|
||||
@ -109,12 +109,12 @@ def compare_dict(path, source, reference):
|
||||
"""
|
||||
Compare two dictionary of a topology
|
||||
"""
|
||||
assert isinstance(source, dict), "Source is not a dict in {}".format(path)
|
||||
assert isinstance(source, dict), f"Source is not a dict in {path}"
|
||||
for key in source:
|
||||
assert key in reference, "Unexpected {} in {} it should be {}".format(key, source, reference)
|
||||
assert key in reference, f"Unexpected {key} in {source} it should be {reference}"
|
||||
for key in sorted(reference.keys()):
|
||||
val = reference[key]
|
||||
assert key in source, "{} is missing in {}".format(key, source)
|
||||
assert key in source, f"{key} is missing in {source}"
|
||||
if (
|
||||
isinstance(val, str)
|
||||
or isinstance(val, float)
|
||||
@ -133,12 +133,12 @@ def compare_dict(path, source, reference):
|
||||
elif key == "version":
|
||||
assert source[key] == __version__
|
||||
else:
|
||||
assert val == source[key], "Wrong value for {}: \n{}\nit should be\n{}".format(key, source[key], val)
|
||||
assert val == source[key], f"Wrong value for {key}: \n{source[key]}\nit should be\n{val}"
|
||||
elif isinstance(val, dict):
|
||||
compare_dict(path + key + "/", source[key], val)
|
||||
elif isinstance(val, list):
|
||||
assert len(val) == len(source[key]), "Not enough value in {} ({}/{}) it shoud be {} not {}".format(
|
||||
key, len(val), len(source[key]), val, source[key]
|
||||
assert len(val) == len(source[key]), (
|
||||
f"Not enough value in {key} ({len(val)}/{len(source[key])}) it shoud be {val} not {source[key]}"
|
||||
)
|
||||
for idx, element in enumerate(source[key]):
|
||||
if isinstance(element, dict):
|
||||
@ -146,4 +146,4 @@ def compare_dict(path, source, reference):
|
||||
else:
|
||||
assert element == val[idx]
|
||||
else:
|
||||
assert False, "Value type for {} is not supported".format(key)
|
||||
assert False, f"Value type for {key} is not supported"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user