Update This blog article was written before chef 12.6 which now includes a
:before notification timer. Take a look at how it works here:
Chef is awesome. The one feature that chef 12 is missing is the ability to do a conditional notify before another resource. I don’t blame chef since no other configuration management tool I’ve tried supports this either. Normally this should be provided by the package.
Windows machine with a custom DLL that is managed by a cookbook. The dll is needed by a service that is also managed by the cookbook.
What do you do if you need to stop the service before you replace the dll. While chef cookbooks run in order, there is no way to determine that a resource is about to be updated. You can use null resources, and send a notify to stop a service, but you can’t know that the service needs to be restarted until after the file is replaced.
Option A: Ask the developer who made the dll to make an MSI package that handles the services (not likely to happen).
Option B: Use the food taster design pattern. (I just made that term up)
Hundreds of years ago, kings and leaders would have prisoners taste their food before they ate so they could determine if the food was poisoned. We will use the same principle to determine if a file is about to be changed.
powershell_script 'stopService' do guard_interpreter :powershell_script code <<-EOH Stop-Service 'foo' EOH only_if "(Get-Service -Name foo)" action :run end cookbook_file 'c:\\windows\\foo.dll' do source 'foo.dll' action :nothing end cookbook_file 'c:\\windows\\foo-chef.dll' do source 'foo.dll' action :create notifies :run, "powershell_script[stopService]", :immediately notifies :create, "cookbook_file[c:\\windows\\foo.dll]", :immediately end powershell_script 'startService' do guard_interpreter :powershell_script cod <<-EOH Start-Service 'foo' EOH only_if "(Get-Service foo.status -eq 'Stopped'" action :run end
Here we have 2 identical files c:\windows\foo-chef.dll c:\windows\foo.dll
If the foo-chef.dll is updated, then chef stop the service and replace the real dll