diff --git a/coriolis/osmorphing/windows.py b/coriolis/osmorphing/windows.py index e87d565d..a28a11e5 100644 --- a/coriolis/osmorphing/windows.py +++ b/coriolis/osmorphing/windows.py @@ -186,6 +186,36 @@ Invoke-Main $NICS_INFO $IPS_INFO """ # noqa +EXTRACT_TEMPLATE = """ +function Extract-Path { + [CmdletBinding()] + Param( + [Parameter(Mandatory=$true)] + [String]$source, + + [Parameter(Mandatory=$true)] + [String]$destination + ) + try { + [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null + $zip = [System.IO.Compression.ZipFile]::OpenRead($source) + foreach ($entry in $zip.Entries) { + $targetPath = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($destination, $entry.FullName)) + if ($entry.FullName -match '[\\/]$') { + if (!(Test-Path $targetPath)) { New-Item -ItemType Directory -Force -Path $targetPath | Out-Null } + } else { + $parentPath = Split-Path $targetPath + if (!(Test-Path $parentPath)) { New-Item -ItemType Directory -Force -Path $parentPath | Out-Null } + [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $targetPath, $true) + } + } + } finally { + if ($zip) { $zip.Dispose() } + } +} +Extract-Path '%(source)s' '%(destination)s' +""" # noqa + class BaseWindowsMorphingTools(base.BaseOSMorphingTools): @@ -301,21 +331,9 @@ def _expand_archive(self, path, destination, overwrite=True): else: self._conn.exec_ps_command( "rm -recurse -force %s" % destination) - else: - LOG.info("Skipping extraction as destination exists") - return self._conn.exec_ps_command( - "if(([System.Management.Automation.PSTypeName]" - "'System.IO.Compression.ZipFile').Type -or " - "[System.Reflection.Assembly]::LoadWithPartialName(" - "'System.IO.Compression.FileSystem')) {" - "[System.IO.Compression.ZipFile]::ExtractToDirectory('%(path)s', " - "'%(destination)s')} else {mkdir -Force '%(destination)s'; " - "$shell = New-Object -ComObject Shell.Application;" - "$shell.Namespace('%(destination)s').copyhere(($shell.NameSpace(" - "'%(path)s')).items())}" % - {"path": path, "destination": destination}, + EXTRACT_TEMPLATE % {"source": path, "destination": destination}, ignore_stdout=True) def _set_service_start_mode(self, key_name, service_name, start_mode): @@ -517,7 +535,7 @@ def _write_cloudbase_init_conf(self, cloudbaseinit_base_dir, "logfile = cloudbase-init.log\r\n" "default_log_levels = \r\n" "comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN\r\n" - "allow_reboot = false\r\n" + "allow_reboot = true\r\n" "plugins = %(plugins)s\r\n" "debug = true\r\n" "san_policy = OnlineAll\r\n" diff --git a/coriolis/tests/osmorphing/test_windows.py b/coriolis/tests/osmorphing/test_windows.py index 75d03965..981dd4e6 100644 --- a/coriolis/tests/osmorphing/test_windows.py +++ b/coriolis/tests/osmorphing/test_windows.py @@ -231,17 +231,8 @@ def test__expand_archive_remove_destination(self): self.conn.exec_ps_command.assert_has_calls([ mock.call("rm -recurse -force %s" % destination), mock.call( - "if(([System.Management.Automation.PSTypeName]" - "'System.IO.Compression.ZipFile').Type -or " - "[System.Reflection.Assembly]::LoadWithPartialName(" - "'System.IO.Compression.FileSystem')) {" - "[System.IO.Compression.ZipFile]::ExtractToDirectory(" - "'%(path)s', '%(destination)s')} else {mkdir -Force " - "'%(destination)s'; $shell = New-Object -ComObject " - "Shell.Application;$shell.Namespace(" - "'%(destination)s').copyhere(($shell.NameSpace(" - "'%(path)s')).items())}" % - {"path": mock.sentinel.archive_path, + windows.EXTRACT_TEMPLATE % + {"source": mock.sentinel.archive_path, "destination": destination}, ignore_stdout=True) ]) @@ -513,7 +504,7 @@ def test__write_cloudbase_init_conf( "logfile = cloudbase-init.log\r\n" "default_log_levels = \r\n" "comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN\r\n" - "allow_reboot = false\r\n" + "allow_reboot = true\r\n" "plugins = %(plugins)s\r\n" "debug = true\r\n" "san_policy = OnlineAll\r\n"