Ubuntu – chef: how to reboot a node only if a confg file is modified

amazon-web-serviceschefUbuntu

ENVIRONMENT: aws opsworks chef 11.10 and ubuntu 14.04.

I'm using a chef recipe to update the /etc/dhcp/dhclient.conf file on an aws opsworks ec2 node in order to add my custom dns search suffix to the search line in the /etc/resolv.conf file.

How do I get my recipe to reboot the node ONLY if the file.insert_line_if_no_match updates the file? I obviously don't want the node rebooted every time the recipe is run.

In my code snippet below the value of node['opsworks']['stack']['name'] is something like a.dev.mydomain.com.

ruby_block "add custom dns domain search suffix" do
  block do
    file = Chef::Util::FileEdit.new("/etc/dhcp/dhclient.conf")
    file.insert_line_if_no_match("/append domain-search/", "append domain-search \"#{node['opsworks']['stack']['name']}\";")
    file.write_file
  end
end

The code snippet above adds the last line to /etc/dhcp/dhclient.conf:

# Configuration file for /sbin/dhclient, which is included in Debian's
#       dhcp3-client package.
#
option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
send host-name = gethostname();
request subnet-mask, broadcast-address, time-offset, routers,
        domain-name, domain-name-servers, domain-search, host-name,
        dhcp6.name-servers, dhcp6.domain-search,
        netbios-name-servers, netbios-scope, interface-mtu,
        rfc3442-classless-static-routes, ntp-servers,
        dhcp6.fqdn, dhcp6.sntp-servers;
append domain-search "a.dev.mydomain.com";

After a reboot, the /etc/dhcp/dhclient.conf is modified as follows:

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 172.16.0.23
search ec2.internal a.dev.mydomain.com

NOTE: I think it is too risky, to try to implement the setting with something like a sudo dhclient -r; sudo dhclient after the file update, but I'd love to hear if anyone has gotten this type of update to work without a reboot.

Best Answer

I would strongly suggest you find a way to do this without restarting the machine. I did something similar on Centos, for example, which was accomplished with a sudo service network restart. Nonetheless, whether you restart the machine or just a single service, you'll use the same pattern.

The "right" way

The right way to do this is with a custom resource/provider. In this case (and there may very well already be one in the community), you would write an LWRP that reads the dhclient.conf file and only modifies it if a change is needed. It would then set updated_by_last_action if the file is updated. At that point you could use a service or execute resource to restart the service/machine. The restart resource would subscribe to changes to the LWRP resource.

The almost as cool way

Or, you do something like this:

execute "add custom dns domain search suffix" do
  command "echo 'append domain-search \"#{node['opsworks']['stack']['name']}\";' >> /etc/dhcp/dhclient.conf"
  not_if { ::File.open('/etc/dhcp/dhclient.conf').read() =~ /append domain-search/ }
end

execute 'restart machine' do
  command 'shutdown immediate -r'
  action :nothing
  subscribes :run, 'execute[add custom dns domain search suffix]'
end