From 7f2c0c7e9c512b3c06b1279e810f1bf96e4e6d76 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:07 +0300 Subject: [PATCH 01/13] refactor: use f-strings in docker compute modules --- gns3server/compute/docker/__init__.py | 4 +- gns3server/compute/docker/docker_vm.py | 146 +++++------------- gns3server/compute/docker/vendor_docker_vm.py | 6 +- 3 files changed, 39 insertions(+), 117 deletions(-) diff --git a/gns3server/compute/docker/__init__.py b/gns3server/compute/docker/__init__.py index bc643ee67..183d39e00 100644 --- a/gns3server/compute/docker/__init__.py +++ b/gns3server/compute/docker/__init__.py @@ -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): diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index 0503c3c7d..97cc661a6 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -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): """ diff --git a/gns3server/compute/docker/vendor_docker_vm.py b/gns3server/compute/docker/vendor_docker_vm.py index 33af64e15..977e3ace4 100644 --- a/gns3server/compute/docker/vendor_docker_vm.py +++ b/gns3server/compute/docker/vendor_docker_vm.py @@ -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) From d5ad4c67c614c05206f8231eddff7e829d6912ac Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:07 +0300 Subject: [PATCH 02/13] refactor: use f-strings in qemu compute modules --- gns3server/compute/qemu/__init__.py | 6 +- gns3server/compute/qemu/qemu_vm.py | 212 ++++++---------------- gns3server/compute/qemu/utils/ziputils.py | 2 +- 3 files changed, 56 insertions(+), 164 deletions(-) diff --git a/gns3server/compute/qemu/__init__.py b/gns3server/compute/qemu/__init__.py index fc4b3d062..351e318e5 100644 --- a/gns3server/compute/qemu/__init__.py +++ b/gns3server/compute/qemu/__init__.py @@ -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" diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index e6021a3f1..48e25ab7c 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -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) diff --git a/gns3server/compute/qemu/utils/ziputils.py b/gns3server/compute/qemu/utils/ziputils.py index 4e229e0ea..a71eb9f46 100644 --- a/gns3server/compute/qemu/utils/ziputils.py +++ b/gns3server/compute/qemu/utils/ziputils.py @@ -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") From 97f6805d0a464f236f405813994108613f58f994 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:07 +0300 Subject: [PATCH 03/13] refactor: use f-strings in iou compute modules --- gns3server/compute/iou/iou_vm.py | 165 ++++++------------------------- 1 file changed, 31 insertions(+), 134 deletions(-) diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py index 531f719a2..a4b6ddf80 100644 --- a/gns3server/compute/iou/iou_vm.py +++ b/gns3server/compute/iou/iou_vm.py @@ -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}") From a5d2bca9216ba97c1d8bbdd36eee3ed6fd97c77d Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:07 +0300 Subject: [PATCH 04/13] refactor: use f-strings in dynamips router node --- gns3server/compute/dynamips/nodes/router.py | 378 ++++---------------- 1 file changed, 71 insertions(+), 307 deletions(-) diff --git a/gns3server/compute/dynamips/nodes/router.py b/gns3server/compute/dynamips/nodes/router.py index e479a291e..c82e39cbf 100644 --- a/gns3server/compute/dynamips/nodes/router.py +++ b/gns3server/compute/dynamips/nodes/router.py @@ -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): """ From fba3ecc5fcd3011ea44cd1c2950de28359397f00 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:08 +0300 Subject: [PATCH 05/13] refactor: use f-strings in dynamips nodes --- .../compute/dynamips/nodes/atm_switch.py | 122 +++--------------- gns3server/compute/dynamips/nodes/bridge.py | 4 +- gns3server/compute/dynamips/nodes/c1700.py | 10 +- gns3server/compute/dynamips/nodes/c2600.py | 10 +- gns3server/compute/dynamips/nodes/c2691.py | 6 +- gns3server/compute/dynamips/nodes/c3600.py | 10 +- gns3server/compute/dynamips/nodes/c3725.py | 6 +- gns3server/compute/dynamips/nodes/c3745.py | 6 +- gns3server/compute/dynamips/nodes/c7200.py | 36 +----- .../compute/dynamips/nodes/ethernet_hub.py | 24 +--- .../compute/dynamips/nodes/ethernet_switch.py | 52 ++------ .../dynamips/nodes/frame_relay_switch.py | 68 ++-------- 12 files changed, 58 insertions(+), 296 deletions(-) diff --git a/gns3server/compute/dynamips/nodes/atm_switch.py b/gns3server/compute/dynamips/nodes/atm_switch.py index b6d55b523..4f41ef893 100644 --- a/gns3server/compute/dynamips/nodes/atm_switch.py +++ b/gns3server/compute/dynamips/nodes/atm_switch.py @@ -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}') diff --git a/gns3server/compute/dynamips/nodes/bridge.py b/gns3server/compute/dynamips/nodes/bridge.py index 82baf36f1..bb63e2479 100644 --- a/gns3server/compute/dynamips/nodes/bridge.py +++ b/gns3server/compute/dynamips/nodes/bridge.py @@ -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 diff --git a/gns3server/compute/dynamips/nodes/c1700.py b/gns3server/compute/dynamips/nodes/c1700.py index 0f609c78a..a3c4c10f1 100644 --- a/gns3server/compute/dynamips/nodes/c1700.py +++ b/gns3server/compute/dynamips/nodes/c1700.py @@ -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 diff --git a/gns3server/compute/dynamips/nodes/c2600.py b/gns3server/compute/dynamips/nodes/c2600.py index d22ff6b31..cd95fefd2 100644 --- a/gns3server/compute/dynamips/nodes/c2600.py +++ b/gns3server/compute/dynamips/nodes/c2600.py @@ -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 diff --git a/gns3server/compute/dynamips/nodes/c2691.py b/gns3server/compute/dynamips/nodes/c2691.py index 26c267aa9..0ebe5c594 100644 --- a/gns3server/compute/dynamips/nodes/c2691.py +++ b/gns3server/compute/dynamips/nodes/c2691.py @@ -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 diff --git a/gns3server/compute/dynamips/nodes/c3600.py b/gns3server/compute/dynamips/nodes/c3600.py index ef9f5f9e2..7810142bd 100644 --- a/gns3server/compute/dynamips/nodes/c3600.py +++ b/gns3server/compute/dynamips/nodes/c3600.py @@ -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 diff --git a/gns3server/compute/dynamips/nodes/c3725.py b/gns3server/compute/dynamips/nodes/c3725.py index 16986be1f..e62cf8ceb 100644 --- a/gns3server/compute/dynamips/nodes/c3725.py +++ b/gns3server/compute/dynamips/nodes/c3725.py @@ -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 diff --git a/gns3server/compute/dynamips/nodes/c3745.py b/gns3server/compute/dynamips/nodes/c3745.py index a268a1d81..d8baccd22 100644 --- a/gns3server/compute/dynamips/nodes/c3745.py +++ b/gns3server/compute/dynamips/nodes/c3745.py @@ -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 diff --git a/gns3server/compute/dynamips/nodes/c7200.py b/gns3server/compute/dynamips/nodes/c7200.py index c1957ec5c..270473039 100644 --- a/gns3server/compute/dynamips/nodes/c7200.py +++ b/gns3server/compute/dynamips/nodes/c7200.py @@ -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 diff --git a/gns3server/compute/dynamips/nodes/ethernet_hub.py b/gns3server/compute/dynamips/nodes/ethernet_hub.py index e093fff2e..abf447a63 100644 --- a/gns3server/compute/dynamips/nodes/ethernet_hub.py +++ b/gns3server/compute/dynamips/nodes/ethernet_hub.py @@ -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}') diff --git a/gns3server/compute/dynamips/nodes/ethernet_switch.py b/gns3server/compute/dynamips/nodes/ethernet_switch.py index 770f83bee..28ecacc46 100644 --- a/gns3server/compute/dynamips/nodes/ethernet_switch.py +++ b/gns3server/compute/dynamips/nodes/ethernet_switch.py @@ -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}') diff --git a/gns3server/compute/dynamips/nodes/frame_relay_switch.py b/gns3server/compute/dynamips/nodes/frame_relay_switch.py index 71bd1e77c..de055a4b5 100644 --- a/gns3server/compute/dynamips/nodes/frame_relay_switch.py +++ b/gns3server/compute/dynamips/nodes/frame_relay_switch.py @@ -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}') From c4584596268cf41b7135df1be851fbfb3b04ab71 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:08 +0300 Subject: [PATCH 06/13] refactor: use f-strings in dynamips NIO modules --- gns3server/compute/dynamips/nios/nio.py | 16 +++------------- .../dynamips/nios/nio_generic_ethernet.py | 10 ++-------- .../compute/dynamips/nios/nio_linux_ethernet.py | 10 ++-------- gns3server/compute/dynamips/nios/nio_udp.py | 12 ++---------- gns3server/compute/dynamips/nios/nio_unix.py | 10 ++-------- gns3server/compute/dynamips/nios/nio_vde.py | 12 ++---------- 6 files changed, 13 insertions(+), 57 deletions(-) diff --git a/gns3server/compute/dynamips/nios/nio.py b/gns3server/compute/dynamips/nios/nio.py index a611014b4..2363a73ae 100644 --- a/gns3server/compute/dynamips/nios/nio.py +++ b/gns3server/compute/dynamips/nios/nio.py @@ -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 diff --git a/gns3server/compute/dynamips/nios/nio_generic_ethernet.py b/gns3server/compute/dynamips/nios/nio_generic_ethernet.py index b77e65f50..19b6d9c29 100644 --- a/gns3server/compute/dynamips/nios/nio_generic_ethernet.py +++ b/gns3server/compute/dynamips/nios/nio_generic_ethernet.py @@ -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): diff --git a/gns3server/compute/dynamips/nios/nio_linux_ethernet.py b/gns3server/compute/dynamips/nios/nio_linux_ethernet.py index 591a187a9..82a3e771d 100644 --- a/gns3server/compute/dynamips/nios/nio_linux_ethernet.py +++ b/gns3server/compute/dynamips/nios/nio_linux_ethernet.py @@ -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): diff --git a/gns3server/compute/dynamips/nios/nio_udp.py b/gns3server/compute/dynamips/nios/nio_udp.py index a9ba056e5..a428b0799 100644 --- a/gns3server/compute/dynamips/nios/nio_udp.py +++ b/gns3server/compute/dynamips/nios/nio_udp.py @@ -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) diff --git a/gns3server/compute/dynamips/nios/nio_unix.py b/gns3server/compute/dynamips/nios/nio_unix.py index 39bbdc774..006df133b 100644 --- a/gns3server/compute/dynamips/nios/nio_unix.py +++ b/gns3server/compute/dynamips/nios/nio_unix.py @@ -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 diff --git a/gns3server/compute/dynamips/nios/nio_vde.py b/gns3server/compute/dynamips/nios/nio_vde.py index 3c26cee82..bbc058c20 100644 --- a/gns3server/compute/dynamips/nios/nio_vde.py +++ b/gns3server/compute/dynamips/nios/nio_vde.py @@ -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): From bbebf2082525d1868e1692f511b70d5118551b85 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:08 +0300 Subject: [PATCH 07/13] refactor: use f-strings in dynamips manager --- gns3server/compute/dynamips/__init__.py | 6 +++--- .../compute/dynamips/dynamips_hypervisor.py | 18 +++++------------- gns3server/compute/dynamips/hypervisor.py | 6 +++--- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/gns3server/compute/dynamips/__init__.py b/gns3server/compute/dynamips/__init__.py index ec2cdacc1..2013f0c35 100644 --- a/gns3server/compute/dynamips/__init__.py +++ b/gns3server/compute/dynamips/__init__.py @@ -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 diff --git a/gns3server/compute/dynamips/dynamips_hypervisor.py b/gns3server/compute/dynamips/dynamips_hypervisor.py index b2c1f7640..11f80221d 100644 --- a/gns3server/compute/dynamips/dynamips_hypervisor.py +++ b/gns3server/compute/dynamips/dynamips_hypervisor.py @@ -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") diff --git a/gns3server/compute/dynamips/hypervisor.py b/gns3server/compute/dynamips/hypervisor.py index 1216499e8..c1d3f5980 100644 --- a/gns3server/compute/dynamips/hypervisor.py +++ b/gns3server/compute/dynamips/hypervisor.py @@ -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)]) From 552c0ca3e0b13c85bf95c08267cac1adf2e2f61e Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:11 +0300 Subject: [PATCH 08/13] refactor: use f-strings in remaining compute modules --- gns3server/compute/base_node.py | 80 ++++----------- gns3server/compute/builtin/nodes/cloud.py | 58 +++-------- .../compute/builtin/nodes/ethernet_switch.py | 38 ++----- gns3server/compute/builtin/nodes/nat.py | 8 +- gns3server/compute/project_manager.py | 4 +- .../compute/ubridge/ubridge_hypervisor.py | 16 +-- .../compute/virtualbox/virtualbox_vm.py | 98 ++++--------------- gns3server/compute/vmware/__init__.py | 14 ++- gns3server/compute/vmware/vmware_vm.py | 86 ++++------------ gns3server/compute/vpcs/vpcs_vm.py | 48 ++------- 10 files changed, 97 insertions(+), 353 deletions(-) diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py index 8bfbb70c7..033ef96d9 100644 --- a/gns3server/compute/base_node.py +++ b/gns3server/compute/base_node.py @@ -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): diff --git a/gns3server/compute/builtin/nodes/cloud.py b/gns3server/compute/builtin/nodes/cloud.py index 5737a196d..c1cfdc251 100644 --- a/gns3server/compute/builtin/nodes/cloud.py +++ b/gns3server/compute/builtin/nodes/cloud.py @@ -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}") diff --git a/gns3server/compute/builtin/nodes/ethernet_switch.py b/gns3server/compute/builtin/nodes/ethernet_switch.py index 759f8a638..929325976 100644 --- a/gns3server/compute/builtin/nodes/ethernet_switch.py +++ b/gns3server/compute/builtin/nodes/ethernet_switch.py @@ -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}') diff --git a/gns3server/compute/builtin/nodes/nat.py b/gns3server/compute/builtin/nodes/nat.py index ce5a4b77e..158f337ee 100644 --- a/gns3server/compute/builtin/nodes/nat.py +++ b/gns3server/compute/builtin/nodes/nat.py @@ -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( diff --git a/gns3server/compute/project_manager.py b/gns3server/compute/project_manager.py index 1bcbae019..d99247201 100644 --- a/gns3server/compute/project_manager.py +++ b/gns3server/compute/project_manager.py @@ -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}) diff --git a/gns3server/compute/ubridge/ubridge_hypervisor.py b/gns3server/compute/ubridge/ubridge_hypervisor.py index 6256f0142..5b26e6db1 100644 --- a/gns3server/compute/ubridge/ubridge_hypervisor.py +++ b/gns3server/compute/ubridge/ubridge_hypervisor.py @@ -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") diff --git a/gns3server/compute/virtualbox/virtualbox_vm.py b/gns3server/compute/virtualbox/virtualbox_vm.py index d5d747503..0876e2553 100644 --- a/gns3server/compute/virtualbox/virtualbox_vm.py +++ b/gns3server/compute/virtualbox/virtualbox_vm.py @@ -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}") diff --git a/gns3server/compute/vmware/__init__.py b/gns3server/compute/vmware/__init__.py index 7aa615927..cc480688e 100644 --- a/gns3server/compute/vmware/__init__.py +++ b/gns3server/compute/vmware/__init__.py @@ -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) diff --git a/gns3server/compute/vmware/vmware_vm.py b/gns3server/compute/vmware/vmware_vm.py index f4636f55a..db54fa55f 100644 --- a/gns3server/compute/vmware/vmware_vm.py +++ b/gns3server/compute/vmware/vmware_vm.py @@ -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}") diff --git a/gns3server/compute/vpcs/vpcs_vm.py b/gns3server/compute/vpcs/vpcs_vm.py index af0acf72e..ec3dd88eb 100644 --- a/gns3server/compute/vpcs/vpcs_vm.py +++ b/gns3server/compute/vpcs/vpcs_vm.py @@ -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): """ From 7a9c600f54c38c8a978c6b7e720d2065085a2108 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:11 +0300 Subject: [PATCH 09/13] refactor: use f-strings in controller modules --- gns3server/controller/__init__.py | 2 +- gns3server/controller/drawing.py | 4 +- gns3server/controller/export_project.py | 2 +- gns3server/controller/gns3vm/__init__.py | 16 +--- .../controller/gns3vm/virtualbox_gns3_vm.py | 75 +++++++------------ gns3server/controller/import_project.py | 2 +- gns3server/controller/link.py | 10 +-- gns3server/controller/project.py | 18 ++--- gns3server/controller/snapshot.py | 4 +- 9 files changed, 47 insertions(+), 86 deletions(-) diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index 67cef57f8..9a65812a8 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -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] diff --git a/gns3server/controller/drawing.py b/gns3server/controller/drawing.py index a67a9988a..08a08d894 100644 --- a/gns3server/controller/drawing.py +++ b/gns3server/controller/drawing.py @@ -72,9 +72,7 @@ class Drawing: return data.decode() except UnicodeError: width, height, filetype = get_size(data) - return '\n\n'.format( - b64=base64.b64encode(data).decode(), filetype=filetype, width=width, height=height - ) + return f'\n\n' except OSError: log.warning("Image file %s missing", filename) return "" diff --git a/gns3server/controller/export_project.py b/gns3server/controller/export_project.py index c1c7aac7b..f70da2537 100644 --- a/gns3server/controller/export_project.py +++ b/gns3server/controller/export_project.py @@ -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: diff --git a/gns3server/controller/gns3vm/__init__.py b/gns3server/controller/gns3vm/__init__.py index 3f69ee001..17fe64b03 100644 --- a/gns3server/controller/gns3vm/__init__.py +++ b/gns3server/controller/gns3vm/__init__.py @@ -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.
The GNS3 VM can be downloaded here.', @@ -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}") diff --git a/gns3server/controller/gns3vm/virtualbox_gns3_vm.py b/gns3server/controller/gns3vm/virtualbox_gns3_vm.py index f4e328424..fe39b3dd3 100644 --- a/gns3server/controller/gns3vm/virtualbox_gns3_vm.py +++ b/gns3server/controller/gns3vm/virtualbox_gns3_vm.py @@ -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}"' ) diff --git a/gns3server/controller/import_project.py b/gns3server/controller/import_project.py index e844d99e7..93b6a1246 100644 --- a/gns3server/controller/import_project.py +++ b/gns3server/controller/import_project.py @@ -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}" diff --git a/gns3server/controller/link.py b/gns3server/controller/link.py index 5cbe94506..ff20f7c6b 100644 --- a/gns3server/controller/link.py +++ b/gns3server/controller/link.py @@ -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) diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py index 04016ed27..c5aedf731 100644 --- a/gns3server/controller/project.py +++ b/gns3server/controller/project.py @@ -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): diff --git a/gns3server/controller/snapshot.py b/gns3server/controller/snapshot.py index 66d659b65..811db0fde 100644 --- a/gns3server/controller/snapshot.py +++ b/gns3server/controller/snapshot.py @@ -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() From bee6b3f8b14c08dbf1420a4e51ab644468950d3b Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:12 +0300 Subject: [PATCH 10/13] refactor: use f-strings in compute tests --- tests/compute/builtin/nodes/test_cloud.py | 22 ++++---- tests/compute/docker/test_docker.py | 6 +-- tests/compute/docker/test_docker_vm.py | 48 ++++++++---------- tests/compute/iou/test_iou_vm.py | 14 +++--- tests/compute/qemu/test_qemu_vm.py | 50 +++++++++---------- .../virtualbox/test_virtualbox_manager.py | 2 +- tests/compute/vpcs/test_vpcs_manager.py | 2 +- tests/compute/vpcs/test_vpcs_vm.py | 2 +- 8 files changed, 70 insertions(+), 76 deletions(-) diff --git a/tests/compute/builtin/nodes/test_cloud.py b/tests/compute/builtin/nodes/test_cloud.py index bebec5fc5..14cb7633d 100644 --- a/tests/compute/builtin/nodes/test_cloud.py +++ b/tests/compute/builtin/nodes/test_cloud.py @@ -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"), ] ) diff --git a/tests/compute/docker/test_docker.py b/tests/compute/docker/test_docker.py index 74c7f365b..ed3fb706e 100644 --- a/tests/compute/docker/test_docker.py +++ b/tests/compute/docker/test_docker.py @@ -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}, diff --git a/tests/compute/docker/test_docker_vm.py b/tests/compute/docker/test_docker_vm.py index 2c15d8927..c98998a81 100644 --- a/tests/compute/docker/test_docker_vm.py +++ b/tests/compute/docker/test_docker_vm.py @@ -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, diff --git a/tests/compute/iou/test_iou_vm.py b/tests/compute/iou/test_iou_vm.py index 45ec5973a..67a0fc5f1 100644 --- a/tests/compute/iou/test_iou_vm.py +++ b/tests/compute/iou/test_iou_vm.py @@ -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 diff --git a/tests/compute/qemu/test_qemu_vm.py b/tests/compute/qemu/test_qemu_vm.py index bfeb02bdf..7b39bc4ae 100644 --- a/tests/compute/qemu/test_qemu_vm.py +++ b/tests/compute/qemu/test_qemu_vm.py @@ -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 diff --git a/tests/compute/virtualbox/test_virtualbox_manager.py b/tests/compute/virtualbox/test_virtualbox_manager.py index 5aa1ddb28..311d02b33 100644 --- a/tests/compute/virtualbox/test_virtualbox_manager.py +++ b/tests/compute/virtualbox/test_virtualbox_manager.py @@ -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 diff --git a/tests/compute/vpcs/test_vpcs_manager.py b/tests/compute/vpcs/test_vpcs_manager.py index 7aad60146..f43d8c6a7 100644 --- a/tests/compute/vpcs/test_vpcs_manager.py +++ b/tests/compute/vpcs/test_vpcs_manager.py @@ -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 diff --git a/tests/compute/vpcs/test_vpcs_vm.py b/tests/compute/vpcs/test_vpcs_vm.py index be4d6a364..4fb672aa6 100644 --- a/tests/compute/vpcs/test_vpcs_vm.py +++ b/tests/compute/vpcs/test_vpcs_vm.py @@ -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): From be943fcdf3aa490199c92a83aae4042bbd86ffbc Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:12 +0300 Subject: [PATCH 11/13] refactor: use f-strings in controller tests --- tests/controller/test_compute.py | 4 ++-- tests/controller/test_node.py | 40 +++++++++++++++---------------- tests/controller/test_project.py | 12 +++++----- tests/controller/test_udp_link.py | 40 +++++++++++++------------------ 4 files changed, 43 insertions(+), 53 deletions(-) diff --git a/tests/controller/test_compute.py b/tests/controller/test_compute.py index 9a05e7c27..4fb3e9f7e 100644 --- a/tests/controller/test_compute.py +++ b/tests/controller/test_compute.py @@ -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, diff --git a/tests/controller/test_node.py b/tests/controller/test_node.py index 717537a37..b80aa50c1 100644 --- a/tests/controller/test_node.py +++ b/tests/controller/test_node.py @@ -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 ) diff --git a/tests/controller/test_project.py b/tests/controller/test_project.py index 4c87119fb..92d51cd82 100644 --- a/tests/controller/test_project.py +++ b/tests/controller/test_project.py @@ -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()) diff --git a/tests/controller/test_udp_link.py b/tests/controller/test_udp_link.py index 4a055ae8a..032bff079 100644 --- a/tests/controller/test_udp_link.py +++ b/tests/controller/test_udp_link.py @@ -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", From 3135c8b7e39e6f0ea87f6eec6ff8ce2bf7164a2b Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:12 +0300 Subject: [PATCH 12/13] refactor: use f-strings in remaining modules, scripts and tests --- gns3server/crash_report.py | 6 +-- gns3server/db/models/base.py | 4 +- gns3server/server.py | 4 +- gns3server/utils/__init__.py | 2 +- gns3server/utils/asyncio/aiozipstream.py | 2 +- gns3server/utils/images.py | 2 +- gns3server/utils/interfaces.py | 4 +- scripts/welcome.py | 42 ++++++++------------ tests/api/routes/controller/test_nodes.py | 12 ++---- tests/api/routes/controller/test_projects.py | 21 +++++----- tests/api/routes/controller/test_version.py | 4 +- tests/test_topologies.py | 30 +++++++------- 12 files changed, 55 insertions(+), 78 deletions(-) diff --git a/gns3server/crash_report.py b/gns3server/crash_report.py index 5d407db4a..8e9e108ad 100644 --- a/gns3server/crash_report.py +++ b/gns3server/crash_report.py @@ -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")), diff --git a/gns3server/db/models/base.py b/gns3server/db/models/base.py index 522486e93..45190577a 100644 --- a/gns3server/db/models/base.py +++ b/gns3server/db/models/base.py @@ -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: diff --git a/gns3server/server.py b/gns3server/server.py index f9824caab..3ec16e456 100644 --- a/gns3server/server.py +++ b/gns3server/server.py @@ -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) diff --git a/gns3server/utils/__init__.py b/gns3server/utils/__init__.py index 286a76757..b1ba96c7d 100644 --- a/gns3server/utils/__init__.py +++ b/gns3server/utils/__init__.py @@ -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): diff --git a/gns3server/utils/asyncio/aiozipstream.py b/gns3server/utils/asyncio/aiozipstream.py index 07770ed0e..fc6f5fdc3 100644 --- a/gns3server/utils/asyncio/aiozipstream.py +++ b/gns3server/utils/asyncio/aiozipstream.py @@ -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: diff --git a/gns3server/utils/images.py b/gns3server/utils/images.py index 4f6e402bb..4db2c2f8d 100644 --- a/gns3server/utils/images.py +++ b/gns3server/utils/images.py @@ -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 diff --git a/gns3server/utils/interfaces.py b/gns3server/utils/interfaces.py index 0585028c9..34f9422b6 100644 --- a/gns3server/utils/interfaces.py +++ b/gns3server/utils/interfaces.py @@ -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, diff --git a/scripts/welcome.py b/scripts/welcome.py index d9ecd21a0..7b1ed7d35 100644 --- a/scripts/welcome.py +++ b/scripts/welcome.py @@ -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"), diff --git a/tests/api/routes/controller/test_nodes.py b/tests/api/routes/controller/test_nodes.py index a2d37922a..cf441a01f 100644 --- a/tests/api/routes/controller/test_nodes.py +++ b/tests/api/routes/controller/test_nodes.py @@ -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 diff --git a/tests/api/routes/controller/test_projects.py b/tests/api/routes/controller/test_projects.py index 3ae35c689..d93905ca0 100644 --- a/tests/api/routes/controller/test_projects.py +++ b/tests/api/routes/controller/test_projects.py @@ -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) diff --git a/tests/api/routes/controller/test_version.py b/tests/api/routes/controller/test_version.py index b0ea854aa..39fd1ee17 100644 --- a/tests/api/routes/controller/test_version.py +++ b/tests/api/routes/controller/test_version.py @@ -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: diff --git a/tests/test_topologies.py b/tests/test_topologies.py index c4320658f..0bbc637a4 100644 --- a/tests/test_topologies.py +++ b/tests/test_topologies.py @@ -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" From 7e1bc67be2d4ebcc7729072943a4b778534ce7a7 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Wed, 30 Sep 2026 20:58:12 +0300 Subject: [PATCH 13/13] chore(ruff): drop UP032 from the ignore baseline --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 85b7f0c75..ef7b82573 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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 ]