How should I install Splunk from remote tgz package? - ansible

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

Related

how to use unix command in src in ansible

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"

Ansible Unarchive command causes error "Failed to find handler"

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.

Running Python script via ansible

I'm trying to run a python script from an ansible script. I would think this would be an easy thing to do, but I can't figure it out. I've got a project structure like this:
playbook-folder
roles
stagecode
files
mypythonscript.py
tasks
main.yml
release.yml
I'm trying to run mypythonscript.py within a task in main.yml (which is a role used in release.yml). Here's the task:
- name: run my script!
command: ./roles/stagecode/files/mypythonscript.py
args:
chdir: /dir/to/be/run/in
delegate_to: 127.0.0.1
run_once: true
I've also tried ../files/mypythonscript.py. I thought the path for ansible would be relative to the playbook, but I guess not?
I also tried debugging to figure out where I am in the middle of the script, but no luck there either.
- name: figure out where we are
stat: path=.
delegate_to: 127.0.0.1
run_once: true
register: righthere
- name: print where we are
debug: msg="{{righthere.stat.path}}"
delegate_to: 127.0.0.1
run_once: true
That just prints out ".". So helpful ...
try to use script directive, it works for me
my main.yml
---
- name: execute install script
script: get-pip.py
and get-pip.py file should be in files in the same role
If you want to be able to use a relative path to your script rather than an absolute path then you might be better using the role_path magic variable to find the path to the role and work from there.
With the structure you are using in the question the following should work:
- name: run my script!
command: ./mypythonscript.py
args:
chdir: "{{ role_path }}"/files
delegate_to: 127.0.0.1
run_once: true
An alternative/straight forward solution:
Let's say you have already built your virtual env under ./env1 and used pip3 install the needed python modules.
Now write playbook task like:
- name: Run a script using an executable in a system path
script: ./test.py
args:
executable: ./env1/bin/python
register: python_result
- name: Get stdout or stderr from the output
debug:
var: python_result.stdout
If you want to execute the inline script without having a separate script file (for example, as molecule test) you can write something like this:
- name: Test database connection
ansible.builtin.command: |
python3 -c
"
import psycopg2;
psycopg2.connect(
host='127.0.0.1',
dbname='db',
user='user',
password='password'
);
"
You can even insert Ansible variables in this string.

How i can access gtm shell with ansible playbook command

I am stuck at this,I could easily set source for GT.M but after this, when I fire gtm command it get stuck,don't get out of it also,somebody please help me out.
my code is as follow:
---
- name: Copying files on local machine and printing Hello msg.
hosts: webservers
user: onkar
remote_user: vistaehr
gather_facts: False
#sudo: False
tasks:
- name: copying local file
copy: src=/home/onkar/onkar/Ansible/HELLO.m dest=/home/vistaehr/VistA/testr
#shell: rm pwd.txt
- name: Print Success
debug: msg="success"
- name: changing ownership of file
#copy: src=/home/onkar/onkar/Ansible/HELLO.m dest=/home/vistaehr/VistA/testr
shell: chown vistaehr:vistaehr /home/vistaehr/VistA/testr/HELLO.m
- name: Setting Source
shell: . /home/vistaehr/VistA/env && gtm
- name: Print Success
debug: msg="success"
- name: zlinking given file
shell: zlink "/home/vistaehr/VistA/testr/HELLO.m"
gtm starts a console, it is an interactive process. Ansible is waiting until the called command is exiting. Since the program never exits, your ansible task will never complete.
What are you trying to archive with calling gtm from Ansible? If you want to start a service you should look into the service module or check out systemd or init.d depending on your system.
Running a command in gtm you can do with piping:
echo 'zlink "/home/vistaehr/VistA/testr/HELLO.m"' | gtm
Or as an ansible task:
- name: Setting Source and zlinking given file
shell: . /home/vistaehr/VistA/env && echo 'zlink "/home/vistaehr/VistA/testr/HELLO.m"' | gtm

How can I check if file has been downloaded in ansible

I am downloading the file with wget from ansible.
- name: Download Solr
shell: wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip
args:
chdir: {{project_root}}/solr
but I only want to do that if zip file does not exist in that location. Currently the system is downloading it every time.
Note: this answer covers general question of "How can i check the file existence in ansible", not a specific case of downloading file.
The problems with the previous answers using "command" or "shell" actions is that they won't work in --check mode. Actually, first action will be skipped, and next will error out on "when: solr_exists.rc != 0" condition (due to variable not being defined).
Since Ansible 1.3, there's more direct way to check for file existance - using "stat" module. It of course also works well as "local_action" to check a local file existence:
- local_action: stat path={{secrets_dir}}/secrets.yml
register: secrets_exist
- fail: msg="Production credentials not found"
when: secrets_exist.stat.exists == False
Unless you have a reason to use wget why not use get_url module. It will check if the file needs to be downloaded.
---
- hosts : all
gather_facts : no
tasks:
- get_url:
url="http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip"
dest="{{project_root}}/solr-4.7.0.zip"
NOTE: If you put the directory and not the full path in the dest ansible will still download the file to a temporary dir but do an md5 check to decide whether to copy to the dest dir.
And if you need to save state of download you can use:
---
- hosts : all
gather_facts : no
tasks:
- get_url:
url="http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip"
dest="{{project_root}}/solr-4.7.0.zip"
register: get_solr
- debug:
msg="solr was downloaded"
when: get_solr|changed
Many modules are already aware of the result and will be skipped if its already there, like file or geturl. Others like command have a creates option, which will skip this command if that file already exists (or doesn't exist, if you use the removes option).
So you should first check the available modules, if they are smart enough already. If not: I recommend the stats module. Advantage over the other solution: No "red errors but ignored" in the output.
- name: Check MySQL data directory existence
stat: path=/var/lib/mysql-slave
register: mysql_slave_data_dir
- name: Stop MySQL master to copy data directory
service: name=mysql state=stopped
sudo: yes
when: not mysql_slave_data_dir.stat.exists
There are at least two options here.
You can register a variable if the file exists, then use a when condition to execute the command on the condition that the file doesn't already exist:
- command: /usr/bin/test -e {{project_root}}/solr/solr-4.7.0.zip
register: solr_zip
ignore_errors: True
- name: Download Solr
shell: chdir={{project_root}}/solr /usr/bin/wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip
when: solr_zip|failed
You could also use the commands module with the creates option:
- name: Download Solr
command: /usr/bin/wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip chdir={{project_root}}/solr creates={{project_root}}/solr/solr-4.7.0.zip
This article might be useful
Out of it comes this example:
tasks:
- shell: if [[ -f "/etc/monitrc" ]]; then /bin/true; else /bin/false; fi
register: result
ignore_errors: True
- command: /bin/something
when: result|failed
- command: /bin/something_else
when: result|success
- command: /bin/still/something_else
when: result|skipped
So basically you can do this checking by registering a variable from a command and checking its return code. (You can also do this by checking its stdout)
- name: playbook
hosts: all
user: <your-user>
vars:
project_root: /usr/local
tasks:
- name: Check if the solr zip exists.
command: /usr/bin/test -e {{project_root}}/solr/solr-4.7.0.zip
ignore_errors: True
register: solr_exists
- name: Download Solr
shell: chdir={{project_root}}/solr wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip
when: solr_exists.rc != 0
This basically says that if the /usr/bin/test -e {{project_root}}/solr/solr-4.7.0.zip command returns a code that is not 0, meaning it doesn't exist then execute the task Download Solr
Hope it helps.
my favourite is to only download the file if it is newer than the local file (which includes when the local file does not exist)
the -N option with wget does this: https://www.gnu.org/software/wget/manual/html_node/Time_002dStamping-Usage.html .
sadly, i don't think there is an equivalent feature in get_url
so a very small change:
- name: Download Solr
shell: chdir={{project_root}}/solr wget -N http://<SNIPPED>/solr-4.7.0.zip
Use the creates argument
- name: Download Solr
shell: creates={{working_directory}}/solr/solr-4.7.0.zip chdir={{working_directory}}/solr wget http://mirror.mel.bkb.net.au/pub/apache/lucene/solr/4.7.0/solr-4.7.0.zip

Resources