Hi. I''ve seen in many modules at puppet-forge this kind of organization: class myclass( $somevar=''value'' ) inherits myclass::params { file { $mydir: ensure => directory, } } class myclass::params { $mydir = ''/some/path'' } Now, I wonder how can I override $mydir from node definition? Or am I missing the whole point, am I supposed to put $mydir inside standard brackets and then call the class with something like: node mynode.mydomain.com { class myclass($mydir=''/some/other/path'') } Thank you -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2012-Sep-05 21:37 UTC
[Puppet Users] Re: Override param from parametrized class?
On Wednesday, September 5, 2012 1:19:16 PM UTC-5, Jakov Sosic wrote:> > Hi. > > I''ve seen in many modules at puppet-forge this kind of organization: > > class myclass( > $somevar=''value'' > ) inherits myclass::params { > file { $mydir: > ensure => directory, > } > } > > class myclass::params { > $mydir = ''/some/path'' > } > > > Now, I wonder how can I override $mydir from node definition?Not as your example is written, read on.> Or am I > missing the whole point, am I supposed to put $mydir inside standard > brackets and then call the class with something like: > > node mynode.mydomain.com { > class myclass($mydir=''/some/other/path'') > } > >I think very likely have overlooked a key aspect of the pattern you observed (or else the modules you are looking at aren''t good teaching examples). The usual usage of the pattern I suspect you''ve seen is more like this: # This might as readily be named mymodule::myclass class mymodule ($myparam = $myparam_default) inherits mymodule::params { file { $myparam: # ... } } class mymodule::params { $myparam_default = ''/some/path'' } The key difference there is that a variable declared by the ::params class is used as a default value for a parameter of the class that inherits it. That''s the *only* reason why class inheritance is reasonable in this particular case. As a matter of good style, classes inherited for this purpose should normally contain only variable declarations. If one class wants to use another class''s variables, but not as class parameter defaults, then it should not inherit from that class. Instead, it should ''include'' that class (provided it is not parametrized) and then refer to the variables by their fully-qualified names, such as $mymodule::params::anothervar. Inheriting the ::params class is simply a trick to ensure the variables are initialized and accessible for use before any part of the class body of the inheriting class is parsed (i.e. in time to be used as parameter defaults). Getting back to your questions, no, you cannot override the value of a class variable, but you *can* provide your own values for class parameters, which will then be used instead of whatever default values may have been declared. That''s done like so: class { "mymodule": # parameters follow... myparam => ''custom value'' } Yes, it looks very much like a resource declaration. No, I don''t think that was a good design decision, but the prevailing opinion at PuppetLabs is different, or was when parametrized classes were added. Before you start swooning over how nice parametrized classes look, let me warn you that they carry some substantial drawbacks. Therefore, I urge you to avoid using them in your own code as much as you can do, at least until you understand Puppet well enough to appreciate why they might make sense in some circumstances (clue me in when you figure that out), and especially until you appreciate the problems they present. Hint: the biggest one is that parametrized classes cannot be declared more than once. There are other, better ways to get data to your classes, notably data access functions such as hiera(), and global or [other]class variables. Puppet 3 does shine up parametrized classes a lot, in large part by integrating hiera directly into parameter value resolution. Nevertheless, you don''t need class parameters, and even in Puppet 3, parametrized classes retain a few pointy bits. Therefore, I''d focus on building classes that rely on hiera (which for Puppet 2.x is a third-party extension) where they need external data, as that will serve you well both now and going forward. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/sHqw7Z31O_sJ. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Jakov Sosic
2012-Sep-07 11:24 UTC
Re: [Puppet Users] Re: Override param from parametrized class?
On 09/05/2012 11:37 PM, jcbollinger wrote:> class { "mymodule": > # parameters follow... > myparam => ''custom value'' > } > > Yes, it looks very much like a resource declaration. No, I don''t think > that was a good design decision, but the prevailing opinion at > PuppetLabs is different, or was when parametrized classes were added.It''s a shame you cannot define multiple instances of parametrized classes with different parameters :( Anyway, how should I approach adding dynamic content into node''s manifest, using a define maybe? -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Davide Ferrari
2012-Sep-07 13:03 UTC
Re: [Puppet Users] Re: Override param from parametrized class?
On 05/09/12 23:37, jcbollinger wrote:> Before you start swooning over how nice parametrized classes look, let > me warn you that they carry some substantial drawbacks. Therefore, I > urge you to avoid using them in your own code as much as you can do, > at least until you understand Puppet well enough to appreciate why > they might make sense in some circumstances (clue me in when you > figure that out), and especially until you appreciate the problems > they present. Hint: the biggest one is that parametrized classes > cannot be declared more than once.I''ve raised this very topic on the IRC channel, due to my frustration with the *bug* [1] that makes impossible to override parameters with custom classes while inheriting, and I still don''t understand *why* is inheritance so bad nad if it''s so, why is it still there? I think inheritance improves a lot manifests/classes readability and personally I hate using global variables and passing parameters (but it''s just a matter of taste). But hey, if there''s any technical reason in Puppet that makes inheritance bad, I''m all ears and happy to change my mind about it :) [1] https://projects.puppetlabs.com/issues/5517 -- Davide Ferrari Senior System Administrator Trovit Search http://www.trovit.com -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2012-Sep-07 13:20 UTC
Re: [Puppet Users] Re: Override param from parametrized class?
On Friday, September 7, 2012 6:25:11 AM UTC-5, Jakov Sosic wrote:> > On 09/05/2012 11:37 PM, jcbollinger wrote: > > > class { "mymodule": > > # parameters follow... > > myparam => ''custom value'' > > } > > > > Yes, it looks very much like a resource declaration. No, I don''t think > > that was a good design decision, but the prevailing opinion at > > PuppetLabs is different, or was when parametrized classes were added. > > It''s a shame you cannot define multiple instances of parametrized > classes with different parameters :( >No, that''s not it. I mean you can''t do that, but the real problem is that you can''t declare the same parametrized class multiple times even with the * same* parameters. That''s one of the things you *can* do with ordinary classes (with the same effect as declaring that class exactly once), and there are several circumstances where it''s a useful ability to have. Classes are singletons, so it doesn''t make sense to try to assign different sets of parameters in different places. If you are trying to model some aspect of your systems that may be present more than once, then it''s certainly a resource, and it should be modeled via one of Puppets built-in resources or via a resource of a custom or defined type. Most of the time you can use a defined type.> > Anyway, how should I approach adding dynamic content into node''s > manifest, using a define maybe? >That''s what I addressed at the end of my previous message. I strongly recommend that you look into hiera. Adding to what I already said, however, resources of defined types are just fine when a resource (as opposed to a class) is in fact what you want. It is worthwhile to understand the difference between class and resource at the conceptual level, because there are some circumstances that require a class. You may save yourself future grief if you start out with classes where they''re appropriate, even if, for the moment, they''re not actually needed. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/ECnytUOh7MgJ. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Jakov Sosic
2012-Sep-07 15:02 UTC
Re: [Puppet Users] Re: Override param from parametrized class?
On 09/07/2012 03:20 PM, jcbollinger wrote:> That''s what I addressed at the end of my previous message. I strongly > recommend that you look into hiera. Adding to what I already said, > however, resources of defined types are just fine when a resource (as > opposed to a class) is in fact what you want. It is worthwhile to > understand the difference between class and resource at the conceptual > level, because there are some circumstances that require a class. You > may save yourself future grief if you start out with classes where > they''re appropriate, even if, for the moment, they''re not actually needed.I don''t think you understood me there :) I use hiera for some purposes, but this is my class: class cobbler ( $service_name = $cobbler::params::service_name, $package_name = $cobbler::params::package_name, $package_ensure = $cobbler::params::package_ensure, $distro_path = $cobbler::params::distro_path, ) inherits cobbler::params { package { $package_name : ensure => $package_ensure, } service { $service_name : ensure => running, enable => true, require => Package[$package_name], } file { $distro_path : ensure => directory, owner => root, group => root, mode => ''0755'', } file { ''/etc/cobbler/settings'': ensure => present, owner => root, group => root, mode => ''0644'', content => template(''cobbler/settings.erb''), notify => Service["$service_name"], } define add_distro ($arch,$isolink){ $distro = $title cobblerdistro { $distro : ensure => present, arch => $arch, isolink => $isolink, destdir => $cobbler::distro_path, require => Service[$cobbler::service_name], } } define del_distro (){ $distro = $title cobblerdistro { $distro : ensure => absent, destdir => $cobbler::distro_path, require => Service[$cobbler::service_name], } } } So, from node manifest, I can do this: node ''mynode'' { class { ''cobbler'': distro_path => ''/data/distro'' } cobbler::add_distro { ''CentOS-6.3-x86_64'': arch => ''x86_64'', isolink => ''http://mi.mirror.garr.it/mirrors/CentOS/6.3/isos/x86_64/CentOS-6.3-x86_64-bin-DVD1.iso'', } cobbler::add_distro { ''CentOS-6.2-x86_64'': arch => ''x86_64'', isolink => ''http://mi.mirror.garr.it/mirrors/CentOS/6.2/isos/x86_64/CentOS-6.2-x86_64-bin-DVD1.iso'', } } Is this OK? -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2012-Sep-10 13:34 UTC
Re: [Puppet Users] Re: Override param from parametrized class?
On Friday, September 7, 2012 10:02:56 AM UTC-5, Jakov Sosic wrote:> > On 09/07/2012 03:20 PM, jcbollinger wrote: > > > That''s what I addressed at the end of my previous message. I strongly > > recommend that you look into hiera. Adding to what I already said, > > however, resources of defined types are just fine when a resource (as > > opposed to a class) is in fact what you want. It is worthwhile to > > understand the difference between class and resource at the conceptual > > level, because there are some circumstances that require a class. You > > may save yourself future grief if you start out with classes where > > they''re appropriate, even if, for the moment, they''re not actually > needed. > > I don''t think you understood me there :) I use hiera for some purposes, > but this is my class: > > class cobbler ( > $service_name = $cobbler::params::service_name, > $package_name = $cobbler::params::package_name, > $package_ensure = $cobbler::params::package_ensure, > $distro_path = $cobbler::params::distro_path, > ) inherits cobbler::params { > package { $package_name : > ensure => $package_ensure, > } > service { $service_name : > ensure => running, > enable => true, > require => Package[$package_name], > } > file { $distro_path : > ensure => directory, > owner => root, > group => root, > mode => ''0755'', > } > file { ''/etc/cobbler/settings'': > ensure => present, > owner => root, > group => root, > mode => ''0644'', > content => template(''cobbler/settings.erb''), > notify => Service["$service_name"], > } > define add_distro ($arch,$isolink){ > $distro = $title > cobblerdistro { $distro : > ensure => present, > arch => $arch, > isolink => $isolink, > destdir => $cobbler::distro_path, > require => Service[$cobbler::service_name], > } > } > define del_distro (){ > $distro = $title > cobblerdistro { $distro : > ensure => absent, > destdir => $cobbler::distro_path, > require => Service[$cobbler::service_name], > } > } > } > > > So, from node manifest, I can do this: > node ''mynode'' { > class { ''cobbler'': > distro_path => ''/data/distro'' > } > cobbler::add_distro { ''CentOS-6.3-x86_64'': > arch => ''x86_64'', > isolink => > '' > http://mi.mirror.garr.it/mirrors/CentOS/6.3/isos/x86_64/CentOS-6.3-x86_64-bin-DVD1.iso'', > > } > cobbler::add_distro { ''CentOS-6.2-x86_64'': > arch => ''x86_64'', > isolink => > '' > http://mi.mirror.garr.it/mirrors/CentOS/6.2/isos/x86_64/CentOS-6.2-x86_64-bin-DVD1.iso'', > > } > } > > > Is this OK? >It depends on what you mean by "OK". Your class is not consistent with my recommendations, but that doesn''t make it wrong. I am recommending that you use *only* hiera to communicate site- and node-specific data to your classes. That is, according to me, you should avoid use of parametrized classes wherever it is feasible to do so. That would mean using parametrized classes only from third-party modules, really, since you can always avoid parametrization in classes you write yourself. Thus, your "cobbler" class might start this way: class cobbler { include ''cobbler::params'' $service_name = hiera(''cobbler_service_name'', $cobbler::params::service_name) $package_name = hiera(''cobbler_package_name'', $cobbler::params::package_name) $package_ensure = hiera(''cobbler_package_ensure'', $cobbler::params::package_ensure) $distro_path = hiera(''cobbler_distro_path'', $cobbler::params::distro_path) # ... Voila, (the beginning of) a non-parametrized version of your class. Nothing else has to change (but see below). Note that the non-parametrized version also doesn''t need the inheritance trick; it uses an ordinary ''include'' instead. On a separate note, the PuppetLabs style recommendation and prevailing opinion agree that type definitions should go into their own files. Thus, instead of add_distro() and del_distro() being defined in the body of class cobbler, they should appear in sibling files add_distro.pp and del_distro.pp. And as a side note, that will actually be much cleaner with the non-parametrized version of class cobbler than it would be with the parametrized version, because 1. It is safe for the definition bodies (in a separate file) to refer to class variables, but not to class parameters (the latter fails in some Puppet versions). 2. The definition bodies can ''include'' class cobbler to ensure that its variables are recognized (which they must not do if ''cobbler'' is parametrized, even if they know the correct parameters, because parametrized classes can be declared at most once) 3. If you do (2), then, at your option, your nodes don''t have to declare class ''cobbler'' at all as long as they declare at least one cobbler::add_distro or cobbler::del_distro resource So, for instance: modules/cobbler/manifests/add_distro.pp: define add_distro ($arch, $isolink) { include ''cobbler'' cobblerdistro { $title : ensure => present, arch => $arch, isolink => $isolink, destdir => $cobbler::distro_path, require => Service[$cobbler::service_name], } } John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/z_FI9FiOJVMJ. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2012-Sep-10 14:01 UTC
Re: [Puppet Users] Re: Override param from parametrized class?
On Monday, September 10, 2012 8:34:33 AM UTC-5, jcbollinger wrote:> > > modules/cobbler/manifests/add_distro.pp: > > define add_distro ($arch, $isolink) { > >Oops, that should be define cobbler::add_distro ($arch, $isolink) { #... John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/XbOkFbWimXkJ. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Jakov Sosic
2012-Sep-11 16:59 UTC
Re: [Puppet Users] Re: Override param from parametrized class?
On 09/10/2012 04:01 PM, jcbollinger wrote:> > > On Monday, September 10, 2012 8:34:33 AM UTC-5, jcbollinger wrote: > > > modules/cobbler/manifests/add_distro.pp: > > define add_distro ($arch, $isolink) { > > > Oops, that should be > > define cobbler::add_distro ($arch, $isolink) { > #... >Thank you for your insights, very helpful! -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.