On Wednesday, July 2, 2014 7:41:18 AM UTC-5, David Schmitt wrote:
>
>
> John seems to have done more reading on this topic.



Henrik's description conflicted with what I thought I knew, so it made 
sense to check the docs.

 

> If it turns out to 
> be true that subclasses can change already set attribute values (at 
> least +> will do so anyways), the Foo[x][y] is already in a deep 
> hellhole of undefinedness and evaluation order dependency. 
>
>

Indeed so.  Resource overrides of any kind have always been a bit dicey, 
and making resource attributes readable really amplifies that.  Overrides 
would still be an issue even if they were universally restricted to 
attributes having as-yet undefined values because omitting an attribute is 
as much an explicit choice as specifying one is.  Assigning an attribute 
can completely change the meaning of a resource.  Consider:

exec { '/bin/create-world-peace': }

Exec['/bin/create-world-peace'] {
  onlyif => '/bin/rm -rf /*'
}


Hmmm ... 
>
>      @file { "/tmp/fail": content => '', tag => [ 'example1', 'example2' 
> ]; } 
>      File <| tag == 'example1' |> { mode => 0644 } 
>      File <| tag == 'example2' |> { mode => 0755 } 
>
> puppet (apply, 3.1.1) will create /tmp/fail with 0755. Changing the 
> order of the two collectors changes the mode of /tmp/fail. 
>
>

Indeed it does.  The docs warn about that specifically.  Overrides of any 
kind are dicey, but overrides via collectors are by far the worst offenders.
 

> > Now, the function lies - it says that virtual (unrealized) resources 
> > are 
> > also "in the catalog", which is not really true. (The concept of 
> > being "defined" is very loosely, uhm... defined) 
>
> I'm not saying it shouldn't be fixed (probably 4.0 is a good target to 
> do so; creating warnings for the "wrong" cases in 3.7). I'm just saying 
> that I don't see the connection to resource defaults. 
>
>

I don't see it either, though they play in the same neighborhood by virtue 
of their various associations with collectors.  To wit, evaluation of a 
collector can change a resource from being 'virtual' to being 'in the 
catalog', and it is an open question whether or how collector predicates 
should interact with resource defaults.

 

> >>> * The File[foo][mode] syntax for lookup of a resource attribute 
> >>> will be 
> >>> more sane, as it will correctly produce the value at that point in 
> >>> time 
> >>> in the evaluation. It is either the value (explicit or default) 
> >>> that 
> >>> will end up in the catalog for a realized resource, or the explicit 
> >>> or 
> >>> default value of an unrealized virtual resource that *may* get a 
> >>> different value when it is later realized (if realized at all). 
> >>> Thus, 
> >>> with a combination of being able to know if a resource is realized 
> >>> or 
> >>> not, it is possible to also be certain that the value is the value 
> >>> that 
> >>> will end up in the catalog). 
> >> 
> >> Even if it's not realized yet, the value can only change iff the 
> >> current 
> >> value is undef, yes? In that case, I'd start with making accesses 
> >> und 
> >> undef values on not-yet-realized resources invalid. Perhaps even 
> >> detect 
> >> when a evaluation-order dependent value is accessed *after* it 
> >> already 
> >> has acquired a value. 
> >> 
> > If unrealized, the value can change when the resource is realized. A 
> > realized resource attribute cannot be changed. An undef realized 
> > value 
> > can change. 
> > 
> > Sorry, but I don't quite understand what you were saying about making 
> > access invalid. Can you elaborate? 
>
> I was trying to say that when an attribute accessor would fail when 
> accessing still-mutable values, it would not silently switcharoo values 
> when the evaluation order changes. If on the other hand an attribute 
> access would change between an actual value and undef or some 
> not-yet-overwritten default depending on evaluation order, that would be 
> a reason to ban its usage from most systems. 
>
> Given the weak immutability (ha!) of attributes as shown in my example 
> above, attribute accessors are already very dangerous. 
>
>

Yes, they are.  But, oh, so tempting....  That's where my candy metaphor 
came from.

 

> >>> * In case you wonder, the ability to lookup an attribute is 
> >>> available 
> >>> server side, when the catalog is produced. Later default values set 
> >>> by 
> >>> the agent cannot (for obvious reasons) not be computed when the 
> >>> catalog 
> >>> is being compiled. 
> >> 
> >> When/how does the agent apply defaults to resources? Have you ment 
> >> "the 
> >> state the agent reads from the running system"? 
> >> 
> > yes, the agent, when the catalog is applied to the node triggers 
> > logic in types and providers that may "set defaults" depending on the 
> > state of the system where it is running. 
>
> That would be Puppet::Type#newtype#newproperty#defaults_to logic then? 
> I would consider types whose defaults_to implementation acts differently 
> on the master and the agent as Very Special[tm] and dangerous. The 
> default provider being a striking counter example of course. 
>
>

I had supposed Henrik simply meant what the chosen provider (not the type) 
does when no value is specified for some parameter -- i.e. exactly when the 
type *does not* use #defaults_to.

 

>
> A different idea to reduce the scope of the problem: Decouple the 
> defaults discussion from the bog of other undefined behaviour by moving 
> default setting to a very strict localized syntax: 
>
>    file { 
>        mode => 0321, 
>        owner => weird; 
>      "/tmp/foo": content => 'foo'; 
>      "/tmp/bar": content => 'bar'; 
>    } 
>
> could be a shorthand for setting those attributes separately on all 
> files in this block. That would make it immediately obvious, that those 
> defaults have a very limited scope and are applied before the closing 
> brace of the file{}. They become syntactically "atomic". They cannot 
> leak to other files in the same class by scrolling off someone's mind. 
> They cannot interfere with collection. The old syntax can be handled 
> separately for compatibility. 
>


I think that's pretty similar to the proposed new behavior for defaults, 
just retrospective instead of prospective -- they apply only to previous 
(as opposed to subsequent) statements in the same lexical scope, and they 
take effect immediately when declared (as opposed to immediately when each 
affected resource is declared).

There was some discussion around the idea that one needed to track whether 
an attribute obtained its value from a resource default so as to know 
whether it could be overridden (outside a subclass and not via a 
collector), but I'm not convinced that's necessary.  I anyway don't think 
it's a fundamental aspect of Henrik's proposal.  If ignoring the 
distinction means less resource overriding then that's not necessarily a 
bad thing.

 

>
> That doesn't change that all the other 
> mutability/evaluation-order/parse-order problems around collection and 
> overriding may have to be addressed, but it would decouple the problems. 
>
>

I agree that it would simplify matters along several dimensions if defaults 
were applied immediately, without distinguishing between defaulted 
parameter values and others, either at the point where affected resources 
are declared (for Lindberg-style defaults) or at the point where the 
defaults themselves are declared (for Schmitt-style defaults, if I 
understand that proposal correctly).  That is basically how I though they 
worked already, though I now understand at least some aspects of why 
currently they don't actually work that way.

Any way around, I think there will be a major upheaval when the scope of 
resource defaults changes.  Would it at least be possible for their scope 
to continue to extend into defined type instances declared within their 
lexical scope?  That would mitigate the problems a bit, without causing any 
unpredictable evaluation-order dependencies.  That would also be consistent 
with how the metaparameters of a defined-type instance are forwarded to the 
resources it contains.  The semantics of wrapper definitions will otherwise 
change significantly, yet subtly.


John

-- 
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/dab7f6df-c7c8-48ce-92a2-cd57488120e2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to