diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py index 56076e83c..7ff62ae07 100644 --- a/gns3server/compute/base_node.py +++ b/gns3server/compute/base_node.py @@ -1226,7 +1226,7 @@ class BaseNode: # mark [tag ] [pcap ] — tag/pcap keyword pairs, any order. self._validate_marker_name(name) - 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 diff --git a/gns3server/compute/builtin/nodes/ethernet_switch.py b/gns3server/compute/builtin/nodes/ethernet_switch.py index 2b9dab4d0..e508649c3 100644 --- a/gns3server/compute/builtin/nodes/ethernet_switch.py +++ b/gns3server/compute/builtin/nodes/ethernet_switch.py @@ -488,19 +488,15 @@ class EthernetSwitch(KernelDatapathMixin, BaseNode): await self._ubridge_send(f'link l2only "{anchor}" on') except UbridgeError as e: log.warning( - 'Ethernet switch "{name}" [{id}]: could not harden cascade end "{anchor}" L2-only: {error}'.format( - name=self._name, id=self._id, anchor=anchor, error=e - ) + f'Ethernet switch "{self._name}" [{self._id}]: could not harden cascade end "{anchor}" L2-only: {e}' ) # Register before _kernel_attach: the marker reconcile recognises # kernel anchors through _kernel_anchors(). self._kernel_ports[port_number] = anchor if not os.path.exists(f"/sys/class/net/{anchor}"): log.info( - 'Ethernet switch "{name}" [{id}]: anchor {anchor} for port {port} does not exist yet ' - "(peer not started); join deferred".format( - name=self._name, id=self._id, anchor=anchor, port=port_number - ) + f'Ethernet switch "{self._name}" [{self._id}]: anchor {anchor} for port {port_number} does not exist yet ' + "(peer not started); join deferred" ) return try: @@ -737,8 +733,8 @@ class EthernetSwitch(KernelDatapathMixin, BaseNode): # a wired port always has previous settings; without them a # diff is impossible and re-enslaving would be guessing log.warning( - 'Ethernet switch "{name}" [{id}]: no previous settings for wired port {port}; ' - "VLAN reconfiguration skipped".format(name=self._name, id=self._id, port=port_number) + f'Ethernet switch "{self._name}" [{self._id}]: no previous settings for wired port {port_number}; ' + "VLAN reconfiguration skipped" ) continue await self._reconfigure_port_vlan(iface, old_settings, new_settings) @@ -769,11 +765,7 @@ class EthernetSwitch(KernelDatapathMixin, BaseNode): else: 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): """ @@ -792,8 +784,4 @@ class EthernetSwitch(KernelDatapathMixin, BaseNode): else: 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}') diff --git a/gns3server/compute/docker/docker_kernel_datapath.py b/gns3server/compute/docker/docker_kernel_datapath.py index 06ce57b44..8c8c62b9a 100644 --- a/gns3server/compute/docker/docker_kernel_datapath.py +++ b/gns3server/compute/docker/docker_kernel_datapath.py @@ -101,11 +101,7 @@ class DockerKernelDatapathMixin(KernelDatapathMixin): 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}'") host_ifc, guest_ifc = self._veth_names(adapter_number, port_number) # The host end lives in the root namespace and survives container @@ -144,12 +140,7 @@ class DockerKernelDatapathMixin(KernelDatapathMixin): adapter.host_ifc = host_ifc self._kernel_veths[(adapter_number, port_number)] = host_ifc log.debug( - "Created veth adapter {adapter_number} port {port_number} with MAC address {mac_address} in namespace {namespace}".format( - adapter_number=adapter_number, - port_number=port_number, - mac_address=mac_address, - namespace=self._namespace, - ) + f"Created veth adapter {adapter_number} port {port_number} with MAC address {mac_address} in namespace {self._namespace}" ) async def _remove_kernel_veths(self): diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index 3d6f611cb..4cb34d85e 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -1815,11 +1815,9 @@ class DockerVM(DockerKernelDatapathMixin, BaseNode): # rejected earlier): the kernel path needs an anchor — the # veth host end, or the persistent TAP of an IOL runner. raise DockerError( - "Adapter {adapter_number} port {port_number} of container '{name}' has no host-side " + f"Adapter {adapter_number} port {port_number} of container '{self.name}' has no host-side " "anchor interface (it was started before the unified-veth datapath); " - "restart the node to attach a kernel link to it".format( - adapter_number=adapter_number, port_number=port_number, name=self.name - ) + "restart the node to attach a kernel link to it" ) # The mechanics (bridge create/addif, capture, markers, filters) # live in KernelDatapathMixin, shared with every other node type @@ -1845,11 +1843,7 @@ class DockerVM(DockerKernelDatapathMixin, BaseNode): # NIO sets it back down). await self._ubridge_send(f'link set "{host_ifc}" up') await self._ubridge_send(f'bridge add_nio_ethernet {bridge_name} "{host_ifc}"') - 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(f'bridge start_capture {bridge_name} "{nio.pcap_output_file}"') await self._ubridge_send(f"bridge start {bridge_name}") @@ -1934,11 +1928,7 @@ class DockerVM(DockerKernelDatapathMixin, 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) diff --git a/gns3server/compute/docker/iol_docker_vm.py b/gns3server/compute/docker/iol_docker_vm.py index a41b66e56..e6d2bf70a 100644 --- a/gns3server/compute/docker/iol_docker_vm.py +++ b/gns3server/compute/docker/iol_docker_vm.py @@ -573,10 +573,10 @@ class IOLDockerVM(VendorDockerVM): anchor = self._kernel_host_ifc(adapter_number, port_number) if anchor is None: raise DockerError( - "Bay {bay}/{unit} of IOL container '{name}' has no TAP anchor to carry a kernel " + f"Bay {adapter_number}/{port_number} of IOL container '{self._name}' has no TAP anchor to carry a kernel " "link (this compute's uBridge lacks the tap module or bridge delete_nio_tap, " "or the node was started before the kernel-datapath support); restart the " - "node after upgrading uBridge".format(bay=adapter_number, unit=port_number, name=self._name) + "node after upgrading uBridge" ) await self._ensure_unix_port_bridge(adapter_number, port_number) await self._ensure_anchor(adapter_number, port_number) diff --git a/gns3server/compute/dynamips/nodes/router.py b/gns3server/compute/dynamips/nodes/router.py index 05c055b13..f763d7dd5 100644 --- a/gns3server/compute/dynamips/nodes/router.py +++ b/gns3server/compute/dynamips/nodes/router.py @@ -340,11 +340,7 @@ class Router(KernelDatapathMixin, BaseNode): # the node was stopped wire themselves as IOS comes up. await self._prepare_tap_datapath() - 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') @@ -1318,11 +1314,7 @@ class Router(KernelDatapathMixin, BaseNode): # Refusing also keeps the kernel wiring's own idempotence check from # silently skipping the attach while rebinding the bookkeeping. if adapter.get_nio(port_number) is not None: - raise DynamipsError( - "Port {port_number} on slot {slot_number} of router '{name}' already has a link".format( - name=self._name, slot_number=slot_number, port_number=port_number - ) - ) + raise DynamipsError(f"Port {port_number} on slot {slot_number} of router '{self._name}' already has a link") if isinstance(nio, NIOBridge): # Kernel datapath: the port's anchor TAP is opened in the @@ -1332,11 +1324,7 @@ class Router(KernelDatapathMixin, BaseNode): # the port unbound instead of half-wired. await self._attach_kernel_nio(slot_number, port_number, nio) adapter.add_nio(port_number, nio) - log.debug( - 'Router "{name}" [{id}]: {nio} bound to port {slot_number}/{port_number}'.format( - name=self._name, id=self._id, nio=nio, slot_number=slot_number, port_number=port_number - ) - ) + log.debug(f'Router "{self._name}" [{self._id}]: {nio} bound to port {slot_number}/{port_number}') return try: @@ -1401,19 +1389,11 @@ class Router(KernelDatapathMixin, BaseNode): if isinstance(nio, NIOBridge): await self._remove_kernel_nio_binding(slot_number, port_number, nio) adapter.remove_nio(port_number) - log.debug( - 'Router "{name}" [{id}]: {nio} removed from port {slot_number}/{port_number}'.format( - name=self._name, id=self._id, nio=nio, slot_number=slot_number, port_number=port_number - ) - ) + log.debug(f'Router "{self._name}" [{self._id}]: {nio} removed from port {slot_number}/{port_number}') return nio 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}') await nio.close() adapter.remove_nio(port_number) @@ -1512,9 +1492,7 @@ class Router(KernelDatapathMixin, BaseNode): if anchor is not None: await self._ubridge_send(f'capture start_kernel {anchor} "{output_file}"') 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 - ) + f'Router "{self._name}" [{self._id}]: starting packet capture on port {slot_number}/{port_number}' ) return @@ -1726,19 +1704,15 @@ class Router(KernelDatapathMixin, BaseNode): if self.status != "started": return raise self._kernel_error( - "Port {slot}/{port} of router '{name}' runs on the relay datapath " - "(this uBridge cannot create persistent TAPs) and cannot carry a kernel link".format( - slot=slot_number, port=port_number, name=self._name - ) + f"Port {slot_number}/{port_number} of router '{self._name}' runs on the relay datapath " + "(this uBridge cannot create persistent TAPs) and cannot carry a kernel link" ) tap_nio = NIOTAP(self._hypervisor, anchor) await tap_nio.create() 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=tap_nio.name - ) + f'vm slot_add_nio_binding "{self._name}" {slot_number} {port_number} {tap_nio.name}' ) except DynamipsError: with contextlib.suppress(DynamipsError): @@ -1764,11 +1738,7 @@ class Router(KernelDatapathMixin, BaseNode): with contextlib.suppress(DynamipsError, OSError): await self.slot_disable_nio(slot_number, port_number) with contextlib.suppress(DynamipsError, OSError): - 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}') with contextlib.suppress(DynamipsError, OSError): await tap_nio.delete() @@ -1788,9 +1758,7 @@ class Router(KernelDatapathMixin, BaseNode): for (slot_number, port_number), tap_nio in list(self._tap_nios.items()): with contextlib.suppress(DynamipsError, OSError): 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 - ) + f'vm slot_remove_nio_binding "{self._name}" {slot_number} {port_number}' ) with contextlib.suppress(DynamipsError, OSError): await tap_nio.delete() diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py index ec7aed43b..d3cd01dfc 100644 --- a/gns3server/compute/iou/iou_vm.py +++ b/gns3server/compute/iou/iou_vm.py @@ -950,18 +950,12 @@ class IOUVM(KernelDatapathMixin, BaseNode): anchor = self._kernel_host_ifc(adapter_number, port_number) if anchor is None: raise self._kernel_error( - "Bay {bay}/{unit} of IOU '{name}' has no TAP anchor to carry a kernel link " + f"Bay {adapter_number}/{port_number} of IOU '{self._name}' has no TAP anchor to carry a kernel link " "(serial ports stay on the relay datapath, and a node whose uBridge lacks " - "iol_bridge add_nio_tap runs relay-only)".format(bay=adapter_number, unit=port_number, name=self._name) + "iol_bridge add_nio_tap runs relay-only)" ) await self._ubridge_send( - 'iol_bridge add_nio_tap {name} {iol_id} {bay} {unit} "{tap}"'.format( - name=self._iol_bridge_name(), - iol_id=self.application_id, - bay=adapter_number, - unit=port_number, - tap=anchor, - ) + f'iol_bridge add_nio_tap {self._iol_bridge_name()} {self.application_id} {adapter_number} {port_number} "{anchor}"' ) await self._kernel_attach(anchor, nio) await self._set_adapter_carrier(adapter_number, not nio.suspend, port_number) @@ -1348,11 +1342,7 @@ class IOUVM(KernelDatapathMixin, BaseNode): # a port carries at most one NIO, and overwriting the one a link # still owns orphans that link's teardown (its host state leaks). if adapter.get_nio(port_number) is not None: - raise IOUError( - "Port {port_number} on adapter {adapter_number} of IOU '{name}' already has a link".format( - name=self._name, adapter_number=adapter_number, port_number=port_number - ) - ) + raise IOUError(f"Port {port_number} on adapter {adapter_number} of IOU '{self._name}' already has a link") # Wire before bookkeeping: an attach that fails mid-way leaves the # port unbound instead of half-wired. @@ -1361,15 +1351,7 @@ class IOUVM(KernelDatapathMixin, BaseNode): await self._attach_kernel_nio(adapter_number, port_number, nio) else: await self._ubridge_send( - "iol_bridge add_nio_udp {name} {iol_id} {bay} {unit} {lport} {rhost} {rport}".format( - name=self._iol_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 {self._iol_bridge_name()} {self.application_id} {adapter_number} {port_number} {nio.lport} {nio.rhost} {nio.rport}" ) location = self._iol_location(adapter_number, port_number) await self._ubridge_apply_filters(location, nio.filters) @@ -1442,7 +1424,7 @@ class IOUVM(KernelDatapathMixin, BaseNode): return self._validate_marker_name(name) # 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: @@ -1452,7 +1434,7 @@ class IOUVM(KernelDatapathMixin, 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}"' await self._ubridge_send(cmd) async def _ubridge_enable_marker_filter(self, location, name, state): @@ -1518,15 +1500,11 @@ class IOUVM(KernelDatapathMixin, BaseNode): # persistent device itself survives for the next link. with contextlib.suppress(UbridgeError): await self._ubridge_send( - "iol_bridge delete_nio_tap {name} {bay} {unit}".format( - name=self._iol_bridge_name(), bay=adapter_number, unit=port_number - ) + f"iol_bridge delete_nio_tap {self._iol_bridge_name()} {adapter_number} {port_number}" ) else: await self._ubridge_send( - "iol_bridge delete_nio_udp {name} {bay} {unit}".format( - name=self._iol_bridge_name(), bay=adapter_number, unit=port_number - ) + f"iol_bridge delete_nio_udp {self._iol_bridge_name()} {adapter_number} {port_number}" ) return nio @@ -1852,9 +1830,7 @@ class IOUVM(KernelDatapathMixin, BaseNode): anchor = self._kernel_host_ifc(adapter_number, port_number) if anchor is None: raise self._kernel_error( - "Bay {bay}/{unit} of IOU '{name}' has no TAP anchor to capture on".format( - bay=adapter_number, unit=port_number, name=self._name - ) + f"Bay {adapter_number}/{port_number} of IOU '{self._name}' has no TAP anchor to capture on" ) await self._ubridge_send(f'capture start_kernel {anchor} "{output_file}"') else: @@ -1886,7 +1862,5 @@ class IOUVM(KernelDatapathMixin, BaseNode): await self._ubridge_send("capture stop_kernel") else: await self._ubridge_send( - "iol_bridge stop_capture {name} {bay} {unit}".format( - name=self._iol_bridge_name(), bay=adapter_number, unit=port_number - ) + f"iol_bridge stop_capture {self._iol_bridge_name()} {adapter_number} {port_number}" ) diff --git a/gns3server/compute/kernel_datapath.py b/gns3server/compute/kernel_datapath.py index 09e80ec4a..4a23c2b51 100644 --- a/gns3server/compute/kernel_datapath.py +++ b/gns3server/compute/kernel_datapath.py @@ -214,17 +214,9 @@ class KernelDatapathMixin: # afterwards (a suspended NIO sets it back down). await self._ubridge_send(f'link set "{anchor}" up') await self._ubridge_send(f'bridge add_nio_ethernet {bridge_name} "{anchor}"') - 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) @@ -328,7 +320,7 @@ class KernelDatapathMixin: if self._kernel_marker_anchor(bridge_name): self._validate_marker_name(name) - cmd = 'marker add_kernel {name} {ifc} "{bpf}"'.format(name=name, ifc=bridge_name, bpf=bpf) + cmd = f'marker add_kernel {name} {bridge_name} "{bpf}"' if tag is not None: cmd += f" tag {tag}" if link_id: @@ -338,7 +330,7 @@ class KernelDatapathMixin: 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}"' await self._ubridge_send(cmd) return await super()._ubridge_add_marker_filter( @@ -614,9 +606,7 @@ class KernelDatapathMixin: await self._ubridge_send(f'tc bpf_drop flush "{host_ifc}"') for offset, line in enumerate(lines): try: - await self._ubridge_send( - 'tc bpf_drop add "{ifc}" {prio} "{expr}"'.format(ifc=host_ifc, prio=10 + offset, expr=line) - ) + await self._ubridge_send(f'tc bpf_drop add "{host_ifc}" {10 + offset} "{line}"') except UbridgeError as e: if "Cannot compile filter" not in str(e): raise @@ -710,9 +700,7 @@ class KernelDatapathMixin: elif "nth" in modes: await self._ubridge_send(f'tc nth_drop "{host_ifc}" off') if quota: - await self._ubridge_send( - 'tc quota_drop "{ifc}" {bytes} {pct}'.format(ifc=host_ifc, bytes=int(quota[0]), pct=int(quota[1])) - ) + await self._ubridge_send(f'tc quota_drop "{host_ifc}" {int(quota[0])} {int(quota[1])}') elif "quota" in modes: await self._ubridge_send(f'tc quota_drop "{host_ifc}" off') if window: diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index 410094348..db842f781 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -1635,10 +1635,8 @@ class QemuVM(KernelDatapathMixin, BaseNode): if not self._tap_datapath: if isinstance(nio, NIOBridge): raise QemuError( - "Adapter {adapter_number} of QEMU VM '{name}' runs on the legacy relay datapath " - "(this uBridge cannot create persistent TAPs) and cannot carry a kernel link".format( - adapter_number=adapter_number, name=self._name - ) + f"Adapter {adapter_number} of QEMU VM '{self._name}' runs on the legacy relay datapath " + "(this uBridge cannot create persistent TAPs) and cannot carry a kernel link" ) await self.add_ubridge_udp_connection(bridge_name, self._local_udp_tunnels[adapter_number][1], nio) return @@ -1646,10 +1644,8 @@ class QemuVM(KernelDatapathMixin, BaseNode): anchor = self._kernel_host_ifc(adapter_number, port_number) if anchor is None: raise QemuError( - "Adapter {adapter_number} port {port_number} of QEMU VM '{name}' has no TAP interface; " - "restart the node to attach a link to it".format( - adapter_number=adapter_number, port_number=port_number, name=self._name - ) + f"Adapter {adapter_number} port {port_number} of QEMU VM '{self._name}' has no TAP interface; " + "restart the node to attach a link to it" ) if isinstance(nio, NIOBridge): await self._kernel_attach(anchor, nio) @@ -1673,11 +1669,7 @@ class QemuVM(KernelDatapathMixin, BaseNode): try: await self._connect_nio(adapter_number, nio) 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}"') await self._set_adapter_carrier(adapter_number, not nio.suspend) if self._replicate_network_connection_state: await self._control_vm(f"set_link gns3-{adapter_number} on")