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.
Related
In my playbook, I plan to run a command X, but this command X might fail the first time then I have a fix for that command. If command X fails, then invoke the fix. After the fix, run command X again.
- name: a block with a command that might fail the first time but can be fixed and then rerun that command
block:
- name: this task might fail the first time
command: command X
rescue:
- name: fix the error caused by command X
command: fix it!
always:
- name: run command the second time
command: command X
But i'm not happy with this structure because:
always is run whatever even if command X succeeds.
command X is very long and I don't like copy and paste the code everywhere.
So do we have a better solution? Any suggestion is appreciated.
[Edit]
I can improve it to:
- name: a block with a command that might fail the first time but can be fixed and then rerun that command
block:
- name: this task might fail the first time
command: command X
rescue:
- name: fix the error caused by command X
command: fix it!
- name: run command the second time
command: command X
But there is still code duplication issue since command X is extremely long and I don't want to copy and paste it.
You only want to run the command a second time when it fails the first time, so it should be part of the rescue.
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.
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.
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.