Option to prune images when deleting template.

pull/1911/head
grossmj 3 years ago
parent bf9a3aee20
commit 332fa47b50

@ -25,14 +25,15 @@ import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
from fastapi import APIRouter, Request, Response, HTTPException, Depends, Response, status from fastapi import APIRouter, Request, HTTPException, Depends, Response, status
from typing import List from typing import List, Optional
from uuid import UUID from uuid import UUID
from gns3server import schemas from gns3server import schemas
from gns3server.db.repositories.templates import TemplatesRepository from gns3server.db.repositories.templates import TemplatesRepository
from gns3server.services.templates import TemplatesService from gns3server.services.templates import TemplatesService
from gns3server.db.repositories.rbac import RbacRepository from gns3server.db.repositories.rbac import RbacRepository
from gns3server.db.repositories.images import ImagesRepository
from .dependencies.authentication import get_current_active_user from .dependencies.authentication import get_current_active_user
from .dependencies.database import get_repository from .dependencies.database import get_repository
@ -97,7 +98,9 @@ async def update_template(
@router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT) @router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_template( async def delete_template(
template_id: UUID, template_id: UUID,
prune_images: Optional[bool] = False,
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)), templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
images_repo: RbacRepository = Depends(get_repository(ImagesRepository)),
rbac_repo: RbacRepository = Depends(get_repository(RbacRepository)) rbac_repo: RbacRepository = Depends(get_repository(RbacRepository))
) -> Response: ) -> Response:
""" """
@ -106,6 +109,8 @@ async def delete_template(
await TemplatesService(templates_repo).delete_template(template_id) await TemplatesService(templates_repo).delete_template(template_id)
await rbac_repo.delete_all_permissions_with_path(f"/templates/{template_id}") await rbac_repo.delete_all_permissions_with_path(f"/templates/{template_id}")
if prune_images:
await images_repo.prune_images()
return Response(status_code=status.HTTP_204_NO_CONTENT) return Response(status_code=status.HTTP_204_NO_CONTENT)

@ -117,10 +117,11 @@ class ImagesRepository(BaseRepository):
images_deleted = 0 images_deleted = 0
for image in images: for image in images:
try: try:
log.debug(f"Deleting image '{image.path}'")
os.remove(image.path) os.remove(image.path)
except OSError: except OSError:
log.warning(f"Could not delete image file {image.path}") log.warning(f"Could not delete image file {image.path}")
if await self.delete_image(image.filename): if await self.delete_image(image.filename):
images_deleted += 1 images_deleted += 1
log.info(f"{images_deleted} image have been deleted") log.info(f"{images_deleted} image(s) have been deleted")
return images_deleted return images_deleted

@ -159,7 +159,7 @@ class TemplatesService:
image = await self._templates_repo.get_image(image_name) image = await self._templates_repo.get_image(image_name)
if not image or not os.path.exists(image.path): if not image or not os.path.exists(image.path):
raise ControllerNotFoundError(f"Image {image_name} could not be found") raise ControllerNotFoundError(f"Image '{image_name}' could not be found")
return image return image
async def _find_images(self, template_type: str, settings: dict) -> List[models.Image]: async def _find_images(self, template_type: str, settings: dict) -> List[models.Image]:

@ -116,6 +116,40 @@ class TestTemplateRoutes:
response = await client.delete(app.url_path_for("delete_template", template_id=template_id)) response = await client.delete(app.url_path_for("delete_template", template_id=template_id))
assert response.status_code == status.HTTP_204_NO_CONTENT assert response.status_code == status.HTTP_204_NO_CONTENT
async def test_template_delete_with_prune_images(
self,
app: FastAPI,
client: AsyncClient,
db_session: AsyncSession,
tmpdir: str,
) -> None:
path = os.path.join(tmpdir, "test.qcow2")
with open(path, "wb+") as f:
f.write(b'\x42\x42\x42\x42')
images_repo = ImagesRepository(db_session)
await images_repo.add_image("test.qcow2", "qemu", 42, path, "e342eb86c1229b6c154367a5476969b5", "md5")
template_id = str(uuid.uuid4())
params = {"template_id": template_id,
"name": "QEMU_TEMPLATE",
"compute_id": "local",
"hda_disk_image": "test.qcow2",
"template_type": "qemu"}
response = await client.post(app.url_path_for("create_template"), json=params)
assert response.status_code == status.HTTP_201_CREATED
response = await client.delete(
app.url_path_for("delete_template", template_id=template_id),
params={"prune_images": True}
)
assert response.status_code == status.HTTP_204_NO_CONTENT
images_repo = ImagesRepository(db_session)
images = await images_repo.get_images()
assert len(images) == 0
# async def test_create_node_from_template(self, controller_api, controller, project): # async def test_create_node_from_template(self, controller_api, controller, project):
# #
# id = str(uuid.uuid4()) # id = str(uuid.uuid4())

Loading…
Cancel
Save