On Jan 31, 3:01 am, Felix Frank <felix.fr...@alumni.tu-berlin.de> wrote: > Hi, > > On 01/30/2012 10:28 PM, Nick wrote: > > > It did sound similar, yes - but unless I misunderstand it, not identical. > > For > > example, I don't understand how Constraints would avoid the problems with > > unifying resources that Nan mentioned. > > as far as I understand, there is no need to merge anything. The catalog > will or will not contain a certain resource.
That is correct. Constraints do not have their own separate Resource instances. Instead, they use resource type and title, or perhaps a resource reference, to identify a resource to which they apply. Traditional Puppet rules are in effect -- there is never more than one Resource per catalog for each (type, title) pair. > If existing, the resource > will have a certain set of parameteres and metaparameters. Each > constraint can be individually compared to this state. If a constrained > resource does not exist, or any of its (meta)parameters deviate from > what the constraint defines, the catalog is no longer valid. And that's getting around to the interesting part. Constraints could leave it there, and that would be a good and useful solution. Something like that could even be implemented in 2.7, as it introduces no incompatibility whatever. I am proposing that constraints might go even further, however, in one or both of these ways: 1) Where the resource definition to which one or more constraints apply does not explicitly specify a value for a constrained parameter or property, applicable constraints are used to *choose* a value (rather than allowing that property to take a default value). This would help with the problem of writing compatible resource definitions in the first place. Example: Somewhere: ---- package { 'foo': provider => 'yum' } Somewhere else: ---- constraint { 'my-package-foo-ensure': resource => Package['foo'], property => 'ensure', forbidden_values => ['absent', 'purged'], preferred_values => 'latest' } Yet another other place: ---- constraint { 'your-package-foo-provider': resource => Package['foo'], property => 'provider', allowed_values => 'yum', } The definition of Package['foo'] explicitly specifies the 'provider' property, so Constraint['your-package-foo-provider'] only validates it, failing catalog compilation if the value does not satisfy the constraint. The definition does not explicitly specify a value for the 'ensure' property, however, so Puppet *chooses* one that is mutually agreeable to the relevant constraints. In this case that would work out to 'latest'. If there is no mutually agreeable value then catalog compilation fails. 2) Extending (1), if constraints are declared for a resource that is not otherwise itself declared for a node, then Puppet synthesizes a declaration, using the applicable contraints to set values for all constrained properties. This could be considered a create_resources() on steroids. These would make Constraints much more useful and powerful because they lessen the burden on module users to write suitable resource declarations. Instead of merely testing after the fact whether an appropriate Resource was declared, item (1) would allow modules to *collaborate* to ensure that suitable Resources are declared, without requiring those modules to have any knowledge of one another. Item (2) would further reduce the burden on module users by alleviating any need for them to explicitly declare modules' needed resources anywhere, though they could provide such declarations if they wished, subject to the same rules that apply already. > The beauty of this design is that the language is very expressive and > all validation can be done by the master. > > Err, right, John? :-) Indeed, the language is not only expressive, but also completely compliant with current DSL syntax. I'm not sure how magical the implementation of the Constraint [meta]resource type would need to be, but at least in principle I think it fits very cleanly into Puppet's model. Furthermore, because all the work is done on the master, *nothing* about the agent or any provider needs to change. Probably no resource type implementation needs to change, either. > > John's example appeared to be wrapping an existing Resource with something > > which > > puts constraints on it, i.e. a layer on top of "Resources". It implies a > > regular > > Resource to wrap somewhere. > > > Whereas what I had in mind was something which in principle at least, was > > more > > basic than a Resource. With an "Assertion" there is nothing being managed, > > or > > mutated, by definition. It defines conditions on a resource (lower-case 'r') > > which can be checked, and merged, but doesn't imply that any Resource > > (upper-case 'R') need to be declared. It's quite possible that one wouldn't > > bother, if you don't need to manage or mutate anything. > > Ah, so you'd have the agent verify if all assertions (which need to > appear as first-class citizens in the catalog) hold true, and otherwise > fail the catalog? And here you have hit on some of my main issues with Assertions, as I understand that proposal: 1) Assertions are tested by the agent (or else they do nothing that constraints do not also do), so they need to be represented in the catalog. This makes them no lighter-weight than ordinary Resources as far as I can tell. 2) Supposing that Assertions are indeed tested by the agent, they defer catalog failures to the agent, which makes module interoperation (the issue we're trying do deal with) harder to test. 3) Assertions leave the burden on module users to provide resource declarations that are agreeable to all modules. > That strikes me as very elegant indeed. I'm not persuaded that it is a broadly useful capability. I acknowledge that there may be cases where one wants the agent to perform a test without changing anything. At present, one would probably use an Exec for the purpose. I tend to think, however, that such cases usually reflect module design shortcomings. The Puppet paradigm is to tell the agent how a node should look, then let the agent make it so. Why, then, would it be desirable to give the agent contradictory node descriptions? Why would it be desirable to give the agent a node description, but not allow it to make the node meet the description? How would either capability further the goal of module interoperability? Especially, why should an interoperability solution that relies on such behaviors be preferred to one that does not? Assertions would be an interoperability aid for one of the same reasons that Constraints would be: they would allow modules to express resource requirements without actually declaring resources. This is a better solution than merging multiple Resource declarations would be because modules' requirements are expressed precisely, and also because there is no change to the invariants of Puppet's data model. In these respects, however, Assertions offer nothing that Constraints do not also offer. > How will situations be handled where assertions won't hold true until > parts of the catalog have been applied? That, too. Assertions would need their own support for resource relationships to adequately address that issue. At this point they don't look lightweight at all to me; rather they look like a full- blown new [meta]resource type (as Constraints also would be). Implementation of Assertions separate from Resources, as Nick suggests, would be tricky. The Assertion provider would need to somehow hook into all other providers, including custom ones, to test whether assertions were satisfied. > > So Resources (upper case 'R') could be thought of as extensions to > > Assertions > > which also supply rules to mutate a system's state, should the conditions > > of the > > Assertion not be met, so that the conditions *are* met. > > Let's not alienate the community by declassing the proven and beloved > Resources ;-) but I've got to say, this idea does hold merit. I think the best chance of integrating something like Assertions into Puppet is to flip that around: assertion nature could be an attribute of (some) Resource instances. Consider its similarities to the effects of the 'audit' metaparameter, for instance. Only in that way can I reconcile Nick's characterization of Assertions as "lightweight" and "low-level" with the apparent design and implementation requirements. > So does the constraint idea. Something tells me that both might be of > benefit, but I'm afraid of years of user confusion to come when everyone > is tasked with understanding the difference between the two and to > decide when to use which. > > If we need to take a pick, there's two things I'd have to say for > constraints: > 1. They're more closely tailored to the problem at hand. > 2. They're stronger in chorus with what puppet is today. > > Assertions would probably widen the borders of what's possible with > puppet (and how easy it is), and they would allow/require us to part > with some paradigms. I'm torn whether we want this sooner than seeing > the multiple declaration problem sorted out in a less intrusive way. There may well be a better solution for module interoperability than Constraints, but Assertions (as I understand them) are not it. I can, however, imagine using Assertions similarly to how I use the like- named features of C and Java -- to validate assumptions and internal consistency in catalogs. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.