bluebook
2010-Dec-17 15:17 UTC
[Puppet Users] Referencing the same package from multiple classes
Hello, I''m new to puppet, so maybe this is a silly question, but an hour of googling has thrown up nothing. I am trying to define a set of classes which each represent different server types in my architecture, for example "dns server" and "web server". A single machine may perform more than one server role - eg it could be both a dns server and a web server. For the types of roles I have, lets call them foo and bar, there are some packages in common. Eg they both require tomcat and jre. So to start off with I tried this: class foo { package { jre-jce: ensure => present} package { tomcat: ensure => ''6.0.20-1''} package { foo-services: ensure => present} } class bar { package { jre-jce: ensure => present} package { tomcat: ensure => ''6.0.20-1''} package { bar-services: ensure => present} } node ''server1'' { include foo include bar } This works fine if I only include one class or the other in the node definition, but if I include both then I get an error "Package[jre- jce] is already defined in file ...; cannot redefine at ..." So now I am trying to find a way to move the package definitions outside of the class definitions, and reference them from there. But I can''t find a syntax which allows me to do that. The closest I have come is this: package { jre-jce: ensure => present} class foo { Package["jre-jce"] {} } but puppet doesn''t like the empty braces. Is there a better way to do what I am trying to do? Or is this the right way but the wrong syntax? Thanks for any help. Paul -- 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.
Nigel Kersten
2010-Dec-17 15:28 UTC
Re: [Puppet Users] Referencing the same package from multiple classes
On Fri, Dec 17, 2010 at 7:17 AM, bluebook <paul.fletcher@gmail.com> wrote:> Hello, > > I''m new to puppet, so maybe this is a silly question, but an hour of > googling has thrown up nothing. > > I am trying to define a set of classes which each represent different > server types in my architecture, for example "dns server" and "web > server". A single machine may perform more than one server role - eg > it could be both a dns server and a web server. > > For the types of roles I have, lets call them foo and bar, there are > some packages in common. Eg they both require tomcat and jre. So to > start off with I tried this: > > class foo { > package { jre-jce: ensure => present} > package { tomcat: ensure => ''6.0.20-1''} > package { foo-services: ensure => present} > } > > class bar { > package { jre-jce: ensure => present} > package { tomcat: ensure => ''6.0.20-1''} > package { bar-services: ensure => present} > } > > node ''server1'' { > include foo > include bar > } > > This works fine if I only include one class or the other in the node > definition, but if I include both then I get an error "Package[jre- > jce] is already defined in file ...; cannot redefine at ..."http://projects.puppetlabs.com/projects/1/wiki/Virtual_Resources Define the virtual resource outside the classes, realize it in both.> > So now I am trying to find a way to move the package definitions > outside of the class definitions, and reference them from there. But > I can''t find a syntax which allows me to do that. The closest I have > come is this: > > package { jre-jce: ensure => present} > > class foo { > Package["jre-jce"] {} > } > > but puppet doesn''t like the empty braces. > > Is there a better way to do what I am trying to do? Or is this the > right way but the wrong syntax? > > Thanks for any help. > > Paul > > -- > 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. > >-- Nigel Kersten - Puppet Labs - http://www.puppetlabs.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.
luke.bigum
2010-Dec-17 15:46 UTC
[Puppet Users] Re: Referencing the same package from multiple classes
Nigel''s Virtual Resources is one way, this is another using only classes. You can put the base software in classes of their own and include these in your ''server classes''. Classes can be included multiple times on a node without causing errors. You''ll want something that looks like: class jre-jce { package { "jre-jce": ... } } class tomcat { package { "tomcat: ... } } class foo { include jre-jce include tomcat ... (do more stuff) ... } class bar { include jre-jce include tomcat ... (do more stuff) ... } node something { include foo include bar } If inside classes foo and bar you need to make sure that things occur after jre-jce is installed you can setup a dependency with require, see: http://docs.puppetlabs.com/references/latest/metaparameter.html#require This is more verbose than using virtual resources, but the I like the advantage that you''ve now already got a place where you can put site wide configuration for tomcat or jre-jce. On Dec 17, 3:17 pm, bluebook <paul.fletc...@gmail.com> wrote:> Hello, > > I''m new to puppet, so maybe this is a silly question, but an hour of > googling has thrown up nothing. > > I am trying to define a set of classes which each represent different > server types in my architecture, for example "dns server" and "web > server". A single machine may perform more than one server role - eg > it could be both a dns server and a web server. > > For the types of roles I have, lets call them foo and bar, there are > some packages in common. Eg they both require tomcat and jre. So to > start off with I tried this: > > class foo { > package { jre-jce: ensure => present} > package { tomcat: ensure => ''6.0.20-1''} > package { foo-services: ensure => present} > > } > > class bar { > package { jre-jce: ensure => present} > package { tomcat: ensure => ''6.0.20-1''} > package { bar-services: ensure => present} > > } > > node ''server1'' { > include foo > include bar > > } > > This works fine if I only include one class or the other in the node > definition, but if I include both then I get an error "Package[jre- > jce] is already defined in file ...; cannot redefine at ..." > > So now I am trying to find a way to move the package definitions > outside of the class definitions, and reference them from there. But > I can''t find a syntax which allows me to do that. The closest I have > come is this: > > package { jre-jce: ensure => present} > > class foo { > Package["jre-jce"] {} > > } > > but puppet doesn''t like the empty braces. > > Is there a better way to do what I am trying to do? Or is this the > right way but the wrong syntax? > > Thanks for any help. > > Paul-- 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.
Stefan Schulte
2010-Dec-17 16:32 UTC
Re: [Puppet Users] Re: Referencing the same package from multiple classes
On Fri, Dec 17, 2010 at 07:46:29AM -0800, luke.bigum wrote:> Nigel''s Virtual Resources is one way, this is another using only > classes. > > You can put the base software in classes of their own and include > these in your ''server classes''. Classes can be included multiple times > on a node without causing errors.Hm personally, I don''t really like that because you can include the class in different scopes: One example: class common { file { ''/tmp/test'': content => $tempvar, ensure => file, } } class foo { $tempvar = "foo" include common } class bar { $tempvar = "bar" include common } node default { include foo include bar } This does not throw a compile error but it really depends on ordering if "foo" or "bar" will be in your file. If you define a virtual resource in one place then everything depends on the scope where you defined that resource and not where you realize it. -Stefan
luke.bigum
2010-Dec-17 17:07 UTC
[Puppet Users] Re: Referencing the same package from multiple classes
That''s a fair point, but I shy away from using variables in one class to influence another as much as possible for two reasons. First is Puppet''s variable scope is confusing at best. Second is I like to have my classes do actions on a specific bit of a system entirely within themselves, so anything that does anything with, say, Apache is in an Apache class and any other class that wants to do something with Apache has to use the Apache class''s defines or sub classes to achieve that functionality. This doesn''t always work out but I try stick to it as much as possible. If I had to do something like your example, I would use sub classes of common that work slightly differently based on the functionality I want. If that wasn''t practical I''d look at trying to achieve the same thing with a define. This won''t work for this exact example as trying to fill the same file with two different contents is not the smartest idea, but just to stay on subject I would try to do something like: #either using a child class class common { file { ''/tmp/test'': content => "default", ensure => file, } } class common::foo inherits common { File[''/tmp/test''] { content => "foo content" } } class foo { include common::foo } #or Using a define class bar { include common common_file{"something": contents => "bar content" } } ... but as I said, including both foo and bar on a node in this exact example would cause compile problems, but hopefully it illustrates my idea :) On Dec 17, 4:32 pm, Stefan Schulte <stefan.schu...@taunusstein.net> wrote:> On Fri, Dec 17, 2010 at 07:46:29AM -0800, luke.bigum wrote: > > Nigel''s Virtual Resources is one way, this is another using only > > classes. > > > You can put the base software in classes of their own and include > > these in your ''server classes''. Classes can be included multiple times > > on a node without causing errors. > > Hm personally, I don''t really like that because you can include the class in > different scopes: > > One example: > > class common { > file { ''/tmp/test'': > content => $tempvar, > ensure => file, > } > } > class foo { > $tempvar = "foo" > include common > } > class bar { > $tempvar = "bar" > include common > } > node default { > include foo > include bar > } > > This does not throw a compile error but it really depends on ordering if > "foo" or "bar" will be in your file. If you define a virtual resource in > one place then everything depends on the scope where you defined that > resource and not where you realize it. > > -Stefan > > application_pgp-signature_part > < 1KViewDownload-- 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.
bluebook
2010-Dec-17 17:59 UTC
[Puppet Users] Re: Referencing the same package from multiple classes
Thanks everyone for the pointers. I''ve gone with the Virtual Resources approach because (a) the description of them more or less exactly matches my use case, and (b) because from a class perspective I''m trying to follow the "is a web server" type of paradigm, and "is a jre-jce" doesn''t really work in that context - it''s too granular, and not a description of the role of the node. Paul On Dec 17, 4:32 pm, Stefan Schulte <stefan.schu...@taunusstein.net> wrote:> On Fri, Dec 17, 2010 at 07:46:29AM -0800, luke.bigum wrote: > > Nigel''s Virtual Resources is one way, this is another using only > > classes. > > > You can put the base software in classes of their own and include > > these in your ''server classes''. Classes can be included multiple times > > on a node without causing errors. > > Hm personally, I don''t really like that because you can include the class in > different scopes: > > One example: > > class common { > file { ''/tmp/test'': > content => $tempvar, > ensure => file, > } > } > class foo { > $tempvar = "foo" > include common > } > class bar { > $tempvar = "bar" > include common > } > node default { > include foo > include bar > } > > This does not throw a compile error but it really depends on ordering if > "foo" or "bar" will be in your file. If you define a virtual resource in > one place then everything depends on the scope where you defined that > resource and not where you realize it. > > -Stefan > > application_pgp-signature_part > < 1KViewDownload-- 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.
Ken Barber
2010-Dec-18 11:50 UTC
[Puppet Users] Re: Referencing the same package from multiple classes
For the record, an alternative that I don''t believe was mentioned is to do something like: if !defined(Package["foo"]) { package {"foo": ensure => installed } } ken. -- 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.
Patrick
2010-Dec-18 19:23 UTC
Re: [Puppet Users] Re: Referencing the same package from multiple classes
On Dec 18, 2010, at 3:50 AM, Ken Barber wrote:> For the record, an alternative that I don''t believe was mentioned is to do something like: > > if !defined(Package["foo"]) { > package {"foo": ensure => installed } > }In general this is a bad idea though. Mostly because it can surprise you in bad ways. -- 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.
Ken Barber
2010-Dec-18 19:46 UTC
Re: [Puppet Users] Re: Referencing the same package from multiple classes
Can you elaborate? On Saturday, December 18, 2010 7:23:57 PM UTC, kc7zzv wrote:> > > On Dec 18, 2010, at 3:50 AM, Ken Barber wrote: > > > For the record, an alternative that I don''t believe was mentioned is to > do something like: > > > > if !defined(Package["foo"]) { > > package {"foo": ensure => installed } > > } > > In general this is a bad idea though. Mostly because it can surprise you > in bad ways. > >-- 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.
Stefan Schulte
2010-Dec-19 08:53 UTC
Re: [Puppet Users] Re: Referencing the same package from multiple classes
On Sat, Dec 18, 2010 at 11:46:50AM -0800, Ken Barber wrote:> Can you elaborate? > > On Saturday, December 18, 2010 7:23:57 PM UTC, kc7zzv wrote: > > > > > > On Dec 18, 2010, at 3:50 AM, Ken Barber wrote: > > > > > For the record, an alternative that I don''t believe was mentioned is to > > do something like: > > > > > > if !defined(Package["foo"]) { > > > package {"foo": ensure => installed } > > > } > > > > In general this is a bad idea though. Mostly because it can surprise you > > in bad ways. > > > >Its an ordering issue. Example node default { include foo if defined(Exec[''uname'']) { include bar } } class foo { exec { ''uname'': command => ''/usr/bin/uname'' } notice("Class[foo] applied for defaultnode") } class bar { notice("Class[bar] applied for defaultnode") } This works but if you include foo after the ifstatement then bar will not be included. If you have a complex dependency chain the right order may not be as obvious as in this example (at least I dont know in which order puppet parses complex and nested class structures [and in my opinion I should not have to know it]) -Stefan
Ken Barber
2010-Dec-19 09:37 UTC
Re: [Puppet Users] Re: Referencing the same package from multiple classes
Stefan - obviously my example doesn''t include classes but I see what you mean. It is an interesting topic :-). So here was my example: if !defined(Package["foo"]) { package {"foo": ensure => installed } } Now if I wanted to define a specific revision, trigger or behaviour I could understand why this would be problematic. For example: if !defined(Package["foo"]) { package {"foo": ensure => "1.2.3", notify => Exec["bar"], } } Would be terrible - because I would lose the arguments if the package was defined elsewhere earlier. That would be dumb. Also - the reverse is true ... by defining your own package you may be ruining someone else''s package definition which defines arguments. Like you say - the ordering can cause problems. FYI - The use-case where I would use the if !defined methodology would be when you are defining a re-usable module that you know may (but not always) conflict with another. Nothing is a silver bullet it seems in puppet, and I have had to use this method at least once or twice to avoid stepping on pre-existing content that I can''t influence :-). ken. On Sunday, December 19, 2010 8:53:18 AM UTC, stefan.schulte wrote:> > On Sat, Dec 18, 2010 at 11:46:50AM -0800, Ken Barber wrote: > > Can you elaborate? > > > > On Saturday, December 18, 2010 7:23:57 PM UTC, kc7zzv wrote: > > > > > > > > > On Dec 18, 2010, at 3:50 AM, Ken Barber wrote: > > > > > > > For the record, an alternative that I don''t believe was mentioned is > to > > > do something like: > > > > > > > > if !defined(Package["foo"]) { > > > > package {"foo": ensure => installed } > > > > } > > > > > > In general this is a bad idea though. Mostly because it can surprise > you > > > in bad ways. > > > > > > > > Its an ordering issue. Example > > node default { > include foo > if defined(Exec[''uname'']) { > include bar > } > } > > class foo { > exec { ''uname'': command => ''/usr/bin/uname'' } > notice("Class[foo] applied for defaultnode") > } > class bar { > notice("Class[bar] applied for defaultnode") > } > > This works but if you include foo after the ifstatement then bar will > not be included. If you have a complex dependency chain the right order > may not be as obvious as in this example (at least I dont know in which > order puppet parses complex and nested class structures [and in my > opinion I should not have to know it]) > > -Stefan > >-- 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.
Patrick
2010-Dec-20 04:21 UTC
Re: [Puppet Users] Re: Referencing the same package from multiple classes
On Dec 19, 2010, at 1:37 AM, Ken Barber wrote:> Would be terrible - because I would lose the arguments if the package was defined elsewhere earlier. That would be dumb. Also - the reverse is true ... by defining your own package you may be ruining someone else''s package definition which defines arguments. Like you say - the ordering can cause problems. > > FYI - The use-case where I would use the if !defined methodology would be when you are defining a re-usable module that you know may (but not always) conflict with another. Nothing is a silver bullet it seems in puppet, and I have had to use this method at least once or twice to avoid stepping on pre-existing content that I can''t influence :-).Ya. This is what I meant. Thanks for explaining. For the original example, it''s just easier to create a tomcat class that has the packages and then include the tomcat class in both service classes. -- 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.