Skip to content

Commit f243272

Browse files
Extract _install_dism_drivers helper
Signed-off-by: Mihaela Balutoiu <mbalutoiu@cloudbasesolutions.com>
1 parent 187a30c commit f243272

2 files changed

Lines changed: 76 additions & 18 deletions

File tree

coriolis/osmorphing/windows.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -801,27 +801,37 @@ def _add_virtio_drivers(self):
801801
virtio_drive, d, virtio_dir, arch) for d in drivers
802802
]
803803

804-
sid = self._get_sid()
805-
# Fails on Nano Server without explicitly granting permissions
806-
file_repo_path = (
807-
"%sWindows\\System32\\DriverStore\\FileRepository" %
808-
self._os_root_dir
809-
)
810-
self._grant_permissions(file_repo_path, "*%s" % sid)
811-
try:
812-
for driver_path in driver_paths:
813-
if self._conn.test_path(driver_path):
814-
self._add_dism_driver(driver_path)
815-
else:
816-
LOG.warn(
817-
"Could not locate driver dir '%s', skipping.",
818-
driver_path
819-
)
820-
finally:
821-
self._revoke_permissions(file_repo_path, "*%s" % sid)
804+
self._install_dism_drivers(driver_paths)
822805
finally:
823806
self._dismount_disk_image(virtio_iso_path)
824807

808+
def _install_dism_drivers(self, driver_paths):
809+
"""Installs the drivers located at the given paths into the offline
810+
Windows image via DISM.
811+
812+
Temporarily grants permissions on the DriverStore FileRepository
813+
(required on Nano Server) for the duration of the installation.
814+
Paths which do not exist are skipped with a warning.
815+
"""
816+
sid = self._get_sid()
817+
# Fails on Nano Server without explicitly granting permissions
818+
file_repo_path = (
819+
"%sWindows\\System32\\DriverStore\\FileRepository" %
820+
self._os_root_dir
821+
)
822+
self._grant_permissions(file_repo_path, "*%s" % sid)
823+
try:
824+
for driver_path in driver_paths:
825+
if self._conn.test_path(driver_path):
826+
self._add_dism_driver(driver_path)
827+
else:
828+
LOG.warning(
829+
"Could not locate driver dir '%s', skipping.",
830+
driver_path
831+
)
832+
finally:
833+
self._revoke_permissions(file_repo_path, "*%s" % sid)
834+
825835
def get_packages(self):
826836
return [], []
827837

coriolis/tests/osmorphing/test_windows.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,3 +1217,51 @@ def test_add_virtio_drivers_missing_iso_url(
12171217

12181218
self.morphing_tools._conn.download_file.assert_not_called()
12191219
mock_mount_disk_image.assert_not_called()
1220+
1221+
@mock.patch.object(windows.BaseWindowsMorphingTools, "_get_sid")
1222+
@mock.patch.object(windows.BaseWindowsMorphingTools, "_grant_permissions")
1223+
@mock.patch.object(windows.BaseWindowsMorphingTools, "_add_dism_driver")
1224+
@mock.patch.object(windows.BaseWindowsMorphingTools, "_revoke_permissions")
1225+
def test_install_dism_drivers(
1226+
self, mock_revoke_permissions, mock_add_dism_driver,
1227+
mock_grant_permissions, mock_get_sid):
1228+
null_sid = "S-1-0-0"
1229+
mock_get_sid.return_value = null_sid
1230+
1231+
existing_driver_path = "e:\\NetKVM\\w11\\amd64"
1232+
missing_driver_path = "e:\\Missing\\w11\\amd64"
1233+
driver_paths = [existing_driver_path, missing_driver_path]
1234+
self.conn.test_path.side_effect = lambda path: (
1235+
path == existing_driver_path)
1236+
1237+
self.morphing_tools._install_dism_drivers(driver_paths)
1238+
1239+
exp_repo_path = "C:\\Windows\\System32\\DriverStore\\FileRepository"
1240+
mock_grant_permissions.assert_called_once_with(
1241+
exp_repo_path, f"*{null_sid}")
1242+
mock_revoke_permissions.assert_called_once_with(
1243+
exp_repo_path, f"*{null_sid}")
1244+
# Only the existing driver path should be installed:
1245+
mock_add_dism_driver.assert_called_once_with(existing_driver_path)
1246+
1247+
@mock.patch.object(windows.BaseWindowsMorphingTools, "_get_sid")
1248+
@mock.patch.object(windows.BaseWindowsMorphingTools, "_grant_permissions")
1249+
@mock.patch.object(windows.BaseWindowsMorphingTools, "_add_dism_driver")
1250+
@mock.patch.object(windows.BaseWindowsMorphingTools, "_revoke_permissions")
1251+
def test_install_dism_drivers_revokes_on_failure(
1252+
self, mock_revoke_permissions, mock_add_dism_driver,
1253+
mock_grant_permissions, mock_get_sid):
1254+
null_sid = "S-1-0-0"
1255+
mock_get_sid.return_value = null_sid
1256+
mock_add_dism_driver.side_effect = IOError
1257+
1258+
self.assertRaises(
1259+
IOError,
1260+
self.morphing_tools._install_dism_drivers, ["e:\\NetKVM"])
1261+
1262+
exp_repo_path = "C:\\Windows\\System32\\DriverStore\\FileRepository"
1263+
mock_grant_permissions.assert_called_once_with(
1264+
exp_repo_path, f"*{null_sid}")
1265+
# Permissions must be revoked even if driver installation fails:
1266+
mock_revoke_permissions.assert_called_once_with(
1267+
exp_repo_path, f"*{null_sid}")

0 commit comments

Comments
 (0)