diff --git a/cloudbaseinit/constant.py b/cloudbaseinit/constant.py index 3a7b772a..5ca4e844 100644 --- a/cloudbaseinit/constant.py +++ b/cloudbaseinit/constant.py @@ -16,6 +16,7 @@ CD_TYPES = { "vfat", # Visible device (with partition table). "iso", # "Raw" format containing ISO bytes. + "files" # Set of files. Considers a number of files in directory as a pseudo-config-drive. } CD_LOCATIONS = { # Look into optical devices. Only an ISO format could be @@ -27,6 +28,8 @@ CD_LOCATIONS = { # Search through partitions for raw ISO content or through volumes # containing configuration drive's content. "partition", + # Search for configuration drive's content in %PROGRAMDATA%\{config drive label} directory + "directory" } POLICY_IGNORE_ALL_FAILURES = "ignoreallfailures" diff --git a/cloudbaseinit/metadata/services/osconfigdrive/windows.py b/cloudbaseinit/metadata/services/osconfigdrive/windows.py index a9163832..bb27b1a1 100644 --- a/cloudbaseinit/metadata/services/osconfigdrive/windows.py +++ b/cloudbaseinit/metadata/services/osconfigdrive/windows.py @@ -228,6 +228,16 @@ class WindowsConfigDriveManager(base.BaseConfigDriveManager): return False + def _get_config_drive_from_directory(self, drive_label, metadata_file): + """Look through directory %PROGRAMDTA%\drive_label for config drive files.""" + sourcefilespath = os.environ["PROGRAMDATA"] + f"\{drive_label}" + if self._meta_data_file_exists(sourcefilespath, metadata_file): + LOG.info('Config Drive found on %s', sourcefilespath) + os.rmdir(self.target_path) + shutil.copytree(sourcefilespath, self.target_path) + return True + return False + @property def config_drive_type_location(self): return { @@ -236,4 +246,5 @@ class WindowsConfigDriveManager(base.BaseConfigDriveManager): "hdd_vfat": self._get_config_drive_from_vfat, "partition_iso": self._get_config_drive_from_partition, "partition_vfat": self._get_config_drive_from_volume, + "directory_files": self._get_config_drive_from_directory } diff --git a/cloudbaseinit/tests/metadata/services/osconfigdrive/test_windows.py b/cloudbaseinit/tests/metadata/services/osconfigdrive/test_windows.py index efc6a186..844433a0 100644 --- a/cloudbaseinit/tests/metadata/services/osconfigdrive/test_windows.py +++ b/cloudbaseinit/tests/metadata/services/osconfigdrive/test_windows.py @@ -468,13 +468,20 @@ class TestWindowsConfigDriveManager(unittest.TestCase): self._test__get_config_drive_files( "vfat", "partition", func) + @mock.patch('cloudbaseinit.metadata.services.osconfigdrive.windows.' + 'WindowsConfigDriveManager.' + '_get_config_drive_from_directory') + def test__get_config_drive_files_directory_files(self, func): + self._test__get_config_drive_files( + "files", "directory", func) + @mock.patch('cloudbaseinit.metadata.services.osconfigdrive.windows.' 'WindowsConfigDriveManager.' '_get_config_drive_files') def _test_get_config_drive_files(self, mock_get_config_drive_files, found=True): - check_types = ["iso", "vfat"] if found else [] - check_locations = ["cdrom", "hdd", "partition"] + check_types = ["iso", "vfat", "files"] if found else [] + check_locations = ["cdrom", "hdd", "partition", "directory"] product = list(itertools.product(check_types, check_locations, [self._fake_label])) product_calls = [mock.call(self._fake_label, self._fake_metadata_file, diff --git a/doc/source/services.rst b/doc/source/services.rst index a38b6438..7c9a776d 100644 --- a/doc/source/services.rst +++ b/doc/source/services.rst @@ -126,7 +126,8 @@ NoCloudConfigDriveService is similar to OpenStack config drive metadata in terms the medium on which the data is provided (as an attached ISO, partition or disk) and similar to the EC2 metadata in terms of how the metadata files are named and structured. -The metadata is provided on a config-drive (vfat or iso9660) with the label cidata or CIDATA. +The metadata is provided on a config-drive (vfat or iso9660) with the label cidata or CIDATA, +or in %PROGRAMDATA%\CIDATA directory. The folder structure for NoCloud is: @@ -150,8 +151,8 @@ Config options for `config_drive` section: * raw_hdd (bool: True) * cdrom (bool: True) * vfat (bool: True) - * types (list: ["vfat", "iso"]) - * locations (list: ["cdrom", "hdd", "partition"]) + * types (list: ["vfat", "iso", "files"]) + * locations (list: ["cdrom", "hdd", "partition", "directory"]) Example metadata: