10

This was a breeze in CFEngine... But I'm in a Puppet environment now, and need to be able to assign/ensure/check certain sysctl.conf variables. In the CFEngine world, I could simply check for specific lines within a config file... I've found a small reference to a sysctl module on the Puppet wiki and a project in github that appears to do what I want.

But neither are really documented well. I'm simply looking for a way to edit a couple of values like net.core.rmem_default and net.core.wmem_max. In the format of the project hosted on github, the config in my init.pp manifest should look like:

class sysctl {

sysctl::value {
        "net.core.rmem_default": value => "9000000";
        "net.core.wmem_default": value => "9000000";
        "net.core.rmem_max": value => "16777216";
        "net.core.wmem_max": value => "16777216";
        }
}

Going through forums and mailing lists, there seems to be confusion over the difference between Puppet plugins and modules. The terms are almost used interchangeably... I ended up needing to enable pluginsync on my clients in order to get past some hairy errors. I thought this was a module!

The current client errors:

info: Loading downloaded plugin /var/lib/puppet/lib/puppet/type/sysctl.rb
info: Loading downloaded plugin /var/lib/puppet/lib/puppet/provider/sysctl/parsed.rb
err: Could not retrieve catalog from remote server: Error 400 on SERVER: Puppet::Parser::AST::Resource failed with error 
ArgumentError: Invalid resource type sysctl::value at /var/lib/puppet/base/modules/sysctl/manifests/init.pp:12 on node shimano.deore.abc.net
    warning: Not using cache on failed catalog
    err: Could not retrieve catalog; skipping run

Any thoughts on how to accomplish this with the least amount of pain?

Edit: Am I affected by this bug?

Edit: Fixed using Augeas library as suggested by Jeff Ferland and from the Puppet wiki.

I created a sysctl module...

class sysctl {

  # nested class/define
  define conf ( $value ) {

    # $name is provided by define invocation

    # guid of this entry
    $key = $name

    $context = "/files/etc/sysctl.conf"

     augeas { "sysctl_conf/$key":
       context => "$context",
       onlyif  => "get $key != '$value'",
       changes => "set $key '$value'",
       notify  => Exec["sysctl"],
     }

  }

   file { "sysctl_conf":
      name => $operatingsystem ? {
        default => "/etc/sysctl.conf",
      },
   }

   exec { "/sbin/sysctl -p":
      alias => "sysctl",
      refreshonly => true,
      subscribe => File["sysctl_conf"],
   }

}

...and another module to set the relevant settings...

class prod_sysctl {

include sysctl

sysctl::conf {

  # increase PID rollover value
  "kernel.pid_max": value =>  "1048576";
  }
}
ewwhite
  • 194,921
  • 91
  • 434
  • 799

3 Answers3

14

Specific answer: Immediately speaking, you're calling sysctl::value, but value isn't declared in your sysctl class. See this example that uses a sysctl::conf declaration. Without the define value, there is no sysctl::value subclass for you to call.


General answer and guidance: The Augeas construct (see also its type reference documentation) that is part of current versions of Puppet allows maintaining lines in a configuration file and even respects context, so it can manage files such as a git configuration. The example below is both to demonstrate functionality and to point you to a great reference collection of Puppet configs -- the live configuration store for Wikipedia servers.

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = https://gerrit.wikimedia.org/r/p/operations/puppet
[branch "production"]
    remote = origin
    merge = refs/heads/production

One simple example from the above configuration documentation would be this:

augeas { "sshd_config":
 context => "/files/etc/ssh/sshd_config",
  changes => [
    "set PermitRootLogin no",
  ],
}

So, if you want to manage your /etc/sysctl.conf, enter the following:

augeas { "sysctl":
 context => "/files/etc/sysctl.conf",
  changes => [
    "set kernel.sysrq = 0",
    #and whatever other lines are interesting to you
  ],
}

The Augeas example also has a construct for a sysctl class based on Augeus that is similar to what you posted in your question, so that may also shed some light.

Jeff Ferland
  • 20,239
  • 2
  • 61
  • 85
  • The define is in a `value.pp` manifest distributed with the `module-sysctl` module. It looks like `define sysctl::value ( $key = 'name', $value ) { ` – ewwhite Feb 21 '12 at 05:02
  • @ewwhite It looks like the bug you linked to could apply to your situation. Can you confirm that the module is loading on your target machine? – Jeff Ferland Feb 21 '12 at 15:09
  • How can I check for the module's presence? – ewwhite Feb 21 '12 at 15:20
  • Going with the Augeas approach. I think I did hit a bug with the other solution. – ewwhite Feb 21 '12 at 16:23
2

I've used this module in the past with RHEL5: puppet-sysctl

To use it, you'll have to install the module to your modules folder (probably /etc/puppet/modules/sysctl) include the class on your node: (include sysctl) and then call the def resource like this:

class s_sysctl::rhel_defaults {
    include sysctl

    # Controls IP packet forwarding
    sysctl::set_value { "net.ipv4.ip_forward": 
                         value => 0 
    }

    # Controls source route verification
    sysctl::set_value { "net.ipv4.conf.default.rp_filter": value => 1 }
}

So you might be wondering, where does this code actually go? I like to organize my puppet tree like this:

site.pp -> nodes.pp -> roles.pp -> /etc/puppet/site-modules/s_sysctl -> /etc/puppet/modules/sysctl

So that way, site-modules contains hiera data, or tunables, and the modules stay generic, plugable and "modular".

robbyt
  • 1,622
  • 3
  • 14
  • 26
  • Yes, it's linked in my question. There's no documentation for the module and I'm not sure where to install it or how to actually use it. – ewwhite Feb 20 '12 at 16:53
  • Sorry I didn't read your entire question :) The module includes a define, which needs to be called in another class. I'll edit my answer and include code... – robbyt Feb 20 '12 at 17:19
  • So with that, the errors I receive are: `err: Could not retrieve catalog from remote server: Error 400 on SERVER: Puppet::Parser::AST::Resource failed with error ArgumentError: Invalid resource type sysctl::value at /var/lib/puppet/base/modules/sysctl/manifests/init.pp:12 on node shimano.deore.abc.net` – ewwhite Feb 20 '12 at 17:29
  • It looks like you're calling a define labeled 'sysctl::value' and not 'sysctl::set_value'. – robbyt Feb 21 '12 at 04:42
  • The define is in a `value.pp` manifest distributed with the `module-sysctl` module. It looks like `define sysctl::value ( $key = 'name', $value ) { ` – ewwhite Feb 21 '12 at 05:04
0

As long as you don't have to change the value (or is satisfied with appending lines with the new values), you can use Common's line. You can use a pair of present/absent configurations when you change the value.

To change the value -- assuming the line already exists --, you can use replace in the same module.

Or you can look at how these definitions are written to make one suited to your task -- which, mind you, I do think is simple and common enough that it should have been provided by the default types of Puppet.

So, why doesn't it? Because Puppet expects you to fully manage the things you are managing. That is, you should distribute the whole sysctl file, instead of just adding or removing one value or another. I'm not saying that's necessarily an easy thing to do, but if you can get away with it, you that's the easiest way of doing it.

Daniel C. Sobral
  • 5,563
  • 5
  • 32
  • 48
  • I don't think managing the entire file is scalable. I knew that the whole file option was a possibility, but use the case of small changes within a RHEL release... There may be `sysctl.conf` defaults that change between versions of RHEL. We may not want to ignore/overwrite those, rather than ensuring a specific parameter can be set/changed. – ewwhite Feb 21 '12 at 15:48
  • @ewwhite Doesn't RHEL have a local override file for `sysctl.conf`? Or do you mean _you_ have different configurations according to the release? In the latter case, you can make a template and have lines selected depending on the OS version. – Daniel C. Sobral Feb 21 '12 at 20:39