From 980ca564ceedeb5245333bcd382ac1b303ffae07 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Fri, 15 Mar 2019 19:44:53 +1000 Subject: [PATCH] windows - Fix module utils with glob paths (#53835) * windows - Fix module utils with glob paths * fix link util tests when using DOS 8.3 paths --- changelogs/fragments/win_mod_utils-paths.yaml | 2 ++ .../Ansible.ModuleUtils.CommandUtil.psm1 | 8 +++--- .../Ansible.ModuleUtils.Legacy.psm1 | 6 ++--- .../Ansible.ModuleUtils.LinkUtil.psm1 | 6 ++--- .../library/command_util_test.ps1 | 21 ++++++++++++--- .../library/symbolic_link_test.ps1 | 27 ++++++++++--------- .../targets/win_module_utils/tasks/main.yml | 1 - 7 files changed, 45 insertions(+), 26 deletions(-) create mode 100644 changelogs/fragments/win_mod_utils-paths.yaml diff --git a/changelogs/fragments/win_mod_utils-paths.yaml b/changelogs/fragments/win_mod_utils-paths.yaml new file mode 100644 index 0000000000..91b5d61cfa --- /dev/null +++ b/changelogs/fragments/win_mod_utils-paths.yaml @@ -0,0 +1,2 @@ +bugfixes: +- windows - Fixed various module utils that did not work with path that had glob like chars diff --git a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 index 44ea3ca969..a4a0974317 100644 --- a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 +++ b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1 @@ -46,12 +46,12 @@ Function Get-ExecutablePath { $full_path = [System.IO.Path]::GetFullPath($executable) if ($full_path -ne $executable -and $directory -ne $null) { - $file = Get-Item -Path "$directory\$executable" -Force -ErrorAction SilentlyContinue + $file = Get-Item -LiteralPath "$directory\$executable" -Force -ErrorAction SilentlyContinue } else { - $file = Get-Item -Path $executable -Force -ErrorAction SilentlyContinue + $file = Get-Item -LiteralPath $executable -Force -ErrorAction SilentlyContinue } - if ($file -ne $null) { + if ($null -ne $file) { $executable_path = $file.FullName } else { $executable_path = [Ansible.Process.ProcessUtil]::SearchPath($executable) @@ -93,7 +93,7 @@ Function Run-Command { # need to validate the working directory if it is set if ($working_directory) { # validate working directory is a valid path - if (-not (Test-Path -Path $working_directory)) { + if (-not (Test-Path -LiteralPath $working_directory)) { throw "invalid working directory path '$working_directory'" } } diff --git a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 index 11400d2117..5734f90c41 100644 --- a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 +++ b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 @@ -321,7 +321,7 @@ Function Get-FileChecksum($path, $algorithm = 'sha1') Helper function to calculate a hash of a file in a way which PowerShell 3 and above can handle #> - If (Test-Path -Path $path -PathType Leaf) + If (Test-Path -LiteralPath $path -PathType Leaf) { switch ($algorithm) { @@ -334,7 +334,7 @@ Function Get-FileChecksum($path, $algorithm = 'sha1') } If ($PSVersionTable.PSVersion.Major -ge 4) { - $raw_hash = Get-FileHash $path -Algorithm $algorithm + $raw_hash = Get-FileHash -LiteralPath $path -Algorithm $algorithm $hash = $raw_hash.Hash.ToLower() } Else { $fp = [System.IO.File]::Open($path, [System.IO.Filemode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite); @@ -342,7 +342,7 @@ Function Get-FileChecksum($path, $algorithm = 'sha1') $fp.Dispose(); } } - ElseIf (Test-Path -Path $path -PathType Container) + ElseIf (Test-Path -LiteralPath $path -PathType Container) { $hash = "3"; } diff --git a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.LinkUtil.psm1 b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.LinkUtil.psm1 index b6f4ad9955..cd42cc1a84 100644 --- a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.LinkUtil.psm1 +++ b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.LinkUtil.psm1 @@ -425,7 +425,7 @@ Function Remove-Link($link_path) { } Function New-Link($link_path, $link_target, $link_type) { - if (-not (Test-Path -Path $link_target)) { + if (-not (Test-Path -LiteralPath $link_target)) { throw "link_target '$link_target' does not exist, cannot create link" } @@ -434,13 +434,13 @@ Function New-Link($link_path, $link_target, $link_type) { $type = [Ansible.LinkType]::SymbolicLink } "junction" { - if (Test-Path -Path $link_target -PathType Leaf) { + if (Test-Path -LiteralPath $link_target -PathType Leaf) { throw "cannot set the target for a junction point to a file" } $type = [Ansible.LinkType]::JunctionPoint } "hard" { - if (Test-Path -Path $link_target -PathType Container) { + if (Test-Path -LiteralPath $link_target -PathType Container) { throw "cannot set the target for a hard link to a directory" } $type = [Ansible.LinkType]::HardLink diff --git a/test/integration/targets/win_module_utils/library/command_util_test.ps1 b/test/integration/targets/win_module_utils/library/command_util_test.ps1 index 3d7405ddae..a015d35c8c 100644 --- a/test/integration/targets/win_module_utils/library/command_util_test.ps1 +++ b/test/integration/targets/win_module_utils/library/command_util_test.ps1 @@ -29,6 +29,21 @@ Assert-Equals -actual $actual.stdout -expected "arg1`r`narg2`r`narg 3`r`n" Assert-Equals -actual $actual.stderr -expected "" Assert-Equals -actual $actual.executable -expected $exe +$test_name = "exe in special char dir" +$tmp_dir = Join-Path -Path $env:TEMP -ChildPath "ansible .ÅÑŚÌβŁÈ [$!@^&test(;)]" +try { + New-Item -Path $tmp_dir -ItemType Directory > $null + $exe_special = Join-Path $tmp_dir -ChildPath "PrintArgv.exe" + Copy-Item -LiteralPath $exe -Destination $exe_special + $actual = Run-Command -command "`"$exe_special`" arg1 arg2 `"arg 3`"" +} finally { + Remove-Item -LiteralPath $tmp_dir -Force -Recurse +} +Assert-Equals -actual $actual.rc -expected 0 +Assert-Equals -actual $actual.stdout -expected "arg1`r`narg2`r`narg 3`r`n" +Assert-Equals -actual $actual.stderr -expected "" +Assert-Equals -actual $actual.executable -expected $exe_special + $test_name = "invalid exe path" try { $actual = Run-Command -command "C:\fakepath\$exe_filename arg1" @@ -86,7 +101,7 @@ $test_name = "test default environment variable" Set-Item -Path env:TESTENV -Value "test" $actual = Run-Command -command "cmd.exe /c set" $env_present = $actual.stdout -split "`r`n" | Where-Object { $_ -eq "TESTENV=test" } -if ($env_present -eq $null) { +if ($null -eq $env_present) { Fail-Json -obj $result -message "Test $test_name failed`nenvironment variable TESTENV not found in stdout`n$($actual.stdout)" } @@ -94,10 +109,10 @@ $test_name = "test custom environment variable1" $actual = Run-Command -command "cmd.exe /c set" -environment @{ TESTENV2 = "testing" } $env_not_present = $actual.stdout -split "`r`n" | Where-Object { $_ -eq "TESTENV=test" } $env_present = $actual.stdout -split "`r`n" | Where-Object { $_ -eq "TESTENV2=testing" } -if ($env_not_present -ne $null) { +if ($null -ne $env_not_present) { Fail-Json -obj $result -message "Test $test_name failed`nenvironment variabel TESTENV found in stdout when it should be`n$($actual.stdout)" } -if ($env_present -eq $null) { +if ($null -eq $env_present) { Fail-json -obj $result -message "Test $test_name failed`nenvironment variable TESTENV2 not found in stdout`n$($actual.stdout)" } diff --git a/test/integration/targets/win_module_utils/library/symbolic_link_test.ps1 b/test/integration/targets/win_module_utils/library/symbolic_link_test.ps1 index c70ab1d23b..1decfe4fd8 100644 --- a/test/integration/targets/win_module_utils/library/symbolic_link_test.ps1 +++ b/test/integration/targets/win_module_utils/library/symbolic_link_test.ps1 @@ -6,8 +6,7 @@ $ErrorActionPreference = 'Stop' -$params = Parse-Args $args; -$path = Get-AnsibleParam -obj $params -name "path" -type "path" -failifempty $true +$path = Join-Path -Path ([System.IO.Path]::GetFullPath($env:TEMP)) -ChildPath '.ansible .ÅÑŚÌβŁÈ [$!@^&test(;)]' $folder_target = "$path\folder" $file_target = "$path\file" @@ -17,13 +16,14 @@ $hardlink_path = "$path\hardlink" $hardlink_path_2 = "$path\hardlink2" $junction_point_path = "$path\junction" -if (Test-Path -Path $path) { - Remove-Item -Path $path -Force -Recurse | Out-Null +if (Test-Path -LiteralPath $path) { + # Remove-Item struggles with broken symlinks, rely on trusty rmdir instead + Run-Command -command "cmd.exe /c rmdir /S /Q `"$path`"" > $null } New-Item -Path $path -ItemType Directory | Out-Null New-Item -Path $folder_target -ItemType Directory | Out-Null New-Item -Path $file_target -ItemType File | Out-Null -Set-Content -Path $file_target -Value "a" +Set-Content -LiteralPath $file_target -Value "a" Function Assert-Equals($actual, $expected) { if ($actual -ne $expected) { @@ -42,7 +42,7 @@ Load-LinkUtils # path is not a link $no_link_result = Get-Link -link_path $path -Assert-True -expression ($no_link_result -eq $null) -message "did not return null result for a non link" +Assert-True -expression ($null -eq $no_link_result) -message "did not return null result for a non link" # fail to create hard link pointed to a directory try { @@ -122,7 +122,7 @@ if ($hardlink_result.HardTargets[0] -ne $hardlink_path -and $hardlink_result.Har if ($hardlink_result.HardTargets[0] -ne $file_target -and $hardlink_result.HardTargets[1] -ne $file_target) { Assert-True -expression $false -message "file $file_target is not a target of the hard link" } -Assert-equals -actual (Get-Content -Path $hardlink_path -Raw) -expected (Get-Content -Path $file_target -Raw) +Assert-equals -actual (Get-Content -LiteralPath $hardlink_path -Raw) -expected (Get-Content -LiteralPath $file_target -Raw) # create a new hard link and verify targets go to 3 New-Link -link_path $hardlink_path_2 -link_target $file_target -link_type "hard" @@ -130,7 +130,7 @@ $hardlink_result_2 = Get-Link -link_path $hardlink_path Assert-True -expression ($hardlink_result_2.HardTargets.Count -eq 3) -message "did not return 3 targets for the hard link, actual $($hardlink_result_2.Targets.Count)" # check if broken symbolic link still works -Remove-Item -Path $folder_target -Force | Out-Null +Remove-Item -LiteralPath $folder_target -Force | Out-Null $broken_link_result = Get-Link -link_path $symlink_folder_path Assert-Equals -actual $broken_link_result.Type -expected "SymbolicLink" Assert-Equals -actual $broken_link_result.SubstituteName -expected "\??\$folder_target" @@ -150,18 +150,21 @@ Assert-Equals -actual $broken_junction_result.HardTargets -expected $null # delete file symbolic link Remove-Link -link_path $symlink_file_path -Assert-True -expression (-not (Test-Path -Path $symlink_file_path)) -message "failed to delete file symbolic link" +Assert-True -expression (-not (Test-Path -LiteralPath $symlink_file_path)) -message "failed to delete file symbolic link" # delete folder symbolic link Remove-Link -link_path $symlink_folder_path -Assert-True -expression (-not (Test-Path -Path $symlink_folder_path)) -message "failed to delete folder symbolic link" +Assert-True -expression (-not (Test-Path -LiteralPath $symlink_folder_path)) -message "failed to delete folder symbolic link" # delete junction point Remove-Link -link_path $junction_point_path -Assert-True -expression (-not (Test-Path -Path $junction_point_path)) -message "failed to delete junction point" +Assert-True -expression (-not (Test-Path -LiteralPath $junction_point_path)) -message "failed to delete junction point" # delete hard link Remove-Link -link_path $hardlink_path -Assert-True -expression (-not (Test-Path -Path $hardlink_path)) -message "failed to delete hard link" +Assert-True -expression (-not (Test-Path -LiteralPath $hardlink_path)) -message "failed to delete hard link" + +# cleanup after tests +Run-Command -command "cmd.exe /c rmdir /S /Q `"$path`"" > $null Exit-Json @{ data = "success" } diff --git a/test/integration/targets/win_module_utils/tasks/main.yml b/test/integration/targets/win_module_utils/tasks/main.yml index 4e0735402e..9faa331747 100644 --- a/test/integration/targets/win_module_utils/tasks/main.yml +++ b/test/integration/targets/win_module_utils/tasks/main.yml @@ -116,7 +116,6 @@ - name: call module with symbolic link tests symbolic_link_test: - path: C:\ansible testing register: symbolic_link - assert: