Skip to content
cli.py 36.9 KiB
Newer Older
from sjrpc.core import RpcError

from cloudcontrol.common.datastructures.orderedset import OrderedSet
from cloudcontrol.server.conf import CCConf
Antoine Millet's avatar
Antoine Millet committed
from cloudcontrol.server.exceptions import (ReservedTagError, BadObjectError,
Antoine Millet's avatar
Antoine Millet committed
                                            BadRoleError, NotConnectedAccountError,
from cloudcontrol.server.election import Elector
from cloudcontrol.server.repository import RepositoryOperationError
from cloudcontrol.server.handlers import listed, Reporter
from cloudcontrol.server.clients import Client, RegisteredCCHandler
from cloudcontrol.server.jobs import (ColdMigrationJob, HotMigrationJob,
                                      CloneJob)
from cloudcontrol.common.tql.db.tag import StaticTag

MIGRATION_TYPES = {'cold': ColdMigrationJob,
                   'hot': HotMigrationJob,}


class CliHandler(RegisteredCCHandler):
    """ Handler binded to the 'cli' role.
    .. currentmodule:: cloudcontrol.server.clients.cli

    .. autosummary::

       CliHandler.list
       CliHandler.start
       CliHandler.stop
       CliHandler.destroy
       CliHandler.pause
       CliHandler.resume
Antoine Millet's avatar
Antoine Millet committed
       CliHandler.disablevirtiocache
       CliHandler.autostart
       CliHandler.undefine
       CliHandler.passwd
       CliHandler.addaccount
       CliHandler.copyaccount
       CliHandler.addtag
       CliHandler.deltag
       CliHandler.tags
       CliHandler.delaccount
       CliHandler.close
       CliHandler.declose
       CliHandler.kill
Antoine Millet's avatar
Antoine Millet committed
       CliHandler.loadrights
       CliHandler.saverights
       CliHandler.execute
       CliHandler.shutdown
       CliHandler.jobs
       CliHandler.cancel
       CliHandler.purge
       CliHandler.attachment
Antoine Millet's avatar
Antoine Millet committed
       CliHandler.loadscript
       CliHandler.savescript
       CliHandler.delscript
       CliHandler.runscript
       CliHandler.loadplugin
       CliHandler.saveplugin
       CliHandler.delplugin
       CliHandler.installplugin
       CliHandler.uninstallplugin
       CliHandler.runplugin
       CliHandler.electiontypes
       CliHandler.election
       CliHandler.migrate
       CliHandler.clone
Antoine Millet's avatar
Antoine Millet committed
       CliHandler.console
       CliHandler.rshell
       CliHandler.rshell_resize
       CliHandler.rshell_wait
       CliHandler.forward
       CliHandler.dbstats
    def list(self, query, method='list'):
        """ List all objects registered on this instance.

        :param query: the query to select objects to show
        """

Antoine Millet's avatar
Antoine Millet committed
        self.logger.debug('Executed list function with query %s', query)
        objects = self.client.list(query, method=method)
        order = OrderedSet(['id'])
        #if tags is not None:
        #    order |= OrderedSet(tags)
        return {'objects': objects, 'order': list(order)}

    def _vm_action(self, query, method, *args, **kwargs):
        """ Do an action on a virtual machine.
        """
        errs = Reporter()
        # Search all hypervisors of selected vms:
        for vm in self.client.list(query, show=('r', 'h', 'p'), method=method):
            if vm['r'] != 'vm':
                errs.error(vm['id'], 'not a vm')
            else:
                hvclient = self.server.get_client(vm['p'])
                if hvclient is None:
                    errs.error(vm['id'], 'offline hypervisor')
                else:
                    try:
                        hvclient.vm_action(method, vm['h'], *args, **kwargs)
                    except Exception as err:
                        errs.error(vm['id'], str(err))
                    else:
                        errs.success(vm['id'], 'ok')
        return errs.get_dict()

    @listed
    def start(self, query):
        """ Start a virtual machine.
        """
        return self._vm_action(query, 'vm_start')

    @listed
    def stop(self, query):
        """ Stop a virtual machine.
        """
        return self._vm_action(query, 'vm_stop')

    @listed
    def destroy(self, query):
        """ Destroy (hard shutdown) a virtual machine.
        """
        return self._vm_action(query, 'vm_destroy')

    @listed
    def pause(self, query):
        """ Pause a virtual machine.
        """
        return self._vm_action(query, 'vm_suspend')

    @listed
    def resume(self, query):
        """ Resume a virtual machine.
        """
        return self._vm_action(query, 'vm_resume')

    @listed
    def disablevirtiocache(self, query):
        """ Set virtio cache to none on VMs disk devices.

        :param query: tql query
        """
        return self._vm_action(query, 'vm_disable_virtio_cache')

    @listed
    def autostart(self, query, flag):
        """ Set autostart flag on VMs.

        :param query: tql query
        :param bool flag: autostart value to set
        """
        return self._vm_action(query, 'vm_set_autostart', flag)

    @listed
    def undefine(self, query, delete_storage=True):
        """ Undefine selected virtual machines.

        :param query: the tql query to select objects.
        :param delete_storage: delete storage of vm.
        :return: a dict where key is the id of a selected object, and the value
            a tuple (errcode, message) where errcode is (success|error|warn) and
            message an error message or the output of the command in case of
            success.
        """

        objects = self.client.list(query, show=('r', 'p', 'h', 'disk*',), method='undefine')
        errs = Reporter()
        for obj in objects:
            if obj['r'] != 'vm':
                errs.error(obj['id'], 'bad role')
                continue
            try:
                hvcon = self.server.get_client(obj['p'])
            except KeyError:
                errs.error(obj['id'], 'hypervisor not connected')
            else:
                if delete_storage:
                    for disk in obj.get('disk', '').split():
                        pool = obj.get('disk%s_pool' % disk)
                        name = obj.get('disk%s_vol' % disk)
                        hvcon.proxy.vol_delete(pool, name)
                hvcon.proxy.vm_undefine(obj['h'])
                errs.success(obj['id'], 'vm undefined')

        return errs.get_dict()

Loading full blame...