Issue #8040 has been updated by Chris Price.

We've had some discussions around this lately, so I'll try to update the ticket 
for posterity:

* There seems to be general consensus that we should be able to get by with 
only two types of "inclusions"; a simple one-level dependency--ala existing 
"require" function--and a "contains" dependency, which basically means 
"anything that has a dependency relationship with me also has the same 
dependency relationship with everything that I am expressing that I 'contain'". 
 For the sake of conversation, we've been using the term "require" to discuss 
the first type of dependency and the term "contain" to describe the second type 
of dependency.

* The current semantics of the "include" keyword (basically: dump this object 
in the catalog without any ordering or dependency information) should not be 
necessary once we have a working implementation of the "require" and "contain" 
semantics.  In fact, the current semantics of "include" probably lead to 
manifests that are not explicit enough, and are prone to causing ordering 
issues that can be difficult to resolve.

* In an ideal world we might like to overlay the new semantics on top of the 
existing terminology; in other words, "include" and the "class {'foo'}" syntax 
would simply change over to the new "contains" meaning.  However, there is 
obvious concern about the backward compatibility issues that this would cause.

* Regardless of the final decision about how this new functionality should be 
expressed in the language, there seems to be general consensus that we should 
try to build a working implementation of it soon.  This could be done as a 
module or function, so as to be non-invasive but available to solicit user 
testing.  We would want to apply this to as many modules on the forge as 
possible (especially those that use the anchor pattern) and ensure that we 
don't come across any unforeseen problems.

* The technical details for the implementation basically just involve making 
sure that every "class" or "container" resource is broken into two nodes in the 
graph: a "before" node and an "after" node.  We will establish implicit 
relationships between contained resources and these "anchor" points 
automatically.  We may try to re-purpose, rename, and clean up the existing 
"whit" nodes, which appear to be a first attempt at doing exactly this... or we 
may get rid of them and modify the "component" nodes to behave this way.

* We intend to change the graph output (dot/graphviz files) to explicitly 
illustrate these before/after anchor points in the graph--right now the graphs 
attempt to hide these.

* We would like to leave the existing catalog format intact as much as 
possible; however there will probably be at least one change required: we need 
a way to distinguish between a "require" edge and a "contain" edge.
----------------------------------------
Bug #8040: Classes should be able to contain other classes to provide a self 
contained module
https://projects.puppetlabs.com/issues/8040#change-63067

Author: Jeff McCune
Status: Accepted
Priority: Normal
Assignee: Chris Price
Category: compiler
Target version: 
Affected Puppet version: 2.6.0
Keywords: anchor containment contain graph modules module self-contained 
dependency reuse usability forge
Branch: 


# Overview #

As a module author, I want to build collections of classes for end users 
shipped as a module.

As a module end-user, I want to manage resources before and that require the 
collection of classes as a self contained unit of functionality.

For example, the end user wants to use a module I write in the following way:

<pre>
node default {
  class { 'java': }
  ->
  class { 'activemq': }
  ->
  class { 'mcollective: }
}
</pre>

Where java, activemq, and mcollective are all discrete modules with multiple 
classes each.  For example, a each module has a class for the packages, a class 
for the configuration files, and a class for the running service if there is a 
service.

With Puppet 2.6, when a class declares another class, the classes are not 
related to each other in any way, containment or dependency.

# Expected Behavior #

The example illustrates the expectation that all resources in the activemq 
module are managed after all resources in the java module and before all 
resources in the mcollective module.

# Actual Behavior #

Without the Anchor Pattern, when class activemq::service is declared from 
within class activemq, the resources float away and are not transitively 
related to java or mcollective.

# Suggested Implementation #

It has been expressed that it may be a viable solution for module authors to be 
able to specify containment edges in the graph from within the Puppet DSL.  
With Puppet 2.6.x and 2.7.x this is not possible.  The Anchor Pattern works 
around this problem by specifying relationship edges to a resource contained 
within the composite class.

# Work Around #

The Anchor Pattern is the current work around for Puppet 2.6.x  When a class 
declares other classes, it should contain them using this pattern:

<pre>
class activemq {

  anchor { 'activemq::begin': }
  anchor { 'activemq::end': }

  class { 'activemq::package':
    require => Anchor['activemq::begin'],
  }
  class { 'activemq::config':
    require => Class['activemq::config'],
    notify => Class['activemq::service'],
  }
  class { 'activemq::service':
    before => Anchor['activemq::end'],
  }

}
</pre>

-- 
Jeff McCune
Puppet Labs
@0xEFF



-- 
You have received this notification because you have either subscribed to it, 
or are involved in it.
To change your notification preferences, please click here: 
http://projects.puppetlabs.com/my/account

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Bugs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-bugs?hl=en.

Reply via email to