On 2014-09-07 20:56, John Bollinger wrote:


On Tuesday, July 8, 2014 3:16:46 PM UTC-5, henrik lindberg wrote:

    On 2014-08-07 18:09, John Bollinger wrote:
     > I tried hard to not like this, but then I recognized how
    congruent it is
     > -- or could be -- with one of my pet ideas: resource constraints.
      Felix
     > implemented part of that idea, but as I understand it, he handled
    only
     > the diagnostic part (recognizing whether constraints were
    satisfied) and
     > not the prescriptive part (updating the catalog, if possible, to
    ensure
     > that declared constraints /are/ satisfied).
     >
     > I don't much like the idea of "overriding" resource declarations as
     > such, but it's not such a big leap to reposition that as simply
     > declaring additional requirements (i.e. constraints) on resources
    that
     > (may) be declared elsewhere.  We get the rest of the way to a
    limited
     > form of prescriptive constraints by collapsing this variety of
    resource
     > overrides with resource declarations.  In other words, consider
    these
     > two expressions:
     >
     > file { '/tmp/hello': ensure => 'file' }
     > File { '/tmp/hello': ensure => 'file' }
     >
     > What if they meant exactly the same thing?  Specifically, what if
    they
     > meant "there must be a resource in the catalog of type File and name
     > '/tmp/hello', having the value 'file' for its 'ensure' property"?
     > Either one would then insert such a resource into the catalog if
     > necessary, and afterward attempt to set the (then) existing
    resource's
     > 'ensure' parameter.
     >
     > I say "attempt to set" the existing resource's parameter, because I
     > think we still need to forbid modifying a value that was set (to a
     > different value) somewhere else.  And that's more complicated
    than just
     > checking for undef, because it may be that undef is itself the
     > intentionally assigned parameter value, so that it would be an
    error to
     > change it.  It also might need to be more permissive for
    subclasses and
     > collectors.
     >
    Note that collection currently can modify any already set value on all
    kinds of resources (regular, virtual and exported) at any point
    throughout the evaluation. How is it that these "rules" are given such
    mighty powers when a rule such as "File['tmp/foo'] { owner => x }" is
    not allowed to override a set mode of the same file? (I understand the
    need to guard against typos and unintentional changes). Basically I see
    File[id] { x => y } as the same expression as File <| title == id |>
    { x
    => y }.



Well, they are manifestly different at least in that the collector
version will realize the selected resource if need be..  I anyway agree
that there is an issue there, but I'm not confident that I characterize
it the same way you do.  That is, I don't think File[id] { x => y } is
too weak; rather, I think File<| title == id |> { x => y } is too
strong.  If one part of my manifest set declares a property value for
some resource, then it is *wrong* for a different part to change it,
because the result no longer satisfies the original requirement.

I can agree with that too. That was my first reaction - overriding anything is just horrible.

There's some room to moderate that position a bit, of course.  For
example, I have less objection to these kinds of changes being performed
via subclasses -- after all, that's the whole point of subclasses.

Yeah, but that is like allowing it if you add "please" to the request,
since there would be nothing stopping you from subclassing and overriding.

One
could also argue, for instance, about whether it should be ok to
override parameters of virtual or exported resources.

I have less qualms about the virtual - they are sort of not baked yet.
It is when they are realized that it gets prickly IMO... also when mutating something that was exported from elsewhere (rewriting history).

I think even
these cases are uncomfortable, but I'm not prepared advocate for their
foreclosure against the opposition that would surely arise.

     > We could go farther with that.  If it seems wasteful to have two
     > different forms of the same statement, then we could apply
    additional
     > semantics to one or the other.  For example, perhaps the
    lowercase form
     > could implicitly declare all unmentioned parameters as undef,
    with the
     > effect that they could not be overridden to anything different..  I
     > don't know whether that would be useful, or whether there is some
    other
     > behavior that would be more useful.  Perhaps it would be best to
    just
     > let the two forms be equivalent, or maybe even to deprecate one.
     >
     >
     >     Anyway, a few corner cases exist. A +> is only allowed if it
    is a
     >     default or override expression.
     >
     >
     >
     > +> is a bit of a dark horse in the regime of overrides, as
    modifying a
     > previously-declared parameter value is inherent in its design.
      On the
     > other hand, it is currently useful for overrides only in
    subclasses and
     > collectors, where modifying a declared value is considered
    acceptable.
     > I don't think it's a major issue that evaluating a statement
    containing
     > a plussignment may yield an error, as long as the meaning of the
     > statement is not itself in question.
     >

    I like the direction this is going! You are absolutely right that
    basically all these expressions (resource attribute settings,
    "overrides", defaults) basically define a set of rules that together
    should define the resulting resources and the values of their
    attributes
    (call them constraints or rules).

    This would mean that +> would be perfectly valid even in definitions
    that does not modify something inherited, instead it basically says
    "use
    both what someone else said, and what I said" (if the parameter can
    hold
    multiple values).



Yes, that's a good reinterpretation.  One of Puppet's weaknesses in this
area is that it currently has few good ways to distinguish parameter
values that are hard requirements from those that are preferences, nor
to distinguish inclusive requirements from exclusive ones.  Using +> to
designate inclusive requirements would help that out some, at least for
multi-valued parameters.

Yes, there needs to be a way to tell puppet how strongly something is
desired... - we could end lines with 'please', 'pretty please' and 'or be killed', the more expletives the higher the desire...

That model breaks down too when used wrong (or facing pathological cases) - look at the number of !important that people have to put into a CSS to get styling right...

There are a number of different cases here:

- I don't have a value, you must supply one
- I have a default value, you may change it
- Once I am given a non-default value, I may not be changed
- I have a constant value
- I can answer if my (current) value is a default value
- You can change my value back to the default (without knowing what that value is)
- I get my value from a provider of a value, you can supply the provider
- You can add values, but not remove any
- Values you set can be changed only by you
- My value is derived from other values
- etc... etc...

And that needs to be joined with a mechanism of who's statement about these things that have precedence:

- by weight
- by time
- by composition (stratas/layers/hierarchy)
- by additional meta rules (rules that describes the importance of the other rules)


     >
     >     Do you like these ideas? Is it worth trying to make this work
    to try it
     >     in practice? (it will take 1-2 days for the implementation,
    and a bit
     >     more to fix all breaking tests).
     >
     >
     >
     > As I said before, I tried to dislike them, but I like them despite
     > myself.  Especially if you're willing to accept my extension.
     >
     >
    Yes, I think your extension was that there is no difference between a
    LHS that is a type (e.g. Notify), and a lower case name of a type (e.g.
    notify). I agree completely.



Yes, that's basically it, but don't overlook that making it so requires
adjustments to the semantics of /both/ kinds of statements.

Oh, yeah.

- henrik

--

Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/

--
You received this message because you are subscribed to the Google Groups "Puppet 
Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-dev/lpka0i%24oje%241%40ger.gmane.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to