propagate OSError to MigrationPreCheckError

OSError will lead instance to ERROR state, change to
MigrationPreCheckError will make the instance status not changed.

Also, modify some test cases to make unit test easier

Closes-Bug: 1694636

Change-Id: I3286c32ca205ffd2d5d1aaab88cc96699476e410
(cherry picked from commit cb565d9bad)
This commit is contained in:
jichenjc 2017-08-19 05:48:30 +08:00
parent 932cf9eee6
commit ae9860774e
4 changed files with 46 additions and 7 deletions

View File

@ -17,6 +17,7 @@ import mock
from os_win import exceptions as os_win_exc
from oslo_config import cfg
from nova import exception
from nova.objects import migrate_data as migrate_data_obj
from nova.tests.unit import fake_instance
from nova.tests.unit.virt.hyperv import test_base
@ -227,3 +228,13 @@ class LiveMigrationOpsTestCase(test_base.HyperVBaseTestCase):
block_migration=mock.sentinel.BLOCK_INFO)
mock_plug_vifs.assert_called_once_with(mock.sentinel.instance,
mock.sentinel.NET_INFO)
def test_check_can_live_migrate_destination_exception(self):
mock_instance = fake_instance.fake_instance_obj(self.context)
mock_check = self._pathutils.check_remote_instances_dir_shared
mock_check.side_effect = exception.FileNotFound(file_path='C:\\baddir')
self.assertRaises(
exception.MigrationPreCheckError,
self._livemigrops.check_can_live_migrate_destination,
mock.sentinel.context, mock_instance, mock.sentinel.src_comp_info,
mock.sentinel.dest_comp_info)

View File

@ -196,6 +196,20 @@ class PathUtilsTestCase(test_base.HyperVBaseTestCase):
mock_named_tempfile.assert_called_once_with(dir=fake_dest_dir)
mock_exists.assert_called_once_with(expected_src_tmp_path)
@mock.patch('os.path.exists')
@mock.patch('tempfile.NamedTemporaryFile')
def test_check_dirs_shared_storage_exception(self, mock_named_tempfile,
mock_exists):
fake_src_dir = 'fake_src_dir'
fake_dest_dir = 'fake_dest_dir'
mock_exists.return_value = True
mock_named_tempfile.side_effect = OSError('not exist')
self.assertRaises(exception.FileNotFound,
self._pathutils.check_dirs_shared_storage,
fake_src_dir, fake_dest_dir)
@mock.patch.object(pathutils.PathUtils, 'check_dirs_shared_storage')
@mock.patch.object(pathutils.PathUtils, 'get_instances_dir')
def test_check_remote_instances_shared(self, mock_get_instances_dir,

View File

@ -22,6 +22,8 @@ from oslo_log import log as logging
from oslo_utils import excutils
import nova.conf
from nova import exception
from nova.i18n import _
from nova.objects import migrate_data as migrate_data_obj
from nova.virt.hyperv import block_device_manager
from nova.virt.hyperv import imagecache
@ -129,9 +131,16 @@ class LiveMigrationOps(object):
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))
try:
# The remote instance dir might not exist or other issue to cause
# OSError in check_remote_instances_dir_shared function
migrate_data.is_shared_instance_path = (
self._pathutils.check_remote_instances_dir_shared(
instance_ref.host))
except exception.FileNotFound as e:
reason = _('Unavailable instance location: %s') % e
raise exception.MigrationPreCheckError(reason=reason)
return migrate_data
def cleanup_live_migration_destination_check(self, ctxt, dest_check_data):

View File

@ -14,6 +14,7 @@
# under the License.
import os
import six
import tempfile
import time
@ -181,11 +182,15 @@ class PathUtils(pathutils.PathUtils):
LOG.debug("Checking if %(src_dir)s and %(dest_dir)s point "
"to the same location.",
dict(src_dir=src_dir, dest_dir=dest_dir))
with tempfile.NamedTemporaryFile(dir=dest_dir) as tmp_file:
src_path = os.path.join(src_dir,
os.path.basename(tmp_file.name))
shared_storage = os.path.exists(src_path)
try:
with tempfile.NamedTemporaryFile(dir=dest_dir) as tmp_file:
src_path = os.path.join(src_dir,
os.path.basename(tmp_file.name))
shared_storage = os.path.exists(src_path)
except OSError as e:
raise exception.FileNotFound(six.text_type(e))
return shared_storage
def check_remote_instances_dir_shared(self, dest):