Check all configdrive types if one errors out

By default, all config drive types are checked.
But if somehow, the implementation of each type
fails, the metadata service errors out and does not
check for the next type.

The issue was reported here:
https://ask.cloudbase.it/question/3094/windows-server-2016-extendvolumespluginp-doesnt-work/

In that case, in the method is_vfat_drive:
  match = VOLUME_LABEL_REGEX.search(out)
  return match.group(1) in CONFIG_DRIVE_LABELS

if match value is None, the return line throws an error:
  AttributeError: 'NoneType' object has no attribute 'group'

To make sure that no other implementation will bubble up
the error, we catch the error in the config_drive metadata
service.

Catching the error will allow that the next config_drive
type will be checked for metadata.

Change-Id: I0d9967ec6a81214c7d78be667cffa4a98758587a
This commit is contained in:
Adrian Vladu 2019-10-25 16:52:03 +03:00
parent 65680437e9
commit 5dba5c60f6
4 changed files with 36 additions and 9 deletions

View File

@ -176,14 +176,20 @@ class WindowsConfigDriveManager(base.BaseConfigDriveManager):
return False
def _get_config_drive_files(self, cd_type, cd_location):
get_config_drive = self.config_drive_type_location.get(
"{}_{}".format(cd_location, cd_type))
if get_config_drive:
return get_config_drive()
else:
LOG.debug("Irrelevant type %(type)s in %(location)s location; "
"skip",
{"type": cd_type, "location": cd_location})
try:
get_config_drive = self.config_drive_type_location.get(
"{}_{}".format(cd_location, cd_type))
if get_config_drive:
return get_config_drive()
else:
LOG.debug("Irrelevant type %(type)s in %(location)s "
"location; skip",
{"type": cd_type, "location": cd_location})
except Exception as exc:
LOG.warning("Config type %(type)s not found in %(loc)s "
"location; Error: '%(err)r'",
{"type": cd_type, "loc": cd_location, "err": exc})
return False
def get_config_drive_files(self, searched_types=None,

View File

@ -394,6 +394,14 @@ class TestWindowsConfigDriveManager(unittest.TestCase):
self._test__get_config_drive_files(
"iso", "cdrom", func)
@mock.patch('cloudbaseinit.metadata.services.osconfigdrive.windows.'
'WindowsConfigDriveManager.'
'_get_config_drive_from_cdrom_drive')
def test__get_config_drive_files_cdrom_iso_failed(self, func):
func.side_effect = Exception
self._test__get_config_drive_files(
"iso", "cdrom", func, found=False)
def test__get_config_drive_files_cdrom_vfat(self):
self._test__get_config_drive_files(
"vfat", "cdrom", None)

View File

@ -105,6 +105,19 @@ class TestVfat(unittest.TestCase):
expected_logging=expected_logging,
expected_response=expected_response)
def test_is_vfat_drive_with_wrong_label(self):
mock_out = b"Not volu label \r\n"
expected_logging = [
"Obtained label information for drive %r: %r"
% (mock.sentinel.drive, mock_out)
]
execute_process_value = (mock_out, None, 0)
expected_response = False
self._test_is_vfat_drive(execute_process_value=execute_process_value,
expected_logging=expected_logging,
expected_response=expected_response)
@testutils.ConfPatcher('mtools_path', 'mtools_path')
@mock.patch('os.chdir')
def test_copy(self, mock_os_chdir):

View File

@ -50,7 +50,7 @@ def is_vfat_drive(osutils, drive_path):
LOG.debug("Obtained label information for drive %r: %r", drive_path, out)
out = out.decode().strip()
match = VOLUME_LABEL_REGEX.search(out)
return match.group(1) in CONFIG_DRIVE_LABELS
return match.group(1) in CONFIG_DRIVE_LABELS if match else False
def copy_from_vfat_drive(osutils, drive_path, target_path):