Repository URL to install this package:
| 
      
        
        
        Version: 
        
         
          
          3.4.51  ▾
        
         | 
# Copyright 2012 Cloudbase Solutions Srl
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
"""
Management class for live migration VM operations.
"""
from os_win import utilsfactory
from oslo_log import log as logging
from oslo_utils import excutils
import nova.conf
from nova.objects import migrate_data as migrate_data_obj
from nova.virt.hyperv import block_device_manager
from nova.virt.hyperv import imagecache
from nova.virt.hyperv import pathutils
from nova.virt.hyperv import serialconsoleops
from nova.virt.hyperv import vmops
from nova.virt.hyperv import volumeops
LOG = logging.getLogger(__name__)
CONF = nova.conf.CONF
class LiveMigrationOps(object):
    def __init__(self):
        self._livemigrutils = utilsfactory.get_livemigrationutils()
        self._pathutils = pathutils.PathUtils()
        self._vmops = vmops.VMOps()
        self._volumeops = volumeops.VolumeOps()
        self._serial_console_ops = serialconsoleops.SerialConsoleOps()
        self._imagecache = imagecache.ImageCache()
        self._vmutils = utilsfactory.get_vmutils()
        self._block_dev_man = block_device_manager.BlockDeviceInfoManager()
    def live_migration(self, context, instance_ref, dest, post_method,
                       recover_method, block_migration=False,
                       migrate_data=None):
        LOG.debug("live_migration called", instance=instance_ref)
        instance_name = instance_ref["name"]
        if migrate_data and 'is_shared_instance_path' in migrate_data:
            shared_storage = migrate_data.is_shared_instance_path
        else:
            shared_storage = (
                self._pathutils.check_remote_instances_dir_shared(dest))
            if migrate_data:
                migrate_data.is_shared_instance_path = shared_storage
            else:
                migrate_data = migrate_data_obj.HyperVLiveMigrateData(
                    is_shared_instance_path=shared_storage)
        try:
            # We must make sure that the console log workers are stopped,
            # otherwise we won't be able to delete / move VM log files.
            self._serial_console_ops.stop_console_handler(instance_name)
            if not shared_storage:
                self._pathutils.copy_vm_console_logs(instance_name, dest)
                self._vmops.copy_vm_dvd_disks(instance_name, dest)
            self._livemigrutils.live_migrate_vm(instance_name,
                                                dest)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.debug("Calling live migration recover_method "
                          "for instance: %s", instance_name)
                recover_method(context, instance_ref, dest, block_migration,
                               migrate_data)
        LOG.debug("Calling live migration post_method for instance: %s",
                  instance_name)
        post_method(context, instance_ref, dest,
                    block_migration, migrate_data)
    def pre_live_migration(self, context, instance, block_device_info,
                           network_info):
        LOG.debug("pre_live_migration called", instance=instance)
        self._livemigrutils.check_live_migration_config()
        if CONF.use_cow_images:
            boot_from_volume = self._block_dev_man.is_boot_from_volume(
                block_device_info)
            if not boot_from_volume and instance.image_ref:
                self._imagecache.get_cached_image(context, instance)
        self._volumeops.initialize_volumes_connection(block_device_info)
        disk_path_mapping = self._volumeops.get_disk_path_mapping(
            block_device_info)
        if disk_path_mapping:
            # We create a planned VM, ensuring that volumes will remain
            # attached after the VM is migrated.
            self._livemigrutils.create_planned_vm(instance.name,
                                                  instance.host,
                                                  disk_path_mapping)
    def post_live_migration(self, context, instance, block_device_info,
                            migrate_data):
        self._volumeops.disconnect_volumes(block_device_info)
        if not migrate_data.is_shared_instance_path:
            self._pathutils.get_instance_dir(instance.name,
                                             create_dir=False,
                                             remove_dir=True)
    def post_live_migration_at_destination(self, ctxt, instance_ref,
                                           network_info, block_migration):
        LOG.debug("post_live_migration_at_destination called",
                  instance=instance_ref)
    def check_can_live_migrate_destination(self, ctxt, instance_ref,
                                           src_compute_info, dst_compute_info,
                                           block_migration=False,
                                           disk_over_commit=False):
        LOG.debug("check_can_live_migrate_destination called",
                  instance=instance_ref)
        migrate_data = migrate_data_obj.HyperVLiveMigrateData()
        migrate_data.is_shared_instance_path = (
            self._pathutils.check_remote_instances_dir_shared(
                instance_ref.host))
        return migrate_data
    def cleanup_live_migration_destination_check(self, ctxt, dest_check_data):
        LOG.debug("cleanup_live_migration_destination_check called")
    def check_can_live_migrate_source(self, ctxt, instance_ref,
                                      dest_check_data):
        LOG.debug("check_can_live_migrate_source called", instance_ref)
        return dest_check_data