Commit b02e5a3e authored by Anael Beutot's avatar Anael Beutot
Browse files

Implemented actions for VMs.

Create/Start/Stop/Destroy/Undefine/Export/Suspend/Resume.
parent 2d763079
Loading
Loading
Loading
Loading
+62 −25
Original line number Diff line number Diff line
@@ -58,34 +58,75 @@ class Handler(HostHandler):
        """Get subtags."""
        global hypervisor

        domain = hypervisor.get_domain_by_name(sub_id)
        domain = hypervisor.domains.get(sub_id)

        if domain is None:
            logger.debug('Failed to find domain with name %s.', sub_id)
            return

        logger.debug('Get tags for sub object: %s', sub_id)
        return get_tags(domain, tags, noresolve_tags)

    def vm_define(self, name):
        pass
    def iter_vms(self, vm_names):
        """Utility function to iterate over VM objects using their names."""
        if vm_names is None:
            return
        # get_domain = self.hypervisor.domains.get
        get_domain = self.hypervisor.domains.get
        for name in vm_names:
            dom = get_domain(name)
            if dom is not None:
                yield dom

    def vm_define(self, data, format='xml'):
        logger.debug('VM define')
        if format != 'xml':
            raise NotImplementedError('Format not supported')

        try:
            return _libvirt.connection.defineXML(data).name()
        except libvirt.libvirtError:
            logger.exception('Error while creating domain')

    def vm_undefine(self, name):
        pass
        logger.debug('VM undefin')
        vm = self.hypervisor.domains.get(name)
        if vm is not None:
            vm.undefine()

    def vm_export(self, name, format='xml'):
        pass
        if format != 'xml':
            raise NotImplementedError('Format not supported')

        vm = self.hypervisor.domains.get(name)

        if vm is None:
            return

        return vm.lv_dom.XMLDesc(0)

    def vm_stop(self, vm_names=None, force=False):
        pass
        logger.debug('VM stop')
        for vm in self.iter_vms(vm_names):
            if force:
                vm.destroy()
            else:
                vm.stop()

    def vm_start(self, vm_names=None):
        pass
        logger.debug('VM start')
        for vm in self.iter_vms(vm_names):
            vm.start()

    def vm_suspend(self, vm_names=None):
        pass
        logger.debug('VM suspend')
        for vm in self.iter_vms(vm_names):
            vm.suspend()

    def vm_resume(self, vm_names=None):
        pass
        logger.debug('VM resume')
        for vm in self.iter_vms(vm_names):
            vm.resume()


class Hypervisor(object):
@@ -129,11 +170,11 @@ class Hypervisor(object):
        # find defined domains
        for dom_name in _libvirt.connection.listDefinedDomains():
            dom = _libvirt.connection.lookupByName(dom_name)
            self.domains[dom.UUID()] = VirtualMachine(dom, self)
            self.domains[dom.name()] = VirtualMachine(dom, self)
        # find started domains
        for dom_id in _libvirt.connection.listDomainsID():
            dom = _libvirt.connection.lookupByID(dom_id)
            self.domains[dom.UUID()] = VirtualMachine(dom, self)
            self.domains[dom.name()] = VirtualMachine(dom, self)

        logger.debug('Domains: %s', self.domains)

@@ -141,36 +182,32 @@ class Hypervisor(object):

    def callback(self, conn, dom, event, detail, opaque):
        """Callback for libvirt event loop."""
        logger.debug('Received event %s on domain %s, detail %s', event,
                     dom.name(), detail)

        event = EVENTS[event]

        if event == 'Added':
            vm = VirtualMachine(dom, self)
            self.domains[vm.uuid] = vm
            self.domains[vm.name] = vm
            self.sjproxy.register(vm.name, 'vm')
            logger.debug('Add domain: %s (%s)', vm.name, vm.uuid)
            logger.info('Add domain: %s (%s)', vm.name, vm.uuid)
        elif event == 'Removed':
            vm = self.domains.pop(dom.UUID())
            logger.debug('About to remove domain')
            vm = self.domains.pop(dom.name())
            self.sjproxy.unregister(vm.name)
            logger.debug('Delete domain: %s (%s)', vm.name, vm.uuid)
            logger.info('Delete domain: %s (%s)', vm.name, vm.uuid)
        elif event in ('Started', 'Suspended', 'Resumed', 'Stopped', 'Saved',
                       'Restored'):
            vm = self.domains.get(dom.UUID())
            vm = self.domains.get(dom.name())
            # sometimes libvirt sent a start event before a created event so be
            # careful
            if vm is not None:
                state = DOMAIN_STATES[dom.info()[0]]
                logger.debug('Domain change state from %s to %s', vm.state,
                logger.info('Domain change state from %s to %s', vm.state,
                             state)
                vm.state = state

    def get_domain_by_name(self, name):
        """Get a domain by name."""
        for d in self.domains.itervalues():
            if d.name == name:
                return d

        return None

    def _count_domain(self, filter=lambda d: True):
        count = 0

+14 −14
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ class VirtualMachine(object):

        #: UUID string of domain
        self.uuid = dom.UUIDString()
        self.name = dom.name()
        #: state of VM: started, stoped, paused
        self.state = STATE[dom.info()[0]]
        #: tags for this VM
@@ -54,29 +55,28 @@ class VirtualMachine(object):

        logger.debug('Virtual Machine tags: %s', self.tags)

    @property
    def name(self):
        return self.lv_dom.name()

    @property
    def lv_dom(self):
        """Libvirt domain instance."""
        return _libvirt.connection.lookupByUUIDString(self.uuid)

    def start():
        pass
    def start(self):
        self.lv_dom.create()

    def stop(self):
        self.lv_dom.shutdown()

    def stop():
        pass
    def suspend(self):
        self.lv_dom.suspend()

    def pause():
        pass
    def resume(self):
        self.lv_dom.resume()

    def define():
        pass
    def destroy(self):
        self.lv_dom.destroy()

    def undefined():
        pass
    def undefine(self):
        self.lv_dom.undefine()

    @property
    def disks(self):
+3 −2
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@ def arch(dom):
        logger.exception('Error while get Architecture tag')


def h():
    pass
def h(dom):
    """Name of the VM."""
    return dom.name


def cpu(dom):