Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Virtual Machines Management(VMM) #3728

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading