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.

Reply via email to