Darrell Fuhriman
2008-Jun-22 00:19 UTC
[Puppet Users] disabling or changing classes and limited behaviors thereof
I know the canonical way to disable a class is to define a ::disabled class and override, but this doesn''t work well in a number of situations. Take for instance, xinetd -- the official way to handle xinetd services are by managing the files in xinetd.d (see trac ticket, #284). But this doesn''t work: class tftp::server { include xinetd e file { ''/etc/xinetd.d/tftp'': source => etc etc etc notify => Service[xinetd], } } class tftp::server::disabled inherits tftp::server { tidy { ''/etc/xinetd.d/tftp'': notify => Service[xinetd] } } At *best*, we would copy it over and delete it every time puppet ran which is -- silly. Plus, if the idea is that you can force a machine into a known state, then you should be putting tftp::server::disabled into your default node definition, only to be over-ridden. That doesn''t work well either. Here''s a different example. If I have sendmail::server and sendmail::client, I can''t seem to override file definitions. For instance: class sendmail::client { file { ''/etc/mail/sendmail.cf'': source => ''sendmail/client/sendmail.cf'', etc, etc, etc. } class sendmail::server inherits sendmail::client { File[/etc/mail/sendmail.cf ] { source => ''sendmail/server/ sendmail.cf'' } } (syntax is from memory, so don''t knock me on that one) This generates an error. The only way to get around it is have both classes inherit a sendmail::common class and then define the file{} differently in each child class. This raises a different problem because now we can''t put sendmail::client into the default node definition. If I do that, then include sendmail::server on the server hosts, I''ll have duplicate definitions of the same file, which generates an error. This is true of any service where the default would be to be a client, and then have servers do something different This raises a couple of other related issues. In cfengine, I can say: someclass:: do stuff !someclass:: do something else AND !sendmailserver:: AddClasses ( sendmailclient ) There doesn''t seem to be any way to do the same thing in puppet, true? Again, this, to me, would seem to violate the principle of ensuring every system is in a known state. (I try to define disables for everything -- if I''m not in classA, then I should make sure that classA cannot be enabled accidentally. (For instance, if someone logs in and starts up a service, and that host shouldn''t be running that service, then it should be shutdown the next time puppet runs) Thoughts? Any suggestions for achieving similar behaviors in puppet? Darrell --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Russ Allbery
2008-Jun-22 01:11 UTC
[Puppet Users] Re: disabling or changing classes and limited behaviors thereof
Darrell Fuhriman <darrell@garnix.org> writes:> Take for instance, xinetd -- the official way to handle xinetd services > are by managing the files in xinetd.d (see trac ticket, #284). But this > doesn''t work: > > class tftp::server { > include xinetd > e file { ''/etc/xinetd.d/tftp'': > source => etc etc etc > notify => Service[xinetd], > } > } > > class tftp::server::disabled inherits tftp::server { > tidy { ''/etc/xinetd.d/tftp'': > notify => Service[xinetd] > } > }Er, why would you do that? class tftp::server::disabled inherits tftp::server { File["/etc/xinetd.d/tftp"] { ensure => absent } }> Plus, if the idea is that you can force a machine into a known state, > then you should be putting tftp::server::disabled into your default node > definition, only to be over-ridden. That doesn''t work well either.That doesn''t make any sense to me. Including either tftp::server or tftp::server::disabled into your configuration will force the config to a known state.> Here''s a different example. If I have sendmail::server and > sendmail::client, I can''t seem to override file definitions. For > instance: > > class sendmail::client { > file { ''/etc/mail/sendmail.cf'': > source => ''sendmail/client/sendmail.cf'', > etc, etc, etc. > } > > class sendmail::server inherits sendmail::client { > File[/etc/mail/sendmail.cf ] { source => ''sendmail/server/ > sendmail.cf'' } > } > > (syntax is from memory, so don''t knock me on that one) > > This generates an error.It doesn''t for me. We do this all the time. We have hundreds of instances of this pattern in our manifests. What is the exact manifest that you tried and what error message did you get?> The only way to get around it is have both classes inherit a > sendmail::common class and then define the file{} differently in each > child class.This is absolutely not necessary. -- Russ Allbery (rra@stanford.edu) <http://www.eyrie.org/~eagle/> --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Adam Jacob
2008-Jun-22 05:04 UTC
[Puppet Users] Re: disabling or changing classes and limited behaviors thereof
On Sat, Jun 21, 2008 at 5:19 PM, Darrell Fuhriman <darrell@garnix.org> wrote:> > > I know the canonical way to disable a class is to define a ::disabled > class and override, but this doesn''t work well in a number of > situations. > > Take for instance, xinetd -- the official way to handle xinetd > services are by managing the files in xinetd.d (see trac ticket, > #284). But this doesn''t work: > > class tftp::server { > include xinetd > e file { ''/etc/xinetd.d/tftp'': > source => etc etc etc > notify => Service[xinetd], > } > } > > class tftp::server::disabled inherits tftp::server { > tidy { ''/etc/xinetd.d/tftp'': > notify => Service[xinetd] > } > } > > At *best*, we would copy it over and delete it every time puppet ran > which is -- silly.Instead of having classes structured this way, you really want to have a definition. define tftp_server($ensure=enabled) { case $ensure { enabled: { file { ''/etc/xinet.d/tftp'': ... ensure => present } # Anyhting else you need to set up a tftp server } } disabled: { file { ''/etc/xinet.d/tftp'': ... ensure => absent } } } Then in the higher-level class that needs a TFTP server, you can say: tftp_server { "foo": ensure => enabled } And just flip to "disabled" when you want it to go away.> Plus, if the idea is that you can force a machine into a known state, > then you should be putting tftp::server::disabled into your default > node definition, only to be over-ridden. That doesn''t work well either.In a fully automated world, it''s going to be faster to nuke a system from orbit and start from scratch than it will be to spend time flipping systems between states with the automation. Not every server will have your tftp::server class applied to it, so I would worry much less about setting your defaults to a bunch of "does not have" kind of definitions. Not that you can''t do this kind of "policy" style enforcement with puppet -- but it''s probably overkill, unless you have very steep audit and change control requirements.> Here''s a different example. If I have sendmail::server and > sendmail::client, I can''t seem to override file definitions. For > instance: > > class sendmail::client { > file { ''/etc/mail/sendmail.cf'': > source => ''sendmail/client/sendmail.cf'', > etc, etc, etc. > } > > class sendmail::server inherits sendmail::client { > File[/etc/mail/sendmail.cf ] { source => ''sendmail/server/ > sendmail.cf'' } > } > > (syntax is from memory, so don''t knock me on that one)Why inherit sendmail::client? Have a sendmail::base class that has the common things (package installation, etc.) and have sendmail::client and sendmail::server inherit from it, both defining the sendmail.cf. Even those terms are probably wrong, though... your machines are fulfilling roles, and those roles have more semantic meaning than "client" and "server". What is a server *doing*? Is it an outbound mail relay? corporate mail server?> This generates an error. The only way to get around it is have both > classes inherit a sendmail::common class and then define the file{} > differently in each child class. This raises a different problem > because now we can''t put sendmail::client into the default node > definition. If I do that, then include sendmail::server on the server > hosts, I''ll have duplicate definitions of the same file, which > generates an error. This is true of any service where the default > would be to be a client, and then have servers do something differentWe handle this a third way, which is to use external node tools and variable assignment to alter the configuration of a given system. So our base class includes ''postfix'', and then we have $mail_server_type which defaults to using a smarthost, but might be set to "outbound_relay" or "smarthost".> This raises a couple of other related issues. In cfengine, I can say: > someclass:: > do stuff > > !someclass:: > do something else > > AND > > !sendmailserver:: > AddClasses ( sendmailclient ) > > > There doesn''t seem to be any way to do the same thing in puppet, true? > Again, this, to me, would seem to violate the principle of ensuring > every system is in a known state. (I try to define disables for > everything -- if I''m not in classA, then I should make sure that > classA cannot be enabled accidentally. (For instance, if someone logs > in and starts up a service, and that host shouldn''t be running that > service, then it should be shutdown the next time puppet runs)Really? I get why you might want that in certain environments.. but in most, is that level really neccessary?> Thoughts? Any suggestions for achieving similar behaviors in puppet?I''m sure it''s possible, but it''s uncommon. Adam -- HJK Solutions - We Launch Startups - http://www.hjksolutions.com Adam Jacob, Senior Partner T: (206) 508-4759 E: adam@hjksolutions.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 -~----------~----~----~----~------~----~------~--~---
Darrell Fuhriman
2008-Jun-24 16:26 UTC
[Puppet Users] Re: disabling or changing classes and limited behaviors thereof
> class tftp::server::disabled inherits tftp::server { > File["/etc/xinetd.d/tftp"] { ensure => absent } > }*smacks forehead* Right. I forgot about ''absent''.> It doesn''t for me. We do this all the time. We have hundreds of > instances of this pattern in our manifests. > > What is the exact manifest that you tried and what error message did > you > get?Well, I pulled it out of revision control and this is the error I get: "Only subclasses can override parameters at /etc/puppet/modules/ sendmail/manifests/init.pp:48 on node mom.projectdx.com" The definition is below, and as you can see it *is* a subclass... d. class sendmail::client { case $operatingsystem { freebsd: { $submitmc = [''/etc/mail/freebsd.submit.mc'', "/etc/mail/$ {fqdn}.submit.mc"] $sendmailmc = [''/etc/mail/freebsd.mc'', "/etc/mail/$ {fqdn}.mc"] } centos: { $submitmc = ''/etc/mail/submit.mc'' $sendmailmc = ''/etc/mail/sendmail.mc'' package { [''sendmail'', ''sendmail-cf'', ''sendmail-devel'', ''sendmail-doc'']: ensure => installed } } } remotefile { $sendmailmc: source => "sendmail/client/$operatingsystem/sendmail.mc", mode => 0444, owner => root, group => 0, notify => [Service[sendmail], Exec[sendmailmake]], } remotefile { $submitmc: source => "sendmail/client/$operatingsystem/submit.mc", mode => 0444, owner => root, group => 0, notify => [Service[sendmail], Exec[sendmailmake]], } exec { ''sendmailmake'': cwd => ''/etc/mail/'', command => ''/usr/bin/make'', } service { ''sendmail'': enable => true, hasstatus => true, hasrestart => true, ensure => running, } } class sendmail::server inherits sendmail::client { include genericserver File[$sendmailmc] { source => "sendmail/server/$operatingsystem/sendmail.mc" } File[$submitmc] { source => "sendmail/server/$operatingsystem/submit.mc" } remotefile { [''authinfo'', ''access'', ''trusted-users'', ''domaintable'', ''mailertable'', ''virtusertable'']: path => "/etc/mail/$name", mode => 0440, source => ''sendmail/server/$name'', notify => ''Exec[sendmailmake]'', } remotefile { ''/etc/aliases'': source => "sendmail/server/aliases", mode => 0444, notify => ''Exec[sendmailmake]'', } } --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Darrell Fuhriman
2008-Jun-24 16:29 UTC
[Puppet Users] Re: disabling or changing classes and limited behaviors thereof
> > will have your tftp::server class applied to it, so I would worry much > less about setting your defaults to a bunch of "does not have" kind of > definitions.Yes and no. In the general case that''s true, I do do fully automated installs. But sometimes you *need* a default disable because the default install has something running that you don''t want running everywhere. Yes, you could do that in your build scripts, but it seems to make just as much sense to me to have puppet handle it. I like having all system configuration in one place.>> Even those terms are probably wrong, though... your machines are > fulfilling roles, and those roles have more semantic meaning than > "client" and "server". What is a server *doing*? Is it an outbound > mail relay? corporate mail server?It''s a rather small environment. It''s the server. Everything else are clients to it. It makes perfect sense in the context.> > Really? I get why you might want that in certain environments.. but > in most, is that level really neccessary?Well, by your own admission, it most certainly can be necessary... Generally the right answer to "doctor, it hurts when I do this" is not "don''t do that." Darrell --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Russ Allbery
2008-Jun-25 06:45 UTC
[Puppet Users] Re: disabling or changing classes and limited behaviors thereof
Darrell Fuhriman <darrell@garnix.org> writes:> Well, I pulled it out of revision control and this is the error I get: > > "Only subclasses can override parameters at /etc/puppet/modules/ > sendmail/manifests/init.pp:48 on node mom.projectdx.com" > > The definition is below, and as you can see it *is* a subclass... > > class sendmail::client { > case $operatingsystem { > freebsd: { > $submitmc = [''/etc/mail/freebsd.submit.mc'', "/etc/mail/$ > {fqdn}.submit.mc"] > $sendmailmc = [''/etc/mail/freebsd.mc'', "/etc/mail/$ > {fqdn}.mc"] > }[...]> remotefile { $sendmailmc: > source => "sendmail/client/$operatingsystem/sendmail.mc", > mode => 0444, > owner => root, > group => 0, > notify => [Service[sendmail], Exec[sendmailmake]], > }[...]> class sendmail::server inherits sendmail::client { > include genericserver > > File[$sendmailmc] { > source => "sendmail/server/$operatingsystem/sendmail.mc" > }[...] I''m not sure what''s wrong here, but the one thing that you''re doing differently than we''re doing is that you''re using variables and assuming the value of the variable is inherited from the parent class. None of our overrides use variables for the name of the object. I wonder if that''s why you''re getting a different result. -- Russ Allbery (rra@stanford.edu) <http://www.eyrie.org/~eagle/> --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Peter Meier
2008-Jun-25 07:03 UTC
[Puppet Users] Re: disabling or changing classes and limited behaviors thereof
Hi> remotefile { $sendmailmc: > source => "sendmail/client/$operatingsystem/sendmail.mc", > mode => 0444, > owner => root, > group => 0, > notify => [Service[sendmail], Exec[sendmailmake]], > }vs.> File[$sendmailmc] { > source => "sendmail/server/$operatingsystem/sendmail.mc" > }this is not the same resource-identifier. Please use Remotefile[$sendmailmc] instead, which should work fine. greets pete --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Russ Allbery
2008-Jun-25 19:29 UTC
[Puppet Users] Re: disabling or changing classes and limited behaviors thereof
Peter Meier <peter.meier@immerda.ch> writes:> Hi >> remotefile { $sendmailmc: >> source => "sendmail/client/$operatingsystem/sendmail.mc", >> mode => 0444, >> owner => root, >> group => 0, >> notify => [Service[sendmail], Exec[sendmailmake]], >> } > > vs. > >> File[$sendmailmc] { >> source => "sendmail/server/$operatingsystem/sendmail.mc" >> } > > > this is not the same resource-identifier. Please use > Remotefile[$sendmailmc] instead, which should work fine.Oh, good catch. Yeah, that''s the problem. Puppet doesn''t allow you to look "inside" definitions with overrides; you have to override the definition itself, not the underlying resource. -- Russ Allbery (rra@stanford.edu) <http://www.eyrie.org/~eagle/> --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---