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_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
|
||||
$result.changed = $true
|
||||
}
|
||||
|
@ -142,14 +142,14 @@ If ($ext -eq ".zip" -And $recurse -eq $false) {
|
|||
}
|
||||
|
||||
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 {
|
||||
Expand-Archive $_.FullName -OutputPath $dest -Force -WhatIf:$check_mode
|
||||
} Catch {
|
||||
Fail-Json -obj $result -message "Error recursively expanding '$src' to '$dest'! Msg: $($_.Exception.Message)"
|
||||
}
|
||||
If ($delete_archive) {
|
||||
Remove-Item $_.FullName -Force -WhatIf:$check_mode
|
||||
Remove-Item -LiteralPath $_.FullName -Force -WhatIf:$check_mode
|
||||
$result.removed = $true
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ If ($ext -eq ".zip" -And $recurse -eq $false) {
|
|||
|
||||
If ($delete_archive){
|
||||
try {
|
||||
Remove-Item $src -Recurse -Force -WhatIf:$check_mode
|
||||
Remove-Item -LiteralPath $src -Recurse -Force -WhatIf:$check_mode
|
||||
} catch {
|
||||
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
|
||||
import_tasks: tests.yml
|
||||
vars:
|
||||
in_check_mode: no
|
||||
- name: create local zip file with non-ascii chars
|
||||
script: create_zip.py {{ output_dir + '/win_unzip.zip' | quote }}
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Clean slate
|
||||
import_tasks: clean.yml
|
||||
- name: copy across zip to Windows host
|
||||
win_copy:
|
||||
src: '{{ output_dir }}/win_unzip.zip'
|
||||
dest: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||
|
||||
- name: Test in check-mode
|
||||
import_tasks: tests.yml
|
||||
vars:
|
||||
in_check_mode: yes
|
||||
- name: unarchive zip (check)
|
||||
win_unzip:
|
||||
src: '{{ win_unzip_dir }}\win_unzip.zip'
|
||||
dest: '{{ win_unzip_dir }}\output'
|
||||
register: unzip_check
|
||||
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_shortcut.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_updates.ps1 pslint:PSCustomUseLiteralPath
|
||||
lib/ansible/modules/windows/win_uri.ps1 pslint:PSAvoidUsingEmptyCatchBlock # Keep
|
||||
|
|
Loading…
Reference in a new issue