Systemd_unit - Use cookbook_file and reload only if changed


Two questions regarding the use of systemd_unit.

  1. How do I make systemd_unit use a “cookbook_file” as the content of a systemd unit file?
  2. I’d like that the systemd_unit is only “reloaded or restarted”, if the definition of the unit file changes. How?

At the moment, I do it like this in my recipe:

systemd_unit_name = "addressservice"
allelv_node = {'id' => "foo"}
src_filename = ::File.join(Chef::Config['file_cache_path'], 'cookbooks', cookbook_name, 'files', 'ubuntu', 'systemd-units', allelv_node['id'], systemd_unit_name + '.service')

systemd_unit "#{systemd_unit_name}.service" do

    action [:create, :enable]
    notifies :reload_or_restart, "systemd_unit[#{systemd_unit_name}.service misc]", :delayed
end # of systemd_unit "#{systemd_unit_name}.service" do

systemd_unit "#{systemd_unit_name}.service misc" do
    name systemd_unit_name
    action :nothing
end # of systemd_unit "#{systemd_unit_name}.service misc" do
  1. So, from the file_cache_path, I read the file and use it as the content for the systemd_unit resource. This seems overly complex and error prone - especially, since I now no longer have “File Specificity” (eg. that /host-$fqdn/$source and /default/$source directory structure).
  2. So that the :reload_or_restart is only done if there was a change, I created a “dummy” systemd_unit with action :nothing, which gets triggered with a notifies action. Is this the right way to go?
  3. What’s the right way to set the “name” of a systemd_unit, if it’s not equal to what’s in the systemd_unit … do line? Is name the right property?

FWIW, we’re using Chef Zero v12.19 on a Ubuntu 16.04 system.


Hi @Alexander_Skwar

Have you tried using templates for creating the unit file?
You could specify a notification to reload/restart the unit file based on the template resource. Every time you would run chef the template resource would generate the appropriate unit file based on the template content. If the there is no difference between the existing unit file and the currently generated unit file, then there would not be a notification fired to the systemd_unit resource

template '/path/to/unit/file' do
  source 'name_of_unit_file_template.erb'
  notifies :reload, 'systemd_unit["#{systemd_unit_name}.service"]', :delayed