win_unzip - LiteralPath fix (#66972)
* win_unzip - LiteralPath fix * Fix up Python sanity issues
This commit is contained in:
parent
d584584474
commit
2a9ec8975f
9 changed files with 149 additions and 131 deletions
2
changelogs/fragments/win_unzip-paths.yaml
Normal file
2
changelogs/fragments/win_unzip-paths.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- win_unzip - Fix support for paths with square brackets not being detected properly
|
|
@ -40,7 +40,7 @@ Function Extract-Zip($src, $dest) {
|
||||||
$entry_target_path = [System.IO.Path]::Combine($dest, $archive_name)
|
$entry_target_path = [System.IO.Path]::Combine($dest, $archive_name)
|
||||||
$entry_dir = [System.IO.Path]::GetDirectoryName($entry_target_path)
|
$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
|
New-Item -Path $entry_dir -ItemType Directory -WhatIf:$check_mode | Out-Null
|
||||||
$result.changed = $true
|
$result.changed = $true
|
||||||
}
|
}
|
||||||
|
@ -142,14 +142,14 @@ If ($ext -eq ".zip" -And $recurse -eq $false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
If ($recurse) {
|
If ($recurse) {
|
||||||
Get-ChildItem $dest -recurse | Where-Object {$pcx_extensions -contains $_.extension} | ForEach-Object {
|
Get-ChildItem -LiteralPath $dest -recurse | Where-Object {$pcx_extensions -contains $_.extension} | ForEach-Object {
|
||||||
Try {
|
Try {
|
||||||
Expand-Archive $_.FullName -OutputPath $dest -Force -WhatIf:$check_mode
|
Expand-Archive $_.FullName -OutputPath $dest -Force -WhatIf:$check_mode
|
||||||
} Catch {
|
} Catch {
|
||||||
Fail-Json -obj $result -message "Error recursively expanding '$src' to '$dest'! Msg: $($_.Exception.Message)"
|
Fail-Json -obj $result -message "Error recursively expanding '$src' to '$dest'! Msg: $($_.Exception.Message)"
|
||||||
}
|
}
|
||||||
If ($delete_archive) {
|
If ($delete_archive) {
|
||||||
Remove-Item $_.FullName -Force -WhatIf:$check_mode
|
Remove-Item -LiteralPath $_.FullName -Force -WhatIf:$check_mode
|
||||||
$result.removed = $true
|
$result.removed = $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ If ($ext -eq ".zip" -And $recurse -eq $false) {
|
||||||
|
|
||||||
If ($delete_archive){
|
If ($delete_archive){
|
||||||
try {
|
try {
|
||||||
Remove-Item $src -Recurse -Force -WhatIf:$check_mode
|
Remove-Item -LiteralPath $src -Recurse -Force -WhatIf:$check_mode
|
||||||
} catch {
|
} catch {
|
||||||
Fail-Json -obj $result -message "failed to delete archive at '$src': $($_.Exception.Message)"
|
Fail-Json -obj $result -message "failed to delete archive at '$src': $($_.Exception.Message)"
|
||||||
}
|
}
|
||||||
|
|
1
test/integration/targets/win_unzip/defaults/main.yml
Normal file
1
test/integration/targets/win_unzip/defaults/main.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
win_unzip_dir: '{{ remote_tmp_dir }}\win_unzip .ÅÑŚÌβŁÈ [$!@^&test(;)]'
|
28
test/integration/targets/win_unzip/files/create_zip.py
Normal file
28
test/integration/targets/win_unzip/files/create_zip.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright: (c) 2019, Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import zipfile
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
filename = b"caf\xc3\xa9.txt"
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile() as temp:
|
||||||
|
with open(temp.name, mode="wb") as fd:
|
||||||
|
fd.write(filename)
|
||||||
|
|
||||||
|
with open(sys.argv[1], mode="wb") as fd:
|
||||||
|
with zipfile.ZipFile(fd, "w") as zip:
|
||||||
|
zip.write(temp.name, filename.decode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
2
test/integration/targets/win_unzip/meta/main.yml
Normal file
2
test/integration/targets/win_unzip/meta/main.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
dependencies:
|
||||||
|
- setup_remote_tmp_dir
|
|
@ -1,15 +0,0 @@
|
||||||
- name: Remove leftover directory
|
|
||||||
win_file:
|
|
||||||
path: C:\Program Files\sysinternals
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: Create new directory
|
|
||||||
win_file:
|
|
||||||
path: C:\Program Files\sysinternals
|
|
||||||
state: directory
|
|
||||||
|
|
||||||
- name: Download sysinternals archive
|
|
||||||
win_get_url:
|
|
||||||
url: https://download.sysinternals.com/files/SysinternalsSuite.zip
|
|
||||||
dest: C:\Windows\Temp\SysinternalsSuite.zip
|
|
||||||
validate_certs: no
|
|
|
@ -1,16 +1,116 @@
|
||||||
- name: Clean slate
|
---
|
||||||
import_tasks: clean.yml
|
- name: create test directory
|
||||||
|
win_file:
|
||||||
|
path: '{{ win_unzip_dir }}\output'
|
||||||
|
state: directory
|
||||||
|
|
||||||
- name: Test in normal mode
|
- name: create local zip file with non-ascii chars
|
||||||
import_tasks: tests.yml
|
script: create_zip.py {{ output_dir + '/win_unzip.zip' | quote }}
|
||||||
vars:
|
delegate_to: localhost
|
||||||
in_check_mode: no
|
|
||||||
|
|
||||||
- name: Clean slate
|
- name: copy across zip to Windows host
|
||||||
import_tasks: clean.yml
|
win_copy:
|
||||||
|
src: '{{ output_dir }}/win_unzip.zip'
|
||||||
|
dest: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||||
|
|
||||||
- name: Test in check-mode
|
- name: unarchive zip (check)
|
||||||
import_tasks: tests.yml
|
win_unzip:
|
||||||
vars:
|
src: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||||
in_check_mode: yes
|
dest: '{{ win_unzip_dir }}\output'
|
||||||
|
register: unzip_check
|
||||||
check_mode: yes
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of unarchive zip (check)
|
||||||
|
win_stat:
|
||||||
|
path: '{{ win_unzip_dir }}\output\café.txt'
|
||||||
|
register: unzip_actual_check
|
||||||
|
|
||||||
|
- name: assert result of unarchive zip (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unzip_check is changed
|
||||||
|
- not unzip_check.removed
|
||||||
|
- not unzip_actual_check.stat.exists
|
||||||
|
|
||||||
|
- name: unarchive zip
|
||||||
|
win_unzip:
|
||||||
|
src: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||||
|
dest: '{{ win_unzip_dir }}\output'
|
||||||
|
register: unzip
|
||||||
|
|
||||||
|
- name: get result of unarchive zip
|
||||||
|
slurp:
|
||||||
|
path: '{{ win_unzip_dir }}\output\café.txt'
|
||||||
|
register: unzip_actual
|
||||||
|
|
||||||
|
- name: assert result of unarchive zip
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unzip is changed
|
||||||
|
- not unzip.removed
|
||||||
|
- unzip_actual.content | b64decode == 'café.txt'
|
||||||
|
|
||||||
|
# Module is not idempotent, will always change without creates
|
||||||
|
- name: unarchive zip again without creates
|
||||||
|
win_unzip:
|
||||||
|
src: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||||
|
dest: '{{ win_unzip_dir }}\output'
|
||||||
|
register: unzip_again
|
||||||
|
|
||||||
|
- name: assert unarchive zip again without creates
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unzip_again is changed
|
||||||
|
- not unzip_again.removed
|
||||||
|
|
||||||
|
- name: unarchive zip with creates
|
||||||
|
win_unzip:
|
||||||
|
src: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||||
|
dest: '{{ win_unzip_dir }}\outout'
|
||||||
|
creates: '{{ win_unzip_dir }}\output\café.txt'
|
||||||
|
register: unzip_again_creates
|
||||||
|
|
||||||
|
- name: assert unarchive zip with creates
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not unzip_again_creates is changed
|
||||||
|
- not unzip_again_creates.removed
|
||||||
|
|
||||||
|
- name: unarchive zip with delete (check)
|
||||||
|
win_unzip:
|
||||||
|
src: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||||
|
dest: '{{ win_unzip_dir }}\output'
|
||||||
|
delete_archive: yes
|
||||||
|
register: unzip_delete_check
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get result of unarchive zip with delete (check)
|
||||||
|
win_stat:
|
||||||
|
path: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||||
|
register: unzip_delete_actual_check
|
||||||
|
|
||||||
|
- name: assert unarchive zip with delete (check)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unzip_delete_check is changed
|
||||||
|
- unzip_delete_check.removed
|
||||||
|
- unzip_delete_actual_check.stat.exists
|
||||||
|
|
||||||
|
- name: unarchive zip with delete
|
||||||
|
win_unzip:
|
||||||
|
src: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||||
|
dest: '{{ win_unzip_dir }}\output'
|
||||||
|
delete_archive: yes
|
||||||
|
register: unzip_delete
|
||||||
|
|
||||||
|
- name: get result of unarchive zip with delete
|
||||||
|
win_stat:
|
||||||
|
path: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||||
|
register: unzip_delete_actual
|
||||||
|
|
||||||
|
- name: assert unarchive zip with delete
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unzip_delete is changed
|
||||||
|
- unzip_delete.removed
|
||||||
|
- not unzip_delete_actual.stat.exists
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
- name: Unarchive sysinternals archive
|
|
||||||
win_unzip:
|
|
||||||
src: C:\Windows\Temp\SysinternalsSuite.zip
|
|
||||||
dest: C:\Program Files\sysinternals
|
|
||||||
register: unzip_archive
|
|
||||||
|
|
||||||
- name: get stat of an extracted file
|
|
||||||
win_stat:
|
|
||||||
path: C:\Program Files\sysinternals\procexp.exe
|
|
||||||
register: unzip_archive_file
|
|
||||||
|
|
||||||
- name: Test unzip_archive (check-mode)
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- unzip_archive is changed == true
|
|
||||||
- unzip_archive.removed == false
|
|
||||||
- unzip_archive_file.stat.exists == false
|
|
||||||
when: in_check_mode
|
|
||||||
|
|
||||||
- name: Test unzip_archive (normal mode)
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- unzip_archive is changed == true
|
|
||||||
- unzip_archive.removed == false
|
|
||||||
- unzip_archive_file.stat.exists == true
|
|
||||||
when: not in_check_mode
|
|
||||||
|
|
||||||
- name: Unarchive sysinternals archive again, use creates
|
|
||||||
win_unzip:
|
|
||||||
src: C:\Windows\Temp\SysinternalsSuite.zip
|
|
||||||
dest: C:\Program Files\sysinternals
|
|
||||||
creates: C:\Program Files\sysinternals\procexp.exe
|
|
||||||
register: unzip_archive_again_creates
|
|
||||||
|
|
||||||
# NOTE: This module is not idempotent, it always extracts, except if we use creates !
|
|
||||||
- name: Test unzip_archive_again_creates (normal mode)
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- unzip_archive_again_creates is changed == false
|
|
||||||
- unzip_archive_again_creates.removed == false
|
|
||||||
when: not in_check_mode
|
|
||||||
|
|
||||||
- name: Test unzip_archive_again_creates (check-mode)
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- unzip_archive_again_creates is changed == true
|
|
||||||
- unzip_archive_again_creates.removed == false
|
|
||||||
when: in_check_mode
|
|
||||||
|
|
||||||
|
|
||||||
- name: Unarchive sysinternals archive again
|
|
||||||
win_unzip:
|
|
||||||
src: C:\Windows\Temp\SysinternalsSuite.zip
|
|
||||||
dest: C:\Program Files\sysinternals
|
|
||||||
delete_archive: yes
|
|
||||||
register: unzip_archive_again
|
|
||||||
|
|
||||||
# NOTE/ This module is not idempotent, it always extracts
|
|
||||||
- name: Test unzip_archive_again
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- unzip_archive_again is changed == true
|
|
||||||
- unzip_archive_again.removed == true
|
|
||||||
|
|
||||||
|
|
||||||
- name: Test whether archive is removed
|
|
||||||
win_stat:
|
|
||||||
path: C:\Windows\Temp\SysinternalsSuite.zip
|
|
||||||
register: stat_archive
|
|
||||||
|
|
||||||
- name: Test stat_archive (normal mode)
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- stat_archive.stat.exists == false
|
|
||||||
when: not in_check_mode
|
|
||||||
|
|
||||||
- name: Test stat_archive (check-mode)
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- stat_archive.stat.exists == true
|
|
||||||
when: in_check_mode
|
|
||||||
|
|
||||||
|
|
||||||
- name: Test extracted files
|
|
||||||
win_stat:
|
|
||||||
path: C:\Program Files\sysinternals\procexp.exe
|
|
||||||
register: stat_procexp
|
|
||||||
|
|
||||||
- name: Test stat_procexp (normal mode)
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- stat_procexp.stat.exists == true
|
|
||||||
when: not in_check_mode
|
|
||||||
|
|
||||||
- name: Test stat_procexp (check-mode)
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- stat_procexp.stat.exists == false
|
|
||||||
when: in_check_mode
|
|
|
@ -7646,7 +7646,6 @@ lib/ansible/modules/windows/win_share.ps1 pslint:PSCustomUseLiteralPath
|
||||||
lib/ansible/modules/windows/win_shell.ps1 pslint:PSUseApprovedVerbs
|
lib/ansible/modules/windows/win_shell.ps1 pslint:PSUseApprovedVerbs
|
||||||
lib/ansible/modules/windows/win_shortcut.ps1 pslint:PSCustomUseLiteralPath
|
lib/ansible/modules/windows/win_shortcut.ps1 pslint:PSCustomUseLiteralPath
|
||||||
lib/ansible/modules/windows/win_snmp.ps1 pslint:PSCustomUseLiteralPath
|
lib/ansible/modules/windows/win_snmp.ps1 pslint:PSCustomUseLiteralPath
|
||||||
lib/ansible/modules/windows/win_unzip.ps1 pslint:PSCustomUseLiteralPath
|
|
||||||
lib/ansible/modules/windows/win_unzip.ps1 pslint:PSUseApprovedVerbs
|
lib/ansible/modules/windows/win_unzip.ps1 pslint:PSUseApprovedVerbs
|
||||||
lib/ansible/modules/windows/win_updates.ps1 pslint:PSCustomUseLiteralPath
|
lib/ansible/modules/windows/win_updates.ps1 pslint:PSCustomUseLiteralPath
|
||||||
lib/ansible/modules/windows/win_uri.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep
|
lib/ansible/modules/windows/win_uri.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep
|
||||||
|
|
Loading…
Reference in a new issue