Issue #8040 has been updated by John Bollinger.
Chris Price wrote: > 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. Are you perhaps forgetting an important class of people when you declare a "general consensus"? Inasmuch as I don't recall anything about this idea having been discussed on puppet-users, and in particular inasmuch as I personally disagree, it seems a bit of a stretch. I am prepared to eat crow if somehow I missed this, but I don't miss much that passes through the list. > * 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. I beg to differ. Perhaps it would be possible to limp along without the functionality currently provided by "include", but those semantics are worthwhile. Among its more common uses, "include" may express * a logical dependency arising because the class in which it appears refers to variables or resources declared in the included class (which does not inherently have order-of-application implications), or * a client-side functional dependency without order-of-application constraints Unneeded relationships should be avoided, because each relationship requires Puppet to consume more memory to track the relationship and to expend more effort to choose an application order, and because unneeded relationships may create cycles that otherwise would not exist. I particularly object to the premise that the semantics of "include" are prone to causing ordering issues. Ordering issues arise because manifest authors either under- **or** over-specify resource relationships. I don't see how one can reasonably expect that reducing authors' expressive options will reduce ordering problems. In any case, the semantics of "include" are not responsible for any such problem. Every ordering problem can be laid squarely at the feet of one or more manifest authors. Moreover, I don't see how forcing manifest authors to express unneeded relationships is likely to make ordering issues less frequent or easier to resolve. With repeatable ordering it may be trickier to *detect* ordering issues arising from missing relationships, but once they are detected they are usually fairly easy to resolve. Certainly, they are no harder to resolve with "include" being present than if it were unavailable, and I'm inclined to think that "include" makes resolving such issues easier. On the other hand, resource cycles, excessive memory usage, and excessive CPU usage arising from excess relationships are more difficult problems. I don't have sufficient visibility to confidently judge whether manifests tend to under-specify relationships, but I don't think it's as simple as that. Discussion on the user list leads me to believe that it's not so uncommon for people to over-specify relationships as well. That seems to happen when manifest authors confuse functional dependency (resource A must be configured for resource B *to operate properly*) with order-of-application dependency (resource A must be configured for resource B *to be configured*). The former does not require any special treatment by Puppet. > * 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. Surely you're joking. What would even be desirable about changing the well-established semantics of an existing function to something markedly different? Notwithstanding the loss of the useful functionality that would be replaced, how is backward compatibility not an overriding concern? The usual practice for this sort of thing is to *deprecate* old functionality prior to removing it, and to introduce new functionality in a way that avoids conflict with the old. Not that I want to see "include" deprecated, but I absolutely do not want to see it replaced by something different under the same name. ---------------------------------------- Bug #8040: Classes should be able to contain other classes to provide a self contained module https://projects.puppetlabs.com/issues/8040#change-68410 Author: Jeff McCune Status: Accepted Priority: Normal Assignee: 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 puppet-bugs@googlegroups.com. To unsubscribe from this group, send email to puppet-bugs+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-bugs?hl=en.