Issue
I would like to extract two files from directory from war archive.
The two files exists in /WEB-INF/classes/
I have tried:
- name: create application.properties in /tmp
unarchive:
src: "/application/webapps/application.war"
dest: "/tmp"
remote_src: yes
extra_opts:
- -j
- WEB-INF/classes/application.properties
- WEB-INF/classes/logback.xml
Error :
"err":"unzip: cannot find or open /WEB-INF/classes/application.properties"
But it doesn't work of course. Any idea?
Solution
Really it looks like Ansible unarchive
module is not meant of this specific use case.
And there is a feature request to actually implement this exact feature.
Long story short: extra_opts
is meant for options, but does not seems be be meant for extra parameters.
What you are looking to do seems like it was possible before this commit, indeed, before this commit, Ansible would do:
cmd = [ self.cmd_path, '-o', self.src ]
if self.opts:
cmd.extend(self.opts)
And so you will end with the command:
unzip -o /application/webapps/application.war -j WEB-INF/classes/application.properties WEB-INF/classes/logback.xml
That should have worked in your use case.
But after this commit, Ansible's code ends up being
cmd = [ self.cmd_path, '-o' ]
if self.opts:
cmd.extend(self.opts)
cmd.append(self.src)
And so, it generates this buggy unzip
command:
unzip -o -j WEB-INF/classes/application.properties WEB-INF/classes/logback.xml /application/webapps/application.war
Now you could work around this bug, but this will make unzip
error, and we will have to sweep this error under the rug, so this should not be the solution of your choice.
But here is the train of thought I went in and what I did to have a working playbook: I identified the issue with the command using ansible-playbook play.yml -vvvv
, that got me the full unzip
command issued by Ansible — there error below have been reduced for brevity:
fatal: [localhost]: FAILED! => {
"changed": false,
"dest": "/tmp/out",
"extract_results": {
"cmd": [
"/usr/bin/unzip",
"-o",
"-j",
"WEB-INF/classes/application.properties",
"WEB-INF/classes/logback.xml",
"test.war",
"-d",
"/tmp/out"
]
}
}
Based on this, I tricked the extra_opts
by reproducing the archive in the src
parameter, so it fits right after the option -j
in the command.
The drawback of this is that is is now generating this command:
unzip -o -j test.war WEB-INF/classes/application.properties WEB-INF/classes/logback.xml test.war
Which means that it is now trying to find the file test.war inside itself, and so it will error because of this.
Here is the errors this yields:
"err": "caution: filename not matched: test.war\n"
So once again, I used a trick with the help of failed_when
to ignore this error, knowing the error it would yield me.
So given:
$ tree ./WEB-INF
./WEB-INF
└── classes
├── application.properties
├── ignore-me.txt
└── logback.xml
1 directory, 3 files
$ tree /tmp
/tmp
0 directories, 0 files
And the playbook:
- hosts: all
gather_facts: no
tasks:
- shell: /usr/lib/jvm/java-1.8-openjdk/bin/jar -cf test.war *
- file:
path: /tmp/out
state: directory
- unarchive:
src: test.war
dest: /tmp/out
remote_src: yes
extra_opts:
- -j
- test.war
- WEB-INF/classes/application.properties
- WEB-INF/classes/logback.xml
register: extract
failed_when: "extract.extract_results.rc != 0 and extract.extract_results.err != 'caution: filename not matched: ' ~ extract.src ~ '\n'"
This yields the recap:
PLAY [all] **********************************************************************************************************************************************
TASK [Create test.war file] *****************************************************************************************************************************
changed: [localhost]
TASK [file] *********************************************************************************************************************************************
changed: [localhost]
TASK [Create test.war file] *****************************************************************************************************************************
ok: [localhost]
PLAY RECAP **********************************************************************************************************************************************
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
And those files:
/ansible # tree /tmp/out
/tmp/out
├── application.properties
└── logback.xml
0 directories, 2 files
Answered By - β.εηοιτ.βε