FAQ

On Tuesday, June 4, 2013 1:22:08 AM UTC-5, Tom Lanyon wrote:
I'm testing a 'cleanup' stage which runs after Stage[main] and removes a
bunch of package resources.

To do this, I tried a simple check of defined(Package[<foo>]) combined
with a custom facter fact (called 'app_packages'):
class app::package::cleaner {

define check_and_remove {
if !defined(Package[$title]) {
package { $title:
ensure => absent
}
}
}

$apps = split($::app_packages, ',')
check_and_remove { $apps: }

}

node 'foo' {
class { 'app::package::cleaner': stage => 'cleanup' }
}
Unfortunately, this results in a dependency cycle. It appears that
putting the Package[$title] resource reference in defined() actually
invokes an implicit dependency between my cleanup helper resource in the
cleanup stage and the original Package resource in the main stage.
Augeas[redacted] => Service[iptables] => Class[Iptables] => Stage[main]
=> Stage[cleanup] => Class[App::Package::Cleaner] =>
App::Package::Cleaner::Check_and_remove[package-434] =>
Package[package-434] => Exec[app-graceful-restart] => Class[App] =>
Stage[main]
Does it do that when Package[package-434] is already declared elsewhere, or
only when it is not?


Is this implicit dependency expected behaviour or am I doing something
Bad(tm)?
Both.

Supposing that the target package is not declared elsewhere (so that the
!defined() condition is true) the definition will declare the package
itself to ensure it absent, and in that case you would expect a
relationship between the defined-type instance and the resource declared by
it. If elsewhere you have specific references to that package, applicable
resource parameter defaults, or collectors that will match that package,
then you can get relationships with it that are not evident from the
defined type body.

On the other hand, defined() is evil. Do not use it. Ever. I usually
attribute its malignancy to the parse-order dependency it inherently
creates -- which is indeed a serious problem -- but in this case I think
trying to use it to approach your problem it has also obfuscated your
manifests enough to confuse you about the scope and nature of some of your
other declarations.

Instead of using defined(), you can apply logic farther upstream to make
the correct declaration in the first (one) place or to apply resource
parameter overrides to the correct resources. Alternatively, you can
simply determine by other means what packages need to be ensured absent,
such as by filtering a list of possible packages against a list of packages
that are supposed to be installed. Some of those options may still
susceptible to the problem you observed, however, if relevant relationships
spring from declarations elsewhere, as I described they may do.

For the record, however, no order-of-application relationship should be
implied by the reference itself. Therefore, when the referenced Package is
declared elsewhere (so that the !defined() condition is false), there
should be a relationship between
App::Package::Cleaner::Check_and_remove[foo] and Package[foo] only if that
relationship is declared somewhere else.


John

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscribe@googlegroups.com.
To post to this group, send email to puppet-users@googlegroups.com.
Visit this group at http://groups.google.com/group/puppet-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 2 of 9 | next ›
Discussion Overview
grouppuppet-users @
categoriespuppet
postedJun 4, '13 at 6:23a
activeJun 14, '13 at 2:28p
posts9
users2
websitepuppetlabs.com

2 users in discussion

Jcbollinger: 5 posts Tom Lanyon: 4 posts

People

Translate

site design / logo © 2022 Grokbase