How to work with Puppet dependencies when installing Nginx 1.0.5 on Ubuntu 11.04
I'm new to Puppet and have a question about working with dependencies.
I'm using Puppet to install Nginx 1.0.5 on Ubuntu 11.04. It requires adding a new apt repository since natty normally comes with Nginx 0.8. At the commandline, the install goes like this:
# apt-get install python-software-properties
# add-apt-repository ppa:nginx/stable
# apt-get update
# apt-get install nginx
So I wrote this Puppet script:
class nginx::install {
package { "nginx":
ensure => present,
require => Exec["nginx_repository"],
}
exec { "add-apt-repository ppa:nginx/stable && apt-get update":
alias => "nginx_repository",
require => Package["python-software-properties"],
}
package { "python-software-properties":
ensure => installed,
}
}
The script works, but the exec{} directive runs every time, instead of 开发者_如何学Pythononly when nginx is actually being installed. Ideally, I'd like the "apt" commands to be run only before actual nginx installation, not when nginx installation is simply being checked.
I have a rudimentary understanding of the notify/subscribe model, but I wasn't sure how to have the nginx directive send a "notify" signal only when actually installing nginx.
Here are two approaches for fixing this:
1)
exec { "add-apt-repository ppa:nginx/stable && apt-get update":
alias => "nginx_repository",
require => Package["python-software-properties"],
creates => "/etc/apt/sources.list.d/nginx-stable-natty.list",
}
That will tell the exec to only run if that file doesn't exist. If there's some other way to check that the exec has run successfully, you could have an onlyif =>
or unless =>
to specify a command to check.
2)
exec { "add-apt-repository ppa:nginx/stable && apt-get update":
alias => "nginx_repository",
require => Package["python-software-properties"],
refreshonly => true,
subscribe => Package["python-software-properties"],
}
That will tell the exec to only run if it's notified, and will tell that package to notify the exec that it should run. (You could instead specify notify => Exec["nginx_repository"]
in the python-software-properties package stanza; the effect of a notify on one end of a relationship is the same as a subscribe on the other end of the relationship.)
The downside of the second approach is that if anything goes wrong, puppet will never figure it out, and if the package is installed some other way than via that puppet rule (such as pulled in as a dependency elsewhere) it will never run the exec (and the nginx package install will keep failing).
In other words, the first approach of having the exec have some way of checking whether or not it has already run is vastly preferable.
You can ensure version independence by using the Facter variable lsbdistcodename
as in the following modification to the creates
attribute in freiheit's code:
exec { "add-apt-repository ppa:nginx/stable && apt-get update":
alias => "nginx_repository",
require => Package["python-software-properties"],
creates => "/etc/apt/sources.list.d/nginx-stable-${lsbdistcodename}.list",
}
For Ubuntu 12.04 Lucid this expands to:
creates => "/etc/apt/sources.list.d/nginx-stable-lucid.list",
精彩评论