I attempted the following: resources { service: purge => true, noop => true } service { sshd: ensure => running; iptables ensure => running; } And got the following message: notice: Starting configuration run err: Found a bug: uninitialized constant Parse notice: Finished configuration run in 0.47 seconds When I remove the ''resources'' line, everything works fine. Also, removing ''noop'' does not make a difference. Thanks, Trevor _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Jan 23, 2007, at 1:29 PM, Trevor Vaughan wrote:> I attempted the following: > > resources { service: purge => true, noop => true } > > service { > sshd: ensure => running; > iptables ensure => running; > } > > And got the following message: > > notice: Starting configuration run > err: Found a bug: uninitialized constant Parse > notice: Finished configuration run in 0.47 seconds > > When I remove the ''resources'' line, everything works fine. Also, > removing ''noop'' does not make a difference.I was trapping an invalid error (Parse::Error instead of Puppet::ParseError). The reason you were encountering that line, though, is that you can''t purge services. You can only purge those resources that have an ''ensure'' attribute for which ''absent'' is a valid value. Services can currently only be stopped and started, they cannot be removed using Puppet. Were you trying to stop other services using this, rather than remove them? I suppose that''s not an unreasonable idea, although it would require aliasing ''stopped'' to ''absent''. I''ve fixed the error-catching, so the error you get should be more informative in the next release, and I''ll fix the surrounding code so this isn''t quite so glaring a failure if something like this happens again. -- A cult is a religion with no political power. -- Tom Wolfe --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
Ah, that makes sense. What I had assumed, and was testing, was that all services not defined would be stopped. That way I didn''t have to know all of the services that might be installed to only start the ones that I wanted. Thanks, Trevor On 1/23/07, Luke Kanies <luke@madstop.com> wrote:> > On Jan 23, 2007, at 1:29 PM, Trevor Vaughan wrote: > > > I attempted the following: > > > > resources { service: purge => true, noop => true } > > > > service { > > sshd: ensure => running; > > iptables ensure => running; > > } > > > > And got the following message: > > > > notice: Starting configuration run > > err: Found a bug: uninitialized constant Parse > > notice: Finished configuration run in 0.47 seconds > > > > When I remove the ''resources'' line, everything works fine. Also, > > removing ''noop'' does not make a difference. > > I was trapping an invalid error (Parse::Error instead of > Puppet::ParseError). > > The reason you were encountering that line, though, is that you can''t > purge services. You can only purge those resources that have an > ''ensure'' attribute for which ''absent'' is a valid value. Services can > currently only be stopped and started, they cannot be removed using > Puppet. > > Were you trying to stop other services using this, rather than remove > them? I suppose that''s not an unreasonable idea, although it would > require aliasing ''stopped'' to ''absent''. > > I''ve fixed the error-catching, so the error you get should be more > informative in the next release, and I''ll fix the surrounding code so > this isn''t quite so glaring a failure if something like this happens > again. > > -- > A cult is a religion with no political power. -- Tom Wolfe > --------------------------------------------------------------------- > Luke Kanies | http://reductivelabs.com | http://madstop.com > > > _______________________________________________ > Puppet-users mailing list > Puppet-users@madstop.com > https://mail.madstop.com/mailman/listinfo/puppet-users >_______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Jan 23, 2007, at 2:24 PM, Trevor Vaughan wrote:> Ah, that makes sense. > > What I had assumed, and was testing, was that all services not > defined would be stopped. That way I didn''t have to know all of > the services that might be installed to only start the ones that I > wanted.Do others think this is reasonable behaviour? If so, I might make ''purge'' accept multiple values, with ''true'' being equivalent to ''absent'', and anything else being the value sent on to the resources. E.g., you could then do: resources { service: purge => stopped } to stop all unmanaged services. The ''purge'' name starts to be a bit weird here, but eh. -- On Bureaucracy.... The Pythagorean theorem contains 24 words. Archimedes Principle, 67. The Ten Commandments, 179. The American Declaration of Independence, 300. And recent legislation in Europe concerning when and where to smoke, 23,942. -- The European, June 23-29, 1995 --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
On Tue, 2007-01-23 at 15:32 -0600, Luke Kanies wrote:> On Jan 23, 2007, at 2:24 PM, Trevor Vaughan wrote: > > > Ah, that makes sense. > > > > What I had assumed, and was testing, was that all services not > > defined would be stopped. That way I didn''t have to know all of > > the services that might be installed to only start the ones that I > > wanted. > > Do others think this is reasonable behaviour?I like that; it seems a natural extension of the ''absent'' behavior> If so, I might make ''purge'' accept multiple values, with ''true'' being > equivalent to ''absent'', and anything else being the value sent on to > the resources. E.g., you could then do: > > resources { service: purge => stopped } > > to stop all unmanaged services. > > The ''purge'' name starts to be a bit weird here, but eh.Maybe it should be called ''unmanaged'' or similar to indicate it applies to all resources that puppet doesn''t know about explicitly. David
On Jan 23, 2007, at 3:53 PM, David Lutterkort wrote:> On Tue, 2007-01-23 at 15:32 -0600, Luke Kanies wrote: >> On Jan 23, 2007, at 2:24 PM, Trevor Vaughan wrote: >> >>> Ah, that makes sense. >>> >>> What I had assumed, and was testing, was that all services not >>> defined would be stopped. That way I didn''t have to know all of >>> the services that might be installed to only start the ones that I >>> wanted. >> >> Do others think this is reasonable behaviour? > > I like that; it seems a natural extension of the ''absent'' behavior > >> If so, I might make ''purge'' accept multiple values, with ''true'' being >> equivalent to ''absent'', and anything else being the value sent on to >> the resources. E.g., you could then do: >> >> resources { service: purge => stopped } >> >> to stop all unmanaged services. >> >> The ''purge'' name starts to be a bit weird here, but eh. > > Maybe it should be called ''unmanaged'' or similar to indicate it > applies > to all resources that puppet doesn''t know about explicitly.Hmm. Maybe I should rearrange things a bit. How about I get rid of the ''purge'' parameter, and make it ''ensure'', such that you could specify any valid value to the type''s ''ensure'' state? Then add another parameter for selecting which resources it applies to, with (initially) ''managed'', ''unmanaged'', and ''all'' being the initially supported values, and ''unmanaged'' being the default? The equivalent to today''s "purge" would be: resources { user: ensure => absent, select => unmanaged } But you could also do: resources { service: ensure => stopped } It might be a good idea to only ever support selecting unmanaged resources, since otherwise you could easily get conflicts, but I''ve got $10 that says someone will ask for it ten seconds after I put out a release without it. -- My favorite was a professor at a University I Used To Be Associated With who claimed that our requirement of a non-alphabetic character in our passwords was an abridgement of his freedom of speech. -- Jacob Haller --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
Luke, That sounds like an excellent solution! Trevor On 1/25/07, Luke Kanies <luke@madstop.com> wrote:> > On Jan 23, 2007, at 3:53 PM, David Lutterkort wrote: > > > On Tue, 2007-01-23 at 15:32 -0600, Luke Kanies wrote: > >> On Jan 23, 2007, at 2:24 PM, Trevor Vaughan wrote: > >> > >>> Ah, that makes sense. > >>> > >>> What I had assumed, and was testing, was that all services not > >>> defined would be stopped. That way I didn''t have to know all of > >>> the services that might be installed to only start the ones that I > >>> wanted. > >> > >> Do others think this is reasonable behaviour? > > > > I like that; it seems a natural extension of the ''absent'' behavior > > > >> If so, I might make ''purge'' accept multiple values, with ''true'' being > >> equivalent to ''absent'', and anything else being the value sent on to > >> the resources. E.g., you could then do: > >> > >> resources { service: purge => stopped } > >> > >> to stop all unmanaged services. > >> > >> The ''purge'' name starts to be a bit weird here, but eh. > > > > Maybe it should be called ''unmanaged'' or similar to indicate it > > applies > > to all resources that puppet doesn''t know about explicitly. > > Hmm. Maybe I should rearrange things a bit. > > How about I get rid of the ''purge'' parameter, and make it ''ensure'', > such that you could specify any valid value to the type''s ''ensure'' > state? Then add another parameter for selecting which resources it > applies to, with (initially) ''managed'', ''unmanaged'', and ''all'' being > the initially supported values, and ''unmanaged'' being the default? > > The equivalent to today''s "purge" would be: > > resources { user: ensure => absent, select => unmanaged } > > But you could also do: > > resources { service: ensure => stopped } > > It might be a good idea to only ever support selecting unmanaged > resources, since otherwise you could easily get conflicts, but I''ve > got $10 that says someone will ask for it ten seconds after I put out > a release without it. > > -- > My favorite was a professor at a University I Used To Be Associated > With who claimed that our requirement of a non-alphabetic character in > our passwords was an abridgement of his freedom of speech. > -- Jacob Haller > --------------------------------------------------------------------- > Luke Kanies | http://reductivelabs.com | http://madstop.com > > > _______________________________________________ > Puppet-users mailing list > Puppet-users@madstop.com > https://mail.madstop.com/mailman/listinfo/puppet-users >_______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Thu, 2007-01-25 at 15:30 -0600, Luke Kanies wrote:> The equivalent to today''s "purge" would be: > > resources { user: ensure => absent, select => unmanaged } > > But you could also do: > > resources { service: ensure => stopped }I _really_ like that .. it seems a very natural extension of how specific resources work. The one wrinkle is that there are now at least three ways to refer to a resource: 1. service { foo: .. } when creating an element in puppet 2. Service[foo] when overriding 3. resources { service: select => ... } for otherwise unspecified resources It''s not a big deal - I just hope that it won''t get confusing over time when selection for 2 and 3 becomes more powerful. David
On Jan 25, 2007, at 5:06 PM, David Lutterkort wrote:> > I _really_ like that .. it seems a very natural extension of how > specific resources work. The one wrinkle is that there are now at > least > three ways to refer to a resource: > > 1. service { foo: .. } when creating an element in puppet > 2. Service[foo] when overriding > 3. resources { service: select => ... } for otherwise unspecified > resourcesDon''t forget Service <| title == foo |>.> It''s not a big deal - I just hope that it won''t get confusing over > time > when selection for 2 and 3 becomes more powerful.I expect it already is, unfortunately. -- We cannot really love anybody with whom we never laugh. --Agnes Repplier --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
Same thread but new thought/question: How will Puppet know what services you have? If the goal is to ensure that you have no rogue services running, will Puppet rely on entries in /etc/init.d to be the list of available services? If not, you would be defining all services that might be on a server and in that case, you could just define them to be not running (or override them as such when needed).
On Jan 26, 2007, at 12:10 AM, Digant C Kasundra wrote:> Same thread but new thought/question: > > How will Puppet know what services you have? If the goal is to > ensure that > you have no rogue services running, will Puppet rely on entries in > /etc/init.d to be the list of available services? If not, you > would be > defining all services that might be on a server and in that case, > you could > just define them to be not running (or override them as such when > needed).I''ve not yet nailed down the best way to list instances, so there is not yet (I believe) consistent behaviour across all types. For services, the default service provider is listed; for most platforms, that means listing the contents of /etc/init.d. -- Discovery consists of seeing what everybody has seen and thinking what nobody has thought. -- Albert Szent-Gyorgyi --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Friday 26 January 2007 01:31, Luke Kanies wrote:> On Jan 25, 2007, at 5:06 PM, David Lutterkort wrote: > > I _really_ like that .. it seems a very natural extension of how > > specific resources work. The one wrinkle is that there are now at > > least > > three ways to refer to a resource: > > > > 1. service { foo: .. } when creating an element in puppet > > 2. Service[foo] when overriding > > 3. resources { service: select => ... } for otherwise unspecified > > resources > > Don''t forget Service <| title == foo |>.At least 2. and 3. could be combined with the selectors from collection like this: Service[ selector ] { parameters } So a override would be Service [ ntp ] { ensure => stopped } while a default would be a) Service [ select == unmanaged ] { ensure => stopped } b) Service [ * ] { ensure => stopped } c) Service [ ] { ensure => stopped } That would be a natural extension of the override syntax. Regards, David - -- - - hallo... wie gehts heute? - - *hust* gut *rotz* *keuch* - - gott sei dank kommunizieren wir über ein septisches medium ;) -- Matthias Leeb, Uni f. angewandte Kunst, 2005-02-15 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFFumGW/Pp1N6Uzh0URArqbAJ0cypnhWnOziYRroOq5RA3dtdIhIQCgg1Mr BFYZHr3JiwZdJP/t03gQ/os=QqtI -----END PGP SIGNATURE-----
Luke Kanies
2007-Feb-02 22:02 UTC
Resource Syntaxes (was Re: "Found a bug" message when purging services)
On Jan 26, 2007, at 2:16 PM, David Schmitt wrote:> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On Friday 26 January 2007 01:31, Luke Kanies wrote: >> On Jan 25, 2007, at 5:06 PM, David Lutterkort wrote: >>> I _really_ like that .. it seems a very natural extension of how >>> specific resources work. The one wrinkle is that there are now at >>> least >>> three ways to refer to a resource: >>> >>> 1. service { foo: .. } when creating an element in puppet >>> 2. Service[foo] when overriding >>> 3. resources { service: select => ... } for otherwise >>> unspecified >>> resources >> >> Don''t forget Service <| title == foo |>. > > At least 2. and 3. could be combined with the selectors from > collection like > this: > > Service[ selector ] { parameters } > > So a override would be > > Service [ ntp ] { ensure => stopped } > > while a default would be > > a) Service [ select == unmanaged ] { ensure => stopped } > b) Service [ * ] { ensure => stopped } > c) Service [ ] { ensure => stopped } > > That would be a natural extension of the override syntax.This is a painful email. I''m trying to come with a consistent model that maps well to Puppet''s syntax, and I''m having a hard time doing it. That does not speak to good language design. This is about all I can come up with: It''s a good idea to at least consider trying to consolidate syntaxes. The real point would be to find a consistent model of the world and then find one or more syntaxes that do a good job of reflecting that model. Right now, we have at least five different ways of thinking about resources: 1) Creation (thing { name: ... }) 2) Modification (Thing[name] { ... }) 3) Resource defaults (Thing { ... }) 4) Modifying otherwise-unmanaged resources on the system (resources { thing: ... }) 5) Finding resources in the database but not modifying them (probably) (Thing <| ... |>) That''s pretty nasty, and it looks like they could be simplified quite a bit. I''m not really in a state to seriously look at this right now, but we should find some way to make it simpler and more consistent, and hopefully more powerful at the same time. -- Criminal: A person with predatory instincts who has not sufficient capital to form a corporation. --Howard Scott --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Friday 02 February 2007 23:02, Luke Kanies wrote:> It''s a good idea to at least consider trying to consolidate > syntaxes. The real point would be to find a consistent model of the > world and then find one or more syntaxes that do a good job of > reflecting that model. > > Right now, we have at least five different ways of thinking about > resources:Actually most of those are resource "definitions" in the farthest sense:> 1) Creation (thing { name: ... })Exhaustive definition of a particular resource.> 2) Modification (Thing[name] { ... })Definition by proxy. The resource in this case never exists as specified by the parent class.> 3) Resource defaults (Thing { ... })This one not, because this requires no particular resource to talk about, just the type.> 4) Modifying otherwise-unmanaged resources on the system > (resources { thing: ... })This one neither, because this requires no particular resource to talk about, just the type. Actually you could say that this is the same as 3) + application.> 5) Finding resources in the database but not modifying them > (probably) (Thing <| ... |>)Definition by proxy again: The virtual/exported resource is only a proxy and will never be realized without a collect/import.> That''s pretty nasty, and it looks like they could be simplified quite > a bit.While it is far from optimal I would reserve such harsh words for things like cfengine where I would never have been able to create the rich manifests I already have written with puppet.> I''m not really in a state to seriously look at this right now, but we > should find some way to make it simpler and more consistent, and > hopefully more powerful at the same time.Changing the syntax will cause a major upheaval. As long as no semantic changes are introduced, this can be helped with a simple translator from the old to the new format. As a little food for thought, I''ll try to write up examples using the selector syntax for the five cases from above: 1) Creation: Thing[name] { ... } 2) Modification: Thing[name] { ... } 3) Resource Defaults: Thing[*] { ... } 4) Modifying otherwise-unmanaged resources on the system: Type["unmanaged"] { ... } 5) Finding and modifying Resources from the database: Type[ selector ] { ... } To solidify that and reap the full potiential of the database and classes, the "database" would hold all resource objects, regardless where they come from: inheritance, define-instantiation(?), virtualisation, export, normal specification (for defaults) or the system (for unmanaged resources) It requires further thoughts how to specify a default selector, when there is only a value: [name] vs. [title == name] or to use the <||> syntax for selectors and stay with [] (array access) for single key referencing. How does this interact with defines and classes? Regards, David - -- - - hallo... wie gehts heute? - - *hust* gut *rotz* *keuch* - - gott sei dank kommunizieren wir über ein septisches medium ;) -- Matthias Leeb, Uni f. angewandte Kunst, 2005-02-15 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFFw8XH/Pp1N6Uzh0URAjKUAJ9l7ILTix2QJGFOX8vgUJNVRAaPHACeOyBW UjenVtBo5iyXo7iyPOKJfqQ=imBE -----END PGP SIGNATURE-----
On Feb 2, 2007, at 5:14 PM, David Schmitt wrote:> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On Friday 02 February 2007 23:02, Luke Kanies wrote: >> It''s a good idea to at least consider trying to consolidate >> syntaxes. The real point would be to find a consistent model of the >> world and then find one or more syntaxes that do a good job of >> reflecting that model. >> >> Right now, we have at least five different ways of thinking about >> resources: > > Actually most of those are resource "definitions" in the farthest > sense:I don''t really agree; we''ve really only got two syntaxes for modifying resources, #1 and #2. #3 will hopefully not be used for much besides removing resources, it''s not a new syntax, and its ability to affect multiple resources is only realized on the client, not on the server. As in the reference to Plato''s Forms, I think it''s important that the syntax be pretty clear about whether we''re talking about resources or resource definitions. For instance, defaults only affect resource definitions -- if you specify a resource, then it will acquire data from the defaults, but the defaults do not apply to all resources, only those you have specified. Additionally, the resource query syntax (with <||> or <<||>>) only finds resources that have been specified and then indicates they should be realized on the system. So only two of the syntaxes have anything to do with creating or modifying resource specification instances. The ''resources'' type is capable of modifying resources, but it explicitly (at least currently) excludes any resources that have specification instances. The <||> syntax does not modify the resource specification instances, it only marks whether they should be turned into resources on the current host.>> 1) Creation (thing { name: ... }) > Exhaustive definition of a particular resource. > >> 2) Modification (Thing[name] { ... }) > Definition by proxy. The resource in this case never exists as > specified by > the parent class.I don''t really know what you mean in "by proxy". the important thing for me is that this syntax modifies existing resource specifications. Currently it can only add new attributes and modify existing ones.>> 3) Resource defaults (Thing { ... }) > This one not, because this requires no particular resource to talk > about, just > the type.The important thing here is that we''re not modifying any resource specifications -- we''re>> 4) Modifying otherwise-unmanaged resources on the system >> (resources { thing: ... }) > This one neither, because this requires no particular resource to > talk about, > just the type. Actually you could say that this is the same as 3) + > application.This is very different, though; the idea is that it specifically targets resources that have no associated specification. I know I''ve talked about changing that, at least in theory, but I expect I never actually would because you''d end up with some pretty opaque results. Possibly I should be using the term ''unspecified'', rather than ''unmanaged'', to make it clear that this only affects those resources that we have not talked about otherwise.>> 5) Finding resources in the database but not modifying them >> (probably) (Thing <| ... |>) > Definition by proxy again: The virtual/exported resource is only a > proxy and > will never be realized without a collect/import.I do not consider this to be a definition; it is simply importing an already-defined resource, or marking a defined resource as part of the final configuration. One other thing to note about this syntax is that we could consider the difference between <||> and <<||>> to be that the former is equivalent to <<| host == $hostname |>>. That is, it''s the exact same function, but restricted just to the exported resources from the virtual host. We still have to have both @ and @@ as resource prefixes, because some resources should be virtual but not exported. I wouldn''t mind having a different way of specifying those, but it''s not that important to me.>> That''s pretty nasty, and it looks like they could be simplified quite >> a bit. > > While it is far from optimal I would reserve such harsh words for > things like > cfengine where I would never have been able to create the rich > manifests I > already have written with puppet.Heh; thanks.>> I''m not really in a state to seriously look at this right now, but we >> should find some way to make it simpler and more consistent, and >> hopefully more powerful at the same time. > > Changing the syntax will cause a major upheaval. As long as no > semantic > changes are introduced, this can be helped with a simple translator > from the > old to the new format.More likely, I would just support multiple syntaxes with deprecation warnings. If the changes were huge, a translator would be a good idea.> As a little food for thought, I''ll try to write up examples using > the selector > syntax for the five cases from above: > > 1) Creation: Thing[name] { ... } > 2) Modification: Thing[name] { ... } > 3) Resource Defaults: Thing[*] { ... } > 4) Modifying otherwise-unmanaged resources on the system: Type > ["unmanaged"] > { ... } > 5) Finding and modifying Resources from the database: Type > [ selector ] { ... }That would be great. We already kind of have two mini-languages that are very similar: One for specifying resource parameters between {}, and one for looking up resources between <||>.> To solidify that and reap the full potiential of the database and > classes, > the "database" would hold all resource objects, regardless where > they come > from: inheritance, define-instantiation(?), virtualisation, export, > normal > specification (for defaults) or the system (for unmanaged resources)It might do so in theory, but it can''t in practice. The defaults don''t exist in any kind of "real" sense, and we can''t write the resources to the database until we''ve successfully compiled the entire configuration because we might write things out and then find out we''ve got a syntax error (it could be that using a db transaction would solve this problem).> It requires further thoughts how to specify a default selector, > when there is > only a value: [name] vs. [title == name] or to use the <||> syntax for > selectors and stay with [] (array access) for single key referencing.I think I like that idea.> How does this interact with defines and classes?Shouldn''t affect things at all. Resources are treated exactly the same for almost the entire process, whether they''re specifications of definitions or of native types. The only time the parser differentiates them is during collection: Part of the compilation process involves expanding defined resources into the contained native resources. I can''t save exported defined resources as a single resource in the database because then the contained resources could get defaults from the collecting host instead of the exporting host, which is almost definitely a bad idea in general. Anyway, I''m definitely interested in seeing what you can come up with. -- I have a switch in my apartment... It doesn''t do anything. Every once in a while, I turn it on and off. One day I got a call... It was from a woman in France... She said, "Cut it out!" -- Stephen Wright --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 [I''ve rearranged the text a bit in an attempt to improve the flow.] On Sunday 04 February 2007 00:00, Luke Kanies wrote:> On Feb 2, 2007, at 5:14 PM, David Schmitt wrote: > > -----BEGIN PGP SIGNED MESSAGE----- > > Hash: SHA1 > > > > On Friday 02 February 2007 23:02, Luke Kanies wrote:> >> 2) Modification (Thing[name] { ... }) > > > > Definition by proxy. The resource in this case never exists as > > specified by > > the parent class. > > I don''t really know what you mean in "by proxy". the important thing > for me is that this syntax modifies existing resource > specifications. Currently it can only add new attributes and modify > existing ones.The statement implies that a parent class has already a definition for this resource. It basically says "Use that definition over there, but do this and this differently", thus "proxying" the original definition. Probably just my non-native abuse of the english language. I apologize. /-- Sidebar: Defaults for various resources --------------------------- |> As in the reference to Plato''s Forms, I think it''s important that the |> syntax be pretty clear about whether we''re talking about resources or |> resource definitions. For instance, defaults only affect resource |> definitions -- if you specify a resource, then it will acquire data |> from the defaults, but the defaults do not apply to all resources, |> only those you have specified. | |A bit off the main line, but a point that jumped at me: "resource{type: }" |and "Type {}" do exactly the same thing for unspecified and specified |resources respectivly. And both can be - in a sense - be overruled by |specifying resources directly. \-----------------------------------------------------------------------> >> 5) Finding resources in the database but not modifying them > >> (probably) (Thing <| ... |>) > > > > Definition by proxy again: The virtual/exported resource is only a > > proxy and > > will never be realized without a collect/import. > > I do not consider this to be a definition; it is simply importing an > already-defined resource, or marking a defined resource as part of > the final configuration.I seem to have confused "definition" and "usage/application/inclusion". Let me try again:> 1) Creation (thing { name: ... })Definition: exhaustive (all attributes enumerated) Application: immediate (within the current context)> 2) Modification (Thing[name] { ... })Definition: incremental (attributes relative to parent) Application: replacing/modifying the parent (within the current context)> 3) Resource defaults (Thing { ... })Definition: none Application: none> 4) Modifying otherwise-unmanaged resources on the system > (resources { thing: ... })Definition: references all otherwise unspecified resources (yes, not really "definition") Application: yes> 5) Finding resources in the database but not modifying them > (probably) (Thing <| ... |>)Definition: none (again, a reference actually) Application: immediate (within the current context) /-- Sidebar: local virtual resources ---------------------------------- |> One other thing to note about this syntax is that we could consider |> the difference between <||> and <<||>> to be that the former is |> equivalent to <<| host == $hostname |>>. That is, it''s the exact |> same function, but restricted just to the exported resources from the |> virtual host. We still have to have both @ and @@ as resource |> prefixes, because some resources should be virtual but not exported. |> I wouldn''t mind having a different way of specifying those, but it''s |> not that important to me. | |What is the use case for these virtual, unexported resources anyway? I |haven''t really got my head around that yet. \----------------------------------------------------------------------> > To solidify that and reap the full potiential of the database and > > classes, > > the "database" would hold all resource objects, regardless where > > they come > > from: inheritance, define-instantiation(?), virtualisation, export, > > normal > > specification (for defaults) or the system (for unmanaged resources) > > It might do so in theory, but it can''t in practice. The defaults > don''t exist in any kind of "real" sense, and we can''t write the > resources to the database until we''ve successfully compiled the > entire configuration because we might write things out and then find > out we''ve got a syntax error (it could be that using a db transaction > would solve this problem).Please note my usage of quotes, as in "database". I should have written "things accessible via selectors" and those can be created on demand/as available when special operators in the selector require them.> > How does this interact with defines and classes? > > Shouldn''t affect things at all. Resources are treated exactly the > same for almost the entire process, whether they''re specifications of > definitions or of native types. > > The only time the parser differentiates them is during collection: > Part of the compilation process involves expanding defined resources > into the contained native resources. I can''t save exported defined > resources as a single resource in the database because then the > contained resources could get defaults from the collecting host > instead of the exporting host, which is almost definitely a bad idea > in general. > > Anyway, I''m definitely interested in seeing what you can come up with.Classes and Defines are both containers for groupings of resources. Classes can be inherited and nested. Defines can only be nested. ( Do "Type[name]{ }" overrides work in the outer Define? ) Classes (and Defines) can access variables from the enclosing scope. Defines take attributes (like all types). Classes have a special syntax for "inclusion". Defines look like normal types. Classes can be included only once. Defines can be used multiple times. Only the last strikes me as a significant difference (the different syntax is only a symptom of this). To add that to the currently floating discussion framework, the number of namevars/keys for a type could not only be increased (for multiple key types) but also decreased to zero for singleton types. For example a NTP daemon which would be currently defined as class: class ntpd { $servers = $ntp_servers ? { '''' => [ time.example.com ], default => $ntp_servers, } # uses the $servers array: file { "/etc/ntpd.conf": content => template( "ntpd.conf.erb" ), } # ... } node ntp { $ntp_servers = [ time.example.com, time.edv-bus.at ] include ntpd } could then look like this: define ntpd[]($servers = [ time.example.com ] ) { # uses the $servers array: file { "/etc/ntpd.conf": content => template( "ntpd.conf.erb" ), } # ... } node ntp { Ntpd[] { servers => [ time.example.com, time.edv-bus.at ], } } While I don''t think that this in itself would be enough to necessitate a new syntax, it would fit into the other suggestions. As a nice sideeffect, I think I found a possibility for varying the namevar/key thing: | define foo[keylist] (attributelist) { contents } So todays defines would be written as | define foo[$name] (...) {...} and multi-key defines like this: | #instead of append_if_no_such_line: | define line[$file, $content] ($ensure = present) { | case $ensure { | absent: { Exec[remove_${line}_if_exists] { cmd => ... } | present: { Exec[add_${line}_if_not_exists] { cmd => ... } | default: { err("message") } and the singleton (as written in the ntp example) | define foo[] (...) {...} Since the key variables within the [] distinguish the different resources of the same type[1], having no key obviously implies that there can be only one instance. Regards, David [1] see also primary key in DBMS lingo; http://en.wikipedia.org/wiki/Primary_key - -- - - hallo... wie gehts heute? - - *hust* gut *rotz* *keuch* - - gott sei dank kommunizieren wir über ein septisches medium ;) -- Matthias Leeb, Uni f. angewandte Kunst, 2005-02-15 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFFxyqO/Pp1N6Uzh0URAm7WAJ0a2+HIZZ3HqdHbo54scDuXrS3kvgCgiVB7 hMQC70DDOoNgO0y2q8QmswY=VCwi -----END PGP SIGNATURE-----
2007/2/5, David Schmitt <david@schmitt.edv-bus.at>:> > > On Sunday 04 February 2007 00:00, Luke Kanies wrote: > > On Feb 2, 2007, at 5:14 PM, David Schmitt wrote: > > Classes and Defines are both containers for groupings of resources. > > Classes can be inherited and nested. > Defines can only be nested. ( Do "Type[name]{ }" overrides work in the > outer > Define? ) > > Classes (and Defines) can access variables from the enclosing scope. > Defines take attributes (like all types). > > Classes have a special syntax for "inclusion". > Defines look like normal types. > > Classes can be included only once. > Defines can be used multiple times.I don''t think this is a "fair comparison" between definitions and classes, as you seem to imply that classes and definitions are almost the same thing. Keep in mind that a definition is a way to create a new type using existing puppet types, so the prior assumption would lead us to saying that puppet types and classes are almost the same, and this is far from true. Types are a way to model some manageable stuff in a machine, while classes are a way to describe a desired state of a collection of resources in a machine (sorry if I''m using the wrong terminology here). So the difference of being used just one time or multiple times is not by design, is a consequence of what they represent. Only the last strikes me as a significant difference (the different syntax> is > only a symptom of this). To add that to the currently floating discussion > framework, the number of namevars/keys for a type could not only be > increased > (for multiple key types) but also decreased to zero for singleton types. > For > example a NTP daemon which would be currently defined as class: > > [snip] >Curiously I have used exactly the same example to argue for the convenience of parameterized classes [1]. I think this is a much more natural way of expressing this kind of configuration, rather than using definitions, partly because of the previous comments about differences between definitions and classes. It would be great if you could take a look at it and comment it (I have started another thread for this) [1] http://www.reductivelabs.com/trac/puppet/wiki/LanguageEvolution#parameterized-classes Best regards Jose _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Monday 05 February 2007 15:23, José González Gómez wrote:> 2007/2/5, David Schmitt <david@schmitt.edv-bus.at>: > > Classes and Defines are both containers for groupings of resources. > > > > Classes can be inherited and nested. > > Defines can only be nested. ( Do "Type[name]{ }" overrides work in the > > outer > > Define? ) > > > > Classes (and Defines) can access variables from the enclosing scope. > > Defines take attributes (like all types). > > > > Classes have a special syntax for "inclusion". > > Defines look like normal types. > > > > Classes can be included only once. > > Defines can be used multiple times. > > I don't think this is a "fair comparison" between definitions and classes, > as you seem to imply that classes and definitions are almost the same > thing. Keep in mind that a definition is a way to create a new type using > existing puppet types, so the prior assumption would lead us to saying that > puppet types and classes are almost the same, and this is far from true. > Types are a way to model some manageable stuff in a machine, while classes > are a way to describe a desired state of a collection of resources in a > machine (sorry if I'm using the wrong terminology here). So the difference > of being used just one time or multiple times is not by design, is a > consequence of what they represent.On the usage of classes vs. defines I have to agree totally. There is no use for a NTP define, because it won't be exported and there must never be two different ntpd on a single machine. On the other hand, making classes for every user you have like user_josé, user_luke and user_david which dance some complicated inheritance dance is equally pointless. My point was primarily about syntax and behaviour - not usage. If classes have parameters, they can do everything defines can do, except being included twice. Thus supporting - from the syntax and behavior point of view - my originial assertion. What is probably needed is to say that | include foo equals | Foo[] {} to save the spurious brackets and braces.> > Only the last strikes me as a significant difference (the different syntax > > is only a symptom of this). To add that to the currently floating > > discussion framework, the number of namevars/keys for a type could not > > only be increased (for multiple key types) but also decreased to zero for > > singleton types. For example a NTP daemon which would be currently defined > > as class: > > > > [snip] > > Curiously I have used exactly the same example to argue for the convenience > of parameterized classes [1]. I think this is a much more natural way of > expressing this kind of configuration, rather than using definitions, > partly because of the previous comments about differences between > definitions and classes. It would be great if you could take a look at it > and comment it (I have started another thread for this) > > [1] > http://www.reductivelabs.com/trac/puppet/wiki/LanguageEvolution#parameteriz >ed-classesNTP seems to be the canonical there-can-only-be-one example ;) Please take a look at my proposal from Saturday, trying to integrate all the various syntaxes into a unified whole. Adding another kind of bracketing seems to be a step into the wrong direction for me. Regards, David - -- - - hallo... wie gehts heute? - - *hust* gut *rotz* *keuch* - - gott sei dank kommunizieren wir über ein septisches medium ;) -- Matthias Leeb, Uni f. angewandte Kunst, 2005-02-15 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFFx1kF/Pp1N6Uzh0URArlfAJ4mprUlA0l8xsGLoy7zzFJOKYjZlQCgn0kO kEpWR+4OYjhvxZxmWNcglQQ=blrY -----END PGP SIGNATURE----- _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Feb 5, 2007, at 10:19 AM, David Schmitt wrote:> > On the usage of classes vs. defines I have to agree totally. There > is no use > for a NTP define, because it won''t be exported and there must never > be two > different ntpd on a single machine. On the other hand, making > classes for > every user you have like user_josé, user_luke and user_david which > dance some > complicated inheritance dance is equally pointless.Your original description of the differences between classes and definitions had a twist of phrase that was somewhat misleading; definitions can have multiple instances, whereas classes are singletons. You can ''include'' classes as many times as you want and it will not be considered to be a conflict. Classes are meant to manage those aspects of your system which are inherently singletons -- services, users, packages, files, etc. Definitions are meant to manage those aspects of your system that will have many copies but that Puppet cannot manage natively -- virtual hosts, trac instances, etc.> My point was primarily about syntax and behaviour - not usage. If > classes have > parameters, they can do everything defines can do, except being > included > twice. Thus supporting - from the syntax and behavior point of view > - my > originial assertion. > > What is probably needed is to say that > > | include foo > > equals > > | Foo[] {} > > to save the spurious brackets and braces.Classes literally started out this way -- the ''include foo'' syntax was just a shorthand for ''foo {}'', and classes couldn''t have parameters. I also wasn''t as clear on the differences between classes and definitions at the time. The problem of class parameters really needs to be solved, but I don''t think making classes and definitions more similar isn''t the solution.> NTP seems to be the canonical there-can-only-be-one example ;) > > Please take a look at my proposal from Saturday, trying to > integrate all the > various syntaxes into a unified whole. Adding another kind of > bracketing > seems to be a step into the wrong direction for me.I figured his bracketing to be less a specific syntax proposal and more an indication of what he wanted to express. -- I had a linguistics professor who said that it''s man''s ability to use language that makes him the dominant species on the planet. That may be. But I think there''s one other thing that separates us from animals. We aren''t afraid of vacuum cleaners. --Jeff Stilson --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
On Feb 5, 2007, at 8:23 AM, José González Gómez wrote:> I don''t think this is a "fair comparison" between definitions and > classes, as you seem to imply that classes and definitions are > almost the same thing. Keep in mind that a definition is a way to > create a new type using existing puppet types, so the prior > assumption would lead us to saying that puppet types and classes > are almost the same, and this is far from true. Types are a way to > model some manageable stuff in a machine, while classes are a way > to describe a desired state of a collection of resources in a > machine (sorry if I''m using the wrong terminology here). So the > difference of being used just one time or multiple times is not by > design, is a consequence of what they represent.Your description of the different uses is exactly correct. Here''s a simple short-hand for figuring out which you should be using: If the $name of all resources involved doesn''t change with every instance of the definition, then you have to use a class. If it does change, then you can use a definition. Classes are singletons and contain singleton resources; definitions are meant to have multiple instances, and all of their contained resources need to vary enough in each definition instance that they end up unique. In this way, José''s statement about the one time/ multiple time distinction being accidental isn''t quite right; it''s the singleton nature of the resources being managed that distinguishes them, mostly. -- Zeilinger''s Fundamental Law: There is no Fundamental Law. --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
On Feb 5, 2007, at 7:00 AM, David Schmitt wrote:>> I don''t really know what you mean in "by proxy". the important thing >> for me is that this syntax modifies existing resource >> specifications. Currently it can only add new attributes and modify >> existing ones. > > The statement implies that a parent class has already a definition > for this > resource. It basically says "Use that definition over there, but do > this and > this differently", thus "proxying" the original definition. > Probably just my > non-native abuse of the english language. I apologize.I don''t know if it''s a language issue; I expect non-native English speakers would apologize for their English a lot less often if I had to try to write their language for them once in a while. :) It sounds like you meant what I thought, then. Note that the current class could have defined that resource, it doesn''t have to be a parent class. This is legal: class thing { file { "/my/file": owner => luke } if (tagged(yay)) { File["/my/file"] { group => luke } } } The current class cannot override values set in that class (i.e., this example could not have overridden the value for ''owner''), but otherwise it behaves the same.> /-- Sidebar: Defaults for various resources > --------------------------- > |> As in the reference to Plato''s Forms, I think it''s important > that the > |> syntax be pretty clear about whether we''re talking about > resources or > |> resource definitions. For instance, defaults only affect resource > |> definitions -- if you specify a resource, then it will acquire data > |> from the defaults, but the defaults do not apply to all resources, > |> only those you have specified. > | > |A bit off the main line, but a point that jumped at me: "resource > {type: }" > |and "Type {}" do exactly the same thing for unspecified and specified > |resources respectivly. And both can be - in a sense - be overruled by > |specifying resources directly. > \--------------------------------------------------------------------- > --That''s a good point, and makes it more obvious that we should be able to unify some syntaxes. They''re so similar in semantics, yet so dissimilar in syntax.> I seem to have confused "definition" and "usage/application/ > inclusion".Ah; ok.> Let me try again: > >> 1) Creation (thing { name: ... }) > Definition: exhaustive (all attributes enumerated) > Application: immediate (within the current context) > >> 2) Modification (Thing[name] { ... }) > Definition: incremental (attributes relative to parent) > Application: replacing/modifying the parent (within the current > context) > >> 3) Resource defaults (Thing { ... }) > Definition: none > Application: none > >> 4) Modifying otherwise-unmanaged resources on the system >> (resources { thing: ... }) > Definition: references all otherwise unspecified resources (yes, not > really "definition") > Application: yes > >> 5) Finding resources in the database but not modifying them >> (probably) (Thing <| ... |>) > Definition: none (again, a reference actually) > Application: immediate (within the current context)I''m much more comfortable with these descriptions.> /-- Sidebar: local virtual resources > ---------------------------------- > |> One other thing to note about this syntax is that we could consider > |> the difference between <||> and <<||>> to be that the former is > |> equivalent to <<| host == $hostname |>>. That is, it''s the exact > |> same function, but restricted just to the exported resources > from the > |> virtual host. We still have to have both @ and @@ as resource > |> prefixes, because some resources should be virtual but not > exported. > |> I wouldn''t mind having a different way of specifying those, but > it''s > |> not that important to me. > | > |What is the use case for these virtual, unexported resources > anyway? I > |haven''t really got my head around that yet. > \--------------------------------------------------------------------- > -There are basically two use cases that I see: If you want to keep all of instances of a given type in one place, and selectively instantiate them on a client. For instance, you could have all of your cron jobs contained in one class, or all users, and then selectively enable them. This could give one group control over the details of the resources, and another group control over which resources go where. Another (and this use case is why I was paid to create this feature) is when your grouping is not simple enough to allow you to have just one definition of a resource. For instance, if you have a user in both the network and sysadmin groups, but s/he is the only such user, then you cannot easily specify this without virtual resources. With virtual resources, though, you define the user somewhere in your configuration, and then realize the user as appropriate: class users { @user { luke: ...; ... } } class network_admins { realize User[luke] } class sysadmins { realize User[luke] } class unix_machines { include sysadmins } class routers { include sysadmins, network_admins } Note that if ''luke'' were defined normally in both user classes, then the ''routers'' hosts would have a conflict. Essentially, virtual resources become singletons that you define once but can include as many times as you want. If your resource modeling is simple enough to not need this functionality, then you should be pretty happy, but it does happen.>> It might do so in theory, but it can''t in practice. The defaults >> don''t exist in any kind of "real" sense, and we can''t write the >> resources to the database until we''ve successfully compiled the >> entire configuration because we might write things out and then find >> out we''ve got a syntax error (it could be that using a db transaction >> would solve this problem). > > Please note my usage of quotes, as in "database". I should have > written "things accessible via selectors" and those can be created on > demand/as available when special operators in the selector require > them.Ok.> Classes and Defines are both containers for groupings of resources. > > Classes can be inherited and nested. > Defines can only be nested. ( Do "Type[name]{ }" overrides work in > the outer > Define? )Yes, you can override definitions, within reason. Currently, the parser handles overrides like this: All classes are evaluated and the resulting resources are stored. All of the resulting overrides are half-evaluated, and if the resource they are overriding exists, the override is completely evaluated and then deleted. Then all resources that are instances of definitions are themselves evaluated, so that they explode to (one or more) other resources. The list of overrides is again evaluated. This happens iteratively until there are no more definitions. If there are overrides left at that point, then we have an error, because we tried to override a resource that does not exist.> Classes (and Defines) can access variables from the enclosing scope. > Defines take attributes (like all types). > > Classes have a special syntax for "inclusion".It''s actually not a special syntax; it''s a function like any other.> Defines look like normal types. > > Classes can be included only once.Classes can be evaluated only once but can be included as many times as you want (although there''s currently a bit of a nasty bug with multiple inclusion; the first include passes on its variables, and the rest are basically null ops).> Defines can be used multiple times.Yep, although I prefer saying they can have multiple instances.> Only the last strikes me as a significant difference (the different > syntax is > only a symptom of this). To add that to the currently floating > discussion > framework, the number of namevars/keys for a type could not only be > increased > (for multiple key types) but also decreased to zero for singleton > types. For > example a NTP daemon which would be currently defined as class: > [snip] > Since the key variables within the [] distinguish the different > resources of > the same type[1], having no key obviously implies that there can be > only one > instance.Huh. I''m not opposed to this, but the internals will need some significant modification in order to handle resources with multiple primary keys. I''m not exactly sure the [] syntax is the best way to describe primary keys, but I don''t have anything else to recommend. It''s funny, the more Puppet develops, the more resources look like a database, with each resource type being a table and each parameter being a column. Supporting multiple primary keys just makes it that much more like a database, and I expect I could save myself a lot of time if I remodeled things internally to just reuse db modeling. -- I believe that if it were left to artists to choose their own labels, most would choose none. -- Ben Shahn --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com