On Tuesday, October 4, 2016 at 6:55:36 AM UTC-5, Prunk Dump wrote:
>
> Hello puppet users !
>
> My problem is simple. I use the following classes in three different 
> stages (setup/main/runtime) :
>
> class { 'apt::client':
>       stage => 'setup',
> }
> ...
> ...
> class { 'hostpkg': }
> ...
> ...
> class { 'extrapkg':
>       stage => 'runtime',
> }
>
> The idea is that the "apt::client" class configure the Debian apt tools. 
> Next the "hostpkg" class install and configure the important packages (ex: 
> those needed to allow the connexion of users). And finally the "extrapkg" 
> class install the secondary packages (internet browser etc ...). But 
> sometimes the "hostpkg" or "extrapkg" packages need some extra apt sources, 
> some apt-pinning or the multiarch. So I created three resources/class :
>
>

Do take care to distinguish between operational relationships and 
management relationships.  Puppet class and resource ordering is about 
satisfying *management* relationships -- that is, situations where Puppet 
can manage resource B only after first ensuring that resource A is in its 
intended target state.  Avoid declaring unnecessary relationships, for 
there is no upside at all to having such relationships, and it incurs added 
risk of problems, such dependency cycles.  In particular, just because 
package B uses or interacts with package A does not necessarily imply that 
A must be managed before B, or vise versa.

Especially take care with run stages, for they are nothing more than a 
convenient mechanism to apply relationships to many pairs of classes at 
once.  Almost inevitably they apply a lot of unneeded relationships, but 
they may nevertheless be the best tool for a select few jobs.  Indeed, the 
Puppet docs 
<https://docs.puppet.com/puppet/latest/reference/lang_run_stages.html#limitations-and-known-issues>
 
say this:

[...] *stages should only be used with the simplest of classes,* and only 
> when absolutely necessary. Mass dependencies like package repositories are 
> effectively the only valid use case.
>

I'm inclined to suppose that there may be other valid use cases at certain 
sites, and I don't think the docs are saying that stages are always the 
best solution for ensuring that package repositories are managed before all 
packages, but do take the docs' remark in the spirit in which I think it 
was intended: run stages are the wrong tool for almost every job.

In your particular case, it may be that class apt::client is indeed one of 
those rare classes that make sense in a non-default stage, but class 
extrapkg seems very unlikely to be such a class.  In the unlikely event 
that you need any puppet-application-ordering relationships between 
resources declared in class extrapkg and (other) classes and resources in 
stage main, I see no barrier to declaring those relationships explicitly.  
Relying on doing so instead of needlessly placing class extrapkg in a 
separate stage may solve some of your problems.

 

> define apt::client::pinning( $package = $title, $pin, $priority, $ensure = 
> present)
> define apt::client::source( $sourcename = $title, $type = 'deb', $uri, 
> $distribution = $apt::client::distribution, $components, $ensure = present)
> class apt::client::multiarch
>
> There three resources are contained in the "apt::client" class as they 
> must be run before "apt-get update" (near "apt::client::end").
>


What resources?  I see (definitions of) two resource *types* and one 
class.  Class apt::client may declare instances of the two types; those 
*instances* are then contained by the class.  It might also declare and 
even also contain (in the relationship sense) class apt::client::multiarch, 
but the declaring and containing are separate considerations.  *Under no 
circumstances*, however, should the *definitions* of these types and this 
class be lexically contained within the definition of class apt::client.  
Each definition should appear in its own file.

 

> The problem come when a package in "extrapkg" need for example the 
> multiarch :
>
> -> From the "extrapkg" class I include the "apt::client::multiarch" class 
> to get the multiarch activated
>


Ok.

 

> -> As the "extrapkg" class is in the "runtime" stage, the 
> "apt::client::multiarch" is contained in the stage
>


Only if class extrapkg contains (relationship sense) class 
apt::client::multiarch, unless I've missed a change somewhere.  Indeed, 
lack of the behavior you describe was once cited as a bug, and that bug 
report was rejected.

If you do this ...

# This should be ok:
include "apt::client::multiarch"

... then you do not automatically put that class in the same run stage as 
the class declaring it.  If, on the other hand, you ...

# Don't do this with a class that may also be
# declared by other classes in different run stages:
contain "apt::client::multiarch"

... then you indeed do create a risk of dependency cycles such as you 
describe next.  The run stages docs warn about this specifically.

 

> -> I get a circular dependency as "apt::client::multiarch" need to be run 
> before "apt::client::end" and so after the beginning of the runtime stage 
> as it is included in the "runtime" stage.
>
> How I can declare, inside a stage, a resource or a class that must not be 
> contained in the stage. It is just "required" and must be run inside it's 
> corresponding stage.
>


A resource is always contained by the class that declares it, and will 
therefore be applied in the same stage as that class.  Run stage assignment 
is not transitive, except for contained classes.  Other classes' run stages 
are determined independently of the stage to which the declaring class, if 
any, is assigned.

If you can rely on apt::client::multiarch to be declared independently of 
anything in class extrapkg, as it seems maybe you can do, then one 
alternative is for class extrapkg simply to ignore it.  On the other hand, 
if you must permit multiple classes to declare that class, and especially 
if it self-declares containment within apt::client, which appears may be 
the case, then you should set its 'stage' metaparameter as needed via 
automated data binding.


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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/ddf08859-3932-490d-841e-bb4dd4239c95%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to