Can I change node run-list while chef-client is being executed?
Scenario:
Chef-client is being executed with this run-list: ‘recipe[master_cookbook]’, ‘recipe[download]’, ‘recipe[install]’, ‘recipe[configure]’. At the run time of chef-client, my master_cookbook have logic to execute specific cookbook. As a result of one test run, master_cookbook found out that I want to execute only ‘recipe[install]’. How can I forbid the execution of download and configure in that case?
From the description, it sounds like you are treating recipes like scripts. Manipulating the runlist goes against the principles of desired state and doesn’t scale well. A better approach is to make the recipes idempotent. You can do this with guard interpreters, and ‘nothing’ action resources.
Here is an example. A new build is only downloaded if ‘build_number’ changes, or doesn’t exist in the destination. The install and configure are only executed if a new file has been downloaded.
Ideally you would store build_number in a databag, or a node attribute, make it querryable from an api opposed to hard coding in your cookbook.
build_number = 1234
remote_file "#{Chef::Config['file_cache_path']}/build#{build_number}.tgz" do
source "https://foo.example.com/build#{build_number}.tgz"
action :create
notifies :run, 'execute[install]'
notifies :run, 'execute[configure]'
end
directory '/opt/build' do
action :create
end
execute 'install' do
command "tar -xvf #{Chef::Config['file_cache_path']}/build#{build_number}.tgz -C /opt/build"
action :nothing
end
execute 'configure' do
command 'foo'
action :nothing
end