fr0zt
fr0zt

Reputation: 861

Ansible - Unarchive module overwriting

i am working with ansible and using a playbook. In this playbook I am performing a download (from a web url) and unarchive of a file into hosts (using unarchive module), and after that I am copying some files from control machine into hosts (using copy module).

What is happening is that every time I use unarchive module, although every file is the same, ansible is overwriting files in hosts. How can I make it so that it does not overwrite if contents are the same?

My playbook:

---
- hosts: group1
sudo: yes
tasks:

  - name: Download and Extract apache
  unarchive:
   src: http://mirrors.up.pt/pub/apache/tomcat/tomcat-9/v9.0.1/bin/apache-tomcat-9.0.1.tar.gz
   dest: /opt/
   remote_src: yes

- name: Copy file to host
  copy: src=/etc/ansible/files/myfile.xml dest=/opt/apache-tomcat-9.0.1/conf/myfile.xml

Upvotes: 6

Views: 16751

Answers (2)

Scottie H
Scottie H

Reputation: 354

I've handled this multiple ways, depending on the situation.

Option 1:
One of the files created by the archive has a specific name, such as foo-version_no
In this case, I can add the option:
creates: 'foo=version_no'

If this file exists, ansible will not extract it.
Caveat:
If the extracted directory is supposed to contain 12 files, and at least 1 of them has been removed or altered, the unarchive module will not replace them.

Option 2:
If there is no version number in the file name, examine one of the files in the extract directory and asses if it is the correct file.
Perhaps a checksum on the file; a grep for a unique parameter; or executing a command with the '--version' option. Register the results into a variable:
register: correct_file

The unarchive command can then have the when parameter:
unarchive: . . . . . . when: (correct_file.stdout != My_Required_Version and correct_file is defined)
The last part, about being defined, is there because, if you determine the extracted files don;t exist at all, you would skip checking the version, so the variable 'correct_file' will be undefined.
Caveat:
See Caveat from Option 1.

Option 3: Use an argument, or extract command that will not over write files if they have not changed.
Caveat: There will still be a little over head, because the extract command needs to asses each file, but will not make a new one.

Option 4:
Have another way to assess the quality of the files in the extracted directory, and set a variable based upon that result.
A simple example would be to run a checksum on all files, the run a checksum on that output, yielding a "Checksum of Checksums"
Ex:
curr_sum=$( cksum $( cksum /path/to/extracted/files/* ) ) if [ $curr_sum -eq $Correct_Value ] then echo "This is OK" exit 0 else echo "This is not ok" exit 1 fi

In ansible, you would run this command and register the result. Then compare the output to the pre-set value:
cmd: "script_name" register: cksum_answer failed_when: failed . . . unarchive: . . . . . . when: cksum_answer.rc == 1

Upvotes: 0

Paul Hodges
Paul Hodges

Reputation: 15273

Add a creates option referencing something the unarchive places.

c.f. the documentation page here (check the version against what you are using.)

e.g.:

- unarchive:
    remote_src : yes
    src        : "{{ url }}"
    dest       : "{{ install_dir }}/"
    creates    : "{{ flagFile }}" 

If the unarchive creates a /tmp/foo directory with a file named bar, then flagFile can be /tmp/foo/bar, and unarchive won't run again if it's already there.

Upvotes: 9

Related Questions