respect upper-case filenames on cdfs

Change-Id: I483eefdadede583bd1d0d088a5e1c82295bf935a
This commit is contained in:
Fabian Schuetz 2023-06-22 15:38:02 +02:00
parent 912eea88ed
commit bc9fd003f5
3 changed files with 55 additions and 9 deletions

View File

@ -163,6 +163,8 @@ class GlobalOptions(conf_base.Options):
'cloudbaseinit.metadata.services.httpservice.HttpService',
'cloudbaseinit.metadata.services'
'.configdrive.ConfigDriveService',
'cloudbaseinit.metadata.services'
'.nocloudservice.NoCloudConfigDriveService',
'cloudbaseinit.metadata.services.ec2service.EC2Service',
'cloudbaseinit.metadata.services'
'.maasservice.MaaSHttpService',

View File

@ -49,10 +49,18 @@ class WindowsConfigDriveManager(base.BaseConfigDriveManager):
super(WindowsConfigDriveManager, self).__init__()
self._osutils = osutils_factory.get_os_utils()
def _meta_data_file_exists(self, drive, metadata_file):
metadata_file = os.path.join(drive, metadata_file)
def _to_cdfs_filename(self, name):
return name.upper().replace('-', '_')
if os.path.exists(metadata_file):
def _from_cdfs_filename(self, name):
return name.lower().replace('_', '-')
def _meta_data_file_exists(self, drive, metadata_file):
if self._osutils._has_cdfs(drive):
LOG.debug("Drive %s has cdfs. Respecting upper-case file names when looking for meta-data.")
metadata_file = self._to_cdfs_filename(metadata_file)
if os.path.exists(os.path.join(drive, metadata_file)):
return True
LOG.debug('%s not found', metadata_file)
@ -61,11 +69,16 @@ class WindowsConfigDriveManager(base.BaseConfigDriveManager):
def _check_for_config_drive(self, drive, required_drive_label,
metadata_file):
label = self._osutils.get_volume_label(drive)
if label and label.lower() == required_drive_label and \
self._meta_data_file_exists(drive, metadata_file):
if label and label.lower() == required_drive_label:
LOG.info('Config Drive found on %s', drive)
return True
LOG.debug("Looking for a Config Drive with label '%s' on '%s'. "
if self._meta_data_file_exists(drive, metadata_file):
LOG.info('Metadata file found on %s', drive)
return True
else:
LOG.info('Metadata file could not be found on %s', drive)
else:
LOG.info("Looking for a Config Drive with label '%s' on '%s'. "
"Found mismatching label '%s'.",
required_drive_label, drive, label)
return False
@ -155,6 +168,10 @@ class WindowsConfigDriveManager(base.BaseConfigDriveManager):
metadata_file):
os.rmdir(self.target_path)
shutil.copytree(drive_letter, self.target_path)
LOG.debug("Renaming local copy of cdfs file names to lower-case.")
for file in os.listdir():
shutil.move(os.path.join(self.target_path, file), os.path.join(self.target_path, self._from_cdfs_filename(file)))
return True
return False
@ -201,7 +218,7 @@ class WindowsConfigDriveManager(base.BaseConfigDriveManager):
if get_config_drive:
return get_config_drive(drive_label, metadata_file)
else:
LOG.debug("Irrelevant type %(type)s in %(location)s "
LOG.info("Irrelevant type %(type)s in %(location)s "
"location; skip",
{"type": cd_type, "location": cd_location})
except Exception as exc:
@ -218,7 +235,7 @@ class WindowsConfigDriveManager(base.BaseConfigDriveManager):
for cd_type, cd_location in itertools.product(searched_types,
searched_locations):
LOG.debug('Looking for Config Drive %(type)s in %(location)s '
LOG.info('Looking for Config Drive %(type)s in %(location)s '
'with expected label %(drive_label)s',
{"type": cd_type, "location": cd_location,
"drive_label": drive_label})

View File

@ -1480,6 +1480,23 @@ class WindowsUtils(base.BaseOSUtils):
# interpreter's bits
return struct.calcsize("P") == 8
def _has_cdfs(self, drive):
out,err,code = self.execute_powershell_command("wmic logicaldisk get deviceid,filesystem")
if code == 0:
lines = out.decode('ascii').replace('\r\r','').splitlines()[1:] # skip header line
for line in lines:
drive_fs = line.split()
LOG.info("Checking drive/fs combination %s/%s" % (drive_fs[0], drive_fs[1]))
if drive.startswith(drive_fs[0].upper()) and drive_fs[1].upper() == "CDFS":
return True
else:
raise exception.WindowsCloudbaseInitException(
"Could not determine file system of drive %s" % drive)
return False
def get_physical_disks(self):
physical_disks = []
@ -1673,6 +1690,16 @@ class WindowsUtils(base.BaseOSUtils):
else:
raise
def execute_powershell_command(self, command, sysnative=True):
base_dir = self._get_system_dir(sysnative)
powershell_path = os.path.join(base_dir,
'WindowsPowerShell\\v1.0\\'
'powershell.exe')
args = [powershell_path, "-command", command]
return self.execute_process(args, shell=False)
def execute_powershell_script(self, script_path, sysnative=True):
base_dir = self._get_system_dir(sysnative)
powershell_path = os.path.join(base_dir,