On Sep 18, 2010, at 3:39 AM, Nigel Kersten wrote:

> On Fri, Sep 17, 2010 at 2:20 PM, Luke Kanies <[email protected]> wrote:
>> On Sep 16, 2010, at 11:29 PM, Nigel Kersten wrote:
>> 
>>> On Thu, Sep 16, 2010 at 7:02 PM, Luke Kanies <[email protected]> wrote:
>>>> On Sep 16, 2010, at 9:48 PM, Nigel Kersten wrote:
>>> 
>>>>>>> So the plan is that the only place you can reliably set global
>>>>>>> resource defaults is directly in your site.pp or in an *import* from
>>>>>>> site.pp ?
>>>>>> 
>>>>>> It's more of a hope than a plan at this point, but really, every 
>>>>>> variable is functionally global, in that you can refer to it from 
>>>>>> anywhere else using the scoping syntax.
>>>>> 
>>>>> Sure, but this model doesn't hold for resource defaults :)
>>>> 
>>>> True dat.  Sorry, I somehow missed that specified resource defaults.
>>>> 
>>>> How do you use them now?  And if you can provide a bit of depth, I'd 
>>>> appreciate it - that is, how deep the class structures go, whether classes 
>>>> set defaults for orthogonal classes (e.g., security for web), and 
>>>> especially whether you have orthogonal, non-global defaults (e.g., 
>>>> defaults that apply non-globally but to more than one portion of your 
>>>> class heirarchy).
>>> 
>>> We would use them even more if you could easily append to resource
>>> defaults...  :)
>> 
>> Huh, I thought we could.
> 
> You can't in any way that I've seen.
> 
> http://projects.puppetlabs.com/issues/871
>  which I hadn't seen, otherwise I wouldn't have filed:
> http://projects.puppetlabs.com/issues/2585

Those are actually slightly different tickets - Jeff's modifies the default 
values, and yours combines the default values with any specified values.

But yeah, it's clear we need to sort that out somehow.  I think yours is the 
harder of the two.

>>> We use them to essentially set up global before/require relationships
>>> between resources and classes, and to set providers for resource types
>>> where there either isn't a default or the default isn't what we want.
>> 
>> So either entirely or essentially global defaults?
> 
> Yes.

In that case nothing in my original proposal (get rid of dynamic scoping) 
really hurts your ability here, since it would only affect non-global defaults.

>>> We have an apt::update class that all packages are set to require, and
>>> that all repositories are set to be before.
>> 
>> This kind of thing would be well-supported by the ability to do something 
>> like include defaults (and maybe variables) from one class into another - 
>> akin to including a Module in ruby.  E.g., with this setup:
>> 
>> class apt {
>>  Package { provider => apt }
>> }
>> 
>> class main {
>>  extend_with apt
>> }
>> 
>> That would take all of the defaults and add them to main, as though they 
>> were defined in main directly.
>> 
>> Would that provide sufficient equivalent functionality?
> 
> So you'd have to do this in every single class in which you defined a
> package resource? That seems less optimal to me.

Not at all - the point is that you'd do it in the top-level main class, and it 
would affect all classes.  So you'd only need to do it once for each package 
type (or other resouce type) per platform or whatever.  I.e., it would look a 
lot like what you do now.

>>> We used to make heavy use of the inherited scope for resource
>>> defaults, but partly due to maintenance issues and partly due to
>>> seeing the writing on the wall on the dev list, we've started using
>>> defined types instead.
>>> 
>>> ie rather than a simple file and exec, both with resource defaults, we
>>> instead make a defined type to abstract them both away. We should
>>> probably have been doing this in the first place.
>> 
>> Do you find this to be a sufficient, or even better, replacement, or do you 
>> just use it because you figure it's more supported?
> 
> For cases like a simple file and exec, we find it to be a better
> replacement, but we're starting to see some of the complications (post
> coming to dev-list soon about this actually).

I'll look for that.

>>>> I've got some ideas for how this might work, including adding a kind of 
>>>> 'add defaults from class A to my class' behaviour, but they're very 
>>>> nebulous.
>>>> 
>>>>>>> and thus not inside a class that may include all your other classes?
>>>>>>> (we have a module 'base' that does all the logic for which other
>>>>>>> classes should be included)
>>>>>> 
>>>>>> This can be pretty easily done using fully qualified variables, but it's 
>>>>>> even better done using extlookup or equivalent.
>>>>> 
>>>>> I disagree pretty strongly that extlookup is better for this specific
>>>>> purpose, even acknowledging how fully qualified variables let you
>>>>> achieve this under the proposed model, and that separating data from
>>>>> models is generally awesome.
>>>> 
>>>> I'd like to hear more about this.
>>> 
>>> It really just comes down to maintainable code that is quickly
>>> understandable. It's much simpler to look in "class base" for the
>>> logic as to what other modules are being included than it is to bury
>>> this data away in extlookup or to put it in the external node
>>> classifier.
>> 
>> But that's only because you're used to looking in that file, right?  Because 
>> shouldn't it generally be easier to see everything in a nice, clean GUI than 
>> that ugly text file? :)
> 
> No way :)
> 
> Are we going to mandate Puppet Dashboard as part of Puppet? I really
> don't see that it fits into everyones workflows....
> 
> We're very much used to reviewing code here, and have an immense
> amount of infrastructure around it.

I've been very open about my goal of getting rid of the 'node' construct in 
Puppet at some point, relying on some kind of node classifier (without any 
requirement that it be a specific one), but I've largely given up on that 
actually happening.

Even having given it up, though, the reason for its existence remains sound - 
Puppet's language should be excellent at building classes, and it turns out 
that associating those classes with nodes can be a very different problem than 
the class definition itself.  This is what drove me to conclude that an 
external node classifier was needed in the first place.

So, it's not so much that I plan on requiring Dashboard, or any specific 
classifier, as that when it comes to compromising node management or class 
definition in Puppet, the choice should be easy, even if doing so actually 
makes node management worse.

As to whether that classifier should use code or a GUI or data or what, I guess 
I'm hoping there are multiple types, but I'd be pretty damn shocked, really, if 
the vast, vast majority of people didn't find a database more appropriate than 
code, just given the ability to inspect the data, do math on it, etc.  I'm a 
code person, too, but there's a lot you can't do with the existing system that 
I think most people -- even code jockeys -- want to do.  Hopefully a 
forthcoming commitment to having CLI access to everything will help.

Does that make sense?

>>> As we have a large and rapidly changing client base, it's easier to
>>> make them self-organizing, with facts that report back certain info
>>> like:
>>> 
>>> * am I a laptop? desktop? server?
>>> * am I in a DMZ?
>>> * what sub-org does my owner belong to?
>>> etc etc
>>> 
>>> and then we make use of those facts to work out what modules should be
>>> imported. This is pretty easily understandable for anyone coming to
>>> the code base for the first time, as they look in base and see
>>> something like:
>>> 
>>> if $owner_org == "engineering" and $hardware_class == "laptop" {
>>>  include engineering::laptop
>>> }
>>> 
>>> That looks (and is) a touch contrived, but we don't necessarily have a
>>> class for every $owner_org, so include $owner_org::$hardware_class
>>> isn't the right solution.
>> 
>> My plan here is to support what we're obligated to call Smart Groups in the 
>> Dashboard - group hosts by fact values, and then allow you to attach class 
>> membership and parameters to those groups.  E.g., in your example, you'd 
>> have a smart group named 'Engineering Laptops' based on a query for all 
>> hosts whose owner_org=engineering and hardware_class=laptop, and you'd add 
>> the 'engineering::laptop' class to it.
>> 
>> Yes, this would be in the dashboard, not the code, but I think that would 
>> end up being more maintainable in the long run, especially since you could 
>> actually quickly see who was actually in that group, which I expect you 
>> cannot do now.
> 
> Again, this all presupposes that we're mandating the Dashboard for
> future Puppet functionality, and I'm not sure I'm entirely comfortable
> with that.

I want to be very clear that I never want to mandate a single solution, but as 
above, I'm certainly hoping that Puppet itself can become much simpler and more 
maintainable by understanding its specific problem domain and getting rid of 
functionality that lies outside of it.

You'll always be able to do the kind of thing you demonstrate above, but that 
doesn't mean we should have as our goal that that be the best way of doing that.

>>> [2] - I still have this pipe dream that we could do away with
>>> environments altogether *if* the external node classifier could set
>>> the modulepath and manifestpath.... Can you imagine how cool and
>>> flexible that would be? It would be trivial to solve the problem of
>>> staged release processes this way...
>> 
>> Hmm.
> 
> Go on... you know this would be awesome.
> 
> Can you imagine being able to essentially create ad-hoc environments
> based upon fact information from the clients?

I'm fine with that as long as the paths don't actually come from the client - 
that's tainted data and shouldn't be used to determine what code is loaded.

-- 
Luke Kanies
http://madstop.com | http://puppetlabs.com | 615-594-8199



-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to