From 2f1bc34589d1dc783fec738c61a6bf4a6e3ff933 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Tue, 19 Mar 2019 11:22:17 +1000 Subject: [PATCH] win_copy - fix glob like paths (#54006) --- changelogs/fragments/win_copy-paths.yaml | 2 + lib/ansible/modules/windows/win_copy.ps1 | 87 +++++++++---------- .../targets/win_copy/defaults/main.yml | 2 +- .../targets/win_copy/tasks/remote_tests.yml | 8 +- .../targets/win_copy/tasks/tests.yml | 4 +- 5 files changed, 51 insertions(+), 52 deletions(-) create mode 100644 changelogs/fragments/win_copy-paths.yaml diff --git a/changelogs/fragments/win_copy-paths.yaml b/changelogs/fragments/win_copy-paths.yaml new file mode 100644 index 0000000000..bfced51fc7 --- /dev/null +++ b/changelogs/fragments/win_copy-paths.yaml @@ -0,0 +1,2 @@ +bugfixes: +- win_copy - Fix issues when using paths with glob like characters, e.g. ``[``, ``]`` diff --git a/lib/ansible/modules/windows/win_copy.ps1 b/lib/ansible/modules/windows/win_copy.ps1 index 83151c830d..5f8b2d36b3 100644 --- a/lib/ansible/modules/windows/win_copy.ps1 +++ b/lib/ansible/modules/windows/win_copy.ps1 @@ -52,9 +52,9 @@ Function Copy-File($source, $dest) { $source_checksum = Get-FileChecksum -path $source } - if (Test-Path -Path $dest -PathType Container) { + if (Test-Path -LiteralPath $dest -PathType Container) { Fail-Json -obj $result -message "cannot copy file from '$source' to '$dest': dest is already a folder" - } elseif (Test-Path -Path $dest -PathType Leaf) { + } elseif (Test-Path -LiteralPath $dest -PathType Leaf) { if ($force) { $target_checksum = Get-FileChecksum -path $dest if ($source_checksum -ne $target_checksum) { @@ -68,9 +68,9 @@ Function Copy-File($source, $dest) { if ($copy_file) { $file_dir = [System.IO.Path]::GetDirectoryName($dest) # validate the parent dir is not a file and that it exists - if (Test-Path -Path $file_dir -PathType Leaf) { + if (Test-Path -LiteralPath $file_dir -PathType Leaf) { Fail-Json -obj $result -message "cannot copy file from '$source' to '$dest': object at dest parent dir is not a folder" - } elseif (-not (Test-Path -Path $file_dir)) { + } elseif (-not (Test-Path -LiteralPath $file_dir)) { # directory doesn't exist, need to create New-Item -Path $file_dir -ItemType Directory -WhatIf:$check_mode | Out-Null $diff += "+$file_dir\`n" @@ -80,15 +80,15 @@ Function Copy-File($source, $dest) { $result.backup_file = Backup-File -path $dest -WhatIf:$check_mode } - if (Test-Path -Path $dest -PathType Leaf) { - Remove-Item -Path $dest -Force -Recurse -WhatIf:$check_mode | Out-Null + if (Test-Path -LiteralPath $dest -PathType Leaf) { + Remove-Item -LiteralPath $dest -Force -Recurse -WhatIf:$check_mode | Out-Null $diff += "-$dest`n" } if (-not $check_mode) { # cannot run with -WhatIf:$check_mode as if the parent dir didn't # exist and was created above would still not exist in check mode - Copy-Item -Path $source -Destination $dest -Force | Out-Null + Copy-Item -LiteralPath $source -Destination $dest -Force | Out-Null } $diff += "+$dest`n" @@ -102,14 +102,13 @@ Function Copy-File($source, $dest) { Function Copy-Folder($source, $dest) { $diff = "" - $copy_folder = $false - if (-not (Test-Path -Path $dest -PathType Container)) { + if (-not (Test-Path -LiteralPath $dest -PathType Container)) { $parent_dir = [System.IO.Path]::GetDirectoryName($dest) - if (Test-Path -Path $parent_dir -PathType Leaf) { + if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { Fail-Json -obj $result -message "cannot copy file from '$source' to '$dest': object at dest parent dir is not a folder" } - if (Test-Path -Path $dest -PathType Leaf) { + if (Test-Path -LiteralPath $dest -PathType Leaf) { Fail-Json -obj $result -message "cannot copy folder from '$source' to '$dest': dest is already a file" } @@ -118,7 +117,7 @@ Function Copy-Folder($source, $dest) { $result.changed = $true } - $child_items = Get-ChildItem -Path $source -Force + $child_items = Get-ChildItem -LiteralPath $source -Force foreach ($child_item in $child_items) { $dest_child_path = Join-Path -Path $dest -ChildPath $child_item.Name if ($child_item.PSIsContainer) { @@ -132,10 +131,9 @@ Function Copy-Folder($source, $dest) { } Function Get-FileSize($path) { - $file = Get-Item -Path $path -Force + $file = Get-Item -LiteralPath $path -Force if ($file.PSIsContainer) { - $dir_files_sum = Get-ChildItem $file.FullName -Recurse - $size = (Get-ChildItem -Path $file.FullName -Recurse -Force | ` + $size = (Get-ChildItem -Literalpath $file.FullName -Recurse -Force | ` Where-Object { $_.PSObject.Properties.Name -contains 'Length' } | ` Measure-Object -Property Length -Sum).Sum if ($null -eq $size) { @@ -178,7 +176,7 @@ Function Extract-Zip($src, $dest) { $entry_target_path = [System.IO.Path]::Combine($dest, $decoded_archive_name) $entry_dir = [System.IO.Path]::GetDirectoryName($entry_target_path) - if (-not (Test-Path -Path $entry_dir)) { + if (-not (Test-Path -LiteralPath $entry_dir)) { New-Item -Path $entry_dir -ItemType Directory -WhatIf:$check_mode | Out-Null } @@ -192,7 +190,7 @@ Function Extract-Zip($src, $dest) { } Function Extract-ZipLegacy($src, $dest) { - if (-not (Test-Path -Path $dest)) { + if (-not (Test-Path -LiteralPath $dest)) { New-Item -Path $dest -ItemType Directory -WhatIf:$check_mode | Out-Null } $shell = New-Object -ComObject Shell.Application @@ -211,7 +209,7 @@ Function Extract-ZipLegacy($src, $dest) { $entry_target_path = [System.IO.Path]::Combine($dest, $decoded_archive_entry) $entry_dir = [System.IO.Path]::GetDirectoryName($entry_target_path) - if (-not (Test-Path -Path $entry_dir)) { + if (-not (Test-Path -LiteralPath $entry_dir)) { New-Item -Path $entry_dir -ItemType Directory -WhatIf:$check_mode | Out-Null } @@ -225,7 +223,7 @@ Function Extract-ZipLegacy($src, $dest) { # once file is extraced, we need to rename it with non base64 name $combined_encoded_path = [System.IO.Path]::Combine($dest, $encoded_archive_entry) - Move-Item -Path $combined_encoded_path -Destination $entry_target_path -Force | Out-Null + Move-Item -LiteralPath $combined_encoded_path -Destination $entry_target_path -Force | Out-Null } } } @@ -242,15 +240,14 @@ if ($copy_mode -eq "query") { $local_checksum = $file.checksum $filepath = Join-Path -Path $dest -ChildPath $filename - if (Test-Path -Path $filepath -PathType Leaf) { + if (Test-Path -LiteralPath $filepath -PathType Leaf) { if ($force) { $checksum = Get-FileChecksum -path $filepath if ($checksum -ne $local_checksum) { - $will_change = $true $changed_files += $file } } - } elseif (Test-Path -Path $filepath -PathType Container) { + } elseif (Test-Path -LiteralPath $filepath -PathType Container) { Fail-Json -obj $result -message "cannot copy file to dest '$filepath': object at path is already a directory" } else { $changed_files += $file @@ -262,12 +259,12 @@ if ($copy_mode -eq "query") { $dirpath = Join-Path -Path $dest -ChildPath $dirname $parent_dir = [System.IO.Path]::GetDirectoryName($dirpath) - if (Test-Path -Path $parent_dir -PathType Leaf) { + if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { Fail-Json -obj $result -message "cannot copy folder to dest '$dirpath': object at parent directory path is already a file" } - if (Test-Path -Path $dirpath -PathType Leaf) { + if (Test-Path -LiteralPath $dirpath -PathType Leaf) { Fail-Json -obj $result -message "cannot copy folder to dest '$dirpath': object at path is already a file" - } elseif (-not (Test-Path -Path $dirpath -PathType Container)) { + } elseif (-not (Test-Path -LiteralPath $dirpath -PathType Container)) { $changed_directories += $directory } } @@ -281,7 +278,7 @@ if ($copy_mode -eq "query") { # a single zip file containing the files and directories needs to be # expanded this will always result in a change as the calculation is done # on the win_copy action plugin and is only run if a change needs to occur - if (-not (Test-Path -Path $src -PathType Leaf)) { + if (-not (Test-Path -LiteralPath $src -PathType Leaf)) { Fail-Json -obj $result -message "Cannot expand src zip file: '$src' as it does not exist" } @@ -306,17 +303,17 @@ if ($copy_mode -eq "query") { $result.src = $src $result.dest = $dest - if (-not (Test-Path -Path $src)) { + if (-not (Test-Path -LiteralPath $src)) { Fail-Json -obj $result -message "Cannot copy src file: '$src' as it does not exist" } - if (Test-Path -Path $src -PathType Container) { + if (Test-Path -LiteralPath $src -PathType Container) { # we are copying a directory or the contents of a directory $result.operation = 'folder_copy' if ($src.EndsWith("/") -or $src.EndsWith("`\")) { # copying the folder's contents to dest $diff = "" - $child_files = Get-ChildItem -Path $src -Force + $child_files = Get-ChildItem -LiteralPath $src -Force foreach ($child_file in $child_files) { $dest_child_path = Join-Path -Path $dest -ChildPath $child_file.Name if ($child_file.PSIsContainer) { @@ -327,7 +324,7 @@ if ($copy_mode -eq "query") { } } else { # copying the folder and it's contents to dest - $dest = Join-Path -Path $dest -ChildPath (Get-Item -Path $src -Force).Name + $dest = Join-Path -Path $dest -ChildPath (Get-Item -LiteralPath $src -Force).Name $result.dest = $dest $diff = Copy-Folder -source $src -dest $dest } @@ -335,19 +332,19 @@ if ($copy_mode -eq "query") { # we are just copying a single file to dest $result.operation = 'file_copy' - $source_basename = (Get-Item -Path $src -Force).Name + $source_basename = (Get-Item -LiteralPath $src -Force).Name $result.original_basename = $source_basename if ($dest.EndsWith("/") -or $dest.EndsWith("`\")) { - $dest = Join-Path -Path $dest -ChildPath (Get-Item -Path $src -Force).Name + $dest = Join-Path -Path $dest -ChildPath (Get-Item -LiteralPath $src -Force).Name $result.dest = $dest } else { # check if the parent dir exists, this is only done if src is a # file and dest if the path to a file (doesn't end with \ or /) - $parent_dir = Split-Path -Path $dest - if (Test-Path -Path $parent_dir -PathType Leaf) { + $parent_dir = Split-Path -LiteralPath $dest + if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { Fail-Json -obj $result -message "object at destination parent dir '$parent_dir' is currently a file" - } elseif (-not (Test-Path -Path $parent_dir -PathType Container)) { + } elseif (-not (Test-Path -LiteralPath $parent_dir -PathType Container)) { Fail-Json -obj $result -message "Destination directory '$parent_dir' does not exist" } } @@ -357,7 +354,7 @@ if ($copy_mode -eq "query") { } # the file might not exist if running in check mode - if (-not $check_mode -or (Test-Path -Path $dest -PathType Leaf)) { + if (-not $check_mode -or (Test-Path -LiteralPath $dest -PathType Leaf)) { $result.size = Get-FileSize -path $dest } else { $result.size = $null @@ -369,29 +366,29 @@ if ($copy_mode -eq "query") { # a single file is located in src and we need to copy to dest, this will # always result in a change as the calculation is done on the Ansible side # before this is run. This should also never run in check mode - if (-not (Test-Path -Path $src -PathType Leaf)) { + if (-not (Test-Path -LiteralPath $src -PathType Leaf)) { Fail-Json -obj $result -message "Cannot copy src file: '$src' as it does not exist" } # the dest parameter is a directory, we need to append original_basename - if ($dest.EndsWith("/") -or $dest.EndsWith("`\") -or (Test-Path -Path $dest -PathType Container)) { + if ($dest.EndsWith("/") -or $dest.EndsWith("`\") -or (Test-Path -LiteralPath $dest -PathType Container)) { $remote_dest = Join-Path -Path $dest -ChildPath $original_basename - $parent_dir = Split-Path -Path $remote_dest + $parent_dir = Split-Path -LiteralPath $remote_dest # when dest ends with /, we need to create the destination directories - if (Test-Path -Path $parent_dir -PathType Leaf) { + if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { Fail-Json -obj $result -message "object at destination parent dir '$parent_dir' is currently a file" - } elseif (-not (Test-Path -Path $parent_dir -PathType Container)) { + } elseif (-not (Test-Path -LiteralPath $parent_dir -PathType Container)) { New-Item -Path $parent_dir -ItemType Directory | Out-Null } } else { $remote_dest = $dest - $parent_dir = Split-Path -Path $remote_dest + $parent_dir = Split-Path -LiteralPath $remote_dest # check if the dest parent dirs exist, need to fail if they don't - if (Test-Path -Path $parent_dir -PathType Leaf) { + if (Test-Path -LiteralPath $parent_dir -PathType Leaf) { Fail-Json -obj $result -message "object at destination parent dir '$parent_dir' is currently a file" - } elseif (-not (Test-Path -Path $parent_dir -PathType Container)) { + } elseif (-not (Test-Path -LiteralPath $parent_dir -PathType Container)) { Fail-Json -obj $result -message "Destination directory '$parent_dir' does not exist" } } @@ -400,7 +397,7 @@ if ($copy_mode -eq "query") { $result.backup_file = Backup-File -path $remote_dest -WhatIf:$check_mode } - Copy-Item -Path $src -Destination $remote_dest -Force | Out-Null + Copy-Item -LiteralPath $src -Destination $remote_dest -Force | Out-Null $result.changed = $true } diff --git a/test/integration/targets/win_copy/defaults/main.yml b/test/integration/targets/win_copy/defaults/main.yml index dcb00b54d0..5d8a1d2351 100644 --- a/test/integration/targets/win_copy/defaults/main.yml +++ b/test/integration/targets/win_copy/defaults/main.yml @@ -1 +1 @@ -test_win_copy_path: C:\ansible\win_copy +test_win_copy_path: C:\ansible\win_copy .ÅÑŚÌβŁÈ [$!@^&test(;)] diff --git a/test/integration/targets/win_copy/tasks/remote_tests.yml b/test/integration/targets/win_copy/tasks/remote_tests.yml index 0a8d41e26c..5abb50200b 100644 --- a/test/integration/targets/win_copy/tasks/remote_tests.yml +++ b/test/integration/targets/win_copy/tasks/remote_tests.yml @@ -315,8 +315,8 @@ that: - remote_copy_folder_to_folder_after_change is changed - remote_copy_folder_to_folder_after_change_actual.matched == 2 - - remote_copy_folder_to_folder_after_change_actual.files[0].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' - - remote_copy_folder_to_folder_after_change_actual.files[1].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' + - remote_copy_folder_to_folder_after_change_actual.files[0].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' + - remote_copy_folder_to_folder_after_change_actual.files[1].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' - name: clear target folder before folder contents to remote test win_file: @@ -410,8 +410,8 @@ that: - remote_copy_folder_content_to_folder_after_change is changed - remote_copy_folder_content_to_folder_after_change_actual.matched == 2 - - remote_copy_folder_content_to_folder_after_change_actual.files[0].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' - - remote_copy_folder_content_to_folder_after_change_actual.files[1].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' + - remote_copy_folder_content_to_folder_after_change_actual.files[0].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' + - remote_copy_folder_content_to_folder_after_change_actual.files[1].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' # https://github.com/ansible/ansible/issues/50077 - name: create empty nested directory diff --git a/test/integration/targets/win_copy/tasks/tests.yml b/test/integration/targets/win_copy/tasks/tests.yml index 7f286dbf27..d15e71f65c 100644 --- a/test/integration/targets/win_copy/tasks/tests.yml +++ b/test/integration/targets/win_copy/tasks/tests.yml @@ -372,8 +372,8 @@ that: - copy_folder_after_change is changed - copy_folder_after_changes_actual.matched == 2 - - copy_folder_after_changes_actual.files[0].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' - - copy_folder_after_changes_actual.files[1].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' + - copy_folder_after_changes_actual.files[0].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' + - copy_folder_after_changes_actual.files[1].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' - name: copy folder's contents (check mode) win_copy: