diff --git a/manifests/init.pp b/manifests/init.pp index 05e7300..fbe0931 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -93,6 +93,21 @@ # # defaults to: `daily` # +# [*smartd_opts*] +# `String` +# +# Command line options for `smartd(8)` startup. Only has an effect if +# `$manage_smartd_opts` is set to `true`. +# +# defaults to: (OS-specific) +# +# [*manage_smartd_opts*] +# `Bool` +# +# Enable or disable management of `smartd(8)` command line options +# (`$smartd_opts`). +# +# defaults to: false # # === Authors # @@ -118,6 +133,8 @@ $warning_schedule = $smartd::params::warning_schedule, $enable_default = $smartd::params::enable_default, $default_options = $smartd::params::default_options, + $smartd_opts = $smartd::params::smartd_opts, + $manage_smartd_opts = $smartd::params::manage_smartd_opts, ) inherits smartd::params { validate_re($ensure, '^present$|^latest$|^absent$|^purged$') validate_string($package_name) @@ -132,6 +149,8 @@ '$warning_schedule must be either daily, once, or diminishing.') validate_bool($enable_default) validate_string($default_options) + validate_string($smartd_opts) + validate_bool($manage_smartd_opts) case $ensure { 'present', 'latest': { @@ -163,11 +182,22 @@ enable => $svc_enable, hasrestart => true, hasstatus => true, + require => File['/var/lib/smartmontools'], } Package[$package_name] -> Service[$service_name] } + if ($manage_smartd_opts == true) and (($ensure == 'present') or ($ensure == 'latest')) { + augeas { 'smartd_opts': + lens => 'Shellvars.lns', + incl => $::smartd::params::smartd_opts_path, + changes => "set ${::smartd::params::smartd_opts_var} '\"${smartd_opts}\"'", + require => Package[$package_name], + notify => Service[$service_name], + } + } + file { 'smartd.conf': ensure => $file_ensure, path => $::smartd::params::config_file_path, @@ -179,6 +209,21 @@ notify => Service[$service_name], } + if $ensure == purged { + $var_lib_ensure = 'absent' + $var_lib_force = true + } else { + $var_lib_ensure = 'directory' + } + + file { '/var/lib/smartmontools': + ensure => $var_lib_ensure, + force => $var_lib_force, + owner => 'root', + group => '0', + mode => '0755', + } + # Special sauce for Debian where it's not enough for the rc script # to be enabled, it also needs its own extra special config file. if $::osfamily == 'Debian' { diff --git a/manifests/params.pp b/manifests/params.pp index 28de190..5718a62 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -22,6 +22,12 @@ $mail_to = 'root' $warning_schedule = 'daily' # other choices: once, diminishing $default_options = undef + $manage_smartd_opts = false + + $smartd_opts_var = $::operatingsystem ? { + 'FreeBSD' => 'smartd_flags', + default => 'smartd_opts', + } $version_string = $::smartmontools_version ? { undef => '0.0', @@ -38,32 +44,52 @@ case $::osfamily { 'FreeBSD': { $config_file_path = '/usr/local/etc/smartd.conf' - $service_name = 'smartd' + $smartd_opts_path = '/usr/local/etc/rc.conf.d/smartd' + $smartd_opts = '-s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' + $service_name = 'smartd' } 'RedHat': { - $config_file_path = $::operatingsystem ? { - # lint:ignore:80chars - 'Fedora' => $::operatingsystemrelease ? { - # No, I am not going to support versions 1-9. - /10|11|12|13|14|15|16|17|18/ => '/etc/smartd.conf', - default => '/etc/smartmontools/smartd.conf', - }, - /RedHat|CentOS|Scientific|SLC|OracleLinux|OEL/ => $::operatingsystemmajrelease ? { - /4|5|6/ => '/etc/smartd.conf', - default => '/etc/smartmontools/smartd.conf', - }, - default => '/etc/smartd.conf', - # lint:endignore + case $::operatingsystem { + 'Fedora': { + case $::operatingsystemmajrelease { + /10|11|12|13|14|15|16|17|18/: { + $config_file_path = '/etc/smartd.conf' + $smartd_opts = '-q never' + } + default: { + $config_file_path = '/etc/smartmontools/smartd.conf' + $smartd_opts = '-q never -s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' + } + } + } + 'RedHat', 'CentOS', 'Scientific', 'SLC', 'OracleLinux', 'OEL': { + case $::operatingsystemmajrelease { + '4', '5', '6': { + $config_file_path = '/etc/smartd.conf' + $smartd_opts = '-q never' + } + default: { + $config_file_path = '/etc/smartmontools/smartd.conf' + $smartd_opts = '-q never -s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' + } + } + } + default: {} } - $service_name = 'smartd' + $smartd_opts_path = '/etc/sysconfig/smartmontools' + $service_name = 'smartd' } 'SuSE': { $config_file_path = '/etc/smartd.conf' - $service_name = 'smartd' + $smartd_opts_path = '/etc/sysconfig/smartmontools' + $smartd_opts = '-s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' + $service_name = 'smartd' } 'Debian': { $config_file_path = '/etc/smartd.conf' - $service_name = 'smartmontools' + $smartd_opts_path = '/etc/default/smartmontools' + $smartd_opts = '-s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' + $service_name = 'smartmontools' } default: { fail("Module ${module_name} is not supported on ${::operatingsystem}") diff --git a/spec/unit/classes/smartd_spec.rb b/spec/unit/classes/smartd_spec.rb index d9c808d..eaa2908 100644 --- a/spec/unit/classes/smartd_spec.rb +++ b/spec/unit/classes/smartd_spec.rb @@ -11,31 +11,46 @@ case facts[:osfamily] when 'RedHat' - service_name = 'smartd' - smartd_conf_path = case facts[:operatingsystem] - when 'RedHat', 'CentOS', 'Scientific', 'OracleLinux', 'SLC', 'OEL' - case facts[:operatingsystemmajrelease].to_i - when 4..6 - '/etc/smartd.conf' - else - '/etc/smartmontools/smartd.conf' - end - when 'Fedora' - case facts[:operatingsystemmajrelase].to_i - when 10..18 - '/etc/smartd.conf' - else - '/etc/smartmontools/smartd.conf' - end - end + service_name = 'smartd' + smartd_opts_path = '/etc/sysconfig/smartmontools' + smartd_opts_var = 'smartd_opts' + case facts[:operatingsystem] + when 'RedHat', 'CentOS', 'Scientific', 'OracleLinux', 'SLC', 'OEL' + case facts[:operatingsystemmajrelease].to_i + when 4..6 + smartd_conf_path = '/etc/smartd.conf' + smartd_opts = '-q never' + else + smartd_conf_path = '/etc/smartmontools/smartd.conf' + smartd_opts = '-q never -s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' + end + when 'Fedora' + case facts[:operatingsystemmajrelase].to_i + when 10..18 + smartd_conf_path = '/etc/smartd.conf' + smartd_opts = '-q never' + else + smartd_conf_path = '/etc/smartmontools/smartd.conf' + smartd_opts = '-q never -s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' + end + end when 'Debian' smartd_conf_path = '/etc/smartd.conf' + smartd_opts_path = '/etc/default/smartmontools' + smartd_opts_var = 'smartd_opts' + smartd_opts = '-s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' service_name = 'smartmontools' when 'Suse' smartd_conf_path = '/etc/smartd.conf' + smartd_opts_path = '/etc/sysconfig/smartmontools' + smartd_opts_var = 'smartd_opts' + smartd_opts = '-s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' service_name = 'smartd' when 'FreeBSD' smartd_conf_path = '/usr/local/etc/smartd.conf' + smartd_opts_path = '/usr/local/etc/rc.conf.d/smartd' + smartd_opts_var = 'smartd_flags' + smartd_opts = '-s /var/lib/smartmontools/smartd. -A /var/lib/smartmontools/attrlog.' service_name = 'smartd' end # case facts[:osfamily] @@ -54,7 +69,20 @@ with_content(/^DEVICESCAN(?: -m root -M daily)?$/). with_notify("Service[#{service_name}]") end - it { is_expected.to contain_service(service_name).with_ensure('running').with_enable(true) } + it do + is_expected.to contain_service(service_name). + with_ensure('running'). + with_enable(true). + with_require('File[/var/lib/smartmontools]') + end + it do + is_expected.to contain_file('/var/lib/smartmontools'). + with_ensure('directory'). + with_owner('root'). + with_group('0'). + with_mode('0755') + end + it { is_expected.not_to contain_augeas('smartd_opts') } if facts[:osfamily] == 'Debian' it { is_expected.to contain_augeas('shell_config_start_smartd').with_changes('set start_smartd "yes"') } @@ -69,6 +97,7 @@ with_ensure('absent'). with_path(smartd_conf_path) end + it { is_expected.not_to contain_augeas('smartd_opts') } it { is_expected.not_to contain_service(service_name) } if facts[:osfamily] == 'Debian' @@ -112,6 +141,7 @@ it_behaves_like 'ensure => (absent|purged)' it { is_expected.to contain_package('smartmontools').with_ensure('purged') } + it { is_expected.to contain_file('/var/lib/smartmontools').with_ensure('absent').with_force(true) } end context 'badvalue' do @@ -121,6 +151,40 @@ end end + context 'smartd_opts are enabled and smartd_opts =>' do + let(:params) { { :manage_smartd_opts => true } } + + context '(undef/default)' do + it do + is_expected.to contain_augeas('smartd_opts'). + with_incl(smartd_opts_path). + with_lens('Shellvars.lns'). + with_changes("set #{smartd_opts_var} '\"#{smartd_opts}\"'"). + with_require('Package[smartmontools]'). + with_notify("Service[#{service_name}]") + end + end + + context 'custom options' do + before { params[:smartd_opts] = '--capabilities --interval=1800' } + + it do + is_expected.to contain_augeas('smartd_opts'). + with_incl(smartd_opts_path). + with_lens('Shellvars.lns'). + with_changes("set #{smartd_opts_var} '\"--capabilities --interval=1800\"'"). + with_require('Package[smartmontools]'). + with_notify("Service[#{service_name}]") + end + end + + context 'a bad value' do + before { params[:smartd_opts] = {} } + + it { is_expected.to raise_error(Puppet::Error, /\{\} is not a string. It looks to be a Hash/) } + end + end + context 'when service_ensure =>' do context 'running' do let(:params) { { :service_ensure => 'running' } } @@ -152,6 +216,36 @@ context 'regardless of operating system' do let(:facts) { { :osfamily => 'FreeBSD' } } + context 'when manage_smartd_opts =>' do + context '(undef/default)' do + let(:params) { {} } + + it { is_expected.not_to contain_augeas('smartd_opts') } + end + + context 'false' do + let(:params) { { :manage_smartd_opts => false } } + + it { is_expected.not_to contain_augeas('smartd_opts') } + end + + context 'true' do + let(:params) { { :manage_smartd_opts => true } } + + it do + is_expected.to contain_augeas('smartd_opts'). + with_lens('Shellvars.lns'). + with_require('Package[smartmontools]') + end + end + + context 'badval' do + let(:params) { { :manage_smartd_opts => 'badval' } } + + it { is_expected.to raise_error(Puppet::Error, /is not a boolean../) } + end + end # context 'manage_smartd_opts =>' + context 'when devicescan =>' do context 'true' do let(:params) { { :devicescan => true } }