Using puppet, you can trigger a command after a file is updated. This works really well where I want to update the sendmail.mc
file, run make sendmail.cf
and then restart the sendmail process. This is exactly what I want, but it didn’t work the way I expected.
Setup and Configuration
I have puppet configured to do all of the above via these three types:
service { 'sendmail': name => $operatingsystem ? { Solaris => $kernelrelease ? { '5.10' => 'svc:/network/smtp:sendmail', default => sendmail, }, default => sendmail, }, ensure => running, enable => true, pattern => $operatingsystem ? { FreeBSD => 'sendmail: accepting connections', default => undef, }, subscribe => $operatingsystem ? { FreeBSD => [ File['sendmail.cf'], ], Solaris => [ File['sendmail.cf'], ], default => [ File['sendmail.cf'], File['/etc/sysconfig/sendmail'], ], }, require => $operatingsystem ? { Solaris => $kernelrelease ? { '5.8' => [ Group['mail'], Pkg['sendmail'], Service['network'], File['sendmail.cf'] ], default => [ User['smmsp'], Group['smmsp'], Group['mail'], Pkg['sendmail'], Service['network'], File['sendmail.cf'] ], }, FreeBSD => [ Group['mail'], Pkg['sendmail'], File['sendmail.cf'] ], default => [ Group['mail'], Pkg['sendmail'], Service['network'], File['sendmail.cf'] ], }, } file { 'sendmail.mc': name => $operatingsystem ? { Solaris => '/etc/mail/cf/cf/sendmail.mc', default => '/etc/mail/sendmail.mc', }, owner => 'root', group => $operatingsystem ? { FreeBSD => 'wheel', Solaris => 'mail', default => 'root', }, mode => $operatingsystem ? { Solaris => 444, default => 644, }, notify => [ Exec['make sendmail.cf'], ], content => template('mail/sendmail.mc.erb'), require => [ Pkg['sendmail'], ], } exec { 'make sendmail.cf': command => $operatingsystem ? { OpenSuSE => 'm4 sendmail.mc > sendmail.cf', default => 'make sendmail.cf', }, cwd => $operatingsystem ? { Solaris => '/etc/mail/cf/cf', OpenSuSE => '/etc', default => '/etc/mail', }, path => ['/usr/bin', '/usr/sbin', '/usr/ccs/bin'], creates => $operatingsystem ? { Solaris => '/etc/mail/cf/cf/sendmail.cf', OpenSuSE => '/etc/sendmail.cf', default => '/etc/mail/sendmail.cf', }, subscribe => [ File['sendmail.mc'], ], refreshonly => true, notify => [ Service['sendmail'], ], require => $operatingsystem ? { OpenSuSE => [ File['sendmail.mc'], Pkg['sendmail-cf'], Pkg['m4'], ], default => [ File['sendmail.mc'], Pkg['sendmail-cf'], Pkg['make'], ], }, }
The Problem
When I update the sendmail.mc.erb
template and perform a puppet run (puppet agent --test
) I get this output:
... info: /Stage[main]/Mail::Sendmail::Server/File[sendmail.mc] Filebucketed /etc/mail/sendmail.mc to puppet with sum cebefed3e17bf2a530289e84a7f250e7 notice: /Stage[main]/Mail::Sendmail::Server/File[sendmail.mc]/content content changed '{md5}cebefed3e17bf2a530289e84a7f250e7' to '{md5}b955c571473569ff48c5c392c98edbba' info: /Stage[main]/Mail::Sendmail::Server/File[sendmail.mc] Scheduling refresh of Exec[make sendmail.cf] info: /Stage[main]/Mail::Sendmail::Server/File[sendmail.mc] Scheduling refresh of Exec[make sendmail.cf] notice: /Stage[main]/Mail::Sendmail::Server/Exec[make sendmail.cf] Triggered 'refresh' from 2 events info: /Stage[main]/Mail::Sendmail::Server/Exec[make sendmail.cf] Scheduling refresh of Service[sendmail] notice: /Stage[main]/Mail::Sendmail::Server/Service[sendmail] Triggered 'refresh' from 1 events ...
If I do a ps
, I see the sendmail process has been restarted, but an ls
shows the sendmail.cf
is older than the sendmail.mc
file. Puppet is lying when it said it did the make sendmail.cf
. Even using the --debug
switch does not show any errors nor does it print out any extra information near the Triggered 'refresh'
line.
The Issue and Solution
The other day I needed to create a locate
class. I decided to use an exec
type to run the updatedb
command and used a creates
tag. I defined the tag incorrectly on one class of hosts, so every 30 minutes it would rerun the updatedb
command. This error triggered an epiphany: I have the creates
in the make sendmail.cf
exec type. I wondered if the creates
tag was the source of my problem. Once I removed:
creates => $operatingsystem ? {
Solaris => '/etc/mail/cf/cf/sendmail.cf',
OpenSuSE => '/etc/sendmail.cf',
default => '/etc/mail/sendmail.cf',
},
… the exec
works as I originally expected. The moral of the story is that creates
takes precedence over subscribe/notify
when triggering the execution of an exec
type.