I'm trying to guard against re-executing of my recipe resources, when included in other recipes, using a lock file to prevent re-downloading and extracting files.
For example, consider a recipe like this:
execute "step1-download" do
command "step1-command"
not_if do ::File.exists?('/var/recipe-already-executed') end
end
execute "step2-extract" do
command "step2-command"
not_if do ::File.exists?('/var/recipe-already-executed') end
end
Is there a way to guard the recipe as a whole, to avoid repeating the guard in every resource of the recipe?
There are a number of things to consider in this example. First, consider the following:
You are doing something like this:
execute 'create directory' do
command 'mkdir -p /path/on/disk && touch created-directory'
not_if { File.exist?('created-directory') }
end
If I delete the directory, but not the "lockfile", then this block will not execute. This could be problematic, and is the reason why we discourage such mechanisms. You should be doing something like this instead:
execute 'create directory' do
command 'mkdir /path/on/disk'
not_if { File.directory?('/path/on/disk') }
end
However, this is entirely unnecessary, because Chef has a built-in resource for handling such situations:
directory '/path/on/disk'
From your example, it seems like you are trying to download, extract, and install a resource. You should really leverage the built-in Chef resources for this, as then you need-not worry about said guards:
remote_file "#{Chef::Config[:file_cache_path]}/whatever.tar.gz" do
source 'https://something.com/file.tar.gz'
action :create_if_missing
notifies :run, 'execute[extract]', :immediately
end
execute 'extract' do
command "tar -xzf #{Chef::Config[:file_cache_path]}/whatever.tar.gz"
action :nothing
notifies :run, 'execute[compile]', :immediately
end
execute 'compile' do
command "./configure && make && make install"
action :nothing
end
You should also look at the remote_install
community cookbook, which provides a handy resource:
remote_install 'bash' do
source 'http://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz'
version '4.3'
checksum 'afc687a28e0e24dc21b988fa159ff9dbcf6b7caa92ade8645cc6d5605cd024d4'
build_command './configure'
compile_command 'make'
install_command 'make install'
en