I operate AmazonLinux2 on EC2 using Ansible. However, when the Unarchive command is executed, the following error is displayed.
"Failed to find handler for \"/tmp/hoge.db.gz\".
Make sure the required command to extract the file is installed.
Command \"/usr/bin/unzip\" could not handle archive. Command \"/usr/bin/gtar\" could not handle archive."
The contents of PlayBook are as follows.
- name: Unarchive hoge
become: yes
unarchive:
src: /tmp/hoge.db.gz
dest: /root/fuga/
remote_src: yes
Below is the information I have examined to identify the cause of the error.
unarchive Requires Command
[root#ip- ~]# which gtar
/usr/bin/gtar
[root#ip- ~]# which unzip
/usr/bin/unzip
[root#ip- ~]# which zipinfo
/usr/bin/zipinfo
PATH
- debug:
var: ansible_env.PATH
"ansible_env.PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin"
The unarchive module cannot handle gzip files unless they are a compressed tar ball (see https://docs.ansible.com/ansible/latest/modules/unarchive_module.html).
You will need to use the copy module to first copy the gzip file, and then the shell module to decompress it using gunzip.
Example:
- copy:
src: /tmp/hoge.db.gz
dest: /root/fuga/hoge.db.gz
- shell: gunzip /root/fuga/hoge.db.gz
You may need to first install gunzip on the managed host
It works if you use the extra_opts like so:
- name: Unarchive hoge
become: true
ansible.builtin.unarchive:
src: /tmp/hoge.db.gz
dest: /root/fuga/
remote_src: yes
extra_opts:
- '-z'
Tested with ansible 2.9.25 and python 3.6.8 on CentOS 8.
Related
Im trying to perform an additional task on the output of stdout_lines.
Here is the playbook:
- name: Change to Splunk user
hosts:
sudo: yes
sudo_user: splunk
gather_facts: true
tasks:
- name: Run WGET & install SPLUNK
command: wget -O splunk-9.0.2-17e00c557dc1-Linux-x86_64.tgz https://download.splunk.com/products/splunk/releases/9.0.2/linux/splunk-9.0.2-17e00c557dc1-Linux-x86_64.tgz
- name: run 'ls' to get SPLUNK_PACKAGE_NAME
shell: 'ls -l'
register: command_output
- debug:
var: command_output.stdout_lines
I am using wget to download Splunk on the server and I need the Splunk package name so that I can extract the file in the next task.
For that, I tried to register ls -l as command_output.
Now, I need to untag it (tar xvzf splunk_package_name.tgz -C/opt), but I dont know how I can use the stdout_lines output in my tar command.
In Ansible, your use case should resume to one single task, using the unarchive module, along with the remote_src parameter set to true and the src one to your URL.
As described in the documentation:
If remote_src=yes and src contains ://, the remote machine will download the file from the URL first.
So, you end up with this single task:
- name: Install Splunk from remote archive
unarchive:
src: "https://download.splunk.com/products/splunk/releases/9.0.2\
/linux/splunk-9.0.2-17e00c557dc1-Linux-x86_64.tgz"
remote_src: true
## with this, you will end up with Splunk installed in /opt/splunk
dest: /opt
I'm trying to move everything under /opt/* to a new location on the remote server. I've tried this using command to run rsync directly, as well as using both the copy and the sychronize ansible module. In all cases I get the same error message saying:
"msg": "rsync: link_stat \"/opt/*\" failed: No such file or directory
If I run the command listed in the "cmd" part of the ansible error message directly on my remote server it works without error. I'm not sure why ansible is failing.
Here is the current attempt using sychronize:
- name: move /opt to new partition
become: true
synchronize:
src: /opt/*
dest: /mnt/opt/*
delegate_to: "{{ inventory_hostname }}"
You should skip the wildcards that is a common mistake:
UPDATE
Thanks to the user: # Zeitounator, I managed to do it with synchronize.
The advantage of using synchronize instead of copy module is performance, it's much faster if you have a lot of files to copy.
- name: move /opt to new partition
become: true
synchronize:
src: /opt/
dest: /mnt/opt
delegate_to: "{{ inventory_hostname }}"
So basically the initial answer was right but you needed to delete the wildcards "*" and the slash on dest path.
Also, you should add the deletion of files on /opt/
File is opened if I run the following command from shell:
ls -l /tmp/uname -n ---file1
I am trying to run it with fetch:
- name: COPY file from remote machine to local
fetch:
src: /tmp/`uname -n`---mem-swap.out
dest: /tmp
But it gives me the error:
file not found: /tmp/uname -n---mem-swap.out
Is it possible to execute it in "src"
Thank you.
This is not possible. A lookup would help if your were running the playbook on a local system, but unfortunately lookups don't run on remotely managed nodes.
As per the other answer, you can run a task first.
But if you are collecting facts first, why not use an Ansible variable?
- name: COPY file from remote machine to local
fetch:
src: /tmp/{{ ansible_nodename }}---mem-swap.out
dest: /tmp
It's possible to register the result and concatenate the src string. For example
- commnad: "uname -n"
register: result
- fetch:
src: "/tmp/{{ result.stdout }}---mem-swap.out"
dest: "/tmp"
Need to unarchive a .zip file then list the unpacked files. This is to select some pattern of files and use them in rest of the code
My playbook yaml snippet is
- name: uarchive the opar zip
unarchive:
src: "{{opar_download_path}}/opar.zip"
dest: "{{opar_download_path}}"
remote_src: yes
list_files: yes
I am not able to find details of how to use the result from "list_files",ie how to store the list of files to a variable. I was referring below document
https://docs.ansible.com/ansible/latest/modules/unarchive_module.html
The list_files: yes includes additional response attribute called files. For better understanding, try to print the output unarchived_list.files, as shown below:
- name: unarchive the opar zip
unarchive:
src: "{{opar_download_path}}/opar.zip"
dest: "{{opar_download_path}}"
remote_src: yes
list_files: yes
register: unarchived_list
- name: print unarchived folder list of files
debug: msg="{{unarchived_list.files}}"
More information on registering variables can be found here: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#registering-variables
I'd like to extract one directory from tar file.
In Linux OS for install directory unpacking - I simply do:
tar -xvf ingres.tar install
For ansible I've tried:
unarchive:
remote_src: yes
src: /ingres/ingres.tar
dest: /ingres
extra_opts:
- "install"
But it doesn't work of course. Any idea?
The GNU tar command has an option to select archive members: --add-file. Section 6.2 of the manual mentions it:
If a file name begins with dash (-), precede it with --add-file option to prevent it from being treated as an option.
However, it works for other files too, which means you can specify this option in the extra_opts of your task to select file(s) or directories to extract:
unarchive:
remote_src: yes
src: /ingres/ingres.tar
dest: /ingres
extra_opts:
- "--add-file"
- "install"