feat: forbid deleting templates and images still used by projects

Deleting a template with prune_images, deleting an image, or pruning
orphan images only checked template references — a project node still
pointing at the image (e.g. via hda_disk_image_backing_file) was left
with a dangling reference and the project could no longer be opened.

- Add controller helpers scanning every known project (opened projects
  via in-memory nodes, closed projects via their .gns3 file) for
  template and image usage; unreadable topologies are skipped
- Guard DELETE /templates/{id}, DELETE /templates/{id}?prune_images,
  DELETE /images/{path} and /images/prune with a 409 listing the
  project names
- Run all template-delete checks before any mutation so a refused
  deletion cannot leave the template gone while its images survive
This commit is contained in:
YueGuobin committed 2026-08-31 22:30:42 +08:00
1 parent 861b7e86ff
commit 13548deae8
8 files changed
+455 -14

No files matched your search

+9
View File
@@ -341,6 +341,15 @@ class TemplatesService:
if self.get_builtin_template(template_id):
raise ControllerForbiddenError(f"Template '{template_id}' cannot be deleted because it is built-in")
template = await self.get_template(template_id)
project_names = self._controller.find_projects_using_template(template_id)
if project_names:
raise ControllerError(
f"Template '{template['name']}' cannot be deleted because it is used by "
f"one or more projects: {', '.join(project_names)}"
)
if await self._templates_repo.delete_template(template_id):
self._controller.notification.controller_emit("template.deleted", {"template_id": str(template_id)})
else: