Search code examples
rubychef-infrachef-recipe

Can I use guards to chef if a windows service is running?


I'm writing a chef recipe and on this I need to perform an operation (run a batch) only if a service is not working. I use this snippet:

batch 'run commnad' do
  cwd target_path + '/bin/win64'
    code 'command to be executed'
    not_if '::Win32::Service.exists?("Service name")'
end

But it does not seems to work. After seeing this question I changed the process using an if clause instead of the guard and it works fine:

if !::Win32::Service.exists?("Service name") then
  batch 'Install zabbix agent' do
    cwd target_path + '/bin/win64'
    code 'command to be executed'
  end
end

But this should not be, for what I understood, the right way to manage this, so I'm wondering: why is the guard not working properly?

Thanks, Michele.


Solution

  • The way you wrote your not_if statement runs the command as a shell script. The shell doesn't know Ruby code, so the whole command will fail. Need to first:

    require win32/service

    In order to use not_if with Ruby code you should put it inside a block instead:

    not_if { ::Win32::Service.exists?("Service name") }
    

    See some more examples here (search for not_if on the page):
    https://docs.chef.io/resource_common.html