5

Overview

I just started using Puppet and have been unable to suss something.

Problem

Because of normalization, when I add two classes to a node with packages that have the same dependencies it fails.

In simple terms have duplicate resources - in this case the package libssl.

Note: packages are being held to prevent latest packages being installed.

Question

What's the best practice way to get round this?

class ssh {
  package { 'openssh-server':
    ensure  => installed,
    require => Package['libssl'],
  }
  package { 'libssl': ensure => installed, }
}

class apache {
  package { 'apache':
    ensure   => installed,
    require  => Package['libssl'], 
  }        
  package { 'libssl': ensure => installed, }
}

node server {
  include apache
  include openssl-server

3 Answers 3

7

You have two choices that are going to look almost the same.

1: make it it's own class.

class ssh {
  package { 'openssh-server':
    ensure => present,
    require => Class['ssl'],
  }
}
class ssl {
  package { 'libssl': ensure => present, }
}

2: virtual resource

class vpackages {
  @package { 'libssl': }
}
class ssh {
  include vpackages
  package { 'openssh-server':
    ensure => present,
    require => Package['libssl'],
  }
  realize Package['libssl']
}

I find it better to break dependencies out into their own modules rather than use virtual resources.

2

If you're using the standard package management to manage the packages installed via Puppet than you should be able to leave off the libssl package dependency in Puppet as that will be handled automatically via the package management system on most systems.

On Debian/Ubuntu as well as RedHat/CentOS/SuSE systems the package management tools will look for dependencies and unless you've gone out of your way to stop the default behavior the additional dependent packages will be included when Puppet tells the system to install the package (in your case simply openssh-server or apache)

4
  • Yes this would be OK if the latest packages were being used. In my case older packages are being 'held' and hence the package versions and dependencies have to specified in the class otherwise Ubuntu goes off and attempts to install the latest version. In doing so I have different classes which have the same package dependencies and hence this resource/package is specified in both classes and because of normalization I get an error! hope this clears up the question
    – hokeycokey
    Mar 20, 2012 at 23:01
  • Well Debian/Ubuntu only holds one version of a package in a distro repo. Only way you'd have multiples is if you're pointing to additional repos that duplicate packages. If you're not wanting to run the latest updates that would include security and bug fixes that's great. I always love insecure machines on the network for the script kiddies to find just like the next guy. Mar 21, 2012 at 15:08
  • Yes I have some back port repos for some specific packages. Don't worry there safe from harm ;)
    – hokeycokey
    Mar 22, 2012 at 22:35
  • If that's the case why don't you PIN the back port repo version so it has priority and then you don't have to hold back packages? Mar 23, 2012 at 12:55
0

It's a bit ugly, but there's a defined() function that returns back true/false. This way you can define resources multiple times, but only "realize" them the first time they're evaluated. (use puppet run stages!)

e.g.,

if defined(Package['libssl']) == false {
  package { 'libssl':
    ensure => installed, 
  }
}
0

You must log in to answer this question.

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