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 [email protected].
> > To unsubscribe from this group, send email to
> > [email protected].
> > 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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-users?hl=en.