Cleanup
This commit is contained in:
parent
5b99e6e990
commit
e92994d2f3
@ -3,8 +3,8 @@ import uuid
|
||||
from fastapi import Response
|
||||
from fastapi.datastructures import QueryParams
|
||||
from sqlmodel import select
|
||||
import libvirt
|
||||
|
||||
from openec2.libvirt import LibvirtSingleton
|
||||
from openec2.api.describe_instances import InstanceDescription, DescribeInstancesResponse, DescribeInstancesResponseReservationSet, describe_instance
|
||||
from openec2.api.shared import InstanceState
|
||||
from openec2.config import OpenEC2Config
|
||||
@ -17,7 +17,7 @@ def describe_instances(
|
||||
db: DatabaseDep,
|
||||
):
|
||||
response_items: list[InstanceDescription] = []
|
||||
conn = libvirt.open("qemu:///system")
|
||||
conn = LibvirtSingleton.of().connection
|
||||
for instance in db.exec(select(Instance)).all():
|
||||
dom = conn.lookupByName(instance.id)
|
||||
running = dom.isActive()
|
||||
@ -25,7 +25,6 @@ def describe_instances(
|
||||
response_items.append(
|
||||
describe_instance(instance, dom),
|
||||
)
|
||||
conn.close()
|
||||
|
||||
return Response(
|
||||
DescribeInstancesResponse(
|
||||
|
@ -6,8 +6,8 @@ import os
|
||||
|
||||
from fastapi.datastructures import QueryParams
|
||||
from sqlmodel import select
|
||||
import libvirt
|
||||
|
||||
from openec2.libvirt import LibvirtSingleton
|
||||
from openec2.config import OpenEC2Config
|
||||
from openec2.db import DatabaseDep
|
||||
from openec2.db.instance import Instance
|
||||
@ -15,7 +15,6 @@ from openec2.db.image import AMI
|
||||
from openec2.api.run_instances import RunInstanceResponse, RunInstanceInstanceSet
|
||||
from openec2.api.describe_instances import describe_instance
|
||||
from openec2.utils.array import parse_array_objects
|
||||
from openec2.utils.cloudinit import create_cloudinit_image
|
||||
|
||||
def create_libvirt_domain(
|
||||
name: str,
|
||||
@ -121,7 +120,7 @@ def run_instances(
|
||||
db.commit()
|
||||
print("Inserted new instance")
|
||||
|
||||
conn = libvirt.open("qemu:///system")
|
||||
conn = LibvirtSingleton.of().connection
|
||||
domain = conn.defineXML(
|
||||
create_libvirt_domain(
|
||||
instance_id,
|
||||
@ -133,7 +132,6 @@ def run_instances(
|
||||
)
|
||||
domain.create()
|
||||
description = describe_instance(instance, domain)
|
||||
conn.close()
|
||||
|
||||
return RunInstanceResponse(
|
||||
request_id=uuid.uuid4().hex,
|
||||
|
@ -3,8 +3,8 @@ import uuid
|
||||
from fastapi import HTTPException
|
||||
from fastapi.datastructures import QueryParams
|
||||
from sqlmodel import select
|
||||
import libvirt
|
||||
|
||||
from openec2.libvirt import LibvirtSingleton
|
||||
from openec2.config import OpenEC2Config
|
||||
from openec2.db import DatabaseDep
|
||||
from openec2.db.instance import Instance
|
||||
@ -17,13 +17,13 @@ def start_instances(
|
||||
config: OpenEC2Config,
|
||||
db: DatabaseDep,
|
||||
):
|
||||
conn = LibvirtSingleton.of().connection
|
||||
instances: list[StartInstancesResponseInstancesSetInstance] = []
|
||||
for instance_id in parse_array_plain("InstanceId", params):
|
||||
instance = db.exec(select(Instance).where(Instance.id == instance_id)).first()
|
||||
if instance is None:
|
||||
raise HTTPException(status_code=404, detail="Unknown instance")
|
||||
|
||||
conn = libvirt.open("qemu:///system")
|
||||
dom = conn.lookupByName(instance_id)
|
||||
|
||||
running = dom.isActive()
|
||||
@ -38,7 +38,6 @@ def start_instances(
|
||||
code=16 if running else 80,
|
||||
name="running" if running else "stopped",
|
||||
)
|
||||
conn.close()
|
||||
|
||||
instances.append(
|
||||
StartInstancesResponseInstancesSetInstance(
|
||||
|
@ -3,8 +3,8 @@ import uuid
|
||||
from fastapi import HTTPException
|
||||
from fastapi.datastructures import QueryParams
|
||||
from sqlmodel import select
|
||||
import libvirt
|
||||
|
||||
from openec2.libvirt import LibvirtSingleton
|
||||
from openec2.config import OpenEC2Config
|
||||
from openec2.db import DatabaseDep
|
||||
from openec2.db.instance import Instance
|
||||
@ -18,13 +18,13 @@ def stop_instances(
|
||||
config: OpenEC2Config,
|
||||
db: DatabaseDep,
|
||||
):
|
||||
conn = LibvirtSingleton.of().connection
|
||||
instances: list[StopInstancesResponseInstancesSetInstance] = []
|
||||
for instance_id in parse_array_plain("InstanceId", params):
|
||||
instance = db.exec(select(Instance).where(Instance.id == instance_id)).first()
|
||||
if instance is None:
|
||||
raise HTTPException(status_code=404, detail="Unknown instance")
|
||||
|
||||
conn = libvirt.open("qemu:///system")
|
||||
dom = conn.lookupByName(instance_id)
|
||||
running = dom.isActive()
|
||||
prev_state = InstanceState(
|
||||
@ -38,7 +38,6 @@ def stop_instances(
|
||||
code=16 if running else 80,
|
||||
name="running" if running else "stopped",
|
||||
)
|
||||
conn.close()
|
||||
|
||||
instances.append(
|
||||
StopInstancesResponseInstancesSetInstance(
|
||||
|
@ -3,8 +3,8 @@ import logging
|
||||
from fastapi import HTTPException
|
||||
from fastapi.datastructures import QueryParams
|
||||
from sqlmodel import select
|
||||
import libvirt
|
||||
|
||||
from openec2.libvirt import LibvirtSingleton
|
||||
from openec2.config import OpenEC2Config
|
||||
from openec2.db import DatabaseDep
|
||||
from openec2.db.instance import Instance
|
||||
@ -18,17 +18,16 @@ def terminate_instances(
|
||||
config: OpenEC2Config,
|
||||
db: DatabaseDep,
|
||||
):
|
||||
conn = LibvirtSingleton.of().connection
|
||||
for instance_id in parse_array_plain("InstanceId", params):
|
||||
instance = db.exec(select(Instance).where(Instance.id == instance_id)).first()
|
||||
if instance is None:
|
||||
raise HTTPException(status_code=404, detail="Unknown instance")
|
||||
|
||||
conn = libvirt.open("qemu:///system")
|
||||
dom = conn.lookupByName(instance_id)
|
||||
if dom.isActive():
|
||||
dom.shutdown()
|
||||
dom.undefine()
|
||||
conn.close()
|
||||
|
||||
# Delete files
|
||||
logger.debug(f"Removing {config.instances.location / instance_id}")
|
||||
|
@ -1,5 +1,4 @@
|
||||
from pydantic_xml import BaseXmlModel, element
|
||||
import libvirt
|
||||
|
||||
from openec2.db.instance import Instance
|
||||
from openec2.api.shared import InstanceState
|
||||
|
@ -13,12 +13,16 @@ class _OpenEC2InstanceConfig(BaseModel):
|
||||
|
||||
types: dict[str, _OpenEC2InstanceType]
|
||||
|
||||
class _OpenEC2LibvirtConfig(BaseModel):
|
||||
connection: str
|
||||
|
||||
class _OpenEC2Config(BaseModel):
|
||||
images: Path
|
||||
seed: Path
|
||||
instances: _OpenEC2InstanceConfig
|
||||
libvirt: _OpenEC2LibvirtConfig
|
||||
|
||||
def get_config() -> _OpenEC2Config:
|
||||
def _get_config() -> _OpenEC2Config:
|
||||
# TODO: Read from disk
|
||||
return _OpenEC2Config(
|
||||
images=Path("/home/alexander/openec2/images"),
|
||||
@ -33,6 +37,26 @@ def get_config() -> _OpenEC2Config:
|
||||
),
|
||||
},
|
||||
),
|
||||
libvirt=_OpenEC2LibvirtConfig(
|
||||
connection="qemu:///system"
|
||||
),
|
||||
)
|
||||
|
||||
OpenEC2Config = Annotated[_OpenEC2Config, Depends(get_config)]
|
||||
class ConfigSingleton:
|
||||
__instance: "ConfigSingleton | None" = None
|
||||
|
||||
config: _OpenEC2Config
|
||||
|
||||
def __init__(self):
|
||||
self.config = _get_config()
|
||||
|
||||
def get_config(self) -> _OpenEC2Config:
|
||||
return self.config
|
||||
|
||||
@staticmethod
|
||||
def of() -> "ConfigSingleton":
|
||||
if ConfigSingleton.__instance is None:
|
||||
ConfigSingleton.__instance = ConfigSingleton()
|
||||
return ConfigSingleton.__instance
|
||||
|
||||
OpenEC2Config = Annotated[_OpenEC2Config, Depends(ConfigSingleton.of().get_config)]
|
||||
|
24
src/openec2/libvirt.py
Normal file
24
src/openec2/libvirt.py
Normal file
@ -0,0 +1,24 @@
|
||||
import libvirt
|
||||
|
||||
from openec2.config import ConfigSingleton
|
||||
|
||||
|
||||
class LibvirtSingleton:
|
||||
__instance: "LibvirtSingleton | None" = None
|
||||
|
||||
# The connection to libvirt
|
||||
connection: libvirt.virConnect
|
||||
|
||||
def __init__(self):
|
||||
self.connection = libvirt.open(
|
||||
ConfigSingleton.of().config.libvirt.connection,
|
||||
)
|
||||
|
||||
def __del__(self):
|
||||
self.connection.close()
|
||||
|
||||
@staticmethod
|
||||
def of() -> "LibvirtSingleton":
|
||||
if LibvirtSingleton.__instance is None:
|
||||
LibvirtSingleton.__instance = LibvirtSingleton()
|
||||
return LibvirtSingleton.__instance
|
@ -1,19 +0,0 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
|
||||
def create_cloudinit_image(
|
||||
seed_file: Path,
|
||||
instance_id: str,
|
||||
user_data: str,
|
||||
):
|
||||
with tempfile.TemporaryDirectory() as _tmp:
|
||||
tmp = Path(_tmp)
|
||||
with (tmp / "meta-data").open("w") as f:
|
||||
f.write(f"instance-id: {instance_id}\nlocal-hostname: {instance_id}")
|
||||
with (tmp / "user-data").open("w") as f:
|
||||
f.write(user_data)
|
||||
|
||||
os.system(f"truncate --size 2M {seed_file}")
|
||||
os.system(f"mkfs.vfat -n cidata {seed_file}")
|
||||
os.system(f"mcopy -oi {seed_file} {tmp / "meta-data"} {tmp / "user-data"} ::")
|
Loading…
Reference in New Issue
Block a user