Hi all, I''m trying to configure Puppet to allow the creation of multiple memcached instances on a system. However, I''m running into the message that only subclasses can override parameters. Perhaps I''m going about this the wrong way, or maybe I just have something slightly wrong. Any advice is welcome. class memcached { package { ''memcached'': ensure => present } # do not want basic configuration file { ''/etc/memcached.conf'': ensure => absent } service { ''memcached'': ensure => running, enable => true, require => Package[''memcached''], } } define memcached::instance () { include memcached $conf = "/etc/memcached_${name}.conf" file { $conf: ensure => present } * Service[''memcached''] { require +> File[$conf] }* } # create first instance in file /etc/memcached_en.conf memcached::instance { ''en'': } The other thing I''d like to do is have Service[''memcached''] set to NOT start unless there is at least one instance, i.e. not start until after the first instance''s config file is in place, but that''s not a showstopper. Thanks, Justin -- 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/-/fic-AkDAfAoJ. 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.
Christopher Wood
2012-Jul-23 21:33 UTC
Re: [Puppet Users] Adding file dependencies to existing service
(inline) On Mon, Jul 23, 2012 at 02:09:01PM -0700, Justin wrote:> Hi all, > I''m trying to configure Puppet to allow the creation of multiple memcached > instances on a system. However, I''m running into the message that only > subclasses can override parameters. Perhaps I''m going about this the wrong > way, or maybe I just have something slightly wrong. Any advice is welcome. > class memcached { > package { ''memcached'': ensure => present } > # do not want basic configuration > file { ''/etc/memcached.conf'': ensure => absent } > service { ''memcached'': > ensure => running, > enable => true, > require => Package[''memcached''], > } > } > define memcached::instance () { > include memcached > $conf = "/etc/memcached_${name}.conf" > file { $conf: ensure => present } > Service[''memcached''] { require +> File[$conf] }This bit is a problem because all defines will declare Service[''memcached''] and thus you''ll get spammed with duplicate definitions. I solved this by using multiple daemons, useful to me because I want to be able to kill a daemon in an emergency without affecting more than one service. Another generic technique I''ve found useful is to have several classes in my module, for instance: 1) thing::software class (installs the defaults file per below, installs the package, installs the init script) 2) thing::extraconfig define (includes thing::software, throw a config file in /etc/thing.d/, something inside this notifies the service) 3) thing::service class (includes thing:;software, declares service { ''thing'': }, basically exists so the service is separate from the software) In your manifest where you call all these, you would have to ensure that thing::extraconfig is declared before thing::service. (Just food for thought.)> } > # create first instance in file /etc/memcached_en.conf > memcached::instance { ''en'': } > The other thing I''d like to do is have Service[''memcached''] set to NOT > start unless there is at least one instance, i.e. not start until after > the first instance''s config file is in place, but that''s not a > showstopper.By my experimentation, memcached will be started by the postinstall scripts when you install the deb/rpm. One technique I''ve found useful (on Ubuntu/Debian) is to declare file { "/etc/default/$software": content => "start=no" } before installing said software. Apt won''t overwrite the defaults file so the daemon won''t start, and you can lay down a custom init script (which doesn''t check the defaults file) after your config files are installed. Here''s how I solved the memcached thing to pop up multiple memcached daemons (obviously derived from https://github.com/saz/puppet-memcached): class memcached::orig_off { $classname = ''memcached'' package { $classname: ensure => installed, } service { $classname: ensure => stopped, enable => false, hasrestart => true, hasstatus => true, require => Package[''memcached''], } } define memcached::daemon ( $max_memory = false, $listen_ip = ''0.0.0.0'', $port = ''11211'', $max_connections = ''8192'' ) { $classname = ''memcached'' $filesource = "puppet:///modules/$classname" case $::operatingsystem { ubuntu, debian: { $user = ''nobody'' $mconfdir = ''/etc/monit/conf.d'' } centos, redhat: { $user = ''memcached'' $mconfdir = ''/etc/monit.d'' } default: { fail("Unsupported platform: ${::operatingsystem}") } } $service1 = "memcached${port}" $config1 = "/etc/memcached${port}.conf" $config1template = "$classname/memcached_sp.conf.erb" $init1 = "/usr/local/sbin/start-memcached${port}" $init1template = "$classname/start_memcached.erb" $init2 = "/etc/init.d/memcached${port}" $init2template = "$classname/init_memcached.erb" $mfile1 = "$mconfdir/${classname}${port}" $mfile1template = "$classname/memcached_monit.erb" $logfile = "/var/log/memcached${port}.log" include memcached::orig_off file { $init1: content => template($init1template), mode => 744, } file { $init2: content => template($init2template), mode => 744, } file { $config1: content => template($config1template), require => Class[''memcached::orig_off''], } service { $service1: ensure => running, enable => true, hasrestart => true, hasstatus => false, require => [File[$init1], File[$init2], File[$config1]], subscribe => File[$config1], } file { $mfile1: content => template($mfile1template), mode => 600, require => Service[$service1], } }> Thanks, > Justin > > -- > You received this message because you are subscribed to the Google Groups > "Puppet Users" group. > To view this discussion on the web visit > [1]https://groups.google.com/d/msg/puppet-users/-/fic-AkDAfAoJ. > 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. > > References > > Visible links > 1. https://groups.google.com/d/msg/puppet-users/-/fic-AkDAfAoJ-- 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.
Justin
2012-Jul-24 00:44 UTC
Re: [Puppet Users] Adding file dependencies to existing service
Chris, Thanks for your response. Your post got me thinking about a different approach that I''m surprised I didn''t think of in the first place. I do prefer to have a single service handling multiple daemons, but I also realized I should be using Hiera for this. So I''m now defining a hash in Hiera on a per-node basis (i.e. %{fqdn}.yaml) like so: memcached_instances: xx: { tcp_port: ''11211'', max_memory: ''512'' } yy: { tcp_port: ''11212'', max_memory: ''512'' } zz: { tcp_port: ''11213'', max_memory: ''512'' } and here''s what I''ve boiled my class down to: class memcached { $instances = hiera_hash(''memcached_instances'') $instance_names = split(inline_template(''<%= instances.keys.join(",") %>''), '','') package { ''memcached'': ensure => present } file { ''/etc/memcached.conf'': ensure => absent, require => Package[''memcached''], } define memcached::instance ( $instance_name = $title ) { $log_file = "/var/log/memcached-${instance_name}.log" $user = ''memcache'' $max_connections = ''1024'' $tcp_port = $memcached::instances[$instance_name][''tcp_port''] $max_memory = $memcached::instances[$instance_name][''max_memory''] file { "/etc/memcached_${instance_name}.conf": ensure => present, content => template(''memcached/etc/memcached.conf.erb''), } } memcached::instance { $instance_names: require => Package[''memcached''], notify => Service[''memcached''], } service { ''memcached'': ensure => running, enable => true, hasrestart => true, hasstatus => false, require => Package[''memcached''], } } It could use some work in how it handles other values in the templates, but it seems to work nicely so far and should scale well. Thanks again for taking the time to post your thoughts and code! Justin On Monday, July 23, 2012 2:33:31 PM UTC-7, Christopher Wood wrote:> > (inline) > > On Mon, Jul 23, 2012 at 02:09:01PM -0700, Justin wrote: > > Hi all, > > I''m trying to configure Puppet to allow the creation of multiple > memcached > > instances on a system. However, I''m running into the message that > only > > subclasses can override parameters. Perhaps I''m going about this the > wrong > > way, or maybe I just have something slightly wrong. Any advice is > welcome. > > class memcached { > > package { ''memcached'': ensure => present } > > # do not want basic configuration > > file { ''/etc/memcached.conf'': ensure => absent } > > service { ''memcached'': > > ensure => running, > > enable => true, > > require => Package[''memcached''], > > } > > } > > define memcached::instance () { > > include memcached > > $conf = "/etc/memcached_${name}.conf" > > file { $conf: ensure => present } > > Service[''memcached''] { require +> File[$conf] } > > This bit is a problem because all defines will declare > Service[''memcached''] and thus you''ll get spammed with duplicate > definitions. I solved this by using multiple daemons, useful to me because > I want to be able to kill a daemon in an emergency without affecting more > than one service. Another generic technique I''ve found useful is to have > several classes in my module, for instance: > > 1) thing::software class (installs the defaults file per below, installs > the package, installs the init script) > 2) thing::extraconfig define (includes thing::software, throw a config > file in /etc/thing.d/, something inside this notifies the service) > 3) thing::service class (includes thing:;software, declares service { > ''thing'': }, basically exists so the service is separate from the software) > > In your manifest where you call all these, you would have to ensure that > thing::extraconfig is declared before thing::service. > > (Just food for thought.) > > > } > > # create first instance in file /etc/memcached_en.conf > > memcached::instance { ''en'': } > > The other thing I''d like to do is have Service[''memcached''] set to > NOT > > start unless there is at least one instance, i.e. not start until > after > > the first instance''s config file is in place, but that''s not a > > showstopper. > > By my experimentation, memcached will be started by the postinstall > scripts when you install the deb/rpm. One technique I''ve found useful (on > Ubuntu/Debian) is to declare file { "/etc/default/$software": content => > "start=no" } before installing said software. Apt won''t overwrite the > defaults file so the daemon won''t start, and you can lay down a custom init > script (which doesn''t check the defaults file) after your config files are > installed. > > Here''s how I solved the memcached thing to pop up multiple memcached > daemons (obviously derived from https://github.com/saz/puppet-memcached): > > class memcached::orig_off { > > $classname = ''memcached'' > > package { $classname: > ensure => installed, > } > > service { $classname: > ensure => stopped, > enable => false, > hasrestart => true, > hasstatus => true, > require => Package[''memcached''], > } > > } > > define memcached::daemon ( $max_memory = false, $listen_ip = ''0.0.0.0'', > $port = ''11211'', $max_connections = ''8192'' ) { > > $classname = ''memcached'' > $filesource = "puppet:///modules/$classname" > > case $::operatingsystem { > ubuntu, debian: { > $user = ''nobody'' > $mconfdir = ''/etc/monit/conf.d'' > } > centos, redhat: { > $user = ''memcached'' > $mconfdir = ''/etc/monit.d'' > } > default: { > fail("Unsupported platform: ${::operatingsystem}") > } > } > > $service1 = "memcached${port}" > $config1 = "/etc/memcached${port}.conf" > $config1template = "$classname/memcached_sp.conf.erb" > $init1 = "/usr/local/sbin/start-memcached${port}" > $init1template = "$classname/start_memcached.erb" > $init2 = "/etc/init.d/memcached${port}" > $init2template = "$classname/init_memcached.erb" > $mfile1 = "$mconfdir/${classname}${port}" > $mfile1template = "$classname/memcached_monit.erb" > $logfile = "/var/log/memcached${port}.log" > > include memcached::orig_off > > file { $init1: > content => template($init1template), > mode => 744, > } > > file { $init2: > content => template($init2template), > mode => 744, > } > > file { $config1: > content => template($config1template), > require => Class[''memcached::orig_off''], > } > > service { $service1: > ensure => running, > enable => true, > hasrestart => true, > hasstatus => false, > require => [File[$init1], File[$init2], File[$config1]], > subscribe => File[$config1], > } > > file { $mfile1: > content => template($mfile1template), > mode => 600, > require => Service[$service1], > } > > } > > > > Thanks, > > Justin > > > > -- > > You received this message because you are subscribed to the Google > Groups > > "Puppet Users" group. > > To view this discussion on the web visit > > [1]https://groups.google.com/d/msg/puppet-users/-/fic-AkDAfAoJ. > > 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. > > > > References > > > > Visible links > > 1. https://groups.google.com/d/msg/puppet-users/-/fic-AkDAfAoJ >-- 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/-/h45x1KhHp0UJ. 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.