Skip to content
cli.py 51.6 KiB
Newer Older
# This file is part of CloudControl.
#
# CloudControl is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# CloudControl is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with CloudControl.  If not, see <http://www.gnu.org/licenses/>.


from sjrpc.core import RpcError

from cloudcontrol.common.datastructures.orderedset import OrderedSet
from cloudcontrol.common.allocation.vmspec import expand_vmspec

from cloudcontrol.server.conf import CCConf
Antoine Millet's avatar
Antoine Millet committed
from cloudcontrol.server.exceptions import (ReservedTagError, BadRoleError,
                                            NotConnectedAccountError, CloneError)
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, KillClientJob, AllocationJob,
Antoine Millet's avatar
Antoine Millet committed
                                      MigrationJob, DiskCopyJob)
from cloudcontrol.server.db import SObject

from cloudcontrol.common.tql.db.tag import StaticTag

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


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

    .. autosummary::

       CliHandler.list
Antoine Millet's avatar
Antoine Millet committed
       CliHandler.wall
       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.shell
       CliHandler.resize
       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)}

Antoine Millet's avatar
Antoine Millet committed
    @listed
    def wall(self, message):
        """ Send a wall to all connected users.
        """

        self.client.check('wall')
        self.server.wall(self.client.login, message)

    @listed
    def loadmotd(self):
        """ Load and return the message of the day.
        """
        return self.server.load_motd()

    @listed
    def savemotd(self, motd):
        """ Save a new message of the day.
        """
        self.server.save_motd(motd)

    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[3:]):  # Strip the vm_ prefix
            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:
                        if method == 'vm_start':
                            hvclient.vm_action('vm_set_autostart', vm['h'], True)
                        elif method in ('vm_stop', 'vm_destroy'):
                            hvclient.vm_action('vm_set_autostart', vm['h'], False)
                        errs.success(vm['id'], 'ok')
        return errs.get_dict()

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

    @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 reset(self, query):
        """ Reset a virtual machine.
        """
        return self._vm_action(query, 'vm_reset')

Loading full blame...