Reputation: 161
So I would like to get chef to clear out a directory AFTER the entire run finishes. I assume the way to do this is through notifies, but I am not having much luck. I have the below code which I thought would delete the cache dir (/var/chef/cache) but it never seems to run.
The logging says that the directory resource was skipped because the action was nothing (which makes sense) during the compile phase, but the action never gets run at the end through the notifies. What am I missing?
directory "delete the dir #{Chef::Config["file_cache_path"]}" do
recursive true
path "#{Chef::Config["file_cache_path"]}"
action :nothing
end
s3_file "download tarball" do
<details>
notifies :delete, "directory[#{prefix} delete the dir #{Chef::Config["file_cache_path"]}]", :delayed
end
Upvotes: 0
Views: 3298
Reputation: 26997
Chef recipes are executed in the order in which they are specified in the run_list
. If you want something to be executed last, put that recipe at the end of your run_list
. Using notifications is not desirable because:
Imagine you are another developer on your team reviewing this code. Why does s3_file
delete the file cache path? There is no comment, etc. Additionally, in a larger, more complex application, you may have notifications to multiple resources. In my experience, humans are very bad at visualizing that level of indirection, and it often causes unnecessary pain.
There are two kinds of notifications in Chef - delayed
and immediate
. Immediate notifications are guaranteed to fire if the invoking resource reports it was updated by the last action. Delayed notifications, however, after everything else is finished executing. If the Chef Client Run (CCR) fails to complete successfully, those notifications will not fire. So using a delayed notification to push something to the "end" of the CCR is not guaranteed to execute.
As HolgerJust pointed out in the comments section, Chef 11 will attempt to run delayed notifications, but this is still not a guaranteed action by the Chef Client.
Furthermore (and the real point about promises here), is that Chef only fires notifications if the resource reports it was updated by the last action. Consider:
user 'sethvargo' do
# ...
notifies :restart, 'service[tomcat]'
end
# ...
service 'tomcat' do
action :nothing
end
The first time this run executes, it will create the user named "sethvargo", which will send the :restart
action to the tomcat service. However, on subsequent runs, the user "sethvargo" already exists, so the notification will not fire.
In your particular example, if s3_file
reports that it was not updated by its last action (aka it did not alter the state of the system), the notification will not fire. That might not seem terrible, until I tell you that updated_by_last_action
is a property that the cookbook developer must proxy. Additionally, it was a property that many community cookbooks did not set in the past. It is very possible that the s3_file
resource does not properly record its status, and therefore does not fire notifications.
As a final note:
Deleting the Chef::Config[:file_cache_path]
is probably a bad idea. If there is a specific file you need to delete, just delete that file. Or tell Chef not to backup files using backup false
on your resource.
Upvotes: 1