8

I want to run mysql_tzinfo_to_sql whenever the tzinfo package (on Ubuntu Server) changes. I figured Puppet can take care of this.

I thought that either Puppet would react to a change in the package version, or if not, then to a change in timestamps of a file contained in the package.

The only way I can see to do this is to have a resource with no direct action, and have an exec depending on it.

The questions I have are:

  1. Is it possible to define a file that is only used to Notify another resource (such as exec)?
  2. Is it possible to define a package resource so that another resource (such as exec) is activated when the package changes or updates?
  3. Is it possible to define an exec resource that runs a shell command line (with pipes and redirection for instance) instead of a command from the filesystem?

Taken all together, it seems overwhelming.

FOLLOWUP: Fantastic answers! In the interest of completeness (and for the record), I should note the following:

  1. The complete shell command of interest is mysql_tzinfo_to_sql | mysql -u root -p password (it loads tzinfo into a MySQL database for MySQL use).
  2. Auditing of /etc/tzinfo would be futile as this is merely the local time zone configuration; the goal is to watch for changes in the tzinfo data itself (thus the watching of /usr/share/zoneinfo).
  3. Likewise, the contents would be the wrong thing to watch - as they're likely not to change; the best would be to watch the mtime or all since the filetimes should change after every tzinfo update.

Also, James Turnbull wrote all about auditing when it was introduced. The Metaparameter Reference contains a short description of the workings of the audit parameter.

2
  • Did either of the answers actually solve the problem? If so, could you accept whichever one solved it best? I'm also interested in this problem, and it would be a useful pointer as to which to follow up. Sep 6, 2012 at 7:56
  • I never did get this to work entirely - I gave up and just do this from time to time (or during install) by hand.
    – Mei
    Sep 7, 2012 at 21:29

4 Answers 4

7

Use the audit attribute to track the file content or package version number and trigger the change by subscribing to the package resource. A few issues with this, this does not work with --noop because the state.yaml file will update the file md5 checksum/package version in --noop mode. I'm not sure if this is a pending bug since I can't track it down at the moment.

file { '/etc/tzinfo':
  audit => content,
}

exec { '/usr/bin/mysql_tzinfo_to_sql':
  subscribe => File['/etc/tzinfo'],
}

A more reliable method is just to duplicate the file elsewhere and use it to trigger updates (the location isn't important we are just tracking the original tzinfo as source).

file { '/etc/puppet/stage/tzinfo':
  source => '/etc/tzinfo',
}

exec { '/usr/bin/mysql_tzinfo_to_sql':
  subscribe => File['/etc/tzinfo'],
}

The second method of course does not work with packages, but you would avoid the --noop and state.yaml problems.

Regarding the third question, yes, you can use pipe and redirects (use an title and put the command in the command attribute):

exec { 
  '/bin/echo foo | grep foo > /tmp/foo':
}
4
  • This is a fantastic answer - although I'm not interested in watching the current timezone, but in changes to the timezone data in /usr/share/tzinfo. Using 'audit => all' against /usr/share/tzinfo should be enough, right?
    – Mei
    Apr 5, 2011 at 16:16
  • If you are trying to recurse the directory, well that doesn't quite work since audit only work on the specified path and it does not recurse. audit => all means audit all attributes, not all files. I would use the second method with recurse if you choose this method.
    – Nan Liu
    Apr 5, 2011 at 21:39
  • Good point - although I did not mean to recurse. The directory /usr/share/tzinfo should have times change everytime the tzdata package is updated - at least, that was my thinking.
    – Mei
    Apr 5, 2011 at 22:34
  • I needed something similar and tried the first method - an audit on a file. In my case, the file is the commit hash of a git checkout from a previous Exec. The method works, except that the change to the file only gets noticed on the puppet run after the one that changes the file. Aug 9, 2012 at 17:32
5

Yes, you should be able to do this.

*theoretical code example

package{'tzinfo':
  audit  => all,
  notify => Exec['mysql_tzinfo_to_sql'],
}

exec{'mysql_tzinfo_to_sql':
  refreshonly  => true,
  command      => "bash -c '/usr/local/bin/mysql_tzinfo_to_sql >> /var/log/stuff.log'",
}
  1. Yes, via the notify meta-parameter. However I'm not 100% positive that the new audit feature in puppet 2.6 will trigger a notify if the package version changes outside of puppet's control.

  2. Yes, with refreshonly => true

  3. Yes, see my example. Puppet runs exec commands outside of an interactive shell for simplicity and security. You can have puppet use bash in subshell mode with the -c switch, but pay mind to the quotes.

3
  • 1
    refreshonly is important here, I think. The bash command seems incongruous: if that command works, then a normal shell command should work too, right? In any case, it sounds like it does.
    – Mei
    Apr 5, 2011 at 16:15
  • Is it that you need to use bash -c to do a redirection? Sep 6, 2012 at 7:55
  • yes, bash -c is required for shell redirection in this example. Puppet does not use an interactive shell for exec.
    – robbyt
    Sep 6, 2012 at 20:54
2

i believe i've been able to get this working. here's the relevant bits of my puppet manifest:

file { '/usr/share/zoneinfo':
  audit => mtime,
  recurse => true,
  notify => Exec['mysql_tzinfo']
}

exec { 'mysql_tzinfo':
  refreshonly => true,
  command => 'mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql',
}

after the first up, the mysql_tzinfo exec is skipped. tested by touch'ing /usr/share/zoneinfo/Etc/UTC, which promped mysql_tzinfo exec to run on the next up.

2

This question is old, but I wandered across it looking for something else, and wanted to add an alternate answer for consideration.

It doesn't use puppet: Since we're wanting to trigger on an RPM install/update why not use an RPM trigger? It leverages the very system used to do the install, extending it properly in a manner for which it was designed.

Building the trigger RPM is verrry simple, and while it's no fun to learn, once the first one is done it can be repeated for other apps and conditions very easily too -- thus, costs is non-zero but benefits quickly and vastly outweigh those costs.

While we're here for Puppet, and the problem is solvable with puppet, I worry that it's leveraging a weak part of a tool to badly respond to a condition that's much easier to trigger on with a tool that's already on the host and a tool into which most admins on the box should have dipped their toe. Sorry to suggest a solution outside the lines, but if you're wandering across this message in the future like I did, and the RPM trigger is an option for you, please do consider it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .