Tag Archives: RHEL

Configuring and Installing Nagios Core 4 on CentOS 6

Introduction

Nagios is a powerful tool that allows you to monitor just about anything. It’s so easy to even take existing legacy system and adapt it to work with Nagios. When I came across kingkiwix and his blog here I wanted to repackage the content in a more user-friendly way for sharing. I wanted a solution that didn’t require me to pull in a bunch of development libraries and compilers. I also wanted a solution that I could re-use on other systems through a version controlled and packaged interface.


Those running CentOS 7.x might be interested in this new blog entry: Nagios Core 4.x Setup for CentOS 7.x.


RPM Solution

RPMs provide a version control and an automated set of scripts to configure the system how I want it. The beauty of them is that if you disagree with
something the tool you’re packaging does, you can feed RPMs patch files to accommodate it without obstructing the original authors intention.

Now I won’t lie and claim I wrote these SPEC files from scratch because I certainly didn’t. I took the stock ones that ship with both products (both Nagios and Nagios-Plugins) and modified them significantly to accommodate and satisfy my compulsive needs. πŸ™‚

My needs required a bit more automation in the setup as well as including:

  • The use of nagiocmd user group.
  • A /etc/nagios/conf.d directory to behave similar to how Apache works. I want to be able to drop configuration files into here and just have it work without re-adjusting configuration files.
  • Alerting Apache on new updates/installs so just installing the package alone is all you need to do.
  • Nagios Plugins should work right away once they are installed.
  • Nagios Plugins and permissions should adapt to the new nagiocmd user and place in a common directory Nagios was already configured to look in.
  • Nagios Plugins has to many dependencies; I wanted to break this up into separate packages for those who needed them. For example, I don’t use MySQL at all; so why should I need the MySQL Libraries installed on my system just to use Nagios Plugins.
  • Nagios group permissions added to /etc/nagios directory for people using third party management applications. Just add any third party app to the Nagios group and they’ll be able to manage your configuration too:
    # substitute <3rdpartyid> for the actual group/id belonging
    # to the software in question.
    usermod -a -G nagios <3rdpartyid>
    

Stop Babbling, Just Give Me All Your Hard Work

Of course here it is:

At a minimum you need to install both Nagios Core (v4.2.0) and it’s accompanied Nagios Plugins (v1.5) package.

For those who are interested, here is a quick direct link to my additions to the building environment and deployment:

I Installed the Packages, Now What?

The RPMs take care of just about everything for you, so there isn’t really much to do at this point.

  • Make sure Apache is running and if it isn’t start it:
    # the following way is a harmless way of checking if Apache is
    # running and starting it if it wasn't (requires root)
    service httpd status || service httpd start
    
    # If it wasn't started in the above command, you may want to
    # consider having it start up each time you reboot your machine
    # through the following command:
    chkconfig httpd --levels 345 on
    
  • Start Nagios
    # Startup Nagios (requires root)
    service nagios start
    
    # Consider having Nagios (Backend) start up each time you reboot
    # your machine through the following command:
    chkconfig nagios --levels 345 on
    
    # You'll also want to set up a nagiosadmin password
    # The below will set you up with one using the pass of 'password'
    sudo htpasswd -cb /etc/nagios/htpasswd.users nagiosadmin password
    

Visiting http://localhost/nagios/ should look similar to this if you followed the steps correctly
Visiting http://localhost/nagios/ should look similar to this if you followed the steps correctly
Yes, that’s right… you’re done! You can access your Nagios Web Interface by visiting http://localhost/nagios. How you configure your system further is beyond the scope of this tutorial/blog. My goal was just to get you started with an out of the box working Nagios solution :).

If your not already familiar with Nagios, you may want to read the documentation so you can monitor more then just the 8 example checks it sets up for you out of the box. There are also some great web configuration tools you can check out as well here.

Package Information

  • Software installs to: /usr/share/nagios
  • Plugins install to: /usr/lib64/nagios/plugins. Keep in mind I packaged everything in such a way that compiling it for 32-bit will work fine. In which case you’ll find plugins installed to: /usr/lib/nagios/plugins
  • Website is accessible at: http://localhost/nagios/ out of the box, but you can adjust it’s web configuration by adjusting /etc/httpd/conf.d/nagios.conf to your likings.
  • Nagios Core 4 configuration file can be found at: /etc/nagios/nagios.cfg and a newly added /etc/nagios/conf.d/ directory has been added to make some things easier to add/remove later.
  • # SELinux Users may wish to turn this flag on if they intend to allow it
    # to call content as root (using sudo) which it must do for some status checks.
    setsebool -P nagios_run_sudo on
    

    I want to repackage this myself

    All of my blogs provide a way to build everything from scratch yourself for those who don’t want to just download the binary packages and roll with them. I use mock for everything I build so I don’t need to haul in development packages into my native environment. You’ll need to make sure mock is setup and configured properly first for yourself:

    # Install 'mock' into your environment if you don't have it already.
    # This step will require you to be the superuser (root) in your native
    # environment.
    yum install -y mock
    
    # Grant your normal every day user account access to the mock group
    # This step will also require you to be the root user.
    usermod -a -G mock YourNonRootUsername
    

    At this point it’s safe to change from the ‘root‘ user back to the user account you granted the mock group privileges to in the step above. We won’t need the root user again until the end of this tutorial when we install our built RPM.

    # Perhaps make a directory and work within it so it's easy to find
    # everything later
    mkdir nagiosbuild
    cd nagiosbuild
    ###
    # Now we want to download all the requirements we need to build
    ###
    # Nagios Core 4
    wget http://prdownloads.sourceforge.net/sourceforge/nagios/nagios-4.2.0.tar.gz
    # Nagios Plugins v1.5
    wget https://www.nagios-plugins.org/download/nagios-plugins-1.5.tar.gz
    # Customize Nagios Spec Files
    wget http://repo.nuxref.com/pub/nuxref/nagios/nagios.spec
    # Customize Nagios Plugin Spec Files
    wget http://repo.nuxref.com/pub/nuxref/nagios/nagios-plugins.spec
    # Nagios Patch to enable a conf.d directory
    wget http://repo.nuxref.com/pub/nuxref/nagios/nagios.conf.d.patch
    # Nagios Patch to fix accumulating files in /tmp/*
    wget http://repo.nuxref.com/pub/nuxref/nagios/configtest.tmp.patch
    # Nagios Plugin Patch to include some sample configurations and
    # setup Nagios to work out of the box
    wget http://repo.nuxref.com/pub/nuxref/nagios/add.sample.command.cfg.patch
    
    ###
    # Prepare our mock environment
    ###
    # Initialize Mock Environment
    mock -v -r epel-6-x86_64 --init
    
    # Copy in our downloaded content:
    mock -v -r epel-6-x86_64 --copyin nagios-4.2.0.tar.gz 
       nagios-plugins-1.5.tar.gz 
       nagios.conf.d.patch 
       add.sample.command.cfg.patch 
       onfigtest.tmp.patch 
       /builddir/build/SOURCES
    
    mock -v -r epel-6-x86_64 --copyin nagios.spec nagios-plugins.spec 
       /builddir/build/SPECS
    
    # Install Dependencies
    mock -v -r epel-6-x86_64 install gd-devel zlib-devel 
       libpng-devel libjpeg-devel doxygen gperf perl-devel net-snmp-devel
    
    # Install Plugin Dependencies
    mock -v -r epel-6-x86_64 install bind-utils mysql-devel net-snmp-utils 
                   postgresql-devel ntp openldap-devel openssh-clients 
                   samba-client /usr/bin/mailq
    
    ###
    # Build Stage
    ###
    # Shell into our enviroment
    mock -v -r epel-6-x86_64 --shell
    
    # Change to our build directory
    cd builddir/build
    
    # Build our RPMS
    rpmbuild -ba SPECS/nagios.spec
    rpmbuild -ba SPECS/nagios-plugins.spec
    
    # we're now done with our mock environment for now; Press Ctrl-D to
    # exit or simply type exit on the command line of our virtual
    # environment
    exit
    
    ###
    # Save our content that we built in the mock environment
    ###
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/SRPMS/nagios-4.2.0-2.el6.src.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/SRPMS/nagios-plugins-1.5-5.el6.src.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-plugins-1.5-5.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-plugins-mysql-1.5-5.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-plugins-pgsql-1.5-5.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-plugins-ldap-1.5-5.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-ntp-1.5-5.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-snmp-1.5-5.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-samba-1.5-5.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-plugins-debuginfo-1.5-5.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-4.2.0-2.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-contrib-4.2.0-2.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-devel-4.2.0-2.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-selinux-4.2.0-2.el6.x86_64.rpm .
    mock -v -r epel-6-x86_64 --copyout \
       /builddir/build/RPMS/nagios-debuginfo-4.2.0-2.el6.x86_64.rpm .
    
    # *Note that all the commands that interact with mock I pass in 
    # the -v which outputs a lot of verbose information. You don't
    # have to supply it; but I like to see what is going on at times.
    
    # **Note: You may receive this warning when calling the '--copyout'
    # above:
    # WARNING: unable to delete selinux filesystems 
    #    (/tmp/mock-selinux-plugin.??????): #
    #    [Errno 1] Operation not permitted: '/tmp/mock-selinux-plugin.??????'
    #
    # This is totally okay; and is safe to ignore, the action you called
    # still worked perfectly; so don't panic :)
    

    Considerations

    If you take Nagios seriously, you will really want to consider expanding it to support one (or all) of the following addons:

    • NRPE - Nagios Remote Plugin Executor
      NRPE – Nagios Remote Plugin Executor
      NRPE – Nagios Remote Plugin Executor
      NRPE is an addon that allows you to execute plugins on remote Linux/Unix hosts. This is useful if you need to monitor local resources/attributes like disk usage, CPU load, memory usage, etc. on a remote host. Similar functionality can be accomplished by using the check_by_ssh plugin, although it can impose a higher CPU load on the monitoring machine – especially if you are monitoring hundreds or thousands of hosts.
    • NSCA - Nagios Service Check Acceptor
      NSCA – Nagios Service Check Acceptor
      NSCA – Nagios Service Check Acceptor
      NSCA is an addon that allows you to send passive check results from remote Linux/Unix hosts to the Nagios daemon running on the monitoring server. This is very useful in distributed and redundant/failover monitoring setups.

    I’m considering packaging these as well to conform with the packages I’ve already provided here, but I’ll do that in another blog some other time if there ends up being a demand for it πŸ™‚.

    Dec 8th, 2013 Update: I ended up creating this blog to extend this one: Configuring and Installing NRPE and NSCA into Nagios Core 4 on CentOS 6.

    Credit

    If you like what you see and wish to copy and paste this HOWTO, please reference back to this blog post at the very least. It’s really all I ask.

    Sources

    I referenced the following resources to make this blog possible:

    Configuring and Installing MediaWiki on CentOS 6

    Introduction

    Wiki’s have got to be the easiest and fastest way to collaborate documents, thoughts, ideas, howto’s etc. In fact, everything I’ve blogged about is mostly cut and copied from my own personal Wiki I maintain on my private network to help me keep track of things.

    There are lots of wiki solutions, but I personally like MediaWiki which uses a relational database on it’s back end. It’s also has a strong background as it’s widely used by the most popular wiki’s being hosted today. Here is how MediaWiki defines itself official (quoted directly from their website):

    MediaWiki is a free software open source wiki package written in PHP, originally for use on Wikipedia. It is now also used by several other projects of the non-profit Wikimedia Foundation and by many other wikis..

    There are tutorials everywhere for this; why make another?
    As an administrator/developer myself, I like to eliminate as many steps as I can and make things as easy as possible. I also like to let the operating systems chosen package management software do most (if not all) of the work if possible. So unlike other tutorials; this solution will do most of the work for you out of the box. I have packaged a self installing RPM that prepares MediaWiki along with some useful extensions. Package management and version control is the real seller I think.

    Whatever, just give me all of your software

    This is what my blogs usually boil down to… so here is the data:

    For those who want to rebuild from source and do not trust my rpm will need to perform the following:

    # If you haven't got mock configured and installed by this point,
    # it's probably better if you read one of the previous blogs I've
    # posted where I show how to set it up.  To keep this blog shorter
    # i'm going to refrain from explaining this step.
    # Since this tutorial supports both CentOS/EPEL 5 and 6 set the
    # version we're interested in:
    VER=6
    
    # Download the packages we need to make this happen:
    # 1. MediaWiki itself
    wget http://download.wikimedia.org/mediawiki/1.21/mediawiki-1.21.2.tar.gz
    # 2. WYSIWYG, manually get it here: 
    # https://docs.google.com/file/d/0B-aiZzKTmWI2bG8yVzBCOWNLamM/view?pli=1
    # or keep using wget for speed (I copied it since I couldn't find a way
    # to direct link to a google drive location).
    wget --output-document=WYSIWYG_MW_v1.20.2.zip https://www.dropbox.com/sh/9dt7klam6ex1kpp/f79PvTQ_g7/20131105/mediawiki/WYSIWYG_MW_v1.20.2.zip?dl=1
    # 3. WYSIWYG patch #1
    wget --output-document=wysiwyg.cancel.fix.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/qxTV7Duu8G/20131105/mediawiki/wysiwyg.cancel.fix.patch?dl=1
    # 4. WYSIWYG patch #2
    wget --output-document=mw-1.21.compatible.patch https://www.dropbox.com/sh/9dt7klam6ex1kpp/qoOCF2P16A/20131105/mediawiki/mw-1.21.compatible.patch?dl=1
    # 5. The RPM SPEC file
    wget --output-document=mediawiki.spec https://www.dropbox.com/sh/9dt7klam6ex1kpp/Cv9_1FynJ-/20131105/mediawiki/mediawiki.spec?dl=1
    # 6. A seperate package labeled as extras (which right now
    #    just contains a working Secure Apache configuration file)
    #    but could be subject to change later such as supporting
    #    Lighthttpd and NginX.
    wget --output-document=extras.tar.gz https://www.dropbox.com/sh/9dt7klam6ex1kpp/2R7BZSuXYW/20131105/mediawiki/extras.tar.gz
    # Initialize our Environment (I hope your set the $VER
    # variable above)
    mock -v -r epel-$VER-x86_64 --init
    
    # Copy in our downloaded content:
    mock -v -r epel-$VER-x86_64 --copyin mediawiki.spec 
       /builddir/build/SPECS
    mock -v -r epel-$VER-x86_64 --copyin 
       mediawiki-1.21.2.tar.gz 
       WYSIWYG_MW_v1.20.2.zip 
       extras.tar.gz 
       mw-1.21.compatible.patch 
       wysiwyg.cancel.fix.patch 
       /builddir/build/SOURCES
    
    # Shell into our enviroment
    mock -v -r epel-$VER-x86_64 --shell
    
    # Change to our build directory
    cd builddir/build
    
    # Build our RPMS
    rpmbuild -ba SPECS/mediawiki.spec
    
    # we're now done with our mock environment for now;
    # Press Ctrl-D to exit or simply type exit on the
    # command line of our virtual environment
    exit
    
    # Grab our packages (v6):
    [ "$VER" == "6" ] && 
      mock -v -r epel-6-x86_64 --copyout 
         /builddir/build/SRPMS/mediawiki-1.21.2-1.el6.src.rpm .
    [ "$VER" == "6" ] && 
      mock -v -r epel-6-x86_64 --copyout 
       /builddir/build/RPMS/mediawiki-1.21.2-1.el6.noarch.rpm .
    
    # -or- Grab our packages (v5):
    [ "$VER" == "5" ] && 
      mock -v -r epel-5-x86_64 --copyout 
       /builddir/build/SRPMS/mediawiki-1.21.2-1.el5.centos.src.rpm .
    [ "$VER" == "5" ] && 
      mock -v -r epel-5-x86_64 --copyout 
       /builddir/build/RPMS/mediawiki-1.21.2-1.el5.centos.noarch.rpm .
    

    Package Information

    • Software installs to: /usr/share/mediawiki
    • Apache configuration placed in: /etc/httpd/conf.d/mediawiki.conf and can be previewed here.
    • WYSIWYG Extension is additionally packaged as an extra for those who wish to use it. The installer will give you the option of adding this. I’ve already applied all of the necessary patches they’ve listed on their website to make it work correctly with MediaWiki v1.21.2. You can view the patch files I created here and here.
    • CentOS/RHEL 5 also supported if you want:

      Keep in mind that MediaWiki requires a bare minimum of PHP v5.3 (and a minimum PostgreSQL v8.4 for those database fans like me). These packages are all available to CentOS 5 users right out of the box and Red Hat 5 users through the EPEL packages.

    Installation Information

    Identified below outline the 3 steps necessary to get up and going.

    Installation Step 1 of 3: Choose Your Database Backend:

    First thing is first, you need to choose a database back end. This tutorial will use PostgreSQL because to me, that is the best and most underrated open source database available today. That said, I’ve identified how to install the other open source choices below. You’ll need to have satisfied at least one of the below options before you can proceed.

    • 1. MySQL:
      # Install Dependencies (if they're not already)
      yum install mysql-server mysql php-mysql
      # Enable Server (if it's not already)
      # Set MySQL to restart at system startup
      chkconfig --level 345 mysqld on
      # Start MySQL (if it's not already)
      service mysqld start
      # Reload Apache (needed if php-mysql was added above)
      service httpd reload
      
    • 2. SqlLite:
      # Install Dependencies (if they're not already)
      yum  install sqlite php-sqlite
      # Reload Apache (needed if php-sqlite was added above)
      service httpd reload
      
    • 3. PostgreSQL:
      # Install Dependencies (if they're not already)
      yum install postgresql postgresql-server php-pgsql
      # Enable Server (if it's not already)
      # Set MySQL to restart at system startup
      chkconfig --level 345 postgresql on
      # Start PostgreSQL (if it's not already)
      # If this is your first time starting it; it may require you to run
      # the following: service postgresql initdb
      # Note: Do not run 'initdb' if your database is already configured
      #       or you will reset it and lose it's contents.  But you are
      #       required the call it the first time.
      service postgresql start
      # Reload Apache (needed if php-pgsql was added above)
      service httpd reload
      # You may need to additional set up some security to allow Apache
      # access to your database.  Depending on your knowledge, the
      # below command may or may not satisfy your needs. But as a quick
      # and dirty solution to gain immediate access to the database
      # (and greatly simplifies this tutorial), I'd advise people to
      # run the following:
      sed -i -e 's/^[ t]*(local|host)([ t]+.*)/#12/g' 
          /var/lib/pgsql/data/pg_hba.conf
      cat << _EOF >> /var/lib/pgsql/data/pg_hba.conf
      # Configure all local database access with trust permissions
      local   all         all                               trust
      host    all         all         127.0.0.1/32          trust
      host    all         all         ::1/128               trust
      _EOF
      # Restart the Database so it takes on the new Client
      # Authentication identified above
      service postgresql restart

    Your installation will not change that significantly if you did not pick PostgreSQL as your chosen backend identified above. In fact, it may even be easier to install since other databases have fewer security restrictions. You can still follow through with the actions explained below.

    Installation Step 2 of 3: Install The MediaWiki Package:

    # Install Dependencies (if they're not already)
    # At the present time I do not generate a GPG signature, so without
    # the --nogpg check yum will tell you it can't install the package.
    yum localinstall mediawiki-1.21.2-1.el6.noarch.rpm --nogpg
    
    # Of if using CentOS/RHEL 5 you can type the following:
    # yum localinstall mediawiki-1.21.2-1.el5.centos.noarch.rpm --nogpg
    
    # Reload Apache (needed if php-sqlite was added above)
    service httpd reload
    
    # If you're using SELinux, then you will have to enable access
    # to your database from Apache (if you haven't already). Otherwise
    # you will receive errors about not being able to connect to
    # your database during the setup stage.
    semanage boolean -m --on httpd_can_network_connect_db
    # for uploading (specifically to images/), this works best:
    semanage fcontext -a -t httpd_sys_content_t '/usr/share/mediawiki(/.*)?'
    restorecon -R /usr/share/mediawiki
    
    Here is what should be displayed to if you installed the mediawiki RPM and visit http://localhost/wiki
    Here is what should be displayed if you installed the mediawiki RPM and visit http://localhost/wiki

    Configure MediaWiki

    You MUST complete "Installation Step 2 of 3" defined above or you"ll receive this error message!
    You MUST complete ‘Installation Step 2 of 3’ defined above or you’ll receive this error message!
    Your screen does not have to look exactly like this; but the most important part is where it tells you that "The environment has been checked. You can install MediaWiki".
    Your screen does not have to look exactly like this; but the most important part is where it tells you that “The environment has been checked. You can install MediaWiki”.

    If you’re reading this far, then you’ve completed both of the installation steps above. Now we want to configure MediaWiki which is now already available to you. You can access it by opening a browser and visiting: http://localhost/wiki. Alternatively, if your doing this remotely, substitute localhost for your sites hostname or IP address. You should be presented with a webpage that looks similar to the screenshot presented here. You’ll want to click on the link that says complete the installation to set the Wiki up for your environment style.

    Follow through the wizard answering all the questions asked of you. If you’re unsure of any answers to the questions being asked, usually the default answers are satisfactory enough.

    Installation Step 3 of 3: The LocalSettings.php

    When you've successfully completed the configuration you will be asked to download LocalSettings.php
    When you’ve successfully completed the configuration you will be asked to download LocalSettings.php
    When you’ve completed the wiki’s installation wizard, it will ask you to save/download a file entitled LocalSettings.php. This file contains all the information the wiki needs to work with. You MUST download this file and copy it to /usr/share/mediawiki.

    # Copy LocalSettings.php into the mediawiki's installation
    # directory; This step is crucial!
    cp LocalSettings.php /usr/share/mediawiki
    
    # Update it's permissions for security sake!
    chown root.apache /usr/share/mediawiki/LocalSettings.php
    chmod 640 /usr/share/mediawiki/LocalSettings.php
    

    LocalSettings.php becomes the final piece of the puzzle; it contains all of the options you choose and will instruct your wiki how to behave. Once this file is in place, you’re finished with the setup! πŸ™‚

    You can access your wiki and record and collaborate information to your hearts content!

    The Apache configuration file that is included with this bundle is smart enough to detect the LocalSettings.php file and switch to it’s full out Wiki mode. Now when you visit your website (http://localhost/wiki) you can begin molding it to your liking. Note that the Apache configuration file included additionally adds support for colons (:) in your wiki paths. This allows you to create wiki’s such as: http://localhost/wiki/MySpecialWikiPage:That:Uses:Colons. Colon’s really make it so your wiki can mold and organize itself like the most popular wiki (Wikipedia.org) website used today.

    Backups

    Always consider that the worst can happen, you should:

    • Take regular backups of your database
    • Make backups of the /usr/share/mediawiki/images directory at the same time as your database backups since this is where other media content can get uploaded to
    • Store your LocalSettings.php you recently downloaded along with the mediawiki rpm package somewhere safe so you can always easily recover.

    July 17th, 2014 Update
    Since this blog was written newer versions of MediaWiki came out along with my repository I host. For those who want to update to the newer version (or just starting out and want to fetch the latest version) you can get it there.
    You can also just download it directly here:

    Just note that I scrapped the WYSIWYG plugin and all the patches I made for it in this release. I did this simply because it’s just getting too dated and no one is updating it anymore. If it’s the first time reading this blog or you’re retrieving MediaWiki for the first time, then this blog and it’s content still applicable (except WYSIWYG references) to the newer version.
    For those of you who already are running a version of MediaWiki and want to upgrade. Upgrade instructions can be found here. Alternatively, if you’re simply upgrading from the version identified in this blog (v1.21), just run the following after you install the new rpm (and then you’re good to go!):

    # Consider making a database backup snapshot of your wiki 'just in case'
    # I didn't have any problems at all, but it doesn't mean you won't.
    # Better safe then sorry... right?
    
    # As root, upgrade your mediawiki package
    yum upgrade -y mediawiki --disablerepo=* 
       --enablerepo=nuxref 
       --enablerepo=nuxref-shared
    
    # Eliminate any reference to WYSIWYG since it will be gone now
    sed -i -e 's|^([^#]+extensions/WYSIWYG/WYSIWYG.php.*)$|#1|g' 
        /usr/share/mediawiki/LocalSettings.php
    
    # Run Upgrade Script
    php /usr/share/mediawiki/maintenance/update.php
    
    # Protect /usr/share/mediawiki/mw-config/ from access
    chown root.apache /usr/share/mediawiki/mw-config/
    chmod 700 /usr/share/mediawiki/mw-config
    

    Another thing you might want to do is bump the file sizes you intend to upload (especially if you’re going to allow .zip, .rar. etc extensions onto your wiki):

    # optionally support extra file extensions that can be uploaded:
    cat << _EOF >> /usr/share/mediawiki/LocalSettings.php
    $wgFileExtensions = array_merge(
        $wgFileExtensions, array(
            'pdf', 'doc', 'docx', 'xls', 'xlsx',
            'rpm', 'tar', 'zip', 'tgz', 'gz',
            )
        );
    _EOF
    
    sed -i -e 's/^(upload_max_filesize *=).*/1 100M/g' /etc/php.ini
    sed -i -e 's/^(post_max_size *=).*/1 100M/g' /etc/php.ini
    
    # Reload service
    service httpd reload
    

    Credit

    Please note that this information took me several days to put together and test thoroughly. I may not blog often; but I want to re-assure the stability and testing I put into everything I intend share.

    If you like what you see and wish to copy and paste this HOWTO, please reference back to this blog post at the very least. It’s really all I ask.

    Sources

    • I used mediawiki.org and view the ideal setup configurations as well as read through peoples notes and work arounds. Note: At the time this blog was created v1.21.2 was the current stable version, so that is what was packaged.
    • WYSIWYG Extension is also packaged in the RPM I provided. I created 2 small patches using the comments here and here.

    Datetools: Date Manipulation and Cron Alternative For Linux

    Introduction to Datetools

    I wrote Datetools (in C++) to allow the manipulation of date time from the command line. It greatly simplified my life and maybe it will help yours out too!. It comprises of two core applications:

    • Dateblock: allows you to block until a scheduled period of time arrives unlike sleep which blocks for a set period of time. I found this so helpful, I ended up additionally building in an python extension for it.
    • Datemath: This application is just a simple way of preforming simple math on the system date.

    The source code can be found here on GitHub if you’re interested in compiling it yourself. Or you can just scroll to the bottom of this blog where I provided the packaged goods.

    Dateblock

    The tool works very similarly to cron and sleep (a combination of the two); you can pass it a crontab string if that’s what you’re used too, or you can simply pass it in variables as arguments as well (as all other commands work):

    Here’s is an example of what I mean:

    # block until a minute divisible by 10 is reached:
    # ex: HH:00, HH:10, HH:20, HH:30, HH:40, and HH:50
    dateblock --minute=/10
    # We will only reach this line when the above scheduled time has
    # been met.
    echo "Scheduled time reached; current time is: $(date)"
    

    An equivalent crontab entry would look like this:

    # block until a minute divisible by 10 is reached:
    /10 * * * * echo "Scheduled time reached; current time is: $(date)"
    

    Dateblock can also do another cool feature called ‘drifting’ which allows you to schedule processes on delayed cycles… Note that drifting is always specified in seconds. For example:

    # Unblock on 5 minute cycles, but 2 minutes (120 seconds) into them:
    # ex: HH:02, HH:07, HH:12, HH:17, HH:22, etc..
    dateblock --minute=/5 --drift=120
    # We will only reach this line when the above scheduled time has
    # been met.
    echo "Scheduled time reached; current time is: $(date)"
    

    An equivalent crontab entry would look like this:

    # block until a minute divisible by 10 is reached:
    /5 * * * * sleep 120; echo "Scheduled time reached; current time is: $(date)"
    

    The complexity of the tool can be as powerful as you want it to be:

    # Unblock only on hours divisible by 5 on the 1st through to the 14th
    # of every month (as well as the 20th). Unblock only when 30 seconds
    # of that minute has elapsed.
     dateblock -o /5 -d 1-14,20 -s 30
    # We will only reach this line when the above scheduled time has
    # been met.
    echo "Scheduled time reached; current time is: $(date)"
    

    There is no way to reproduce this in a crontab unless the 30 second reference at the end is unnecessary… in that case:

    # block until a minute divisible by 10 is reached:
    0 /5 1-14,20 * * sleep 120; echo "Scheduled time reached; current time is: $(date)"
    

    Just like crontabs, dateblock supports minute, hour, day of month, month and day of week. In addition, dateblock support seconds too. dateblock accepts traditional crontab entries as well as arguments:

    #     day of week (0 - 6) (Sunday=0) --+
    #     month (1 - 12) ---------------+  |
    #     day of month (1 - 31) -----+  |  |
    #     hour (0 - 23) ----------+  |  |  |
    #     min (0 - 59) --------+  |  |  |  |
    #  ***sec (0 - 59) -----+  |  |  |  |  |
    #                       |  |  |  |  |  |
    #                       -  -  -  -  -  -
    # Dateblock Cron Entry: *  *  *  *  *  *
    # Cron Crontab Entry:      *  *  *  *  *
    
    # Unblock on the specific hours of 0 and 12:
    # ex: HH:00, HH:12
    $> dateblock --cron="0 0 00,12"
    

    You’ll notice in the above, I didn’t bother specifying the remaining cron fields… In this case they will assume the default of *. But you can feel free to specify a * for readability. The other thing to observe is the addition of the second column which isn’t present in a regular crontab entry. It’s rules are no different then what you’ve already learned from other fields.

    Testing

    Simply adding a –test (-t) switch to your dateblock entry will allow you to test the tool in a debugging mode to which it will present to you the current time followed by when it would have unblocked for had you not provided the –test (-t) switch. It’s a great way to calculate when the next processing time will be.

    Python Extension

    To handle scheduled processes for my websites, I created a python extension for dateblock. This allowed to extend it’s flexibility with other offline processing… consider the following example:

    from dateblock import dateblock
    while True:
        # /5 as first argument means unblock on the 5th second of each minute
        dateblock('/5')
        print 'begin processing ...'
        # your code here...
        # if you want, you can even report the next unblock time
        print 'Done processing; blocking until %s' % 
            dateblock('/5', block=False).strftime('%Y-%m-%d %H:%M:%S')
    

    You can also also access the drift as such:

    from dateblock import dateblock
    print 'Unblock at %s' % 
        dateblock('/5', drift=120, block=False).strftime('%Y-%m-%d %H:%M:%S')
    

    Finally the python extension allows you to pass in a datetime object as an argument for calculating a time based on another (and not the current time which is the default).

    from dateblock import dateblock
    from datetime import datetime
    from datetime import timedelta
    
    # 31 days ago
    reftime = datetime.now() - timedelta(days=31)
    
    print('Would blocking until %s' % 
        dateblock('/5', drift=120, block=False, )
          .strftime('%Y-%m-%d %H:%M:%S') + 
        " if time was %s" % reftime
          .strftime('%Y-%m-%d %H:%M:%S'))
    

    Things to Consider

    Just like sleep, dateblock uses SIGALARM to manage its wake up time. Therefore if your code relies heavily on SIGALARM for another purposes, dateblock may not be a solution for you since you could interrupt it’s reliability (though not likely). This really shouldn’t be a big concern because this exact same warning comes with the sleep libraries we’ve been using for years. But it does mean that sleep could interfere with dateblock just as dateblock could interfere with sleep if they were both used in separate threads.

    Dateblock vs Sleep
    Dateblock vs Sleep

    Why would I use dateblock over sleep?

    Scheduling is the key… If your program relies completely on sleep, then the only thing you’re accomplishing is cpu throttling (controlling unnecessary thrashing). This is approach is fine if you’re going to just retry connecting to an unresponsive server in ?? seconds. But what if timing becomes an important factor of your application? The dateblock tool ensures you only unblock at absolute times vs sleep which unblocks at relative times with respect to when it was called.

    Dateblock also allows your program to chronologically work in turn with other applications that may be on their own processing cycle. Such as something delivering data at the top of every hour. You may wish to have your program wake up 5 min after the top of each hour to perform the processing regardless of when your program was started.

    Datemath

    There isn’t as much to be said about Datemath; I personally never found a Linux/Unix tool that would allow me to script date/time calculations from the command line. For that reason, this tool exists.
    Here is an example of the tools function:

    # what time is it now?
    date +'%Y-%m-%d %H-%M-%S'
    # The above output was '2013-10-26 09-42-21' at the time of this blog
    # what time will it be 5 months and 3 days from now
    datemath --months=5 --days=3 --format='%Y-%m-%d %H-%M-%S'
    # the above output was '2014-03-29 09-42-21' at the time of this blog
    # and this makes sense... this is the calculation we want.
    

    The tool supports negative values for calculating into the past as well and will handle leap years in the calculations too.

    # what time is it now?
    date +'%Y-%m-%d %H-%M-%S'
    # The above output was '2013-10-26 09-45-45' at the time of this blog
    # What was the current date 753 days ago?
    datemath --days=-753 --format='%Y-%m-%d %H-%M-%S'
    # the above output was '2011-10-04 09-45-45' at the time of this blog
    # and this makes sense... this is the calculation we want.
    

    No Python Module For Datemath

    There is no python module for datemath because Python’s datetime and timedelta libraries already provide a fantastic solution for the same problem datemath solves…

    # Simple code example to show why it really isn't
    # necessary to port datemath to Python:
    from datetime import datetime
    from datetime import timedelta
    in_the_past = datetime.now() - timedelta(minutes=15)
    print '15 minutes ago: %s' % in_the_past
                                  .strftime('%Y-%m-%d %H:%M:%S')
    

    Just give me the goods

    No problem, below are the RPMS as well as their accompanied source packages:

    Package Download Description
    dateblock
    el6.rpm
    /
    el7.rpm
    The powerful (cron like) command line interface (CLI) tool.
    python-dateblock
    el6.rpm
    /
    el7.rpm
    The python extension for dateblock.
    datemath
    el6.rpm
    /
    el7.rpm
    The datemath command line interface tool.
    datetools
    el6.rpm
    /
    el7.rpm
    An optional package which includes licensing and information.

    Note: The source rpm can be obtained here which builds everything you see in the table above. It’s not required for the application to run, but might be useful for developers or those who want to inspect how I put the package together.

    No way, I’m building this myself; I don’t trust you

    That’s okay, I understand; here is how you can build it yourself:

    # Install 'mock' into your environment if you don't have it already
    # This step will require you to be the superuser (root) in your native
    # environment.
    yum install -y mock
    
    # Grant your normal every day user account access to the mock group
    # This step will also require you to be the root user.
    usermod -a -G mock YourNonRootUsername
    

    At this point it’s safe to change from the ‘root‘ user back to the user account you granted the mock group privileges to in the step above. We won’t need the root user again until the end of this tutorial when we install our built RPM.

    # Create an environment we can work in
    mkdir datetool-build
    
    # Change into our temporary working directory
    cd datetool-build
    
    curl -L --output datetools-0.8.1.tar.gz \
       https://github.com/caronc/datetools/archive/v0.8.1.tar.gz
    
    # Extract Spec File
    tar xfz datetools-0.8.1.tar.gz \
       datetools-0.8.1/datetools.spec \
          --strip-components=1
    
    # Initialize Mock Environment
    mock -v -r epel-6-x86_64 --init
    
    # Now install our dependencies
    mock -v -r epel-6-x86_64 --install boost-devel libstdc++-devel 
              glib-devel python-devel autoconf automake libtool
    
    # Copy in our downloaded content:
    mock -v -r epel-6-x86_64 --copyin datetools-0.8.1.tar.gz
       /builddir/build/SOURCES
    mock -v -r epel-6-x86_64 --copyin datetools.spec 
       /builddir/build/SPECS
    
    # Shell into our environment
    mock -v -r epel-6-x86_64 --shell
    
    # Change to our build directory
    cd builddir/build
    
    # Build our RPMS
    rpmbuild -ba SPECS/datetools.spec
    
    # we're now done with our mock environment for now; Press Ctrl-D to exit
    # or simply type exit on the command line of our virtual environment
    exit
    

    Future Considerations

    This is totally up in the air, at the moment the tool does everything I needed at the time. However I could see the following becoming a useful feature in the future:

    • Pass in a different time into both programs (instead of always working with the current time) (You can already do this with the dateblock python extension).
    • Have dateblock additionally take in a program and arguments as input to have it automatically execute the call to it when the scheduled time is reached. In addition to this, it means the dateblock tool would daemonize itself and run in the background on reoccurring schedules.
    • Add a devel package and create a shared library for C++ linking; perhaps the binary tools and extensions could link here too. Right now the library is just so small it’s really nothing to just include it statically as it is now.
    • Got an idea of your own? Pass it along! You can also submit a pull request to me on GitHub here.

    Credit

    Please note that this information took me several days to put together and test thoroughly. I may not blog often; but I want to re-assure the stability and testing I put into everything I intend share.

    If you like what you see and wish to copy and paste this information, please reference back to this blog post at the very least. It’s really all I ask.