FAQ
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.

Search Discussions

  • Christopher Wood at Jul 23, 2012 at 9:33 pm
    (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 at Jul 24, 2012 at 12:44 am
    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.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppuppet-users @
categoriespuppet
postedJul 23, '12 at 9:09p
activeJul 24, '12 at 12:44a
posts3
users2
websitepuppetlabs.com

2 users in discussion

Justin: 2 posts Christopher Wood: 1 post

People

Translate

site design / logo © 2022 Grokbase