The Puppetlabs docs state that in order for one class to require another class you should use the relationship chaining syntax and declare both classes in your outer nodes.

I have a repo class which creates the yum repo definition that many packages in each modole depend on. In each module I have a Class['repo'] -> Class['modulename'] statement and both classes are declared in the node. However, when puppet runs it doesn't always execute the repo class before the module class as expected. Why not? Example below (puppet 2.6.16):

This question came from our site for system and network administrators.

As per your flag, @Michelle, I've removed the bounty comment. Unfortunately it cannot be changed. However, the bountied question gets attention even without the notice.
–
ThiefMaster♦Jul 27 '12 at 10:41

I like your thinking. I think it's solved in 3.2.* or not?
–
Jimmy KaneNov 19 '13 at 22:24

4 Answers
4

In Puppet 2.6, when a class declares another class, the resources in
the interior class are not contained by the exterior class. This
interacts badly with the pattern of composing complex modules from
smaller classes, as it makes it impossible for end users to specify
order relationships between the exterior class and other modules.

The anchor type lets you work around this. By sandwiching any interior
classes between two no-op resources that are contained by the
exterior class, you can ensure that all resources in the module are
contained.

Have you considered run stages as an alternative mechanism? With a run stage, you can associate a class with a 'stage'. By default, everything occurs during the main stage. But you can set up a stage that occurs before main, and then associate that class with that 'before main' stage.

A repo is a really good candidate for a before stage. You really don't want any packages to be retrieved before your repos are set up the way you want; it can be a massive headache if you are mirroring your own package repos and lag the official repos.

The trickier scenarios are when a new puppetized server accidentally fetches a package before you've even declared you repo, and it gets it from the up-to-date public mirrors; then your repo is installed (and presumably you've remove the public mirrors now). Because this machine 'snuck in' a new artifact, dependency hell situations can easily arise where a too-new package is stopping packages you care about from being installed, because the package in question won't install because it you already have installed a too-new version and many package managers won't downgrade for you; you have to manually intervene. This situation essentially requires manual debugging to fix; just fixing your puppet rules isn't enough because the damage is done.

So just associate all repo definitions with a before phase, and be done with it. Stop tracking dependencies on your packages to repos and breath easier.