testcodezz
testcodezz

Reputation: 67

unzip -j -o not working through Ansible, but working directly on host

I am trying to grab one file from app.war called test.properties, this command works perfectly on a RHEL host when I run it directly on it:

unzip -j -o /home/test/app.war "*test.properties*"

But, when I run the same thing in Ansible, it does not work, it does not extract anything, there is no change:

- name: Extract test.properties file
  shell: 'unzip -j -o /home/test/app.war "*test.properties*"'

FYI, I CANNOT use Unarchive Module due to Ansible being version 2.9 . Am I doing anything wrong Ansible side? Maybe I am missing something extra like sudo or quotes?

Upvotes: 0

Views: 1287

Answers (1)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39194

It would actually be a better idea to get what you learned in your previous question and to feed it back in the proper Ansible module: unarchive, as it does allow you to feed the -j option in the extra_opts parameter.

Given the task:

- unarchive:
    src: /home/test/app.war 
    dest: /tmp
    include:
      - '*test.properties'
    extra_opts:
      - -j

You will get any file ending in test.properties only, thanks to the include parameter, extracted in the /tmp folder without any of its original path structure, thanks to the option -j given to extra_opts.


Since you are on a 2.9 version of Ansible — which I really recommend you to upgrade, due to its end of life being 31 December 2021 — what you can do it to use the trick raised in this comment from Ansible issue tracker:

The extra_opts are placed before the module arguments, with the .zip file before the filename to extract. The error resulting from the .zip file argument placed by the module may then be ignored by ignore_errors: yes

Source: @ossm1db comment on Ansible issue tracker

But, we can try to have a better hack, with the usage of failed_when in order to have as less false positive as possible, something like:

- unarchive:
    src: /home/test/app.war
    dest: /tmp
    extra_opts:
      - -j 
      - /home/test/app.war
      - '*test.properties'
  register: _unarchive
  failed_when:
    - "not _unarchive.extract_results.out is search(
        'extracting: .*/test.properties'
      )"
    - _unarchive.extract_results.rc != 0

Two things to note here:

  1. Mind that, the path to the WAR file have to be repeated in the src parameter and the extra_opts one, that is what makes it a ugly solution that called for the addition of include in later version.
  2. There are false positive that might arise here, with the usage of failed_when, namely the command could fail behind the scene, but Ansible will still marks it as ok, as long as the regex extracting: .*/test.properties is matched in the extraction output. This is actually what @ossm1db is raising in their comment in the issue tracker quoted above.

Upvotes: 1

Related Questions