Skip to content

Commit

Permalink
Add Virtual Machines Management(VMM)
Browse files Browse the repository at this point in the history
Signed-off-by: Yongxue Hong <[email protected]>
  • Loading branch information
YongxueHong committed Jul 27, 2023
1 parent 47fd481 commit 467987f
Show file tree
Hide file tree
Showing 13 changed files with 694 additions and 0 deletions.
64 changes: 64 additions & 0 deletions virttest/vt_agent/instance_drivers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import json
import signal
from functools import partial

import six

from abc import ABCMeta
from abc import abstractmethod

import aexpect

from . import qemu
from . import libvirt


@six.add_metaclass(ABCMeta)
class InstanceDriver(object):
def __init__(self, kind, spec):
self._kind = kind
self._params = json.loads(spec)
self._process = None
self._cmd = None
self._devices = None

@abstractmethod
def create_devices(self):
raise NotImplementedError

@abstractmethod
def make_cmdline(self):
raise NotImplementedError

def run_cmdline(self, command, termination_func=None, output_func=None,
output_prefix="", timeout=1.0, auto_close=True, pass_fds=(),
encoding=None):
self._process = aexpect.run_tail(
command, termination_func, output_func, output_prefix,
timeout, auto_close, pass_fds, encoding)

def get_pid(self):
return self._process.get_pid()

def get_status(self):
return self._process.get_status()

def get_output(self):
return self._process.get_output()

def is_alive(self):
return self._process.is_alive()

def kill(self, sig=signal.SIGKILL):
self._process.kill(sig)


def get_instance_driver(kind, spec):
instance_drivers = {
"qemu": qemu.QemuInstanceDriver(spec),
"libvirt": libvirt.LibvirtInstanceDriver(spec),
}

if kind not in instance_drivers:
raise OSError("No support the %s instance driver" % kind)
return instance_drivers.get(kind, spec)
12 changes: 12 additions & 0 deletions virttest/vt_agent/instance_drivers/libvirt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from . import InstanceDriver


class LibvirtInstanceDriver(InstanceDriver):
def __init__(self, spec):
super(LibvirtInstanceDriver, self).__init__("libvirt", spec)

def create_devices(self):
pass

def make_cmdline(self):
pass
56 changes: 56 additions & 0 deletions virttest/vt_agent/instance_drivers/qemu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import logging

from virttest.qemu_devices import qdevices, qcontainer

from . import InstanceDriver

LOG = logging.getLogger("avocado.agent." + __name__)


class QemuInstanceDriver(InstanceDriver):
def __init__(self, spec):
super(QemuInstanceDriver, self).__init__("qemu", spec)

def create_devices(self):

def _add_name(name):
return " -name '%s'" % name

def _process_sandbox(devices, action):
if action == "add":
if devices.has_option("sandbox"):
return " -sandbox on "
elif action == "rem":
if devices.has_option("sandbox"):
return " -sandbox off "

qemu_binary = "/usr/libexec/qemu-kvm"
name = self._params.get("name")
self._devices = qcontainer.DevContainer(qemu_binary, name)
StrDev = qdevices.QStringDevice

self._devices.insert(StrDev('qemu', cmdline=qemu_binary))

qemu_preconfig = self._params.get("qemu_preconfig")
if qemu_preconfig:
self._devices.insert(StrDev('preconfig', cmdline="--preconfig"))

self._devices.insert(StrDev('vmname', cmdline=_add_name(name)))

qemu_sandbox = self._params.get("qemu_sandbox")
if qemu_sandbox == "on":
self._devices.insert(
StrDev('qemu_sandbox', cmdline=_process_sandbox(self._devices, "add")))
elif qemu_sandbox == "off":
self.devices.insert(
StrDev('qemu_sandbox', cmdline=_process_sandbox(self._devices, "rem")))

defaults = self._params.get("defaults", "no")
if self._devices.has_option("nodefaults") and defaults != "yes":
self._devices.insert(StrDev('nodefaults', cmdline=" -nodefaults"))

return self._devices

def make_cmdline(self):
self._cmd = self._devices.cmdline()
return self._cmd
Empty file.
Empty file.
88 changes: 88 additions & 0 deletions virttest/vt_agent/managers/vmm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import json
import logging

from .. import instance_drivers

LOG = logging.getLogger("avocado.agent." + __name__)


class VMMError(Exception):
pass


class VirtualMachinesManager(object):
def __init__(self):
self._filename = "/var/instances"
self._instances = self._load()

@property
def instances(self):
return self._load()

def _dump_instances(self):
with open(self._filename, "w") as details:
json.dump(self._instances, details)

def _load_instances(self):
try:
with open(self._filename, 'r') as instances:
return json.load(instances)
except Exception:
return {}

def _save(self):
self._dump_instances()

def _load(self):
return self._load_instances()

def register_instance(self, name, info):
if name in self._instances:
LOG.error("The instance %s is already registered.", name)
return False
self._instances[name] = info
self._save()
return True

def unregister_instance(self, name):
if name in self._instances:
del self._instances[name]
self._save()
return True
LOG.error("The instance %s is not registered" % name)
return False

def get_instance(self, name):
return self._instances.get(name)

def update_instance(self, name, info):
self._instances.get(name).update(info)
self._save()

@staticmethod
def build_instance(driver_kind, spec):
instance_info = {}
instance_driver = instance_drivers.get_instance_driver(driver_kind, spec)
instance_info["devices"] = instance_driver.create_devices()
instance_info["driver"] = instance_driver
return instance_info

def run_instance(self, instance_id):
instance_info = self.get_instance(instance_id)
instance_driver = instance_info["driver"]
cmdline = instance_driver.make_cmdline()
instance_info["cmdline"] = cmdline
process = instance_driver.run_cmdline(cmdline)
instance_info["process"] = process

def stop_instance(self, instance_id):
instance_info = self.get_instance(instance_id)
instance_driver = instance_info["driver"]
if instance_driver.is_alive():
pass

def get_instance_status(self, instance_id):
pass

def get_instance_pid(self, instance_id):
pass
38 changes: 38 additions & 0 deletions virttest/vt_agent/services/virt/vmm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import logging

from ...managers import vmm

VMM = vmm.VirtualMachinesManager()

LOG = logging.getLogger('avocado.service.' + __name__)


def build_instance(instance_id, instance_driver, instance_spec):
if instance_id in VMM.instances:
raise vmm.VMMError(f"The instance {instance_id} was registered.")

LOG.info(f"Build the instance {instance_id} by {instance_spec}")

instance_info = VMM.build_instance(instance_driver, instance_spec)
VMM.register_instance(instance_id, instance_info)


def run_instance(instance_id):
VMM.run_instance(instance_id)


def stop_instance(instance_id):
VMM.stop_instance(instance_id)


def get_instance_status(instance_id):
return VMM.get_instance_status(instance_id)


def get_instance_pid(instance_id):
return VMM.get_instance_pid(instance_id)


def get_instance_monitors(instance_id):
return []

Empty file added virttest/vt_vmm/__init__.py
Empty file.
Loading

0 comments on commit 467987f

Please sign in to comment.