Hi there, After quite a long time out of puppet business I''m back, and the first thing I''m doing is rephrasing my puppet manifests using modules. I started with the NTP module (a classic, I guess). I have (more or less) the following: In modules/ntp/manifests/init.pp: $ntp_localtime = "/usr/share/zoneinfo/Europe/Madrid" class ntp { ... some stuff using the ntp_localtime variable (a file resource with ensure => ntp_localtime) ... } $ntp_server = "es.pool.ntp.org" class ntp::ntp_server inherits ntp { ... some stuff including a template that uses ntp_server variable ... } class ntp::ntp_client inherits ntp { ... some stuff ... } Somewhere in manifests/site.pp and its included files: node ''someNode'' { include ntp::ntp_server } Now the questions (by the way, I''m using puppet 0.23.2 in both the puppet and the master): 1. I had to manually add ntp:: to the classes included in the ntp module, as if I don''t do it that way puppet isn''t able to find those classes. Anyway, if I just include ntp, puppet is able to find the class ntp in the module ntp. After reading the wiki and some messages in the mailing list I thought that puppet should also be able to find the ntp_server and ntp_client without having to manually add the ntp:: namespace in its definition... am I doing anything wrong here? 2. If I include ntp everything works as expected, and the ntp_localtime is used correctly. However if I include ntp:ntp_server the template doesn''t seem to be able to find the ntp_server variable (Failed to parse template ntp/etc/ntp.conf.server: Could not find value for ''ntp_server'' at /etc/puppet/modules/ntp/manifests/init.pp:66). This works if I define the variable inside the node. Again, what am I doing wrong here? Thanks in advance, best regards Jose _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Nov 18, 2007, at 3:57 PM, José González Gómez wrote:> > 1. I had to manually add ntp:: to the classes included in the ntp > module, as if I don''t do it that way puppet isn''t able to find > those classes. Anyway, if I just include ntp, puppet is able to > find the class ntp in the module ntp. After reading the wiki and > some messages in the mailing list I thought that puppet should also > be able to find the ntp_server and ntp_client without having to > manually add the ntp:: namespace in its definition... am I doing > anything wrong here?Glad to have you back, José. I''m somewhat unclear on where classes are in what files, but here''s the behaviour: If a class is asked for (usually by the ''include'' function) that is currently unknown, first try to load the module for that class, and if it is still missing, try to load the module-specific file for that class. The file path is determined by starting at the module''s manifests directory and replacing :: with /, then tacking .pp onto the end. Note that this is for 0.23.2; I don''t think autoloading existed before that, and certainly not in 0.22.x. Thus, if you say ''include ntp::ntp_server'', here''s what Puppet will do: 1) load $modules/ntp/manifests/init.pp 2) If the class still doesn''t exist, load $modules/ntp/manifests/ ntp_server.pp 3) If the class still doesn''t exist, fail. Note that it''s a bit redundant to name your classes that way -- you can just as easily use ''ntp::server''.> 2. If I include ntp everything works as expected, and the > ntp_localtime is used correctly. However if I include > ntp:ntp_server the template doesn''t seem to be able to find the > ntp_server variable (Failed to parse template ntp/etc/ > ntp.conf.server: Could not find value for ''ntp_server'' at /etc/ > puppet/modules/ntp/manifests/init.pp:66). This works if I define > the variable inside the node. Again, what am I doing wrong here?There''s an ordering issue when autoloading, and it''s somewhat intractable -- Puppet evaluates all code outside of any class before it evaluates any other classes. This works fine when you use ''import'', because all files are imported before any code is evaluated. However, when you use autoloading, some files are only imported while parsing, which means that some code -- and particularly, all the code outside of classes and definitions -- has already been evaluated. Puppet makes no attempt to catch this code and evaluate it for you. If you have code outside of classes or definitions in your modules, you must explicitly import them, rather than relying on autoloading. -- Susskind''s Rule of Thumb: Don''t ask what they think. Ask what they do. --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
On Nov 19, 2007 6:11 AM, Luke Kanies <luke@madstop.com> wrote:> On Nov 18, 2007, at 3:57 PM, José González Gómez wrote: > > > > 1. I had to manually add ntp:: to the classes included in the ntp > > module, as if I don''t do it that way puppet isn''t able to find > > those classes. Anyway, if I just include ntp, puppet is able to > > find the class ntp in the module ntp. After reading the wiki and > > some messages in the mailing list I thought that puppet should also > > be able to find the ntp_server and ntp_client without having to > > manually add the ntp:: namespace in its definition... am I doing > > anything wrong here? > > Glad to have you back, José. > > I''m somewhat unclear on where classes are in what files, but here''s > the behaviour: > > If a class is asked for (usually by the ''include'' function) that is > currently unknown, first try to load the module for that class, and > if it is still missing, try to load the module-specific file for that > class. The file path is determined by starting at the module''s > manifests directory and replacing :: with /, then tacking .pp onto > the end. Note that this is for 0.23.2; I don''t think autoloading > existed before that, and certainly not in 0.22.x. > > Thus, if you say ''include ntp::ntp_server'', here''s what Puppet will do: > > 1) load $modules/ntp/manifests/init.pp > 2) If the class still doesn''t exist, load $modules/ntp/manifests/ > ntp_server.pp > 3) If the class still doesn''t exist, fail.All the classes are defined in modules/ntp/manifests/init.pp, so I guess they should be found. The question is, should I define the class as ntp_server, or should I add the namespace explicitly (ntp::ntp_server)? From my tests, it seems you must manually add the name space to all the classes, that way autoloading works ok and the classes are found, but that seems a bit awkward.> > > Note that it''s a bit redundant to name your classes that way -- you > can just as easily use ''ntp::server''.Thanks for the suggestion, those classes came from a place where adding ntp_ in front of their name made sense.> > > > 2. If I include ntp everything works as expected, and the > > ntp_localtime is used correctly. However if I include > > ntp:ntp_server the template doesn''t seem to be able to find the > > ntp_server variable (Failed to parse template ntp/etc/ > > ntp.conf.server: Could not find value for ''ntp_server'' at /etc/ > > puppet/modules/ntp/manifests/init.pp:66). This works if I define > > the variable inside the node. Again, what am I doing wrong here? > > There''s an ordering issue when autoloading, and it''s somewhat > intractable -- Puppet evaluates all code outside of any class before > it evaluates any other classes. This works fine when you use > ''import'', because all files are imported before any code is evaluated. > > However, when you use autoloading, some files are only imported while > parsing, which means that some code -- and particularly, all the code > outside of classes and definitions -- has already been evaluated. > Puppet makes no attempt to catch this code and evaluate it for you. > > If you have code outside of classes or definitions in your modules, > you must explicitly import them, rather than relying on autoloading. >So summing up, you must: 1. Add the namespace manually to all the classes (or whatever) defined in a module if you want to use autoloading. This means that you cannot change the name of a module just changing the name of the directory where it is placed under $modules. 2. If you define any variable (or code) outside classes, manually import the module in order to make it work properly. In my case these variables are used to provide default values for some parameters of the classes, is there any best practice regarding this? Best regards Jose _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Nov 20, 2007, at 4:29 PM, José González Gómez wrote:> > All the classes are defined in modules/ntp/manifests/init.pp, so I > guess they should be found. The question is, should I define the > class as ntp_server, or should I add the namespace explicitly > (ntp::ntp_server)? From my tests, it seems you must manually add > the name space to all the classes, that way autoloading works ok > and the classes are found, but that seems a bit awkward.What do you mean, manually adding the namespaces? Namespaces aren''t assumed based on presence in a module, if that''s what you mean, but that''s what every other language I''ve ever used does -- in Ruby, you have to say ''class One::Two'', even if the file is in one/two.rb.> So summing up, you must: > 1. Add the namespace manually to all the classes (or whatever) > defined in a module if you want to use autoloading. This means that > you cannot change the name of a module just changing the name of > the directory where it is placed under $modules.Yes, I guess this is true.> 2. If you define any variable (or code) outside classes, manually > import the module in order to make it work properly. In my case > these variables are used to provide default values for some > parameters of the classes, is there any best practice regarding this?There isn''t a better solution right now, unfortunately. -- We are here on Earth to do good to others. What the others are here for, I don''t know. -- W. H. Auden --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com
On Nov 21, 2007 5:05 PM, Luke Kanies <luke@madstop.com> wrote:> On Nov 20, 2007, at 4:29 PM, José González Gómez wrote: > > > > All the classes are defined in modules/ntp/manifests/init.pp, so I > > guess they should be found. The question is, should I define the > > class as ntp_server, or should I add the namespace explicitly > > (ntp::ntp_server)? From my tests, it seems you must manually add > > the name space to all the classes, that way autoloading works ok > > and the classes are found, but that seems a bit awkward. > > What do you mean, manually adding the namespaces? > > Namespaces aren''t assumed based on presence in a module, if that''s > what you mean, but that''s what every other language I''ve ever used > does -- in Ruby, you have to say ''class One::Two'', even if the file > is in one/two.rb. >You''re right, I didn''t think of it this way... in Java you have to declare the package inside the file, and this package must fit with the path where the file is. Maybe it would be handy to have some kind of construct that lets you declare a namespace that applies to everything in a file? By the way, are you able to add a namespace to a variable defined outside a class? I tried to do it, so everything in the module fell under the same namespace, but I got an error telling me that I can''t assign a variable in another namespace (or something like that, I can reproduce it if you need it). I think this is because when puppet finds a qualified variable it assumes the namespace part must match the name of a class (this is, the variable it''s inside a class), and that you''re trying to redefine it''s value illegally. Regarding this, I have a puzzling feeling about namespaces... I mean, when you find a quallified item in puppet, the namespace may be a manually created one, the name of a class or the name of a module (anything else?). I have the feeling that this may cause problems but I may be wrong. Best regards Jose _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
José González Gómez schrieb:> Hi there, > > After quite a long time out of puppet business I''m back, and the first > thing I''m doing is rephrasing my puppet manifests using modules. I > started with the NTP module (a classic, I guess). I have (more or less) > the following:Hi José, sorry to barge in so late, but I''m currently a bit overloaded. Would you mind taking a look over my published ntp module at http://reductivelabs.com/trac/puppet/wiki/CompleteConfiguration and tell me what I could do better so you wouldn''t need to write your own module? Regards, DavidS
José González Gómez schrieb:> You''re right, I didn''t think of it this way... in Java you have to > declare the package inside the file, and this package must fit with the > path where the file is. Maybe it would be handy to have some kind of > construct that lets you declare a namespace that applies to everything > in a file?I guess you could add "class foo {}" around the whole file. But this messes with scoping, so be wary.> By the way, are you able to add a namespace to a variable defined > outside a class? I tried to do it, so everything in the module fell > under the same namespace, but I got an error telling me that I can''t > assign a variable in another namespace (or something like that, I can > reproduce it if you need it). I think this is because when puppet finds > a qualified variable it assumes the namespace part must match the name > of a class (this is, the variable it''s inside a class), and that you''re > trying to redefine it''s value illegally. > > Regarding this, I have a puzzling feeling about namespaces... I mean, > when you find a quallified item in puppet, the namespace may be a > manually created one, the name of a class or the name of a module > (anything else?). I have the feeling that this may cause problems but I > may be wrong.It can''t be the name of a module, since - as noted earlier - modules do not cause namespaceing. For the remaining two, it doesn''t make a difference, since "include foo::bar" does the same thing, irrespective of being specified as "class foo { class bar {} }" or "class foo::bar { }". Regards, DavidS
On Nov 23, 2007 11:00 AM, David Schmitt <david@schmitt.edv-bus.at> wrote:> José González Gómez schrieb: > > Hi there, > > > > After quite a long time out of puppet business I''m back, and the first > > thing I''m doing is rephrasing my puppet manifests using modules. I > > started with the NTP module (a classic, I guess). I have (more or less) > > the following: > > Hi José, > > sorry to barge in so late, but I''m currently a bit overloaded. > > > > Would you mind taking a look over my published ntp module at > http://reductivelabs.com/trac/puppet/wiki/CompleteConfiguration and tell > me what I could do better so you wouldn''t need to write your own module? > >In fact I took a look to it and it''s seems quite intereseting. It''s not your fault and I don''t discard using it in the future, but right now I have two problems: I need a quick solution, and with all this time away from puppet I''ve become a bit outdated, so I don''t understand many of the things you do there (specially things involving virtual and exported resources), so I prefer to stay away from something I don''t feel able to modify until I get in shape again regarding puppet. Best regards Jose _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Nov 23, 2007 11:05 AM, David Schmitt <david@schmitt.edv-bus.at> wrote:> José González Gómez schrieb: > > Regarding this, I have a puzzling feeling about namespaces... I mean, > > when you find a quallified item in puppet, the namespace may be a > > manually created one, the name of a class or the name of a module > > (anything else?). I have the feeling that this may cause problems but I > > may be wrong. > > It can''t be the name of a module, since - as noted earlier - modules do > not cause namespaceing. For the remaining two, it doesn''t make a > difference, since "include foo::bar" does the same thing, irrespective > of being specified as "class foo { class bar {} }" or "class foo::bar { > }". >Well, I know a module doesn''t create a namespace, but what I really meant is the syntax for module autoloading is the same as used in namespacing. "include foo::bar" may reference a class bar inside a class foo, or a class explicitly named foo:bar, either in the main manifest or in a module named foo which may get autoloaded if foo::bar didn''t exist.. Best regards Jose _______________________________________________ Puppet-users mailing list Puppet-users@madstop.com https://mail.madstop.com/mailman/listinfo/puppet-users
On Nov 22, 2007, at 1:43 AM, José González Gómez wrote:> > You''re right, I didn''t think of it this way... in Java you have to > declare the package inside the file, and this package must fit with > the path where the file is. Maybe it would be handy to have some > kind of construct that lets you declare a namespace that applies to > everything in a file?There is one; it''s called a class. :)> By the way, are you able to add a namespace to a variable defined > outside a class? I tried to do it, so everything in the module fell > under the same namespace, but I got an error telling me that I > can''t assign a variable in another namespace (or something like > that, I can reproduce it if you need it). I think this is because > when puppet finds a qualified variable it assumes the namespace > part must match the name of a class (this is, the variable it''s > inside a class), and that you''re trying to redefine it''s value > illegally.Yep. The whole qualified variable thing was a surprisingly simple modification and didn''t affect any semantics so it was an easy decision. Making it posssible for one class to modify variables in another class, though... I think that''s pretty different and unlikely to be accepted. If you''re just hoping to create variables in a single namespace but never actually create a class for that namespace, that would be a pretty big change for Puppet, since namespaces map directly to classes.> Regarding this, I have a puzzling feeling about namespaces... I > mean, when you find a quallified item in puppet, the namespace may > be a manually created one, the name of a class or the name of a > module (anything else?). I have the feeling that this may cause > problems but I may be wrong.Clearly I''m at an advantage because I wrote the stuff, but it seems pretty simple. Classes and definitions are created relative to a namespace, with the default being "" (which is called :main internally, as a symbol, so it can''t conflict with user-defined classes). When you evaluate a class or a definition, a scope is created. When evaluating the value of a variable, the variable can have a namespace prefixed, which allows you to look up a value in a specific class''s scope. I think your confusion is stemming from the linkage between namespaces and the paths used during importing, but really, they are only loosely linked. ''import'' has some special ability to find files by looking in modules and such, but once a file is loaded, all that matters is the content of the file, not where it was loaded from. Maybe this is a bad idea, though... -- Some people are afraid of heights. I''m afraid of widths. -- Stephen Wright --------------------------------------------------------------------- Luke Kanies | http://reductivelabs.com | http://madstop.com