preload
Using Rake to Generate Ocra exe’s Using Word Spellcheck from Ruby
Feb 16

First off, let me say that there is not an original thought in any of this code, since it has all been taken from a number of different articles out on the Internet. The Daemonizing code was taken from the Active State Code Recipes area.

One of my customers has a number of database servers that we would like to monitor and see what the state of the clusters are. The problem is that the clustat command — that used to be run-able by everyone in a lesser version of RHEL — is now only usable by root in RHEL v5.3!. Not wanting to give out root access to everyone, we decided that a quick little custom server that provided the output of the clustat command in XML format would do the trick. Then I just wrote a Ruby program to query all the Clustat XML servers and display the results in a readable format. If there is enough interest, I can post a public version of that program.

Here’s the code:

import sys
import os
import subprocess
import SocketServer
from socket import *
import fcntl
import struct

class CluStatHandler(SocketServer.BaseRequestHandler) :

   def handle(self) :
     p = subprocess.Popen(['clustat', '-x'], stdout=subprocess.PIPE)
     out, err = p.communicate()
     self.request.send(out)

def get_ip_address(ifname):

	s = socket(AF_INET, SOCK_STREAM)
	return inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24])

def main():

   HOST = get_ip_address('bond5')
   PORT = 2113

   server = SocketServer.TCPServer((HOST, PORT), CluStatHandler)
   server.serve_forever()

if __name__ == "__main__" :
   try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            sys.exit(0)
   except OSError, e:
        print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
        sys.exit(1)

   # decouple from parent environment
   os.chdir("/")
   os.setsid()
   os.umask(0) 

   # do second fork
   try:
       pid = os.fork()
       if pid > 0:
           # exit from second parent, print eventual PID before
           print "Daemon PID %d" % pid
           sys.exit(0)
   except OSError, e:
       print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
       sys.exit(1) 

   # start the daemon main loop
   main() 

The main() function sets up the SocketServer, which in turn calls the Handler to go run the clustat command in XML mode (the ‘-x’ parameter), and return the output. Since the servers that my customer has includes several network interfaces, I also had to figure out a way to start the server on the right interface. The get_ip_address function opens a socket on the specified interface, and then queries for its IP address.

A very handy tool to have in your bag of tricks!

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon

Leave a Reply