6

When defining dependencies in a class each Package can be globally defined just once. I have hierarchy of configuration and some packages should be installed on all machines (that goes to default configuration) but other should be installed only on some category of machines. How I am supposed to check whether that package is already on a machine when Puppet threat is as a duplicate declaration?

  Duplicate declaration: Package[wget] is already declared 

should I use a function like this?

  if defined( Package[$package] ) {
    debug("$package already installed")
  } else {
    package { $package: ensure => $ensure }
  }

I would expect from configuration tool to deal whith this issue by default... am I missing something?

Tombart
  • 2,013
  • 3
  • 27
  • 47

2 Answers2

7

You can use the ensure_resource() from stdlib module:

$packages = $::osfamily ? {
    'Debian' => [ 'fcgiwrap', ],
    'RedHat' => [ 'spawn-fcgi', 'git' ],
}
ensure_resource('package', $packages, {'ensure' => 'present'})

So, say, if git is installed by some other class already, that would be skipped. You should not care of defining a package only once throughout the puppet configuration.

Tombart
  • 2,013
  • 3
  • 27
  • 47
synapse
  • 216
  • 2
  • 3
5

When you have duplicate packages, that's one way of dealing with it. The other way is to avoid the problem in the first place by using virtual resources:

Declaring a virtual resource

class packages {
  @package {
    ['cryptsetup-bin',
     'cryptsetup',
     'cifs-utils',
     'e2fsprogs',
     'libmysql-ruby',
     'parted',
     'pigz',
      'sshfs' ]:
        ensure => present,
    }
}

Realizing a virtual resource (you can realize resources multiple times):

include packages
realize Package['pigz']

Another approach is to separate out the duplicated code into another class - i.e. a 'wget' class.

Reference: Virtual Resource Puppet Doc

рüффп
  • 620
  • 1
  • 11
  • 24
Craig Watson
  • 9,370
  • 3
  • 30
  • 46
  • 1
    by `realize Package['pigz']` you would install just the `pigz` package or the whole group? – Tombart Mar 10 '13 at 18:11
  • Just the `pigz` package. When you define resources like that you can refer to them individually. The packages won't actually be used unless you 'realize' them though. – Craig Watson Mar 10 '13 at 18:42
  • 1
    There's also the singleton module: https://github.com/pdxcat/puppet-module-singleton – ptman Mar 10 '13 at 21:20
  • What happens if another Puppet module also declares the same virtual @package resource? For example, multiple packages referencing something as pedestrian as "openssh-clients" – EmmEff Feb 07 '14 at 18:45
  • @EmmEff If two virtual packages are defined, standard Puppet "duplicate resource" errors will be thrown, hence the importance of declaring virtual resources in one place only. When Puppet compiles the manifest, it will deduplicate realized virtual resources and ensure that only one is created. This is the direct opposite of normally-declared resources, where only one can ever be created. Docs here: http://docs.puppetlabs.com/puppet/3/reference/lang_virtual.html – Craig Watson Feb 07 '14 at 23:26
  • As I suspected... I do not have control of other modules that import common packages. This solution doesn't work for me. Thanks for the clarification. – EmmEff Feb 08 '14 at 23:25