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.