From ba220780a9300e616c99502f1f8f8510986a180a Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Sat, 2 May 2026 12:52:33 +0800 Subject: [PATCH 1/2] fix: improve hostname validation error messages with allowed characters When a hostname validation fails, the error message now includes the allowed character set to help users provide valid names. Co-Authored-By: Claude Opus 4.6 --- gns3server/compute/docker/docker_vm.py | 2 +- gns3server/compute/dynamips/nodes/router.py | 2 +- gns3server/compute/iou/iou_vm.py | 2 +- gns3server/compute/qemu/qemu_vm.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gns3server/compute/docker/docker_vm.py b/gns3server/compute/docker/docker_vm.py index 5586cfb70..023fec125 100644 --- a/gns3server/compute/docker/docker_vm.py +++ b/gns3server/compute/docker/docker_vm.py @@ -188,7 +188,7 @@ class DockerVM(BaseNode): """ if not is_rfc1123_hostname_valid(new_name): - raise DockerError(f"'{new_name}' is an invalid name to rename Docker container '{self._name}'") + raise DockerError(f"'{new_name}' is an invalid name to rename Docker container '{self._name}'. Allowed characters: letters (a-z, A-Z), digits (0-9), and hyphens (-). The name cannot start or end with a hyphen.") super(DockerVM, DockerVM).name.__set__(self, new_name) @property diff --git a/gns3server/compute/dynamips/nodes/router.py b/gns3server/compute/dynamips/nodes/router.py index 1eea64e3e..45397122b 100644 --- a/gns3server/compute/dynamips/nodes/router.py +++ b/gns3server/compute/dynamips/nodes/router.py @@ -1682,7 +1682,7 @@ class Router(BaseNode): """ if not is_ios_hostname_valid(new_name): - raise DynamipsError(f"{new_name} is an invalid name to rename router '{self._name}'") + raise DynamipsError(f"{new_name} is an invalid name to rename router '{self._name}'. Allowed characters: letters (a-z, A-Z), digits (0-9), and hyphens (-). The name must start with a letter, end with a letter or digit, and be 63 characters or fewer.") await self._hypervisor.send(f'vm rename "{self._name}" "{new_name}"') diff --git a/gns3server/compute/iou/iou_vm.py b/gns3server/compute/iou/iou_vm.py index 32dc01ef2..6bb4b24f2 100644 --- a/gns3server/compute/iou/iou_vm.py +++ b/gns3server/compute/iou/iou_vm.py @@ -367,7 +367,7 @@ class IOUVM(BaseNode): """ if not is_ios_hostname_valid(new_name): - raise IOUError(f"'{new_name}' is an invalid name to rename IOU node '{self._name}'") + raise IOUError(f"'{new_name}' is an invalid name to rename IOU node '{self._name}'. Allowed characters: letters (a-z, A-Z), digits (0-9), and hyphens (-). The name must start with a letter, end with a letter or digit, and be 63 characters or fewer.") if self.startup_config_file: content = self.startup_config_content content = re.sub(r"hostname .+$", "hostname " + new_name, content, flags=re.MULTILINE) diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index e712ddd49..7edb15809 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -197,7 +197,7 @@ class QemuVM(BaseNode): """ if not is_rfc1123_hostname_valid(new_name): - raise QemuError(f"'{new_name}' is an invalid name to rename Qemu node '{self._name}'") + raise QemuError(f"'{new_name}' is an invalid name to rename Qemu node '{self._name}'. Allowed characters: letters (a-z, A-Z), digits (0-9), and hyphens (-). The name cannot start or end with a hyphen.") super(QemuVM, QemuVM).name.__set__(self, new_name) @property From a6dcab81106e878bf3e053ccbd6ab8ae31e7c03b Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Thu, 30 Apr 2026 09:38:55 +0800 Subject: [PATCH 2/2] fix: avoid AttributeError when password is not provided in compute update When updating a compute without providing a password field, compute_update.password is None and calling .get_secret_value() on it causes a 500 Internal Server Error. Only set the password in update_values when a password is actually provided. Co-Authored-By: Claude Opus 4.6 --- gns3server/db/repositories/computes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gns3server/db/repositories/computes.py b/gns3server/db/repositories/computes.py index 6c6f0f930..181b92aa6 100644 --- a/gns3server/db/repositories/computes.py +++ b/gns3server/db/repositories/computes.py @@ -69,7 +69,8 @@ class ComputesRepository(BaseRepository): async def update_compute(self, compute_id: UUID, compute_update: schemas.ComputeUpdate) -> Optional[models.Compute]: update_values = compute_update.model_dump(exclude_unset=True) - update_values["password"] = compute_update.password.get_secret_value() + if compute_update.password is not None: + update_values["password"] = compute_update.password.get_secret_value() query = update(models.Compute).\ where(models.Compute.compute_id == compute_id).\