mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
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:
8 files changed
+455
-14
No files matched your search
@@ -197,11 +197,16 @@ async def prune_images(
|
||||
"""
|
||||
Prune images not attached to any template.
|
||||
|
||||
Images referenced by a node in any project (opened or closed) are kept.
|
||||
|
||||
Required privilege: Image.Allocate
|
||||
"""
|
||||
|
||||
skip_images = get_builtin_disks()
|
||||
await images_repo.prune_images(skip_images)
|
||||
# a single pass over all projects' node properties protects every
|
||||
# referenced file name at once
|
||||
referenced_filenames = Controller.instance().collect_referenced_image_filenames()
|
||||
await images_repo.prune_images(list(skip_images) + list(referenced_filenames))
|
||||
|
||||
|
||||
@router.post(
|
||||
@@ -309,6 +314,10 @@ async def delete_image(
|
||||
template_names = ", ".join([template.name for template in templates])
|
||||
raise ControllerError(f"Image '{image_path}' is used by one or more templates: {template_names}")
|
||||
|
||||
project_names = Controller.instance().find_projects_using_image(image.filename)
|
||||
if project_names:
|
||||
raise ControllerError(f"Image '{image_path}' is used by one or more projects: {', '.join(project_names)}")
|
||||
|
||||
try:
|
||||
os.remove(image.path)
|
||||
except OSError:
|
||||
|
||||
Reference in new issue
Block a user