The question is as the title said, how to save only the "play recap" of ansible to a file or variable?
I am trying to make a web UI using Flask to make the user use ansible easier without writing any script or playbook, just write some hosts' IP address and click on what you want to do and flask/python script will call and play the premade playbook. The problem is I can't really tell the user whether the task is successfully done or not, because it only shows on Linux terminal. Therefore I want to "catch" only the "play recap" of the playbook and show it on a web page to tell the user the result.
Since the environment and setup isn't further described, it is assumed you are just running ansible-playbook ... from CLI and send the output to STDOUT.
In such case you could use commands like
ansible-playbook deployment.yml | tee deployment.log
sed -n '/PLAY RECAP/,$p' deployment.log
and proceed further from there.
Thanks to
Linux - grep from certain lines to the end of file
Is there a way to print only Ansible PLAY RECAP into CSV or HTML file and mail it?
Regarding an own plugin, you may take advantage from Ansible Issue #14367 "Show aggregated playbook execution recap at the bottom of play recap" or Access Ansible playbook results after run.
Related
I am setting a value on cpu.rt_runtime_us with echo command, like:
echo 950000 > /sys/fs/cgroup/cpu,cpuacct/user.slice/cpu.rt_runtime_us
It is on Redhat OS.
Is there more elegant way to configure it?
I'd like to use it in an ansible playook and I don't like using shell task and run this command every time playbook is run.
Appreciate any good proposal or a good practice for this kind of setting from ansible.
I am trying to update the version of some software through Ansible for a server.
- name: upgrade firmware version
shell: bash -x bmc_firmware_update.sh -k -F BMC_0204.00.bin_enc -s 1
this could take about 15 mins to run. I have another command to run after that, i.e
-name: something else
shell: bash -x bmc_firmware_update.sh -k -F BMC_0204.00.bin_enc -s 2.
I came across wait_for: timeout=300 but I want to know if there is a better way to go about making sure that the first one is successfully completed before the second shell command is run. Please advice!
Apparently this has nothing to do with Ansible.
Programs runs in foreground by default.
#sorin this is Ansible related!
#op; You can append to the firmware_update.sh script that when finished, it writes a certain value to specific path. Then let Ansible check that file and if that value is there. If it is, continue, if not, retry.
Another possibility is to write the logic in the bash scripts themselves.
I have been working now for 2 weeks on a playbook to deploy CKAN with Ansible on RHEL. I manage to get the site up and running with:
- name: test ckan
shell: ". {{ckan_user.home_path}}/{{ckan_site_name}}/bin/activate && paster serve /etc/ckan/{{ckan_site_name}}/development.ini"
args:
chdir: "{{ckan_user.home_path}}/{{ckan_site_name}}/src/ckan"
The result is that the playbook is stuck in an infinite loop saying:
'Escalation succeeded'.
I'm sure that there is an easy fix, but I can't find it...
Any ideas are more than welcome.
Add “&& exit” or something after your shell command.
Also, register the task, then read it at the next task to see what the output value is.
In this way, you can stop or continue the play based on the output of the task.
I can access the remote server without problem and I would like to send bwcli command which is a CLI of Broadworks server. I am using a shell code to send the command.
Normally if i want to enter the cli I type bwcli but it is not recognized when doing it remotely so I am sendig this sudo -u bworks /usr/local/broadworks/bw_base/bin/bwcli
instead like this:
#! /usr/bin/expect
expect ":"
send "sudo -u bworks /usr/local/broadworks/bw_base/bin/bwcli\r"
expect ">"
send "?\r"
expect "AS_CLI>"
My playbook is done like this:
-script: /home/ansible/playbooks/David/get_command.sh >> bwcli_login.log
When the playbook is ran it shows OK=1 changed=1 unreachable=0 failed=0.
So I am assuming that it works,but when I go to open "bwcli_login.log" I find it empty.
This is only my first step in the code I would like when I enter the CLI the I send some other commands to retrieve some information for the server. And it is annoying that I am stuck at the first step :(
I appreciate if somebody can tell me why the file output file is empty? What I am doing wrong?
Is it works when you manually run the script on the remote server without ansible ?
You can execute a script with different user without using sudo su <username> in your script, also check/share the output from ansible with stdout_lines, it will be easier to debug.
script:
#! /usr/bin/expect
expect ":"
send "/usr/local/broadworks/bw_base/bin/bwcli\r"
expect ">"
send "?\r"
expect "AS_CLI>"
ansible:
- name: run script
script: /home/ansible/playbooks/David/get_command.sh
become: yes
become_user: bworks
register: out
- debug: var=out.stdout_lines
Have you tried to use ansible expect_module ?
I am not famialer with BroadWorks at all, but maybe you can try to do something like the below example.
You will need:
The command module takes command to run,
responses - Mapping of expected string/regex and string to respond with. If the response is a list, successive matches return successive responses.
http://docs.ansible.com/ansible/latest/expect_module.html
I am not sure if the below example it is what you need or if it will work, just something to work with.
- name: expect test
expect:
command: /usr/local/broadworks/bw_base/bin/bwcli
response:
'>': "?\r"
You must consider that when in the BroadWorks CLI, the 'cd' command acts similarly to the equivalent shell command to navigate from one CLI context to the other. However, I'm not sure there is a root as in 'send "cd /Monitoring/Report"\r'.
To get back in the root of the CLI, you could use: 'send "qa; cd Monitoring/Report;"\r' instead.
Furthermore to verify that you moved to the right CLI context, you might want to ' expect "Monitoring/Report>"' intead of '>'.
Note that expect could be used to define functions.
I had the same issue. I found that you need to run the bwcli command with the -nobash option.
Playbook:
- name: Play 1
hosts: mediaservers
tasks:
- name: Play - 1 change to bwcli using script
script: /etc/ansible/bwcli.sh
args:
executable: /usr/bin/expect
register: bwcli_output
- debug: var=bwcli_output
Expect Script
#!/usr/bin/expect
# This will set a timeout for each send command sent to remote server
set timeout 20
spawn bash
send "bwcli -nobash\r";
expect "*_CLI*"
send "int;snmp;v3u\r"
expect "*V3Users*"
send "delete bwems\r"
expect "*Warning: The SNMP Agent needs to be restarted*"
send "get\r"
expect "*_CLI*"
send "exit\r"
expect "*Yes*\r"
send "Yes\r"
expect eof
To write the stdout of a command (in this case, echo hi) to a file, you can do:
echo hi > outfile
I would like a command instead of a redirection or pipe so that I do not need to invoke a shell. This is eventually for use with Ansible, which calls python's subprocess.POpen.
I am looking for:
stdout-to-file outfile echo hi
tee makes copying stdout to a file easy enough, but it accepts stdin, not a separate command.
Is there a common, portable command that does this? It's easy enough to write one, of course, but that's not the question. Ultimately, in Ansible, I want to do:
command: to-file /opt/binary_data base64 -d {{ base64_secret }}
Instead of:
shell: base64 -d {{ base64_secret }} > /opt/binary_data
Edit: Looking for a command available on RHEL 7, Fedora 21
What you are actually looking for, is a Ansible Module, which takes two parameters,
The actual command
A file to redirect the output of above command
In this case, you could use shell module instead of command module, which allows such redirections.
e.g.
- shell: /usr/bin/your_command >> output.log
You could check the source and example documentation here.
This is the simplest. And I believe you are aware of this. I am just putting this across for anyone new to shell/command modules reading this thread.
If you don't like to do it that way, you could still write a wrapper module, which accepts the "file name" as an argument and will run as,
- custommodule: output.log /usr/bin/your_command
All you may need to do is fork the repo, look into existing modules, and customize yours accordingly.
Not sure if that is what you want, but in Ansible - Save registered variable to file I have found what I have needed:
- name: "Gather lsof"
command: lsof
register: lsof_command
- name: "Save lsof log"
local_command:
copy content="{{ lsof_command.stdout }}" dest="/root/lsof.log"
Or, in my specific case (might be useful for you as well) playbook was running on system A, but I needed the log from B and having it saved to localhost (because A system is hitting B and I want to log B's state):
- name: "Gather lsof on B"
delegate_to: B
command: lsof
register: lsof_command
run_once: true
- name: "Save lsof log"
local_action:
copy content="{{ lsof_command.stdout }}" dest="/root/lsof.log"
run_once: true
IMO run_once: true is required in my case, as I want the log gathered only once per playbook run (not say 10 times if playbook is running on 10 systems).
Space for improvement would be to save stderr as well or possibly failing "Save lsof log" task when it is not empty.