Hi,
I'm doing another pass on the subject (I like to fight for my
ideas ;-)).
You can dump it if it doesn't make any sense as I'm clearly lacking some
deserved sleep :-).
On Mon, 2008-10-20 at 19:09 -0500, Luke Kanies wrote:
> On Oct 18, 2008, at 7:40 AM, Brice Figureau wrote:
> > [snipped]
> > We could have a syntax that means "collection" as a new puppet type.
> > We could even store a collection in a puppet variable.
> > If the result of the collection is "not used" (ie a statement
> > instead of
> > a rvalue), then it means "realize/import/override"
>
> If we store a collection in a variable, does that mean it doesn't get
> evaluated? If we do so, does that mean we can do things like:
>
> $variable { foo => bar }
I guess so. Note that I wrote this without really thinking about the
whole consequences on puppet :-)
> Is there a difference in what the collection does (other than,
> obviously, the override) between a collection with and without an
> override? I.e., if we wanted to collect virtual resources, realize
> them, and override them, would it take two collections (one to
> realize, one to override)? I think I know the answer, based on the
> text below, but figured I'd ask.
I don't think so. You can override and realize (or collect) at the same
time in the same syntax, isn't it?
> If we have a query with no source (or @ symbols) and no override, what
> does it mean? Is it a language warning?
It is a language error if used as a plain statement or left value.
In the current puppet, you can't write an isolated:
File["/tmp/toto"]
It's the exact same thing, it has no meaning.
It _could_ be used as a reference to a collection in what I originally
had in mind, if used as an rvalue.
OK, maybe this has no use or no meaning, but the "collection" syntax
would allow to express:
file {
...
require => @File[ tag == "ldap" ]
}
> >
> > Let's say we have a language structure that "builds" a collection. We
> > have to say
> > * where this collection comes (catalog, external source of any kind,
> > virtual)
> > * selecting/filtering query
> > * any override
> >
> > Maybe we can introduce a new keyword?
> > collect<Resource>(source)[query] { override }
> >
> > Or maybe write it simply like this:
> > Resource(source)[query] { override }
> >
> > I always thought the <| |> and <<| |>> syntax was not fitting
> > perfectly
> > in the puppet language, hence my proposal to have the query in [] to
> > match the Resource[title] syntax.
> > When the query is a simple string, then it would be expanded as "title
> > == string" which maps back to the current "resource selection".
>
> I disagree with the <||> syntax not being awesome, but I'm apparently
> the only person who thinks that.
lol :-)
That's not the syntax that is bizarre, it just doesn't look "puppet" to
me (ok I'm used to it now, so it looks "puppet" now).
I don't mind if you want to keep this syntax for queries.
But in my mind writing:
File["/tmp/toto"]
is a generalization of writing
File <| title == "/tmp/toto" |>
even if in the fact it is totally different (I mean in puppet as of
now).
My vision of the things is much more:
* there are no more "collect" statement (ie Resource<||> or
Resource<<||>>)
* there is a syntax expressing: reference to a collection (ie
Resource(source)[query])
* collection references can be realized or collected, which in turns
means realizing the collection or collect it.
* collection references can be used where a resource reference is used.
Because a resource reference is not more than a reference to a
collection of only 1 non virtual resource.
* you can apply overrides to such reference, which means, once it is
collected/realized (or used) it is overriden. This would also trigger
collection/realization. This can only be used as a whole statement of
course (no rvalue).
> But yes, I've also thought that the Resource["title"] syntax could be
> equivalent to Resource[title == "title"].
>
> That would get a bit hard to parse, I think, since I'm pretty sure the
> title can be any rvalue, and supporting either an rvalue by itself or
> a full query syntax might be a touch hard.
Yes, I understand where the problem is. If you want to go this way you
can build up on the expression stuff I contributed. It deals with
rvalues being part of boolean expressions.
Then the grammar could be written as:
collection RBRACK expression LBRACK
The difficulty is then to tell to the expression code to produce a query
code matching the original query that would be executed in
Collector.match?, which the expression system doesn't yet support (but I
don't see why it wouldn't be possible).
> >
> > The source can be either:
> > * empty -> means catalog, and we're back to the simpler syntax
> > * catalog, same as empty
> > * virtual
> > * any defined external source coming from puppet.conf, with the only
> > known type at this stage is active_record or storeconfigs. The
> > puppet.conf syntax should be specified too.
> >
> > Since it might be cumbersome to add the source everywhere, we could
> > have
> > shorter syntax (see below).
> >
> > There's no need to change the override syntax which is clear and
> > understandable and works fine.
> >
> > So to summarize, here's how I see it:
> >
> > * Catalog resources:
> >
> > Resource[query] { override }
> >
> > Ex:
> > File["/tmp/test"] { mode => 0666 }
> > or
> > User[ uid == 1000 ] { groups => staff }
> > or
> > User(catalog)[ uid == 1000 ] { groups => staff }
>
> This seems fine, except maybe that last bit. Puppet's language
> doesn't have any concept of keywords like 'catalog', and I'm a bit
> uncomfortable with the function-like syntax. I don't know what else
> to suggest for it, but those two things make me hesitate.
OK, why not using a syntax ala C++ templates:
User<catalog>[ uid == 1000 ] { groups => staff }
catalog would just be a reserved word for a specific source. If you
don't want to call it catalog, you can call it node (it is the resources
defined in the current node after all).
> >
> > * Virtual resources
> >
> > Resource(virtual)[query] { override }
> >
> > Ex:
> > File(virtual)["/tmp/test"] { override }
> > or
> > File(virtual)[ tag == test ] { override }
> >
> > We can have a short syntax for virtual:
> > @File[ query ] { override }
> >
> > or in its simplest form:
> > @File
>
> Interesting idea -- reusing the @ signs for virtual/exported for the
> collections too -- I like that. I'm not totally against the (virtual)
> syntax, but...
The (virtual) or (catalog) syntax is just to unify the whole syntax into
something that is general:
Resource(source)[query] { override }
With the (source) being optional which means catalog when missing.
Or with short syntax, prefixed by @ or @@.
The { override } block would also be optional. If used, it adds an
override pass on the realized, collected or referenced resource.
> >
> > Used alone, it means "realize"
> > It should also be possible to write:
> >
> > $collection = @File
> > realize( $collection )
> > to achieve the same thing
>
> Interesting; ok.
>
> >
> > * Exported resources
> >
> > File(storedconfigs)[ tag == test ] { override }
> >
> > if we one day have more than one external source.
> > Let's say, I have an ldap source of resource defined in my
> > puppet.conf, ala:
> >
> > [mysource]
> > sourcetype = ldap
> > ldaphost= localhost
> >
> > Then I could use the following in my manifests:
> >
> > File(mysource)[ tag == test ] { override }
>
> puppet.conf doesn't currently supporting having this kind of named
> collection of parameters -- the sections are for environments and
> nothing else, at this point. I'm not sure how easily I could add one,
> either.
Maybe there could be a sources.conf ala fileserver.conf which would
contain the defined sources (minus the mandatory ones, like catalog and
storedconfig or active_record). If you generalize the storeconfigs
system to allow resource storage in other scheme, you'll need to have a
way to configure it one way or another.
> >
> > And for storeconfigs, we can have a shorter syntax:
> > @@File[ query ] {override}
> >
> > or, in its simplest form:
> > @@File
> >
> > which means all resources of type File that are exported in
> > storeconfigs.
>
> Wouldn't this find all exported resources, and, um, do nothing with
> them?
Yes, as I presented the whole thing, I think you're right.
> Or are you suggesting that the query syntaxes could be used to export/
> virtualize resources?
That would break my aforementionned unifying rule saying that all
collections are in fact references to collection :-(
I guess you'd have to:
collect( @@File )
which is not as good as the current syntax.
Or allow a straight isolated "collection reference" (ie exported or
virtual, but not catalog) to realize/collect itself?
> >
> > Comments, and flames accepted :-)
> >
> >> Barring any brilliant ideas from others, I'd say just provide the
> >> behaviour change described above (the local resource query operates
> >> against all resources, and marks virtual resources as non-virtual).
> >
> > OK, so instead of acting only on virtual resources, we scan both
> > virtual
> > resources and catalog resources, select them, override them
> > accordingly
> > and if we ever encounter one that is virtual, we realize it.
> > Is it right?
>
> Yeah, that's what I was recommending.
That's something that should be doable without touching too much code in
collector.rb.
What would happen if I change collector.rb to _always_ return all
resources matching the query beit virtual or real (but not exported)?
Wouldn't that produce twice the same resources?
I think I have to study the whole process a little bit more.
> >
> >> Note that the evaluate_generators method in Parser::Compiler should
> >> be
> >> evaluated to make sure its behaviour still makes sense with this
> >> change, along with the 'fail_on_unevaluated' method in the same
> >> class.
> >
> > I'll try to assess this later this week. But I think
> > evaluate_generators
> > will still be used by storeconfigs resources, right?
>
> Every collection would be evaluated in the evaluate_generators method,
> and any overrides would need to end up in the fail_on_unevaluated
> method (although I'm not exactly sure if it's even necessary for
> overrides related to collections -- I suppose the overrides would
> happen when the collections are evaluated).
I don't think it matters, in the end the resources get overriden in
Compiler.finish(). I'm not sure that moving the overriding directly in
evaluate_collections (or evaluate_generators) brings us any advantage.
Or maybe I'm wrong and I don't see your point?
--
Brice Figureau <[EMAIL PROTECTED]>
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---