Wednesday, June 20, 2012

Build Firewall Builder 'FWbuilder' 5.1.0 for Fedora 17

Howdy, FirewallBuilder released version 5.1.0 without providing an officially built rpm for Fedora 17. This post will build an rpm for Fedora 17 using the src rpm for Fedora 16 If you need help configuring the rpmbuild environment, start here. First, download the fwbuilder-5.1.0.3599-1.fc16.src.rpm file to your local directory. Next, extract the src.rpm
$ cd ~/tmp/fwbuilder
$ rpm2cpio fwbuilder-5.1.0.3599-1.fc16.src.rpm | cpio -idvm
$ mv fwbuilder-5.1.0.3599.tar.gz ~/rpmbuild/SOURCES/
$ mv fwbuilder-5.1.0.3599.spec ~/rpmbuild/SPECS/
A patch file is required due to the following build error:
../fwbuilder/uint128.h: In member function 'std::string uint128::to_string() const':
../fwbuilder/uint128.h:469:95: warning: format '%lX' expects argument of type 'long unsigned int', but argument 3 has type 'long long unsigned int' [-Wformat]
../fwbuilder/uint128.h:469:95: warning: format '%lX' expects argument of type 'long unsigned int', but argument 4 has type 'long long unsigned int' [-Wformat]
../fwbuilder/uint128.h:471:58: warning: format '%lX' expects argument of type 'long unsigned int', but argument 3 has type 'long long unsigned int' [-Wformat]
In file included from ThreadTools.cpp:31:0:
../fwbuilder/ThreadTools.h:168:5: error: 'ssize_t' does not name a type
ThreadTools.cpp:182:82: error: no 'ssize_t libfwbuilder::TimeoutCounter::read(int, void*, size_t) const' member function declared in class 'libfwbuilder::TimeoutCounter'
make[4]: *** [.obj/ThreadTools.o] Error 1
The patch was built using the following diff (patch credit debian bug 674349)
$ diff -u src/libfwbuilder/src/fwbuilder/ThreadTools.h.orig src/libfwbuilder/src/fwbuilder/ThreadTools.h > ~/rpmbuild/SOURCES/fwbuilder-5.1.0.3599.ssize_t.patch
--- src/libfwbuilder/src/fwbuilder/ThreadTools.h.orig 2012-06-20 11:31:12.029364056 -0500
+++ src/libfwbuilder/src/fwbuilder/ThreadTools.h 2012-06-20 11:09:36.000000000 -0500
@@ -31,6 +31,7 @@
 
 #include  //for time_t definition
 #include 
+#include 
 
 #include 
 #include 
Either run through the diff to generate the patch file or copy and paste the above diff into the new patch file ~/rpmbuild/SOURCES/fwbuilder-5.1.0.3599.ssize_t.patch Now edit the fwbuilder-5.1.0.3599.spec file to include the new patch file
--- fwbuilder-5.1.0.3599.spec.orig 2012-03-22 04:17:55.000000000 -0500
+++ fwbuilder-5.1.0.3599.spec 2012-06-20 11:51:09.901734348 -0500
@@ -20,6 +20,7 @@
 Group:          %{guigroup}
 Url:            http://www.fwbuilder.org/
 Source:         http://prdownloads.sourceforge.net/fwbuilder/%{name}-%{version}.tar.gz
+Patch1:         fwbuilder-5.1.0.3599.ssize_t.patch
 Packager:       Vadim Kurland 
 
 Buildroot:      %{_tmppath}/%{name}-%{version}-root
@@ -48,6 +49,7 @@
 
 %prep
 %setup 
+%patch1 -p0
 ./autogen.sh
 
 %build

Then run the build
$ cd ~/rpmbuild/SPECS
$ rpmbuild -ba fwbuilder-5.1.0.3599.spec
The result is the rpm containing
$ rpm -qpl ../RPMS/x86_64/fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64.rpm |more
/usr/bin/fwb_iosacl
/usr/bin/fwb_ipf
/usr/bin/fwb_ipfw
/usr/bin/fwb_ipt
/usr/bin/fwb_pf
/usr/bin/fwb_pix
/usr/bin/fwb_procurve_acl
/usr/bin/fwbedit
/usr/bin/fwbuilder
/usr/share/applications/fwbuilder.desktop
/usr/share/doc/fwbuilder-5.1.0.3599
...
Install the rpm using yum
$ sudo yum install ../RPMS/x86_64/fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64.rpm 
Loaded plugins: fs-snapshot, langpacks, presto, refresh-packagekit
Examining ../RPMS/x86_64/fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64.rpm: fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64
Marking ../RPMS/x86_64/fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package fwbuilder.x86_64 0:5.1.0.3599-1.fc17.uabeng will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=====================================================================================================================
 Package         Arch         Version                         Repository                                        Size
=====================================================================================================================
Installing:
 fwbuilder       x86_64       5.1.0.3599-1.fc17.uabeng        /fwbuilder-5.1.0.3599-1.fc17.uabeng.x86_64        36 M

Transaction Summary
=====================================================================================================================
Install  1 Package
Hope this helps other FC17 FWbuilder users out there!

Friday, June 1, 2012

HowTo: Converting EXT4 to BTRFS in Fedora 17

This HowTo documents the steps I used on a Fedora 17 x86_64 test machine to convert the root file system from Ext4 to Btrfs.

Anaconda (Fedora installer) doesn't support the creation or manipulation of Btrfs file systems in the graphical installer. Support for this is slated for Fedora 18, at which time, Btrfs may become the default file system!

It is possible, however, to create Btrfs file systems at install time via Kickstart.

The virtual machine was installed with Fedora 17 x86_64 using default partitioning (LVM and Ext4) and selecting the Desktop profile.

If possible, create the partitions without LVM. (see section at the bottom for an example of this and UUID)

In the examples, the root file system is a logical volume: /dev/mapper/vg_f17vm-lv_root

Following the install and the initial boot, I rebooted using the Fedora 17 x86_64 Live CD and chose the option to Try Fedora.

I initially tried to perform the conversion using the Fedora 17 DVD and rescue mode, however the btrfs-convert utility isn't included. The live CD, however, includes the Btrfs utilities.

Convert EXT4 root

All of the steps are performed using the terminal, so open a Gnome Terminal and SU to root:
$ su -

Run fsck on the file system
# fsck.ext4 -f /dev/mapper/vg_f17vm-lv_root

Convert from ext4 to btrfs. The metadata stage can take a while on a large populated file system (on an 1.5TB ext4 file system with approx 500GB of data, a good mix of large and small files, this step took about 1.5 hours)
# btrfs-convert /dev/mapper/vg_f17vm-lv_root

creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.

Mount the freshly converted btrfs root file system so that we can make some modifications (fstab, SELinux)
# mkdir /mnt/btrfs
# mount -t btrfs /dev/mapper/vg_f17vm-lv_root /mnt/btrfs

Edit fstab to change the root file system from ext4 to btrfs
# vi /mnt/btrfs/etc/fstab

#/dev/mapper/vg_f17vm-lv_root              ext4   defaults    1 1
/dev/mapper/vg_f17vm-lv_root              btrfs   defaults    1 1

Force the system to automatically relabel the SELinux context for the root file system during boot.
# touch /mnt/btrfs/.autorelabel

NOTE: In my test, the Fedora 17 system would hang with systemd library permissions errors prior to getting to the SELinux auto relabel step.

To work around this, I rebooted back into the Live CD and change the SELinux policy to "permissive" from "enforcing". During the next boot, the permission errors went by and then the SELinux autorelabel ran to completion.
# vi /mnt/btrfs/etc/selinux/config

#SELINUX=enforcing
SELINUX=permissive

The Btrfs conversion process created a subvolume of the old ext4 file system. The following commands mount the subvolume and file system, demonstrating the power of Btrfs.
# mkdir /mnt/{ext2_saved,ext4}
# mount -t btrfs -o subvol=ext2_saved /dev/mapper/vg_f17vm-lv_root /mnt/ext2_saved
# mount -t ext4 -o loop,ro /mnt/ext2_saved/image /mnt/ext4

The contents of the ext4 and btrfs mounts should be identical, sans the changes made above to fstab and config.

It's possible to roll back the conversion by first unmounting the file systems and then rolling it back using the -r switch
# umount /dev/mapper/vg_f17vm-lv_root
# btrfs-convert -r /dev/mapper/vg_f17vm-lv_root

If you decide to stay with btrfs, you can delete the subvolume snapshot of the original ext4 system
# btrfs subvolume delete /mnt/btrfs/ext2_saved

Reboot into the installed OS and the system should perform the relabel and then come up with your shiny new btrfs file system.

To make things really cool, install the yum-plugin-fs-snapshot Yum plugin. This plugin will create a btrfs subvolume of your root file system prior to installing updates. The end result, you can roll back from yum updates. Test that you can mount the snapshot of the ext4 file system

Once the system is up and running, don't forget to set the SELinux policy back to "enforcing"

Issues:
  1. It appears that some of the systemd services attempt to start prior to the SELinux .autorelabel step. This results in permission errors that prevent the system from booting. Temporarily change the SELinux policy to "permissive" to work past this.
  2. During boot, you may see errors logged by the systemd-fsck service failing for lv_root due to missing fsck.btrfs. I suspect that the btrfs-progs rpm failed to create a symlink of fsck.btrf pointing to /usr/sbin/btrfsck
systemd-fsck[858]: fsck: fsck.btrfs: not found
systemd-fsck[858]: fsck: error 2 while executing fsck.btrfs for /dev/mapper/vg_f17vm-lv_root

Convert Luks Encrypted EXT4 home

If your file system is encrypted with Luks, you'll have the additional step of decrypting the file system prior to running the conversion
# cryptsetup luksOpen /dev/mapper/vg_f17vm-lv_home luks_home
# fsck.ext4 -f /dev/mapper/luks_home
# btrfs-convert /dev/mapper/luks_home

creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.

Converting Non LVM Ext4 and UUID in /etc/fstab

If you don't use LVM (recommended based on everything I've ready, since it's not needed for btrfs), your /etc/fstab may mount the partitions using the UUID. After converting the file system to btrfs, the UUID will change.

These steps demonstrate how to convert the root file syste, a non LVM ext4 partition, /dev/sda2.
# fsck.ext4 -f /dev/sda2
# btrfs-convert /dev/sda2

creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.
Identify the UUID using blkid (can also look under /dev/disk/by-uuid
# blkid /dev/sda2

/dev/sda2: UUID="56d1e02b-3120-44c3-b8f8-d3289012e447" UUID_SUB="13f7b26b-42b1-41bb-a9dc-c928ad033f6d" TYPE="btrfs" 


# mkdir /mnt/btrfs
# mount -t btrfs /dev/sda2 /mnt/btrfs


Edit fstab to change the root file system from ext4 to btrfs and replace the UUID with the new UUID
# vi /mnt/btrfs/etc/fstab

#UUID=e14bd8d6-ac8a-4f15-8169-f0a9bdf4b69e /                       ext4    defaults        1 1
UUID=56d1e02b-3120-44c3-b8f8-d3289012e447 /                       btrfs    defaults        1 1
UUID=f4cdf95d-66eb-4428-960d-23b289ffb63e /boot                   ext4    defaults        1 2

Chroot to the real root file system and update grub.cfg using grub2-mkconfig

# mount -o bind /dev /mnt/btrfs/dev
# mount -o bind /proc /mnt/btrfs/proc
# mount -o bind /sys /mnt/btrfs/sys
# mount /dev/sda1 /mnt/btrfs/boot

# chroot /mnt/btrfs

# grub2-mkconfig -o /boot/grub2/grub.cfg 

Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.4.3-1.fc17.x86_64
Found initrd image: /boot/initramfs-3.4.3-1.fc17.x86_64.img
Found linux image: /boot/vmlinuz-3.3.4-5.fc17.x86_64
Found initrd image: /boot/initramfs-3.3.4-5.fc17.x86_64.img
Warning: Please don't use old title `Fedora Linux, with Linux 3.3.4-5.fc17.x86_64' for GRUB_DEFAULT, use `Advanced options for Fedora Linux>Fedora Linux, with Linux 3.3.4-5.fc17.x86_64' (for versions before 2.00) or `gnulinux-advanced-/dev/sda2>gnulinux-3.3.4-5.fc17.x86_64-advanced-/dev/sda2' (for 2.00 or later)
done
Exit out of the chroot and unmount the file systems
# exit
# umount /mnt/btrfs/boot
# umount /mnt/btrfs/dev
# umount /mnt/btrfs/proc
# umount /mnt/btrfs/sys
# umount /mnt/btrfs


Reboot and you should be good to go. The selinux relabeling can take a while!

References:

Friday, May 4, 2012

Script to Query Dell Warranty Status

I'm sure there are more elegant ways of obtaining the warranty status for your Dell hardware, but none-the-less, here's a Ruby script I wrote that does just that :-)

Script: query_dell_st.rb

The script currently has two modes, single lookup and batch lookup.

Single lookup takes two arguments:
  • --host HOSTNANE
  • --svctag SERVICE_TAG
Bulk requires only a single argument pointing to an input file containing a single entry "HOSTNAME SERVICE_TAG" per line for each device.
  • --file FILE
Example single lookup:

$ ./query_dell_st.rb --svctag GT7D8P1 --host lin-srv01
Host: lin-srv01
 Model: PowerEdge R410
 Service Tag: GT7D8P1
 Warranty Exp: 617 days left


Over the next few days I'll add more features (CSV and tab delimited output, for example) as well as address bugs and error handling.

Hopefully the script is useful to others.

Friday, April 13, 2012

HowTo: Disable User List on RHEL6 / CentOS6 Login Window

Quick bit of code to disable the user list on the RHEL6 / CentOS6 login screen.

# gconftool-2 --direct --config-source=xml:readwrite:/etc/gconf/gconf.xml.defaults --type bool --set /apps/gdm/simple-greeter/disable_user_list true

Useful Gconf References:

Thursday, March 29, 2012

Ghetto-timemachine Ruby Backup Script

I decided to try my hand at some Ruby scripting and figured, what better way than to port one of my existing Perl scripts.

The result is the Ruby ghetto-timemachine.rb backup script!

The code is maintained here:
https://github.com/flakrat/ghetto-timemachine

So, what does it do? In a nutshell, it performs daily backups using a combination of hard links and rsync that result in a Time Machine like backup that uses very little additional space beyond the initial backup and the size of any files that change.

Example usage:
  • Local source to local destination with comma separated list of excludes
    
    ./ghetto-timemachine.rb --src ~/Pictures --dest /media/USB/backup --excludes \*.raw,\*.bmp
    
  • Local source to remote destination
    
    ./ghetto-timemachine.rb --src ~/Pictures --dest flakrat@rathole:/backup --excludes \*.raw,\*.bmp
    
Nightly cron job running at 1:10AM

10 1 * * * /home/flakrat/bin/ghetto-timemachine.rb --src ~/Pictures --dest flakrat@rathole:/backup --excludes \*.raw,\*.bmp

See the README for a more detailed description of the backup and rotation process.

Thursday, March 15, 2012

Fedora 16 Gnome Terminal Redraw Doesn't Always Completely Render

I've noticed an issue on my Fedora 16 workstation where Gnome Terminal redraws don't always completely render.

For example, it could be as simple as pressing the up arrow key to scroll through the CLI history (or ESC K for the 'set -o vi' crowd). A good percentage of the time when I'd do that, the command line wouldn't completely render, CTRL C and scrolling again usually cleared it up.

I also experienced the behavior a lot when in VI. Scroll or jump to a line and the text would end up being a combination of the previous page and the new location.

I experienced the issue using Nouveau and binary Nvidia drivers.

The following Bugzilla ticket provided a possible workaround. I've only just implemented the ENV variables, but after 1 day of use I have yet to experience the issue, where as before it was pretty consistent.

To globally apply the settings, add the following variables to end of /etc/gdm/Xsession

# Attempting to fix the Gnome terminal redraw issue:
# https://bugzilla.redhat.com/show_bug.cgi?id=720605
export CLUTTER_DEBUG=disable-culling
export CLUTTER_PAINT=disable-clipped-redraws:disable-culling


Reboot, log back in and hopefully the issue goes away :-)

Tuesday, January 31, 2012

CentOS 6.2 Installation issue with Dell Precision Workstation T7500

Attempting to kickstart a new Dell Precision Workstation T7500 with an nVidia Quadro 2000 with the CentOS6.2 DVD media resulted in a kernel panic. All signs pointed to the community built nouveau module "nouveau_probe_i2c_addr panic"

I'm not so worried about the nouveau module working, since the kickstart process installs the official nVidia binary release.

To work around the issue and allow the system to boot fully into the installer, simply add "rblacklist=nouveau" to the argument list:


> vmlinuz initrd=initrd.img ks=http://srv1/ks/wks-el6.cfg rdblacklist=nouveau reboot=pci

Wednesday, January 18, 2012

How to Configure Nagios Check_MK to Report Number of Package Updates Need on Client

The Check_mk Updates plugin was posted to the Check_mk mailing list by Jonathan Mills. The following Blog entry covers the steps I took to integrate it in my environment. I opted to distribute the two plugin files to the clients via puppet rather than RPM.
  • OMD version: 0.51.20111117
  • Puppet version: 2.6.12
  • Server is CentOS 5.7 x86_64
  • Clients are CentOS 5.7, CentOS 6.2, RHEL5.7, Fedora 16 ix86,x86_64
Refrences This check currently only works with Yum based clients (tested on CentOS 5 and 6, RHEL5 and Fedora 16) and requires the yum-security package (EL5) or yum-plugin-securities (EL6) The plugin attempts to identify security and non-security packages that are pending install. For RHEL, it's simple to get this info via "yum --security check-update"

$ sudo yum --security check-update
Loaded plugins: dellsysid, rhnplugin, security
Limiting package lists to security relevant ones
Needed 6 of 17 packages, for security

kernel.x86_64                        2.6.18-274.17.1.el5             rhel-x86_64-client-5
kernel-devel.x86_64                  2.6.18-274.17.1.el5             rhel-x86_64-client-5
kernel-headers.x86_64                2.6.18-274.17.1.el5             rhel-x86_64-client-5
libxml2.i386                         2.6.26-2.1.12.el5_7.2             rhel-x86_64-client-5
libxml2.x86_64                       2.6.26-2.1.12.el5_7.2             rhel-x86_64-client-5
libxml2-python.x86_64                2.6.26-2.1.12.el5_7.2             rhel-x86_64-client-5
For CentOS and most likely Scientific Linux, the security errata are not provided with the repos, so the above command will always report 0 security updates. This is solved in the plugin by parsing the results of the -v (verbose) output.
  1. Add the client side scripts to the puppet server (Puppet isn't necessary, you can install the RPM provided in the tar file on the check_mk post)
    • Create the file directories under site
      
      $ mkdir -p var/lib/puppet/files/site/etc/check_mk
      $ mkdir -p var/lib/puppet/files/site/usr/lib/check_mk_agent/plugins 
      
    • Create the check_updates.cfg etc file
      
      $ vim var/lib/puppet/files/site/etc/check_mk/check_updates.cfg 
      
      
      
      # +------------------------------------------------------------------+
      # |             ____ _               _        __  __ _  __           |
      # |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
      # |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
      # |           | |___| | | |  __/ (__|   <    | |  | | . \            |
      # |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
      # |                                                                  |
      # | Copyright Mathias Kettner 2010             mk@mathias-kettner.de |
      # +------------------------------------------------------------------+
      #
      # This file is part of Check_MK.
      # The official homepage is at http://mathias-kettner.de/check_mk.
      #
      # check_mk is free software;  you can redistribute it and/or modify it
      # under the  terms of the  GNU General Public License  as published by
      # the Free Software Foundation in version 2.  check_mk is  distributed
      # in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
      # out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
      # PARTICULAR PURPOSE. See the  GNU General Public License for more de-
      # ails.  You should have  received  a copy of the  GNU  General Public
      # License along with GNU Make; see the file  COPYING.  If  not,  write
      # to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
      # Boston, MA 02110-1301 USA.
      
      # check_updates.cfg
      # This file configures mk_check_updates.
      
      # interval (seconds) between runs of 'yum check-update'
      INTERVAL=7200
      
      # path to log file
      LOG="/var/log/check_updates.log"
      
    • Create the mk_check_updates script (The script has updates that I made to resolve some issues related to the priorities yum plugin and yum output beginning with Keeping or Removing, so it's slightly different than the original source)
      
      $ vim var/lib/puppet/files/site/usr/lib/check_mk_agent/plugins/mk_check_updates 
      
      
      
      #!/bin/bash
      #
      # OUTPUT:
      # (security) (non-security) (runtime) (check age)
      # <<<updates>>>
      # 7 40 7 209
      
      # Unix time (seconds since Unix epoch)
      START=$(date +%s)
      
      TIME=
      AGE=
      
      INTERVAL=86400                          # default interval once a day
      LOG="/var/log/check_updates.log"        # default path to log file
      
      # Source config file if it exists
      if [ -e "/etc/check_mk/check_updates.cfg" ]; then
          . /etc/check_mk/check_updates.cfg
      fi
      
      # function run_check_update
      run_check_update () {
      if which yum >/dev/null; then
      
        if [ ! -e "/var/run/yum.pid" ]; then
      
          cat /dev/null > $LOG
      
          # Check for security RPMS
          yum -v --security check-update | egrep '(i.86|x86_64|noarch)' | egrep -v '\(priority\)' |\
       egrep -v '(^Keeping|^Removing|^Nothing|^Excluding|^Looking)' | sed 's/^.*--> //g' | while read L
          do
      
            RPM=$(echo $L | awk '{print $1}')
            Q=$(echo ${L} | grep 'non-security' > /dev/null; echo $?)
            if [ $Q -eq 0 ]; then
              echo "non-security $RPM" >> $LOG
            else
              echo "security $RPM" >> $LOG
            fi
      
          done
      
        fi
      fi
      }
      
      # function timeyet
      timeyet () {
      LAST=$(stat -c '%Y' $LOG)
      NOW=$(date +%s)
      AGE=$((NOW - LAST))
      [ $AGE -gt $INTERVAL ] && TIME=1 || TIME=0
      }
      
      # See if it's time to run 'yum check-updates' yet
      if [ ! -e $LOG ]; then
        touch $LOG
        run_check_update
        timeyet
      else
        timeyet
        if [ $TIME = 1 ]; then
          run_check_update
          timeyet
        fi
      fi
      
      # Gather results from log file
      SEC=$(grep '^security' $LOG | wc -l)
      NON=$(grep '^non-security' $LOG | wc -l)
      
      # Unix time (seconds since epoch)
      END=$(date +%s)
      
      RUNTIME=$((END - START))
      
      echo '<<<updates>>>'
      echo $SEC" "$NON" "$RUNTIME" "$AGE
      exit 0
      
      
    • Add the scripts to git
      
      $ git add var/lib/puppet/files/site/usr/lib/check_mk_agent/plugins/mk_check_updates
      $ git add var/lib/puppet/files/site/etc/check_mk/check_updates.cfg 
      $ git commit -a -m "Adding check_mk client side scripts to report yum updates"
      $ git push
      
    • Add the scripts to the check_mk class to ensure that the clients get the code
      
      $ vim etc/puppet/manifests/classes/check_mk.pp
      
      
      
      # etc/puppet/manifests/classes/check_mk.pp
      
      class check_mk {
         case $operatingsystem {
            "centos",
            "fedora",
            "redhat": {
               package {["check_mk-agent", "check_mk-agent-logwatch"]:
                  ensure   => latest,
                  notify   => Service["xinetd"],
               }
               service { "xinetd":
                  ensure     => running,
                  enable     => true,
               }
               file { "/etc/check_mk/check_updates.cfg":
                  owner => "root",
                  group => "root",
                  mode => 755,
                  source => "puppet:///site/etc/check_mk/check_updates.cfg",
               }
               file { "/usr/lib/check_mk_agent/plugins/mk_check_updates":
                  owner => "root",
                  group => "root",
                  mode => 755,
                  source => "puppet:///site/usr/lib/check_mk_agent/plugins/mk_check_updates",
               }
           }
            default: { }
         }
      }
      
    • Ensure that the check_mk class is included in the node definitions (currently included in the baseclass template)
    • Git commit the changes to check_mk.pp class and push to the git server
  2. Install the python script on the nagios server (note user defined checks go in local/share/check_mk/checks, if you put them into $SITE/share.... they won't survive the next OMD upgrade)
    
    $ su - sitename
    $ vim local/share/check_mk/checks/updates
    
    
    
    #!/usr/bin/python
    # -*- encoding: utf-8; py-indent-offset: 4 -*-
    
    # Jonathan Mills 10/2011
    
    # Example output from agent:
    # [security] [non-security] [runtime (seconds)] [age of results (seconds)]
    # <<<updates>>>
    # 7 40 0 13
    #
    
    updates_default_values = (5, 20)
    
    # inventory
    def inventory_updates(checktype, info):
        #if len(info) >= 1 and len(info[0]) >= 1:
        #    return [ (None, None) ]
        inventory = []
        inventory.append( (None, "updates_default_values") )
        return inventory
    
    
    # check
    def check_updates(_no_item, params, info):
        # unpack check parameters
        min_num_sec, min_num_nonsec = params
    
        for line in info:
            perfdata = []
            sec = int(line[0])
            nonsec = int(line[1])
            age = int(line[3])
            infotext = "%s Security Updates, %s Non-Critical Updates  (Last Checked %s seconds ago)" % (sec, nonsec, age)
            perfdata.append( ( "Runtime (sec)", int(line[2]) ) )
            if sec > min_num_sec:
                return (2, "CRITICAL - " + infotext, perfdata)
            elif nonsec > min_num_nonsec:
                return (1, "WARNING - " + infotext, perfdata)
            else:
                return (0, "OK - " + infotext, perfdata)
    
    # declare the check to Check_MK
    check_info['updates'] = (check_updates, "Updates", 1, inventory_updates)
    
  3. Add a new time period 'nightly' to nagios that can be used to limit this check to running daily from 3AM to 4AM
    
    $ vim etc/nagios/conf.d/timeperiods.cfg 
    
    
    ###############################################################################
    # TIMEPERIODS.CFG - SAMPLE TIMEPERIOD DEFINITIONS
    #
    # NOTES: This config file provides you with some example timeperiod definitions
    #        that you can reference in host, service, contact, and dependency
    #        definitions.
    #
    #        You don't need to keep timeperiods in a separate file from your other
    #        object definitions.  This has been done just to make things easier to
    #        understand.
    #
    ###############################################################################
    
    # This defines a timeperiod where all times are valid for checks,
    # notifications, etc.  The classic "24x7" support nightmare. :-)
    define timeperiod{
        timeperiod_name 24x7
        alias           24 Hours A Day, 7 Days A Week
        sunday          00:00-24:00
        monday          00:00-24:00
        tuesday         00:00-24:00
        wednesday       00:00-24:00
        thursday        00:00-24:00
        friday          00:00-24:00
        saturday        00:00-24:00
    }
    
    # 'workhours' timeperiod definition
    define timeperiod{
           timeperiod_name workhours
           alias           Normal Work Hours
           monday          08:00-17:00
           tuesday         08:00-17:00
           wednesday       08:00-17:00
           thursday        08:00-17:00
           friday          08:00-17:00
    }
    
    # 'none' timeperiod definition
    define timeperiod{
        timeperiod_name  none
        alias            No Time Is A Good Time
    }
    
    # 'nightly' timeperiod definition
    define timeperiod{
             timeperiod_name         nightly
             alias                   Nightly Check
             sunday                  03:00-04:00  ; Every Sunday of every week
             monday                  03:00-04:00  ; Every Monday of every week
             tuesday                 03:00-04:00  ; Every Tuesday of every week
             wednesday               03:00-04:00  ; Every Wednesday of every week
             thursday                03:00-04:00  ; Every Thursday of every week
             friday                  03:00-04:00  ; Every Friday of every week
             saturday                03:00-04:00  ; Every Saturday of every week
    }
    
    
  4. Add the new check to check_mk main.mk file
    
    $ vim etc/check_mk/main.mk
    
    
    
    # check-updates (OMD 0.52 requires user defined vars to prepend and underscore)
    _updates_default_values = (6, 20) # check-updates: critical when 6 or more sec updates, warning when 20 or more non-sec updates
    
    extra_service_conf["check_period"] = [
      ( "nightly", ALL_HOSTS, [ "Updates" ] ), # check-updates: Only check for updates from 3 to 4AM as set in timeperiods.cfg
    ]
    
    extra_host_conf["max_check_attempts"] = [
      ( "1", ALL_HOSTS, [ "Updates" ] ), # check-updates: Only check for updates once
    ]
    
    # Enable notifications for specific services
    extra_service_conf["notifications_enabled"] = [
      ( "1", ALL_HOSTS, ["Check_MK"]),
      ( "0", ALL_HOSTS, ["Updates"]), # check-updates: Don't notify for security OS updates
      ( "1", ALL_HOSTS, ["Memory used"]),
      ( "1", ALL_HOSTS, ["IPMI Sensor Summary","fs_*"]),
      ( "1", ["linsrv"], ["IPMI Sensor Summary","ambient_temp"]),
      ( "1", ALL_HOSTS, ["Multipath *"]),
      ( "1", ["kvm"], ALL_HOSTS, ["CPU load"]),
      ( "1", ["kvm"], ALL_HOSTS, ["CPU utilization"]),
      ( "1", ["mailsrv"], ["Postfix Queue"]),
      ( "1", ["linsrv"], ALL_HOSTS, ["Dell OMSA"]),
      ( "0", ALL_HOSTS, ALL_SERVICES), # and disable notifications for everything else
    ]
    
    service_groups = [
      ( "updates", ALL_HOSTS, [ "Updates" ] ), # check-updates: Create updates service group to make viewing in web interface easier
    ]
    
    define_servicegroups = {
       "updates" : "RHEL/CentOS Yum Updates", # check-updates: Can now statically link to a service group web view: http://nagios.server/sitename/check_mk/view.py?view_name=servicegroup&servicegroup=updates
    }
    
    
  5. Rerun the inventory for the nodes
    
    $ check_mk -II node-01
    ...
    
    or for all nodes
    $ check_mk -II
    
  6. Reload the services
    
    $ check_mk -O
    
    
  7. Check the web page for the nodes, alternatively you can go straight to the Updates overview page:
    https://nagios.server/sitename/check_mk/view.py?view_name=servicegroup&servicegroup=updates