2
votes

I have a Puppet class which, among other things, sets up a whole bunch of Debian repositories, performs an apt-get update and then installs a few packages.

The ordering must be strictly as follows:

  1. setup apt sources
  2. apt-get update
  3. install application packages

To define the ordering, I have used the following chaining after declaring all of my resources:

File['/etc/apt/apt.conf','/etc/apt/sources.list'] ->
Exec['apt-get update'] ->
Class['vim','sudo', ..., ..., ]

However, here is the issue:

If I set vim to install only if the host is a virtual machine, and the host I am performing the Puppet run on is physical, the run will fail. I assume this is because it is attempting to run Class['vim'] as per my chaining but cannot find the class declaration due to the contents of the if statement not being parsed.

Here is the code:

if $::is_virtual == 'true' {
    class {'vim': 
      set_default => true,
  }
}

I can work around this by adding a "requires => Exec['apt-get update']" to my vim resource declaration and removing from my chain, but this feels a bit hacky. Here is what my class declaration looks like once I do this:

if $::is_virtual == 'true' {
    class {'vim':
      requires => Exec['apt-get update'],
      set_default => true,
  }
}

Does anybody have any other methods of dealing with such ordering issues? Is there anyway I can deal with ordering classes held within conditional statements which may or may not be triggered via chaining? Any advice is appreciated.

1
Writing dependency chains like this is hacky exactly because of issues like the one you're dealing with now. It's much safer to handle dependencies by require/notify/subscribe. - Mateusz M.

1 Answers

1
votes

Your approach using require is sound. If you really have to stick to the chaining operator, you can wrap the if block in yet another class.

class site::vim {
    if $::is_virtual == 'true' { ... }
}

Then include and chain Class[site::vim], which will honor the is_virtual value on its own.