summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Borean <jborean93@gmail.com>2020-01-31 12:59:46 +1000
committerGitHub <noreply@github.com>2020-01-31 12:59:46 +1000
commit2a9ec8975feeb58142dc88abba252f55ed8f3a1d (patch)
tree91d14ccfb7ddb43d13abc738149faf798945b178
parentd58458447474ed233cbef6b54df30fab1de99013 (diff)
downloadansible-2a9ec8975feeb58142dc88abba252f55ed8f3a1d.tar.gz
win_unzip - LiteralPath fix (#66972)
* win_unzip - LiteralPath fix * Fix up Python sanity issues
-rw-r--r--changelogs/fragments/win_unzip-paths.yaml2
-rw-r--r--lib/ansible/modules/windows/win_unzip.ps18
-rw-r--r--test/integration/targets/win_unzip/defaults/main.yml1
-rw-r--r--test/integration/targets/win_unzip/files/create_zip.py28
-rw-r--r--test/integration/targets/win_unzip/meta/main.yml2
-rw-r--r--test/integration/targets/win_unzip/tasks/clean.yml15
-rw-r--r--test/integration/targets/win_unzip/tasks/main.yml124
-rw-r--r--test/integration/targets/win_unzip/tasks/tests.yml99
-rw-r--r--test/sanity/ignore.txt1
9 files changed, 149 insertions, 131 deletions
diff --git a/changelogs/fragments/win_unzip-paths.yaml b/changelogs/fragments/win_unzip-paths.yaml
new file mode 100644
index 0000000000..76e4b9acaf
--- /dev/null
+++ b/changelogs/fragments/win_unzip-paths.yaml
@@ -0,0 +1,2 @@
+bugfixes:
+- win_unzip - Fix support for paths with square brackets not being detected properly
diff --git a/lib/ansible/modules/windows/win_unzip.ps1 b/lib/ansible/modules/windows/win_unzip.ps1
index a5c194415b..234c774c3a 100644
--- a/lib/ansible/modules/windows/win_unzip.ps1
+++ b/lib/ansible/modules/windows/win_unzip.ps1
@@ -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)"
}
diff --git a/test/integration/targets/win_unzip/defaults/main.yml b/test/integration/targets/win_unzip/defaults/main.yml
new file mode 100644
index 0000000000..52d808d88c
--- /dev/null
+++ b/test/integration/targets/win_unzip/defaults/main.yml
@@ -0,0 +1 @@
+win_unzip_dir: '{{ remote_tmp_dir }}\win_unzip .ÅÑŚÌβŁÈ [$!@^&test(;)]'
diff --git a/test/integration/targets/win_unzip/files/create_zip.py b/test/integration/targets/win_unzip/files/create_zip.py
new file mode 100644
index 0000000000..41b6ff068b
--- /dev/null
+++ b/test/integration/targets/win_unzip/files/create_zip.py
@@ -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()
diff --git a/test/integration/targets/win_unzip/meta/main.yml b/test/integration/targets/win_unzip/meta/main.yml
new file mode 100644
index 0000000000..9f37e96cd9
--- /dev/null
+++ b/test/integration/targets/win_unzip/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+- setup_remote_tmp_dir
diff --git a/test/integration/targets/win_unzip/tasks/clean.yml b/test/integration/targets/win_unzip/tasks/clean.yml
deleted file mode 100644
index 64ac0d3fbf..0000000000
--- a/test/integration/targets/win_unzip/tasks/clean.yml
+++ /dev/null
@@ -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
diff --git a/test/integration/targets/win_unzip/tasks/main.yml b/test/integration/targets/win_unzip/tasks/main.yml
index ed4dc22877..2dab84be56 100644
--- a/test/integration/targets/win_unzip/tasks/main.yml
+++ b/test/integration/targets/win_unzip/tasks/main.yml
@@ -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
diff --git a/test/integration/targets/win_unzip/tasks/tests.yml b/test/integration/targets/win_unzip/tasks/tests.yml
deleted file mode 100644
index 46ec1e97ec..0000000000
--- a/test/integration/targets/win_unzip/tasks/tests.yml
+++ /dev/null
@@ -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
diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt
index af937e667b..4dd021304e 100644
--- a/test/sanity/ignore.txt
+++ b/test/sanity/ignore.txt
@@ -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