Bernard2324
Bernard2324

Reputation: 125

How to Change Chef Execution Order?

I am running a Chef recipe, however it appears to be running out of order.

#
# Cookbook:: monit
# Recipe:: default
#
# Copyright:: 2017, The Authors, All Rights Reserved.


yum_package 'install Requirements' do
    package_name ['libtool', 'automake', 'autoconf', 'bison', 'flex', 'zlib-devel', 'git']
    action :install
end

script 'install monit' do
    interpreter "bash"
    code <<-EOH
        git clone https://[email protected]/tildeslash/monit.git monit
        cd monit/
        ./bootstrap
        ./configure --without-pam --without-ssl --sysconfdir=/etc --prefix=/usr
        make && make install
    EOH
end

iptables_rule 'monit_web' do
    action :enable
end

template '/etc/monitrc' do
    owner 'root'
    mode '0700'
    source 'monitrc.erb'
end

execute 'monit reload' do
    require 'mixlib/shellout'
    cmnd = Mixlib::ShellOut.new('monit start all')
    cmnd.run_command
    if cmnd.error?
        cmndd = Mixlib::ShellOut.new('monit reload')
        cmndd.run_command
    else
        puts cmnd.stdout
    end
end

script 'start service' do
    interpreter "bash"
    code <<-EOF
        monit
        monit start all
    EOF
end

Based on my understanding, the script resource 'install monit' should run prior to the execute resource 'monit reload.' That does not appear to be the case; I'm receiving the following error:

================================================================================
Recipe Compile Error in /var/chef/cache/cookbooks/monit/recipes/default.rb
================================================================================

Errno::ENOENT
-------------
No such file or directory - monit

Cookbook Trace:
---------------
  /var/chef/cache/cookbooks/monit/recipes/default.rb:38:in `block in from_file'
  /var/chef/cache/cookbooks/monit/recipes/default.rb:35:in `from_file'

Relevant File Content:
----------------------
/var/chef/cache/cookbooks/monit/recipes/default.rb:

 31:    mode '0700'
 32:    source 'monitrc.erb'
 33:  end
 34:
 35:  execute 'monit reload' do
 36:    require 'mixlib/shellout'
 37:    cmnd = Mixlib::ShellOut.new('monit start all')
 38>>   cmnd.run_command
 39:    if cmnd.error?
 40:            cmndd = Mixlib::ShellOut.new('monit reload')
 41:            cmndd.run_command
 42:    else
 43:            puts cmnd.stdout
 44:    end
 45:  end
 46:
 47:  script 'start service' do

System Info:
------------
chef_version=13.9.1
platform=centos
platform_version=7.5.1804
ruby=ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-linux]
program_name=chef-client worker: ppid=14633;start=14:44:25;
executable=/opt/chef/bin/chef-client

I have confirmed that the program 'monit' is not installed. Why is Chef skipping the script, and jumping to execute? This was working fine at one point, I'm not sure why it suddenly stopped working.

Upvotes: 2

Views: 562

Answers (2)

Brandon Miller
Brandon Miller

Reputation: 5065

You should familiarize yourself with the Chef Client Overview. Especially the order of the Compile the resource collection phase and Converge the node phase.

As a general rule; resources run during convergence but any ruby code that's not in a ruby_block resource runs during compilation. So, in this case the ruby code you have for monit reload is actually running during the compile phase. You'd need to modify that resource to be a ruby_block. Like this:

ruby_block 'monit reload' do
  block do
    require 'mixlib/shellout'
    cmnd = Mixlib::ShellOut.new('monit start all')
    cmnd.run_command
    if cmnd.error?
        cmndd = Mixlib::ShellOut.new('monit reload')
        cmndd.run_command
    else
        puts cmnd.stdout
    end
  end
  action :run
end

Upvotes: 2

coderanger
coderanger

Reputation: 54211

Read coderanger.net/two-pass but basically you just hid some compile time Ruby code inside an execute resource. That doesn’t work. You can use the resource normally or use a ruby_block.

Upvotes: 0

Related Questions