85 lines
2.5 KiB
Python
85 lines
2.5 KiB
Python
import logging
|
|
import uuid
|
|
|
|
from fastapi import HTTPException, Response
|
|
from fastapi.datastructures import QueryParams
|
|
from sqlmodel import select
|
|
|
|
from openec2.libvirt import LibvirtSingleton
|
|
from openec2.config import OpenEC2Config
|
|
from openec2.db import DatabaseDep
|
|
from openec2.db.instance import Instance
|
|
from openec2.db.user import User
|
|
from openec2.utils.array import parse_array_plain
|
|
from openec2.images import garbage_collect_image
|
|
from openec2.ipam import remove_instance_dhcp_mapping
|
|
from openec2.api.shared import InstanceInfo
|
|
from openec2.api.describe_instances import describe_instance_state
|
|
from openec2.api.terminate_instances import TerminateInstancesResponse, InstancesSet
|
|
|
|
|
|
logger = logging.getLogger()
|
|
|
|
|
|
def terminate_instances(
|
|
params: QueryParams,
|
|
config: OpenEC2Config,
|
|
db: DatabaseDep,
|
|
user: User,
|
|
):
|
|
instances: list[InstanceInfo] = []
|
|
conn = LibvirtSingleton.of().connection
|
|
image_ids: set[str] = set()
|
|
for instance_id in parse_array_plain("InstanceId", params):
|
|
instance = db.exec(select(Instance).where(Instance.id == instance_id)).first()
|
|
if instance is None:
|
|
continue
|
|
# raise HTTPException(status_code=404, detail="Unknown instance")
|
|
|
|
# Check for permission issues
|
|
if instance.owner_id != user.id:
|
|
# TODO: Add the error to the response
|
|
continue
|
|
|
|
dom = conn.lookupByName(instance_id)
|
|
prev_state = describe_instance_state(dom)
|
|
if dom.isActive():
|
|
dom.shutdown()
|
|
current_state = describe_instance_state(dom)
|
|
dom.undefine()
|
|
|
|
instances.append(
|
|
InstanceInfo(
|
|
instanceId=instance.id,
|
|
currentState=current_state,
|
|
previousState=prev_state,
|
|
),
|
|
)
|
|
|
|
# Delete files
|
|
logger.debug(f"Removing {config.instances.location / instance_id}")
|
|
instance_disk = config.instances.location / instance_id
|
|
instance_disk.unlink()
|
|
|
|
image_ids.add(instance.imageId)
|
|
remove_instance_dhcp_mapping(
|
|
instance.id, instance.interfaceMac, instance.privateIPv4, db
|
|
)
|
|
db.delete(instance)
|
|
|
|
db.commit()
|
|
|
|
# Garbage collect AMIs
|
|
for image_id in image_ids:
|
|
garbage_collect_image(image_id, db)
|
|
|
|
return Response(
|
|
TerminateInstancesResponse(
|
|
requestId=uuid.uuid4().hex,
|
|
instancesSet=InstancesSet(
|
|
item=instances,
|
|
),
|
|
).to_xml(),
|
|
media_type="application/xml",
|
|
)
|