Commit 8aad7a20 authored by Antoine Millet's avatar Antoine Millet
Browse files

Implemented new-gen VM migrations

parent e157378d
Loading
Loading
Loading
Loading
+51 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ from cloudcontrol.node.exc import (
    UndefinedDomain, DRBDError, PoolStorageError
)
from cloudcontrol.node.hypervisor.jobs import (
    ImportVolume, ExportVolume, TCPTunnel, DRBD,
    ImportVolume, ExportVolume, TCPTunnel, DRBD
)
from cloudcontrol.node.utils import execute

@@ -318,6 +318,56 @@ class Handler(HostHandler):
            logger.error(msg)
            raise UndefinedDomain(msg)

    @libvirt_handler
    def vm_reset(self, name):
        logger.debug('VM reset %s', name)
        try:
            self.hypervisor.domains[name].reset()
        except libvirt.libvirtError:
            logger.exception('Error while resetting VM %s', name)
            raise
        except KeyError:
            msg = 'Cannot reset VM %s because it is not defined' % name
            logger.error(msg)
            raise UndefinedDomain(msg)

    @libvirt_handler
    def vm_cycle(self, name):
        logger.debug('VM cycle %s', name)
        try:
            self.hypervisor.domains[name].destroy()
            time.sleep(1)
            self.hypervisor.domains[name].start()
        except libvirt.libvirtError:
            logger.exception('Error while cycle VM %s', name)
            raise
        except KeyError:
            msg = 'Cannot cycle VM %s because it is not defined' % name
            logger.error(msg)
            raise UndefinedDomain(msg)

    @libvirt_handler
    def vm_change_title(self, name, new_title):
        logger.debug('VM edit title %s', name)
        try:
            self.hypervisor.domains[name].title = new_title
        except libvirt.libvirtError:
            logger.exception('Error while changing VM title %s', name)
            raise
        except KeyError:
            msg = 'Cannot change title open VM %s because it is not defined' % name
            logger.error(msg)
            raise UndefinedDomain(msg)

    @libvirt_handler
    def vm_migrate(self, name, dest_uri, live=False):
        try:
            dom = self.hypervisor.domains[name]
        except KeyError:
            raise UndefinedDomain('Cannot migrate VM %s because it is not defined', name)

        dom.migrate(dest_uri, live=live)

    @libvirt_handler
    def vm_migrate_tunneled(self, name, tun_res, migtun_res, unsafe=False,
                            timeout=60.):
+24 −0
Original line number Diff line number Diff line
@@ -512,3 +512,27 @@ class VirtualMachine(object):

        self.from_tunnel = None
        self.from_stream = None

    def migrate(self, dest_uri, live=False):
        volumes = list(self.iter_disks())  # Store volumes for future cleanup

        flags = (libvirt.VIR_MIGRATE_PEER2PEER
                 | libvirt.VIR_MIGRATE_PERSIST_DEST
                 | libvirt.VIR_MIGRATE_UNDEFINE_SOURCE)

        if live:
            flags |= (libvirt.VIR_MIGRATE_LIVE
                      | libvirt.VIR_MIGRATE_NON_SHARED_DISK
                      | libvirt.VIR_MIGRATE_AUTO_CONVERGE)
        else:
            flags |= libvirt.VIR_MIGRATE_OFFLINE

        error = self.lv_dom.migrateToURI3(dest_uri, {}, flags)

        if error:
            raise RuntimeError('Unable to migrate VM')
        else:
            if live:  # In live mode, we are responsible for source volume cleaning
                for volume in volumes:
                    # Delete VM storage after migration success:
                    self.hypervisor.storage.delete_volume(volume.storage, volume.name)
+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ from xml.etree import ElementTree as et

import pyev

from cloudcontrol.common.jobs import Job

from cloudcontrol.node.exc import TunnelError, DRBDAllocationError, DRBDError
from cloudcontrol.node.jobs import BaseIOJob, ForkedJob
from cloudcontrol.node.utils import SocketBuffer, subproc_call, Singleton