Select Page

Location aware Bind for RedHat 5.3

Previously I wrote about RPMs I built to GeoIP enable Bind using the original patches at http://www.caraytech.com/geodns/.

I have now refreshed this for the latest CentOS 5.3, the details of the patch, install instructions etc has not changed, read the previous article I wrote for the details, the new RPMs are below:

NOTE: When you install these RPMs you won’t see a /etc/named.conf being created and a few other odd things, these are bugs that exist in the CentOS provided RPMs, they do the same.

bind-9.3.4-10.P1geodns.el5.i386.rpm
bind-chroot-9.3.4-10.P1geodns.el5.i386.rpm
bind-devel-9.3.4-10.P1geodns.el5.i386.rpm
bind-libbind-devel-9.3.4-10.P1geodns.el5.i386.rpm
bind-libs-9.3.4-10.P1geodns.el5.i386.rpm
bind-utils-9.3.4-10.P1geodns.el5.i386.rpm
bind-sdb-9.3.4-10.P1geodns.el5.i386.rpm
caching-nameserver-9.3.4-10.P1geodns.el5.i386.rpm

bind-9.3.4-10.P1geodns.el5.x86_64.rpm
bind-chroot-9.3.4-10.P1geodns.el5.x86_64.rpm
bind-libbind-devel-9.3.4-10.P1geodns.el5.x86_64.rpm
bind-devel-9.3.4-10.P1geodns.el5.x86_64.rpm
bind-libs-9.3.4-10.P1geodns.el5.x86_64.rpm
bind-sdb-9.3.4-10.P1geodns.el5.x86_64.rpm
bind-utils-9.3.4-10.P1geodns.el5.x86_64.rpm
caching-nameserver-9.3.4-10.P1geodns.el5.x86_64.rpm

bind-9.3.4-10.P1geodns.el5.src.rpm

bind.spec-diff

Generic Stomp Client

I’ve been playing a bit with Stomp and ActiveMQ to help with some of my distributed management problems so needed a nice generic client for it.

I wrote one in Ruby, the code can be found here, you’ll need the Stomp rubygem to use it.

To use it set environment variables STOMP_USER and STOMP_PASSWORD and run it as below, you can also pass the user/pass to it as command line options but that will expose your password in ps output.

% stompclient --server your.server
AMQ> subscribe /topic/foo
Subscribing to /topic/foo
AMQ> /topic/foo bar
Sending 'bar' to /topic/foo
13:48:49:/topic/foo> bar
AMQ> detail
No longer showing details
AMQ> /topic/foo bar
Sending 'bar' to /topic/foo
bar


So it’s just a simple little frontend, it uses Ruby’s readline library which slows things down a bit as it does some blocking polling of input, if you’re sending loads of messages directed at this client it will seem a bit sluggish, unavoidable unfortunately.

flashpolicyd 2.0

I wrote a multi threaded server for Adobe Flash Policy requests, some background from Adobe:

Since policy files were first introduced, Flash Player has
recognized /crossdomain.xml as a master location for URL policy files. However, prior to version 9,0,115,0,
Flash Player did not recognize a fixed master location for socket policy files.
Flash Player 9,0,115,0 introduces a concept of socket master policy files,
which are served from the fixed TCP port number 843.

If your application currently requires /crossdomain.xml files to work properly while making Socket requests you should pay close attention to this, as of the current latest version of Flash Player your application will STOP working if you do not run a policy server.  You need to read this link and take appropriate action.

The servers that Adobe provides are not full featured so I set out to write one, the resulting server can be found on my wiki at http://www.devco.net/pubwiki/FlashPolicyd I will regularly post updates here.

A quick feature list:

  • Serves XML files on port 834 using the Adobe protocol
  • Multi Threaded for performance, but limited due to Ruby’s green threads, testing did not find this to be a problem though
  • Supports logging to a log file, debug mode can be toggled on the fly via Unix signals
  • Debugging information such as thread lists can be dumped using Unix signals
  • Adjustable frequency of status messages showing amount of connections, problematic ones and current connection counts

The tar ball includes the main daemon, a Red Hat compatible init script, a standard Nagios monitoring script and a Puppet module for installation on a Red Hat machine.

You need just the basic Ruby installed, I suggest Ruby newer than 1.8.1 due to bugs in the Logger class on 1.8.1.

Version 2 can be downloaded at http://www.devco.net/code/flashpolicyd-2.0.tgz

Adventures with Ruby

Some more about my continuing experiences with ruby, in my last post I said

the language does what you’d expect and as you’ll see in my next post
spending a week with it on and off is enough to write a capable multi
threaded socket server.

As it turns out I quickly lived to regret saying that.  Soon after I hit publish I started running into some problems with the very same socket server.

A bit of background, Adobe has made a change to how things work moving away from their previous crossdomain.xml file served over HTTP for cross domain authorization to a new model that requires you to run a special TCP server on port 834 serving up XML over a special protocol.  I won’t go into how brain dead I think this is, suffice to say I needed to run one of those for a client.  Adobe of course does provide a server for this, but it has some issues, I chose the simplest of their examples – Perl under xinetd – and quickly discovered that it has no concept of timeouts, or anything that doesn’t speak it’s protocol.  The end result is that you just end up with a ever growing number of perl stuff running waiting around for ages.

I took this as a challenge to write something real under Ruby using it as a learning experience as well, so set out to write a multi threaded server for this.  At first glance it looks almost laughably trivial:  The Ruby STL includes GServer – a very nice class that does the hard work of thread management for you, you just inherit from it and supply the logic for your protocol and let it do the rest, awesome.

I wrote this, put in logging, options parsing and all the various bits I needed, tested it locally – 10 concurrent workers doing 200,000 requests and it served it in no time at all with limited CPU impact. I then wrote RC scripts, config files and all that and deployed it at my client.

Real soon after deploying it I noticed the wheels came off a bit.  I, out of curiosity, put in some regular logging that would print lines like:

Jun 23 08:23:37 xmpp1 flashpolicyd[7610]: Had 10042 clients of which 285 were bogus. Uptime 0 days 14 hours 2 min. 23 client(s) connected now.

Note in that line how it claims to have 23 connections at present? That’s complete b/s, I added the ability to dump actual created threads and there just weren’t enough threads for 23 clients and the TCP stack agreed…Turns out gserver has issues handling bad network connections – my clients are over GPRS, Modems, and all sorts – and it seems threads die without GServer removing them from it’s list of active connections.

This is a small problem except that GServer uses the connection count towards figuring out if you’ve hit its max connections setting.  So while I could just set that to some huge figure, it does indicate theres a memory leak – array grows for ever.  Not to mention it just leaving me with a bad taste in my mouth over the quality of my new and improved solution.

Naturally I gave up on GServer I didn’t feel like installing all sorts of Gems on the servers so figured I’ll just write my own thread handling.  While it’s not trivial its by far not the most complex thing I’ve ever done.  Happy in this case with a bit of wheel reinventing for the sake of learning. 

I chose to use the Ruby STL Logger Library for logging and even added the ability to alter log level on the fly through sending signals to the process, very nice and I were able to re-use much of the option parsing code etc from my previous attempt so this only took a few hours.

I did the development on my Mac using TextMate – the really kick arse Mac text editor that has nice Ruby support – the Mac is on Ruby 1.8.6.  I intended to run this on RHEL 4 and 5, they have Ruby 1.8.1 and 1.8.5 respectively, so I was really setting myself up for problems all of my own making.

Turn out Logger has a bug, fixed here in revision 6262 without any useful svn log, that only bit me on the RHEL 4 machine.  It would open the initial log correctly with line buffering enabled, but once it rotates the log the new log and subsequent ones wouldn’t have line buffering.  Which in my case means I get log lines showing up once every 5 hours!

This sux a lot, and it’s unlikely that RedHat will backport such a small little thing, and since RedHat 4 will be here till 2012 I guess I’ll just have to patch it myself or move to RedHat 5 on this server, something I planned to do anyway.

So something that should have been fairly trivial has turned into a bit of a pain, not really Ruby’s fault that I am using 1.8.1 when much newer versions are out, but not nice regardless.  At the end of it all my flash server is working really well and handling clients perfectly with no leaking or anything bad

I, [2008-06-26T23:02:36.607920 #22532]  INFO — : -604398464: Had 15611 clients of which 423 were bogus. Uptime 0 days 13 hours 41 min. 0 connection(s) in use now.

Those bogus clients are ones that timeout or just otherwise never complete a request, these were the ones that would trip up GServer in the past.

Once I’ve done documenting it I’ll be releasing the flash server here

New programming language of choice – Ruby

I have fallen out of love with Perl some time ago, I cannot point to one specific thing about it that put me off, I think it’s just a general un-sexyness about it now.

I have been doing some Java and PHP development that was very OOP heavy and have been doing OO coding since school in the Pascal 6 days, I find it’s almost become the natural way of thinking when thinking about problems.  OO though does not generally translate well to scripting tasks which is what I generally use Perl for so it’s not been too bad.

I am however a Perl 4 coder, Perl 5’s OO syntax really puts me off, I’ve used it, have written some pluggable systems in the past where plugins were Perl Ojbects, but I’ve never liked them…with Perl 6 coming (or not) having to relearn a large chunk of Perl is becoming inevitable so I figured I might as well switch.  This is a decision I’ve made ages ago.

I could however not decide on where to go from here?  There are several contenders out there for scripting languages thesedays and weighing up their merits is a time consuming business for sure. 

So along came Puppet, I am doing massive amount of Puppet work now for 3 clients and my own systems.  Puppet is extendible using Ruby code as it’s written in Ruby itself so I think the decision has been made.  I still have no interest in using it on the web, but for scripting I’ve found my new love.

I wont go into long examples and discussions about the Ruby Language, but I’ll say I have learned in the space of a week on the train and have found it incredibly friendly and usable.  The Core and Standard Libraries are rich and modern including out of the box XML, YAML, SOAP, XML-RPC and very powerful networking libraries such as GServer.

Documentation has been generally good but I did buy a copy of Beginning Ruby From Novice to Professional which I believe is a awesome introduction to the language, I followed that up with The Ruby Way 2nd Edition and Ruby Cookbook.

Beginning Ruby takes you on a gentle stroll through a lot of the major features of the language, shows you Strings, Arrays, Numbers, OO, Threads, Sockets and RPC.  It doesn’t go too deep into any of these subjects, for instance it does not show much about Mutexes or any locking methods inside threads, but it puts down a very solid framework to go from.

The Ruby Way is more task based and goes into more detail about the tasks, returning to the threads example, The Ruby Way discusses Mutexes and shows some of the concurrency issues you can expect, it has a whole chapter devoted to Threading. 

These two books more than put you in a position to quickly and effectively use any of the online documentation resources so I would greatly recommend this combination.

I have skimmed through the Cookbook, it’s your typical O’Reilly Cookbook – I mostly bought it because I have 6 or 7 other Cookbook titles and they are all invaluable, I spent an hour with it so far and it looks to live up to this reputation.

If you’ve programmed before in any serious way picking up Ruby should be a walk in the park, the syntax is great, the language does what you’d expect and as you’ll see in my next post spending a week with it on and off is enough to write a capable multi threaded socket server.

Rework of puppet facts for /etc/facts.txt

Previously I blogged a custom fact that reads /etc/facts.txt to build up some custom facts for use in Puppet manifests, well I’ve since learned a thing or two about Ruby and have improved the code, new code below:


if File.exists?(“/etc/facts.txt”)
   File.open(“/etc/facts.txt”).each do |line|
      var = nil
      value = nil

      var = $1 and val = $2 if line =~ /^(.+)=(.+)$/

      if var != nil && val != nil
         Facter.add(var) do
            setcode { val }
         end
      end
   end
end

As I mentioned previously I knew the code was horrible and had a whole redundant loop in it but couldn’t get it going otherwise.  The big change is in choice of variable names to use inside the setcode, sees value must be a reserved word or something, so now the code is much cleaner.