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

DRBD handlers.

parent 52cb794d
Loading
Loading
Loading
Loading
+102 −2
Original line number Diff line number Diff line
@@ -15,8 +15,10 @@ from cloudcontrol.node.hypervisor.lib import (
    EventLoop as VirEventLoop,
)
from cloudcontrol.node.hypervisor.domains import VirtualMachine
from cloudcontrol.node.exc import UndefinedDomain, PoolStorageError
from cloudcontrol.node.hypervisor.jobs import ImportVolume, ExportVolume, TCPTunnel
from cloudcontrol.node.exc import UndefinedDomain, PoolStorageError, DRBDError
from cloudcontrol.node.hypervisor.jobs import (
    ImportVolume, ExportVolume, TCPTunnel, DRBD,
)


logger = logging.getLogger(__name__)
@@ -119,6 +121,12 @@ class Handler(HostHandler):
        self.main.reset_handler('tun_connect', self.tun_connect)
        self.main.reset_handler('tun_connect_hv', self.tun_connect_hv)
        self.main.reset_handler('tun_destroy', self.tun_destroy)
        self.main.reset_handler('drbd_setup', self.drbd_setup)
        self.main.reset_handler('drbd_connect', self.drbd_connect)
        self.main.reset_handler('drbd_role', self.drbd_role)
        self.main.reset_handler('drbd_takeover', self.drbd_takeover)
        self.main.reset_handler('drbd_sync_status', self.drbd_sync_status)
        self.main.reset_handler('drbd_shutdown', self.drbd_shutdown)

        # if everything went fine, unregister the timer
        self.timer.stop()
@@ -171,6 +179,12 @@ class Handler(HostHandler):
        self.main.remove_handler('tun_connect')
        self.main.remove_handler('tun_connect_hv')
        self.main.remove_handler('tun_destroy')
        self.main.remove_handler('drbd_setup')
        self.main.remove_handler('drbd_connect')
        self.main.remove_handler('drbd_role')
        self.main.remove_handler('drbd_takeover')
        self.main.remove_handler('drbd_sync_status')
        self.main.remove_handler('drbd_shutdown')
        # launch connection timer
        self.timer.start()

@@ -470,6 +484,92 @@ class Handler(HostHandler):
        self.main.job_manager.cancel(res['jid'])
        self.main.job_manager.remove(res['jid'])

    def drbd_setup(self, pool, name):
        """Create DRBD volumes.

        :param pool: storage pool
        :param name: storage volume name
        """
        pool = self.hypervisor.storage.get_storage(pool)
        if pool is None:
            raise DRBDError('Cannot setup DRBD: pool storage does not exist')
        elif pool.type != 'logical':
            raise DRBDError('Cannot setup DRBD: pool storage is not LVM')

        volume = pool.volumes.get(name)
        if volume is None:
            raise DRBDError('Cannot setup DRBD: volume does not exist')

        try:
            job = self.main.job_manager.create(DRBD, self.hypervisor.storage,
                                               pool, volume)
        except Exception:
            logger.exception('Error while creating DRBD job')
            raise

        job.setup()

        logger.debug('DRBD setup successfull')
        return dict(
            jid=job.id,
            port=job.drbd_port,
        )

    def drbd_connect(self, res, remote_res, remote_ip):
        """Set up DRBD in connect mode. (Wait for connection and try to connect
        to the remote peer.

        :param res: previous result of `drbd_setup` handler
        :param remote_res: result of remote `drbd_setup` handler
        :param remote_ip: IP of remote peer
        """
        job = self.main.job_manager.get(res['jid'])
        job.connect(remote_ip, remote_res['port'])
        job.wait_connection()

    def drbd_role(self, res, primary):
        """Set up DRBD role.

        :param res: previous result of `drbd_setup` handler
        :param bool primary: if True, set up in primary mode else secondary
        """
        job = self.main.job_manager.get(res['jid'])
        if primary:
            job.switch_primary()
        else:
            job.switch_secondary()

    def drbd_takeover(self, res, state):
        """Set up DRBD device as the VM disk. FIXME

        :param res: previous result of `drbd_setup` handler
        :param state: FIXME
        """
        job = self.main.job_manager.get(res['jid'])
        job.takeover()

    def drbd_sync_status(self, res):
        """Return synchronization status of a current DRBD job.

        :param res: previous result of `drbd_setup` handler
        """
        status = self.main.job_manager.get(res['jid']).status()
        result = dict(
            done=status['disk'] == 'UpToDate',
            completion=status['percent'],
        )
        logger.debug('DRBD status %s', result)
        return result

    def drbd_shutdown(self, res):
        """Destroy DRBD related block devices.

        :param res: previous result of `drbd_setup` handler
        """
        logger.debug('DRBD shutdown')
        job = self.main.job_manager.get(res['jid'])
        job.cleanup()


class Hypervisor(object):
    """Container for all hypervisor related state."""