chef-solo getting logs from a bash script - ruby

I am executing a shell script via chef like below
execute 'Run postgres data migration' do
command '/home/ubuntu/build-target/infra-base/psql10_migration.sh'
live_stream true
action :run
only_if { ::File.exist?('/home/ubuntu/build-target/infra-base/psql10_migration.sh') }
end
My chef logs are directed to a file (log_location '/var/log/arkin/chef-run.log' )
Right now I am not getting any logs from the bash script psql10_migration.sh. Can someone let me know how can I get the logs from the bash script ?

Used in bash redirection like below
execute 'Run postgres data migration' do
command '/home/ubuntu/build-target/infra-base/psql10_migration.sh >> /home/ubuntu/logs/psql10-migration.log 2>&1'
action :run
only_if { ::File.exist?('/home/ubuntu/build-target/infra-base/psql10_migration.sh') }
end

Related

Can I use guards to chef if a windows service is running?

I'm writing a chef recipe and on this I need to perform an operation (run a batch) only if a service is not working.
I use this snippet:
batch 'run commnad' do
cwd target_path + '/bin/win64'
code 'command to be executed'
not_if '::Win32::Service.exists?("Service name")'
end
But it does not seems to work. After seeing this question I changed the process using an if clause instead of the guard and it works fine:
if !::Win32::Service.exists?("Service name") then
batch 'Install zabbix agent' do
cwd target_path + '/bin/win64'
code 'command to be executed'
end
end
But this should not be, for what I understood, the right way to manage this, so I'm wondering: why is the guard not working properly?
Thanks,
Michele.
The way you wrote your not_if statement runs the command as a shell script.
The shell doesn't know Ruby code, so the whole command will fail.
Need to first:
require win32/service
In order to use not_if with Ruby code you should put it inside a block instead:
not_if { ::Win32::Service.exists?("Service name") }
See some more examples here (search for not_if on the page):
https://docs.chef.io/resource_common.html
Here is the working example (Chef 13)
require 'win32/service'
windows_service "jenkins" do
action [:stop, :disable]
only_if { ::Win32::Service.exists?("jenkins")}
end

Echo messages from a script run by Puppet

I am writing a bash script that will be run by puppet by an Exec resource (I know. It is not ideal). I would like to know if is possible create debug messages in the script. Normally in Bash I use echo and in a manifest I use notify. But echo seems not work when the script is executed as an Exec resource in Puppet.
Check the documentation here for the logoutput attribute: https://docs.puppet.com/puppet/latest/reference/types/exec.html#exec-attribute-logoutput
You can always see the output from your echo in the script during Puppet agent execution with logoutput set to true.
For example:
exec { '/bin/sh script.sh': logoutput => true }

Chef run sh script

I have a problem trying to run shell script via Chef (with docker-provisioning).
This is how I try to execute my script:
bash 'shell_try' do
user "root"
run = "#{some_path_to_script}/my_script.sh some_params"
code " #{run} > stdout.txt 2> stderr.txt"
end
(note that this script should run another scripts, processes and write logs)
Here's no errors in the output, but when I log into machine and run ps aux process isn't running.
I guess something wrong with permissions (or env variables), because when I try the same command manually - it works.
A bash resource just runs the provided script text directly, if you wanted to run a long-running process generally you would set up an Upstart or systemd service and use the service resource to start it.
Finally find a solution (thanks to #coderanger) -
Install supervisor:
Download supervisor cookbook
Add:
include_recipe 'supervisor::default'
Add my service to supervisor:
supervisor_service "name" do
action :enable
#action :start
command '/path/script.sh start'
end
Run supervisor service
All done!
Please see the Chef documentation for your resource: https://docs.chef.io/resource_bash.html. The bash resource does not support a run attribute. Text of the code attribute is run as a bash script. The default action is to run the script unless told otherwise by the resource.
bash 'shell_try' do
user "root"
code " #{run} > stdout.txt 2> stderr.txt"
action :run
end
The code attribute is written to a temporary file where it is then run using the attributes specified in the resource.
The line run = "#{some_path_to_script}/my_script.sh some_params" at this point does nothing.

How to achieve idempotence when we execute bash script in ruby/knife environment?

I am trying to execute bash script in knife/Ruby environment. For example:
cookbook_file "test.sh" do
path "/tmp/test.sh"
mode "755"
action :create
end
bash "execute test.sh on #{nodeName}" do
code <<-EOH
sh test.sh arg1 arg2
EOH
#only_if { false }
end
How can I use only_if or not_if? So when we execute second time and the contents of "test.sh" is not changed, it should skip execution. I am getting this:
* cookbook_file[test.sh] action create (up to date)
but it still executes second time, third time...
You wouldn't use a guard, instead you would use a notification:
execute 'run test' do
action :nothing
command 'bash /tmp/test.sh arg1 arg2'
end
cookbook_file "test.sh" do
path "/tmp/test.sh"
mode "755"
notifies :run, 'execute[run test]', :immediately
end
Notifications trigger when a resources updates, so any time the cookbook file changes, it will run the execute. Also you want to be using execute instead of bash or script because you are running a command rather than an inline script file.

Chef - execute vs bash resource

I used both the execute resource or the bash resource.
Both achieve the same result:
bash 'Execute my script' do
user 'root'
cwd '/mydir'
code <<-EOH
./myscript.sh
EOH
end
execute 'Execute my script' do
user 'root'
cwd '/mydir'
command './myscript.sh'
end
The only difference I see is that bash actually creates a shell script (named /tmp/chef-script#{date}{#id}) where code is written.
What is the best practice to execute a shell script with Chef between execute or bash resource ?
For a single script, use an execute. The bash resource is for including the script contents inline in the recipe code.
In bash & execute block we need to write code to catch the error as if you add more than one command & the chef takes the status of the last command.
To make it more clear - when the Bash/execute block has only one command chef catches the issue ,if the next command is successful then it takes the last command status.
bash 'Execute my script' do
user 'root'
cwd '/mydir'
code <<-EOH
./myscript.sh
ls srini ##This will fail
ls ## this will be successful
EOH
end
execute 'Execute my script' do
user 'root'
cwd '/mydir'
command './myscript.sh'
command 'ls srini' #will fail
command 'ls' # will be successful
end

Resources