diff --git a/README.md b/README.md index 1a13c0e..32c42f7 100644 --- a/README.md +++ b/README.md @@ -1,142 +1,143 @@ # puppet-memcached [![Build Status](https://secure.travis-ci.org/saz/puppet-memcached.png)](http://travis-ci.org/saz/puppet-memcached) Manage memcached via Puppet ## Show some love If you find this module useful, send some bitcoins to 1Na3YFUmdxKxJLiuRXQYJU2kiNqA3KY2j9 ### Supported Puppet versions * Puppet >= 5 * Last version supporting Puppet 3: v3.0.2 ## How to use ``` Starting with version 3.0.0, memcached will be listening on 127.0.0.1 only. This should make setups more secure (e.g. if there are no firewall rules in place). To change this behavior, you need to set listen_ip to '0.0.0.0'. ``` ### Use roughly 90% of memory ```ruby class { 'memcached': } ``` ### Set a fixed memory limit in MB ```ruby class { 'memcached': max_memory => 2048 } ``` ### Use 12% of available memory ```ruby class { 'memcached': max_memory => '12%' } ``` ### Install multiple memcached instances the multiinstance support uses a systemd instance unit file. This will be placed at `/etc/systemd/system/memcached@.service`. It allows us to manage multiple instances via the same unit file. To start a simple instance, you only need to know the desired TCP port: ```puppet memcached::instance{'11222':} ``` that's it! It will bind to localhost and listen to TCP port 11222. You might want to tune the systemd limits, for example the number of file descriptors (LimitNOFILE) or the number of processes (LimitNPROC): ```puppet memcached::instance{'11222': limits => { 'LimitNOFILE' => 8192, 'LimitNPROC' => 16384, } } ``` All systemd limits are documented in the [systemd documentation](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Process%20Properties). Another usecase. Let's assume your name is Eric and you want to change the actual memcached parameters, for example to bind it to every interface: ```puppet memcached::instance{'11222': override_content => "[Service]\nEnvironment='LISTEN=-l 0.0.0.0'", } ``` Maybe Eric also wants to override the cache size (the unit is MB): ```puppet memcached::instance{'11222': override_content => "[Service]\nEnvironment=CACHESIZE=4096\n", } ``` last but not least, Eric might also want to override the maximum amount of connections (the default is 1024): ```puppet memcached::instance{'11222': override_content => "[Service]\nEnvironment=MAXCONN=4096\n", } ``` Now Eric wants to use all those three settings at the same time: ```puppet memcached::instance{'11222': override_content => "[Service]\nEnvironment=MAXCONN=4096\nEnvironment=CACHESIZE=4096\nEnvironment='LISTEN=-l 0.0.0.0'\n", } ``` Instead of passing a long string with multiple `\n`, Eric can also put the content in a file and provide that: ```puppet memcached::instance{'11222': override_source => "${module_name}/memcached_11222_override.conf\n", } ``` ### Other class parameters * $package_ensure = 'present' * $logfile = '/var/log/memcached.log' * $logstdout = false (Set this to true to disable logging to a file/syslog entirely, useful when memcached runs in containers) * $pidfile = '/var/run/memcached.pid' (Debian family only, set to false to disable pidfile) * $max_memory = false * $max_item_size = false * $min_item_size = false * $factor = false * $lock_memory = false (WARNING: good if used intelligently, google for -k key) -* $listen_ip = '127.0.0.1' +* $listen = '127.0.0.1' (if TLS/SSL is enabled, 'notls' prefix can be used to disable for specific listeners "notls::") +* $listen_ip = '127.0.0.1' (deprecated, listen will take precedence over this) * $tcp_port = 11211 * $udp_port = 0 * $manage_firewall = false * $user = '' (OS specific setting, see params.pp) * $max_connections = 8192 * $verbosity = undef * $unix_socket = undef * $install_dev = false (TRUE if 'libmemcached-dev' package should be installed) * $processorcount = $::processorcount * $service_restart = true (restart service after configuration changes, false to prevent restarts) * $use_sasl = false (start memcached with SASL support) * $use_tls = false (start memcached with TLS support) * $tls_cert_chain = undef * $tls_key = undef * $tls_ca_cert = undef * $tls_verify_mode = 1 (0: None, 1: Request, 2: Require, 3: Once) * $notls_listener_addr = '127.0.0.1' * $notls_listener_port = undef * $large_mem_pages = false (try to use large memory pages) diff --git a/manifests/init.pp b/manifests/init.pp index 7bbf30b..2f26e86 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,148 +1,154 @@ # == Class: memcached # # Manage memcached # # == Parameters # [* syslog *] # Boolean. # If true will pipe output to /bin/logger, sends to syslog. # class memcached ( Enum['present', 'latest', 'absent'] $package_ensure = 'present', Boolean $service_manage = true, Optional[Stdlib::Absolutepath] $logfile = $memcached::params::logfile, Boolean $logstdout = false, Boolean $syslog = false, Optional[Stdlib::Absolutepath] $pidfile = '/var/run/memcached.pid', Boolean $manage_firewall = false, $max_memory = '95%', Optional[Variant[Integer, String]] $max_item_size = undef, Optional[Variant[Integer, String]] $min_item_size = undef, Optional[Variant[Integer, String]] $factor = undef, Boolean $lock_memory = false, + Optional[Variant[String,Array[String]]] $listen = undef, Optional[Variant[Stdlib::Compat::Ip_address,Array[Stdlib::Compat::Ip_address]]] $listen_ip = '127.0.0.1', Integer $tcp_port = 11211, Integer $udp_port = 0, String $user = $memcached::params::user, Integer $max_connections = 8192, Optional[String] $verbosity = undef, Optional[String] $unix_socket = undef, String $unix_socket_mask = '0755', Boolean $install_dev = false, Variant[String,Integer] $processorcount = $facts['processors']['count'], Boolean $service_restart = true, Boolean $auto_removal = false, Boolean $use_sasl = false, Boolean $use_tls = false, Optional[Stdlib::Absolutepath] $tls_cert_chain = undef, Optional[Stdlib::Absolutepath] $tls_key = undef, Optional[Stdlib::Absolutepath] $tls_ca_cert = undef, Optional[Integer] $tls_verify_mode = 1, Optional[Stdlib::IP::Address] $notls_listener_addr = '127.0.0.1', Optional[Stdlib::Port] $notls_listener_port = undef, Boolean $use_registry = $memcached::params::use_registry, String $registry_key = 'HKLM\System\CurrentControlSet\services\memcached\ImagePath', Boolean $large_mem_pages = false, Boolean $use_svcprop = $memcached::params::use_svcprop, String $svcprop_fmri = 'memcached:default', String $svcprop_key = 'memcached/options', Optional[Array[String]] $extended_opts = undef, String $config_tmpl = $memcached::params::config_tmpl, Boolean $disable_cachedump = false, ) inherits memcached::params { # Logging to syslog and file are mutually exclusive # Fail if both options are defined if $syslog and str2bool($logfile) { fail 'Define either syslog or logfile as logging destinations but not both.' } if $use_tls { if $tls_cert_chain == undef or $tls_key == undef { fail 'tls_cert_chain and tls_key should be set when use_tls is true.' } } if $package_ensure == 'absent' { $service_ensure = 'stopped' $service_enable = false } else { $service_ensure = 'running' $service_enable = true } - # Handle if $listen_ip is not an array - $real_listen_ip = [$listen_ip] + if $listen { + # Handle if $listen is not an array + $real_listen = [$listen] + } else { + # Handle if $listen_ip is not an array + $real_listen = [$listen_ip] + } package { $memcached::params::package_name: ensure => $package_ensure, provider => $memcached::params::package_provider, } if $install_dev { package { $memcached::params::dev_package_name: ensure => $package_ensure, require => Package[$memcached::params::package_name], } } if $manage_firewall { firewall { "100_tcp_${tcp_port}_for_memcached": dport => $tcp_port, proto => 'tcp', action => 'accept', } if $udp_port != 0 { firewall { "100_udp_${udp_port}_for_memcached": dport => $udp_port, proto => 'udp', action => 'accept', } } } if $service_restart and $service_manage { $service_notify_real = Service[$memcached::params::service_name] } else { $service_notify_real = undef } if ( $memcached::params::config_file ) { file { $memcached::params::config_file: ensure => 'file', owner => 'root', group => 0, mode => '0644', content => template($config_tmpl), require => Package[$memcached::params::package_name], notify => $service_notify_real, } } if $service_manage { service { $memcached::params::service_name: ensure => $service_ensure, enable => $service_enable, hasrestart => true, hasstatus => $memcached::params::service_hasstatus, } } if $use_registry { registry_value { $registry_key: ensure => 'present', type => 'string', data => template($config_tmpl), notify => $service_notify_real, } } if $use_svcprop { svcprop { $svcprop_key: fmri => $svcprop_fmri, property => $svcprop_key, value => template($memcached::params::config_tmpl), notify => $service_notify_real, } } } diff --git a/templates/memcached.conf.erb b/templates/memcached.conf.erb index bc9edac..d12b60b 100644 --- a/templates/memcached.conf.erb +++ b/templates/memcached.conf.erb @@ -1,106 +1,106 @@ # File managed by puppet # Run memcached as a daemon. -d <% if @pidfile -%> # pidfile -P <%= @pidfile %> <% end -%> # Log memcached's output logfile <%= @logfile -%> <% if @verbosity -%> # Verbosity -<%= @verbosity %> <% end -%> # Use MB memory max to use for object storage. -m <%= scope.call_function('memcached::max_memory', [@max_memory]) %> <% if @lock_memory -%> # Lock down all paged memory. There is a limit on how much memory you may lock. -k <% end -%> <% if @use_sasl -%> # Start with SASL support -S <% end -%> <% if @use_tls -%> # Start with TLS support -Z -o ssl_chain_cert=<%= @tls_cert_chain %> -o ssl_key=<%= @tls_key %> <% if @tls_ca_cert -%> -o ssl_ca_cert=<%= @tls_ca_cert %> <% end -%> -o ssl_verify_mode=<%= @tls_verify_mode %> <% if @notls_listener_port -%> -l notls:<%= @notls_listener_addr %>:<%= @notls_listener_port %> <% end -%> <% end -%> <% if @unix_socket -%> # UNIX socket path to listen on -s <%= @unix_socket %> # UNIX socket access mask -a <%= @unix_socket_mask %> <% else -%> -<% if @real_listen_ip -%> -# IP to listen on --l <%= @real_listen_ip.join(',') %> +<% if @real_listen -%> +# interfaces to listen on +-l <%= @real_listen.join(',') %> <% end -%> # TCP port to listen on -p <%= @tcp_port %> # UDP port to listen on -U <%= @udp_port %> <% end -%> # Run daemon as user -u <%= @user %> <% if @large_mem_pages -%> # Try to use large memory pages (if available) -L <% end -%> # Limit the number of simultaneous incoming connections. -c <%= @max_connections %> # Number of threads to use to process incoming requests. -t <%= @processorcount %> <% if @max_item_size -%> # Override the default size of each slab page -I <%= @max_item_size %> <% end -%> <% if @min_item_size -%> # Override the default size of each slab page -n <%= @min_item_size %> <% end -%> <% if @factor -%> # Override the default factor -f <%= @factor %> <% end -%> <% if @auto_removal -%> # Disable automatic removal of items from the cache when out of memory -M <% end -%> <% if @extended_opts -%> -o <%= @extended_opts.join(',') -%> <% end -%> <% if @disable_cachedump -%> -X <% end -%> diff --git a/templates/memcached_freebsd_rcconf.erb b/templates/memcached_freebsd_rcconf.erb index e957c69..de16e58 100644 --- a/templates/memcached_freebsd_rcconf.erb +++ b/templates/memcached_freebsd_rcconf.erb @@ -1,83 +1,83 @@ ### MANAGED BY PUPPET ### DO NOT EDIT <%- enabled = "YES" if !@service_manage enabled = "NO" end flags = [] # required flags flags << "-d -u #{@user} -P #{@pidfile} -t #{@processorcount}" # optional flags if @item_size flags << "-I #{@item_size}" end -if @real_listen_ip - flags << "-l #{@real_listen_ip.join(',')}" +if @real_listen + flags << "-l #{@real_listen.join(',')}" end if @lock_memory flags << "-k" end if @max_connections flags << "-c #{@max_connections}" end #TODO: wtf do we do with this? #if @logfile #end if @tcp_port flags << "-p #{@tcp_port}" end if @udp_port flags << "-U #{@udp_port}" end if @unix_socket flags << "-s #{@unix_socket} -a #{@unix_socket_mask}" end if @verbosity flags << "-#{@verbosity}" end flags << "-m #{scope.call_function('memcached::max_memory', [@max_memory])}" if @use_sasl flags << "-S" end if @use_tls flags << "-Z" flags << "-o ssl_chain_cert=#{@tls_cert_chain}" flags << "-o ssl_key=#{@tls_key}" if @tls_ca_cert flags << "-o ssl_ca_cert=#{@tls_ca_cert}" end flags << "-o ssl_verify_mode=#{@tls_verify_mode}" if @notls_listener_port flags << "-l notls:#{@notls_listener_addr}:#{@notls_listener_port}" end end if @large_mem_pages flags << "-L" end if @disable_cachedump flags << "-X" end if @extended_opts flags << "-o #{@extended_opts.join(',')}" end -%> memcached_enable="<%= enabled %>" memcached_flags="<%= flags.join(" ") %>" diff --git a/templates/memcached_svcprop.erb b/templates/memcached_svcprop.erb index e24386a..a1b46f2 100644 --- a/templates/memcached_svcprop.erb +++ b/templates/memcached_svcprop.erb @@ -1,95 +1,95 @@ <%- result = [] if @verbosity # Verbosity result << '"-' + @verbosity.to_s + '"' end # Use MB memory max to use for object storage. result << '"-m" "' + scope.call_function('memcached::max_memory', [@max_memory]).to_s + '"' if @lock_memory # Lock down all paged memory. There is a limit on how much memory you may lock. result << '"-k"' end if @use_sasl # Start with SASL support result << '"-S"' end if @use_tls # Start with TLS support result << '"-Z"' result << '"-o" "ssl_chain_cert="' + @tls_cert_chain + '"' result << '"-o" "ssl_key="' + @tls_key + '"' if @tls_ca_cert result << '"-o" "ssl_ca_cert="' + @tls_ca_cert + '"' end result << '"-o" "ssl_verify_mode="' + @tls_verify_mode + '"' if @notls_listener_port result << '"-l" "notls:"' + @notls_listener_addr + ':' + @notls_listener_port + '"' end end if @unix_socket # UNIX socket path to listen on result << '"-s" "' + @unix_socket + '"' # UNIX socket access mask result << '"-a" "' + @unix_socket_mask + '"' else - if @real_listen_ip - # IP to listen on - result << '"-l" "' + @real_listen_ip.join(',') + '"' + if @real_listen + # interface to listen on + result << '"-l" "' + @real_listen.join(',') + '"' end # TCP port to listen on if @tcp_port result << '"-p" "' + @tcp_port.to_s + '"' end # UDP port to listen on if @udp_port result << '"-U" "' + @udp_port.to_s + '"' end end # Run daemon as user result << '"-u" "' + @user + '"' if @large_mem_pages # Try to use large memory pages (if available) result << '"-L"' end # Limit the number of simultaneous incoming connections. result << '"-c" "' + @max_connections.to_s + '"' # Number of threads to use to process incoming requests. result << '"-t" "' + @processorcount.to_s + '"' if @max_item_size # Override the default size of each slab page result << '"-I" "' + @max_item_size.to_s + '"' end if @min_item_size result << '"-n" "' + @min_item_size.to_s + '"' end if @factor result << '"-f" "' + @factor.to_s + '"' end if @auto_removal # Disable automatic removal of items from the cache when out of memory result << '"-M"' end if @extended_opts result << '"-o" "' + @extended_opts.join(',') + '"' end if @disable_cachedump result << '"-X"' end -%> <%= result.join(' ') -%> diff --git a/templates/memcached_sysconfig.erb b/templates/memcached_sysconfig.erb index 8713b24..25badda 100644 --- a/templates/memcached_sysconfig.erb +++ b/templates/memcached_sysconfig.erb @@ -1,88 +1,88 @@ <%- result = [] if @verbosity result << '-' + @verbosity.to_s end if @lock_memory result << '-k' end -if @real_listen_ip - result << '-l ' + @real_listen_ip.join(',') +if @real_listen + result << '-l ' + @real_listen.join(',') end if @udp_port result << '-U ' + @udp_port.to_s end if @unix_socket result << '-s ' + @unix_socket.to_s + ' -a ' + @unix_socket_mask.to_s end if @max_item_size result << '-I ' + @max_item_size.to_s end if @min_item_size result << '-n ' + @min_item_size.to_s end if @factor result << '-f ' + @factor.to_s end if @extended_opts result << '-o ' + @extended_opts.join(',') end if @disable_cachedump result << '-X' end result << '-t ' + @processorcount.to_s if @use_tls result << '-Z' result << '-o ssl_chain_cert=' + @tls_cert_chain result << '-o ssl_key=' + @tls_key if @tls_ca_cert result << '-o ssl_ca_cert=' + @tls_ca_cert end result << '-o ssl_verify_mode=' + @tls_verify_mode.to_s if @notls_listener_port result << '-l notls:' + @notls_listener_addr + ':' + @notls_listener_port end end if @use_sasl result << '-S' end if !@logstdout # log to syslog via logger if @syslog && !@logfile result << '2>&1 |/bin/logger &' # log to log file elsif @logfile && !@syslog result << '>> ' + @logfile + ' 2>&1' end end -%> <%- if scope['osfamily'] != 'Suse' -%> PORT="<%= @tcp_port %>" USER="<%= @user %>" MAXCONN="<%= @max_connections %>" CACHESIZE="<%= scope.call_function('memcached::max_memory', [@max_memory]) %>" OPTIONS="<%= result.join(' ') %>" <%- else -%> MEMCACHED_PARAMS="<%= result.join(' ') %>" ## Path: Network/WWW/Memcached ## Description: username memcached should run as ## Type: string ## Default: "memcached" ## Config: memcached # # username memcached should run as # MEMCACHED_USER="<%= @user %>" ## Path: Network/WWW/Memcached ## Description: group memcached should be run as ## Type: string ## Default: "memcached" ## Config: memcached # # group memcached should be run as # MEMCACHED_GROUP="<%= @user %>" <%- end -%> diff --git a/templates/memcached_windows.erb b/templates/memcached_windows.erb index a3618dc..0d16918 100644 --- a/templates/memcached_windows.erb +++ b/templates/memcached_windows.erb @@ -1,40 +1,40 @@ <%- result = [] if @verbosity result << '-' + @verbosity.to_s end if @lock_memory result << '-k' end -if @real_listen_ip - result << '-l ' + @real_listen_ip.join(',') +if @real_listen + result << '-l ' + @real_listen.join(',') end if @tcp_port result << '-p ' + @tcp_port.to_s end if @udp_port result << '-U ' + @udp_port.to_s end if @max_item_size result << '-I ' + @max_item_size.to_s end if @min_item_size result << '-n ' + @min_item_size.to_s end if @factor result << '-f ' + @factor.to_s end result << '-t ' + @processorcount if @max_connections result << '-c ' + @max_connections end if @extended_opts result << '-o ' + @extended_opts.join(',') end if @logfile result << '>> ' + @logfile + ' 2>&1' end if @disable_cachedump result << '-X' end -%> c:\memcached\memcached.exe -d runservice <%= result.join(' ') %>