Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 only 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.

like image 679
richardkmiller Avatar asked Aug 26 '11 19:08

richardkmiller


2 Answers

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.

like image 128
freiheit Avatar answered Sep 24 '22 01:09

freiheit


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",
like image 26
Chris Robinson Avatar answered Sep 24 '22 01:09

Chris Robinson