diff --git a/manifests/ipmi.pp b/manifests/ipmi.pp index 498425d2ddfee2dbdd2d961cfce70b344fd66491..ef894599413469e534da096feff94d6abd37aab6 100644 --- a/manifests/ipmi.pp +++ b/manifests/ipmi.pp @@ -1,119 +1,271 @@ -# base::ipmi and base::noipmi +# base::ipmi: ipmi classes to load, and suppress loading, IPMI client & server. # -# ipmi classes to load, and suppress loading, ipmi client modules. -# Loading of ipmi is automatically suppressed on VMware platforms. +# Most of the time, you should use it like this: +# +# include base::ipmi +# +# That will enable IPMI for physical systems, and will disable IPMI for virtual +# systems (including EC2 systems). This cannot be overridden. +# +# If you want to disable IPMI (for example, on workstations), use it like this: +# +# class { 'base::ipmi': +# ensure => absent, +# } +# +# WARNING: On a running system, changing base::ipmi::ensure from present to +# absent may not work properly, depending on what user-space stuff is using +# IPMI functionality. If you get errors, restart. -class base::ipmi { +class base::ipmi ( + $ensure = present, +) { - # disable ipmi and ipmievd on vmware (or others). facter string comparison + # If we are virtual or on EC2, then explicitly disable IPMI if $::is_virtual == 'true' or $::ec2_profile == 'default-paravirtual' { - case $::operatingsystem { - 'debian', 'ubuntu': { - package { 'ipmitool': ensure => purged } - } - 'redhat': { - service { 'ipmi': - ensure => stopped, - enable => false, - } - } - default: {} - } - } else { - case $::osfamily { - 'Debian': { - package { 'ipmitool': - ensure => present; - } - if ($::kernelmajversion >= '3.13') { - # no msghandler module on kernels > 3.13 - base::os::kernel_module { 'ipmi_si': - ensure => present, - } - } - else { - base::os::kernel_module { 'ipmi_msghandler': + $real_ensure = absent + } + else { + $real_ensure = $ensure + } + + # Check to see what we should do + case $real_ensure { + 'present': { + case $::osfamily { + 'Debian': { + + # First, install the ipmitool package + package { 'ipmitool': ensure => present; } - base::os::kernel_module { 'ipmi_si': - ensure => present, - require => Base::Os::Kernel_module['ipmi_msghandler']; + + # Next, install the config file + file { '/etc/default/ipmievd': + content => template('base/ipmi/etc/default/ipmievd.erb'), + require => Package['ipmitool'], } - } - base::os::kernel_module { 'ipmi_devintf': - ensure => present, - require => Base::Os::Kernel_module['ipmi_si']; - } - service { 'ipmievd': - ensure => running, - name => 'ipmievd', - enable => true, - hasstatus => false, - status => 'pidof ipmievd', - require => [Base::Os::Kernel_module['ipmi_devintf'], - File['/etc/default/ipmievd'] - ], - } - file { '/etc/default/ipmievd': - content => template('base/ipmi/etc/default/ipmievd.erb'), - notify => Service['ipmievd'], - } - } - 'RedHat': { - case $::lsbmajdistrelease { - '6', '7': { - package { 'OpenIPMI': ensure => present; } - } - default: { - package { - 'OpenIPMI-tools': ensure => present; - 'OpenIPMI': ensure => present; + + # Next, install kernel modules + # For Debian 8+, the package brings in everything it needs by + # default. But, if we are re-enabling we need to recover a file that + # we deleted. We then have to trigger systemd to load modules. + if $::operatingsystem == 'Debian' and $::lsbmajdistrelease >= 8 { + exec { 'Re-create /usr/lib/modules-load.d/ipmievd.conf': + command => '/usr/bin/apt-get install --reinstall ipmitool', + creates => '/usr/lib/modules-load.d/ipmievd.conf', + require => Package['ipmitool'], + notify => Exec['Load modules from /usr/lib/modules-load.d/ipmievd.conf'], } + exec { 'Load modules from /usr/lib/modules-load.d/ipmievd.conf': + command => 'systemctl restart systemd-modules-load.service', + notify => Service['ipmievd'], + refreshonly => true, + } + + # Our ipmievd requirements are just the package & the config file. + $ipmievd_requirements = [Package['ipmitool'], + File['/etc/default/ipmievd'], + ] } - } - service { 'ipmi': - ensure => running, - name => 'ipmi', - enable => true, - hasstatus => true, - require => Package['OpenIPMI'], - } - case $::lsbmajdistrelease { - '5', '6': { - service { 'ipmievd': - ensure => running, - name => 'ipmievd', - enable => true, - hasstatus => true, - require => $::lsbmajdistrelease ? { - '5' => Package['OpenIPMI-tools'], - default => Package['OpenIPMI'], - }, + # For older Debian, and all Ubuntu, we must load the modules. + else { + # Start with ipmi_msghandler + base::os::kernel_module { 'ipmi_msghandler': + ensure => present, } + + # Load lots of additional modules + # In Unbuntu, Kernel 3.13 apparently had one IPMI function compiled + # into the kernel, meaning there was no driver to load. + # See Ubuntu bug #1284334 + # Also, there's a kernel module called 'ipmi_watchdog', but it has + # alot of options to set on load, so we don't try to load it. + if $::operatingsystem == 'Ubuntu' + and $::kernelmajversion == '3.13' + { + $additional_ipmi_modules = [ + 'acpi_ipmi', + 'ipmi_devintf', + 'ipmi_poweroff', + ] + } else { + $additional_ipmi_modules = [ + 'acpi_ipmi', + 'ipmi_devintf', + 'ipmi_poweroff', + 'ipmi_si', + ] + } + base::os::kernel_module { $additional_ipmi_modules: + ensure => present, + require => Base::Os::Kernel_module['ipmi_msghandler'], + } + + # Set our requirements for starting ipevd + $ipmievd_requirements = [Base::Os::Kernel_module['ipmi_devintf'], + File['/etc/default/ipmievd'] + ] + } + + # Finally, start the ipmievd service + service { 'ipmievd': + ensure => running, + name => 'ipmievd', + enable => true, + hasstatus => false, + status => 'pidof ipmievd', + require => $ipmievd_requirements, + } + } # Done handling ensure => present for osfamily Debian + + # Catch RHEL and related systems + 'RedHat': { + + # We need to have the OpenIPMI package + package { 'OpenIPMI': + ensure => present, } + + # For RHEL 5 and earlier, the client is a separate package + if $::lsbmajdistrelease <= 5 { + package { 'OpenIPMI-tools': + ensure => present, + } + $ipmi_package = [Package['OpenIPMI'], + Package['OpenIPMI-tools'], + ] + } else { + $ipmi_package = Package['OpenIPMI'] + } + + # Define and start the services + # (For RHEL <= 5, we don't need the client to start the service) + service { 'ipmi': + ensure => running, + name => 'ipmi', + enable => true, + hasstatus => true, + require => $ipmi_package, + } + + # ipmievd is a separate service, starting with RHEL 5 + service { 'ipmievd': + ensure => running, + name => 'ipmievd', + enable => true, + hasstatus => true, + require => $ipmi_package, + } + } # Done handling ensure => present for osfamily RedHat + + default: { + fail('base::ipmi does not recognize this osfamily') } - } - } + } # Done checking $osfamily + } # Done handling ensure => 'present' - # Disable cipher zero. Some IPMI report the ciphers backwards so we work - # around it. Puppet 2.6.3 doesn't support provider param for exec. - # Working around it. The signal file /etc/noipmi allows this execution to - # be suppressed on systems that don't have ipmi. - exec { 'ipmitool lan set 1 cipher_privs XaaaaaaaaaaaaaX': - unless => 'bash -c \'if [ ! -e /etc/noipmi ] && ! `ipmitool lan print | grep -q "Cipher Suite Priv Max : Not Available"`; then ipmitool lan print | grep "Cipher Suite Priv Max" | cut -d: -f2 | egrep -q "^ XaaaaaaaaaaaaaX"; fi\'', - } - } -} + 'absent': { + case $::osfamily { + 'Debian': { + # Stop the IPMI service + service { 'ipmievd': + ensure => stopped, + name => 'ipmievd', + enable => false, + hasstatus => false, + status => 'pidof ipmievd', + require => $ipmievd_requirements, + } + + # Remove any remaining ipmievd configuration + file { '/etc/default/ipmievd': + ensure => absent, + require => Service['ipmievd'], + } + + # Unload lots of additional modules + # In Unbuntu, Kernel 3.13 apparently had one IPMI function compiled + # into the kernel, meaning there was no driver to unload. + # See Ubuntu bug #1284334 + if $::operatingsystem == 'Ubuntu' + and $::kernelmajversion == '3.13' + { + $dependent_ipmi_modules = [ + 'acpi_ipmi', + 'ipmi_devintf', + 'ipmi_poweroff', + 'ipmi_watchdog' + ] + base::os::kernel_module { $dependent_ipmi_modules: + ensure => absent, + require => Service['ipmievd'], + } + } else { + # This is a little more annoying, as we have two dependency levels + # to deal with. + $additional_ipmi_modules = [ + 'acpi_ipmi', + 'ipmi_devintf', + 'ipmi_poweroff', + 'ipmi_watchdog', + ] + base::os::kernel_module { $additional_ipmi_modules: + ensure => absent, + require => Service['ipmievd'], + } + + $dependent_ipmi_modules = 'ipmi_si' + base::os::kernel_module { $dependent_ipmi_modules: + ensure => absent, + require => Base::Os::Kernel_module[$additional_ipmi_modules], + } + } + + # Unload the ipmi_msghandler, the root for most IPMI stuff + base::os::kernel_module { 'ipmi_msghandler': + ensure => absent, + require => Base::Os::Kernel_module[$dependent_ipmi_modules], + } + + # For Debian 8+, make sure modules are not re-loaded on startup + if $::operatingsystem == 'Debian' and $::lsbmajdistrelease >= 8 { + file { '/usr/lib/modules-load.d/ipmievd.conf': + ensure => absent, + } + } -class base::noipmi inherits base::ipmi { - Base::Os::Kernel_module['ipmi_si'] { ensure => absent } - Base::Os::Kernel_module['ipmi_devintf'] { ensure => absent } - File['/etc/default/ipmievd'] { ensure => absent } + # Packages: The IPMI daemon and the client come in one package. + # Some people might want to keep the client, so we don't delete it. + } # Done handling ensure => absent for osfamily Debian - Service['ipmievd'] { ensure => stopped } + 'RedHat': { + # Make sure the IPMI service isn't running + service { 'ipmi': + ensure => stopped, + enable => false, + } - file { '/etc/noipmi': - mode => '0644', - content => "ipmi is not supported on this system\n", + # Make sure the IPMI packages are uninstalled + # (We keep tools, but remove the server/driver) + package { 'OpenIPMI': + ensure => purged; + } + } + default: { + fail('base::noipmi does not recognize this OS family') + } + } # Dont handling ensure => absent for osfamily RedHat + + # Leave a file marker on the system saying that IPMI is disabled + file { '/etc/noipmi': + mode => '0644', + content => "ipmi is not supported, or has been disabled in Puppet.\n", + } + } # Done handling ensure => absent + + default: { + fail("Valid values for base::ipmi::ensure are 'present' or 'absent'") + } } } diff --git a/templates/ipmi/etc/default/ipmievd.erb b/templates/ipmi/etc/default/ipmievd.erb index 448a62425d2d40bfd0a97c84e2168b18b25e452c..acfff56d74ae38ede39d44aab4aa5610892ec880 100644 --- a/templates/ipmi/etc/default/ipmievd.erb +++ b/templates/ipmi/etc/default/ipmievd.erb @@ -1,7 +1,7 @@ ENABLED=true <% if ((@operatingsystem == 'Debian' and @lsbmajdistrelease >= 8) \ - or (@operatingsystem == 'Ubuntu' and @lsbmajdistrelease.split('.')[0].to_i >= 14)) + or (@operatingsystem == 'Ubuntu' and !@lsbmajdistrelease.split('.')[0].nil? and @lsbmajdistrelease.split('.')[0].to_i >= 14)) %> IPMIEVD_OPTIONS="open daemon" <% end -%>