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";
}
}
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.
One simple example from the above configuration documentation would be this:
So, if you want to manage your /etc/sysctl.conf, enter the following:
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.
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:
So you might be wondering, where does this code actually go? I like to organize my puppet tree like this:
So that way, site-modules contains hiera data, or tunables, and the modules stay generic, plugable and "modular".
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 ofpresent
/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.