Sierra Wireless USB881 3G Modem WAN on WRTSL54GS via OpenWrt Kamikaze

As noted in a previous post National Shame: Swaths of Non-Rural US without Broadband; Time for Re-Divestiture, there is no Cable Modem service or DSL in my neighborhood. Up until a few  months ago, I did have a pretty nice point to point Dual Raido Full Duplex 802.11n connection that could do about 12Mbps symetrical. The only reason I had that link in the first place was because I had been in the wireless and ISP business and knew someone who would hook me up. Unfortunately the friend who supplied it to me went had to shut down his network due to Depression 2.0.

So the only way I’ve been able to have an Internet connection at home is to use a 3G wireless modem. I had an AT&T / Sierra Wireless USB881 3G modem that my brother had given to me when I was sick in a hospital that didn’t have any Internet (and that hospital wasn’t in some 3rd world nation, it was in downtown San Francisco! More National-Shame).

Since I wanted to supply my whole house with always on connectivity I needed to hook the 3G modem to a router. And being the cheapskate / hacker I am I decided I needed to use one of the Linksys WRTSL54GS routers that happen to have USB ports on them to do it.Turned out that there isn’t too much documenation on doing this, particularly if you want to use the Web GUI that comes with OpenWrt.

The latest version of OpenWrt (Kamikaze 8.09) along with the packages that go along with it has everything needed to make the WRTSL54GS work with many of the 3G USB modems including the Sierra Wireless 881. Th WRTSL54GS is based on the Broadcom BCM47XX chipset. This determines which version of the OpenWrt firmware to download and install.

If you are installing on top of the standard Linksys firmware, you’ll want to install rom the brcm47xx directory and use the WrtSL54GS specific file: openwrt-wrtsl54gs-squashfs.bin. If you have already installed OpenWrt and want to update or start from scratch, you would go to the same brcm47xx directory and download the generic openwrt-brcm47xx-squashfs.trx file .(You’ll probably want both in case you have a problem after you install OpenWrt firmware. Note that I won’t go into how to restore the original Linksys firmware. There are instructions to do this, I never did).

Hook up your computer (Mac, Linux or Legacy Windows) to the router via ethernet to the router’s LAN port (not the WAN port). Make sure that you still have some kind of Internet connection to your computer.

If you are using the standard Linksys software, go to the firmware upgrade page of the Web GUI and load the openwrt-wrtsl54gs-squashfs.bin that you should have downloaded by now. Don’t disturb the router while it loads. Wait till the LEDs on the front panel stop blinking and then try to reconnect to the router via http://192.168.1.1 (If you don’t know how to do this step, forget about doing the rest of this how-to except see the note at the botom to just buy a commercial router that can do utilize 3G modems out of the box.)

At this point you should see something like:

OpenWrt Login

OpenWrt Login

You can log in with any password at this point and you should see:

OpenWrt Greeting Page

OpenWrt Greeting Page

Click on the “Administration” Menu Bar Item to get to the full Admin menu from where you can select on “Network” so you can activate the ethernet WAN:

Network Select

Network Select

You will then want to enable the eth1 as the WAN interface so that you can plug the router into an ethernet that has an Internet connection. Once you clicked to enable wan/eth1, then click on “Save & Apply”:

Enable Eth1 WAN

Enable Eth1 WAN

Use the OpenWrt Opakgs system to download the kernel drivers for USB and package for doing PPP scripts by selecting System->Software:

Select System Software

Select System Software

And then click on the “Update ackage lists” link:

Update Package Lists Link

Update Package Lists Link

If you get “Error (Code 256), it means your router is not properly hooked up to an Internet connection on the WAN port.

I had to use my Mac in Internet Sharing mode in order to have Internet both to my Mac and to the router while setting it up since my only Internet connection was he 3G modem. To turn on Internet Sharing on the Mac (once you had the 3G Modem connected to the Mac) is to go to System Preferences-Sharing and turn on Internet Sharing:

Macintosh Internet Sharing

Enabling Internet Sharing on the Mac

For some reason the Mac Internet Sharing and the OpenWrt/Linksys Ethernet WAN port would not get the Router IP Address via DHCP, so I had to manually set the router’s WAN interface IP addresses. I also had to Add DNS Server as an “Additional Field”. Here’s how I had set up the WAN / Eth1 Interface on the OpenWrt Network->Interfaces->WAN page. You probably don’t have to do this if you have the router hooked up to some other Internet source:

Enabling Internet Sharing on the Mac

Configuring OpenWRT WAN to used a fixed IP address. You shouldn't normally have to do this.

Once you get the temporary Internet connection to your router going, you’ll want to select:

kmod-usb-core
kmod-usb-serial
kmod-usb-ohci
kmod-usb-serial-sierrawireless
comgt

I also installed kmod-usb2

You do that by selecting the appropriate items:

ksmod

and then scrolling to the bottom and selecting “Perform Actions:

finishupdate

Then reboot or power cycle the router.

Once it comes up, you can now reconfigure the router WAN port to use the 3G Modem. First go to the WAN configuration page in order to delete the old ETH1 WAN interfaces:

Network WAN Interface Select

Network WAN Interface Select

You’ll want to delete the current WAN entry by clicking on the “Remove entry” button and then click on “Save & Apply” at the bottom of the page:

Remove WAN Entry

Remove WAN Entry

Then create a new WAN interface by clicking on “Add Entry”:

Add WAN Entry

Add WAN Entry

Then in the new entry select UMTS/3G as the protocol

protocol

Fill in using the appropriate info for your carrier. I got my info by looking at the Macintosh System-Preferences->Network-Mini Card->Advanced:

network-modem

You should now plug your 3G modem into the router. Then set the  OpenWrt Network->Interfaces->WAN page as shown below (with your own proper info for APN, Username, password and optionally PIN code), when done hit “Save & Apply”:

final-wan

You probably need to reboot at this point. When it comes up, you should be working with 3G!

NOTE: For those of you who just want to have a 3G conection thru a router you are probably better off buying a CradlePoint router. You can get nice package deals from the 3GStore (I have no affiliation with them, its just the place I would probably have bought one myself).

Updating RabbitMQ and RabbitMQ-Stomp to RabbitMQ 1.5.3

I noticed that the rabbitmq-stomp had stopped working on my servers after a reboot. The servers were using the Ubuntu debian package of rabbitmq and had been updgraded to RabbitMQ 1.5.3 and stomp had not since I was manually installing rabbitmq-stomp from the mercurial repositories (cause I could not find any ubuntu packages for rabbitmq-stomp).

If you used something similar to the install process described in my earlier Deploying RabbitMQ and Stomp on Ubuntu you can do the following:

Update RabbitMQ server

For Ubuntu

sudo apt-get update
sudo apt-get upgrade rabbitmq-server

For Macintosh Leopard

Need to update the rabbitmq-codegen and rabbitmq-server using mercurial:

cd /usr/lib/erlang/lib/rabbitmq-codegen
hg pull
hg update rabbitmq_v1_5_3
cd /usr/lib/erlang/lib/rabbitmq-server
hg pull
hg update rabbitmq_v1_5_3

For both Ubuntu and Leopard

Update RabbitMQ-Stomp
cd /usr/lib/erlang/lib/rabbitmq-stomp
hg pull
hg update rabbitmq_v1_5_3

You can see what release tags are available after th hg pull via the command:

hg tags

Make sure there isn’t already an /etc/rabbitmq/rabbitmq.conf . If there is merge /etc/default/rabbitmq into /etc/rabbitmq/rabbitmq.conf (/opt/local/etc/ instead of /etc if you are using MacPorts)

Otherwise just move it:

mv /etc/default/rabbitmq /etc/rabbitmq/rabbitmq.conf

Rebuild the rabbitmq-stomp programs

Still in /usr/lib/erlang/lib/rabbitmq-stomp

For Ubuntu

make RABBIT_SERVER_SOURCE_ROOT=../rabbitmq_server-1.5.3 all
/etc/init.d/rabbitmq-server restart

For Macintosh Leopard

make all

If you updated rabbitmq-server make sure it builds and run

cd /usr/lib/erlang/lib/rabbitmq-server
make -j run

If it starts ok you can quit and then from now on run it by issuing the command:

/opt/local/lib/erlang/lib/rabbitmq-server/scripts/rabbitmq-server -detached

Installing Apache Thrift on Ubuntu and Leopard

The instructions for installing the Apache Thrift on the Wiki missed a few key things in terms of installing on Ubuntu (8.04 in my case) and Macintosh OS X Leopard (10.5.6).

Gitting the latest source

For instance they show you how to get the latest via SVN or a snapshop via wget. But the wget actually gets it from a git repository, but they don’t tell you how to directly git it! Which is:

git clone git://git.thrift-rpc.org/thrift.git

That will create a a source distribution of thrift in a directory called thrift.

The git repository is where the developers are really working according to the Developers Wiki on the GitRepository. There is also a copy on github.

Requirements

The relevant requirements as stated by the wiki are:

GNU build tools: autoconf 2.59+ (2.60+ recommended), automake 1.9+, libtool 1.5.24+
boost 1.34.0+
g++ 3.3.5+
pkgconfig (Use MacPorts for Mac OS X)
lex and yacc (developed primarily with flex and bison)

Well, for Ubuntu it wasn’t quite clear what was really required. The GettingUbuntuPackages wiki page listed only a few of the required packages. Max Luebbe has a blog page that has a more in depth list:

apt-get install libboost-dev libevent-dev python-dev automake pkg-config libtool flex bison sun-java5-jdk

We already had Sun Java6 installed and that worked fine, so I didn’t include sun-java5-jdk. But we didn’t have g++ installed, so also do:

apt-get install g++

Confusingly, the ./configure did not fail saying there was no g++ but failed by saying there was no boost. It took a while to figure out it was actually not finding boost because it could not compile the little configure test script that was used to detect if boost was installed or not!

So the actual apt-get used on our ubuntu 8.04 server was:

sudo apt-get install g++ libboost-dev libevent-dev python-dev automake pkg-config libtool flex bison

On the Mac you can use the MacPorts to install the required packages.. Max also had a good page on Installing Apache Thrift on Mac OS X 10.5 Leopard that doesn’t require MacPorts.

sudo port selfupdate
sudo port install boost
sudo port install pkgconfig

The pkg.m4 workaround

As noted in the Thrift Wiki FAQ,the ./configure command may generate an error like:

./configure: line 21183: syntax error near unexpected token `MONO,'
./configure: line 21183: `  PKG_CHECK_MODULES(MONO, mono >= 1.2.6, have_mono=yes, have_mono=no)'

This will happen if there is no pkg.m4 file in the aclocal directory of the thrift source tree. For the Macintosh, install pkgconfig via MacPorts and copy /opt/local/share/aclocal to aclocal (assuming you are in the thrift source distro):

cp /opt/local/share/aclocal/pkg.m4 aclocal

This is not necessary in ubuntu if you have installed pkgconfig there.

Actual Build and Installation

In the Thrift directory run:

./bootstrap.sh

on the Mac if boost was installed with MacPorts use the following (If you manually installed boost elsewhere use that path instead):

./configure --with-boost=/opt/local

on Ubunto you can just say”

./configure

On both Mac and Ubuntu:

make
sudo make install

If you want any of the bindings for different languages, cd into lib and there are directories for each language. Its not always clear what to do to build them. For the ruby one what I ended up doing was:

cd lib/rb
sudo ruby setup.rb

Next step

Figure out how to test and use Thrift!

Cross Domain RESTful AJAX with jQuery and Rails 2.2.2

Flinn Mueller aka actsasflinn wrote an blog post Cross domain RESTful JSON-P with Rails back in July. There he showed how to monkeypatch Rails to allow json-p to do all the REST verbs even when going across domains. He also showed how to make the json-p calls with jquery. A very nice solution that we take advantage of in one of our apps. The only problem we had was that it stopped working when we upgraded to Rails 2.2.2.

There are other issues using this technique. To quote Flinn:

Achtung! Monkey patching with the above will expose your create method without using an actual post. Imho no big deal, others might be more cautious (CAPTCHAis always an option), ymmv.

See his original article for details on how to use it generally. 

The problem with the monkeypatch that he wrote up is that Rails 2.2.2 changed the function that was monkeypatched so the patch stopped working. Below is code that will work on both pre and post 2.2.2 Rails:

module ActionController
  class AbstractRequest

    def request_method

      if Rails::VERSION::STRING < "2.2.2"

        @request_method ||= begin

          method = (parameters[:_method].blank? ? @env['REQUEST_METHOD'] : parameters[:_method].to_s).downcase

          if ACCEPTED_HTTP_METHODS.include?(method)

            method.to_sym

          else

            raise UnknownHttpMethod, "#{method}, accepted HTTP methods are #{ACCEPTED_HTTP_METHODS.to_a.to_sentence}"

          end

        end

      else

        method = @env['REQUEST_METHOD']

        method = parameters[:_method] unless parameters[:_method].blank?

        HTTP_METHOD_LOOKUP[method] || raise(UnknownHttpMethod, "#{method}, accepted HTTP methods are #{HTTP_METHODS.to_sentence}")
      end

    end

  end
end

Installing PoolParty on Mac OS X and Ubuntu

In my search for the ultimate open source tool for deploying our service onto the “Clouds” I am now trying the new PoolParty. (Though I’m finding that the github wiki for PoolParty is a better reference).

Its got what seems to be a nice clean Ruby based Domain Specific Language (DSL) and set of unix shell commands for automating the deployment and management of scalable apps in the cloud.  I’ll have to play with it to see how real it is. But so far it at least seems easier than raw puppet.

This post will mainly document how I installed PoolParty and got it to basically work. Its still a pretty early release so there were a few issues. Thanks to ausser and fairchild_ on the #PoolParty IRC Channel for some help.

Some Prerequisites

This is not an exhaustive list, but I found that the following gems needed to be installed:

  • echoe
  • newgem
  • rake
  • activesupport
  • hoe
  • logging
  • ruby2ruby

Maybe Not Install from Gem

You can theoretically install from git gems:

gem install --source http://gems.github.com auser-poolparty

But I found that the gem that was there at the instant I was trying had some problems. In particular it included a file (bin/server-query-agent) in the gemspec that wasn’t in the actual gem so the gem install failed.

Install from Git

So I went with using the git repository. Plus I figure I’m going to be living on the edge with this for a while so might as well be prepared.

So instead to get it from git cd to someplace you want to install the source tree to PoolParty and:

git clone git://github.com/auser/poolparty.git

You can then try the following which will clean and rebuild the gem and then install it locally:

rake local_deploy

If you want to just build the gem and not install it locally:

rake gem

In ether case there will also be a copy of the gem in pkg/poolparty-0.2.94.gem
(Where the 0.2.94 may be different based on the version at the time of the git clone)

Issue while installing from Git

I had a similar problem with the git install as I did with the gem. It looked like the Manifest.txt and poolparty.gemspec also had bin/server-query-agent in them and it wasn’t in the distro. I asked on the IRC channel and was told that server-query-agent shouldn’t be there. The suggestion was to remove Manifest.txt (and I presumed poolparty.gemspec) and rebuild things using rake.

So I did remove the two files and eventually did:

rake gemspec

Then edited the generated Manifest.txt and poolparty.gemspec to remove all references to dirs / files that start with .git since the rake process just included them as part of what should be included.

Then I ran:

rake local_deploy

as described earlier.

I happened to build this all on the Mac (Leopard) and then just copied the gem to an Ubuntu 8.10 system and did a gem install:

sudo gem instal  poolparty-0.2.94.gem

And it installed fine, recursively installing all gem dependencies.

Conclusion

Next post will be on using PoolParty to get something going on Amazon EC2.

HOWTO: Install iClassify on Ubuntu and Mac OS X Leopard

Update:

The folks who developed iClassify have come out with a total framework that is an alternative to iClassify/Puppet called opscode-chef. I will be looking into that soon and not do anymore work with iClassify (unless Chef turns out to suck or something, but at first glance it looks pretty good!).

 

iClassify Description

From the creator’s of iClassify HJK Solutions website:

iClassify allows for the easy registration and classification of nodes. Most of the time, a node is a server. With iClassify:

  • Nodes register themselves with a central web service, including reporting Facter facts.
  • You can then tag those nodes, and add manual attributes.
  • You can search the nodes with a full text search engine
  • You can write recipies for icagent to auto-classify and auto-attribute your nodes.
  • You can tie it in to Puppet as an external node classification tool, enabling you to easily configure hundreds of nodes at a time.
  • You can tie it in to Capistrano, and have a dynamic ad-hoc configuration tool.

We are considering using it along with Puppet and Amazon EC2 for deployment of some of our infrastructure.

Install iClassify

Original Instructions are at HJK Solutions. Some of the following quotes liberally from that site but adds the things I learnt along the way as well as how to do it on a Mac.

Prerequisites

Ruby Gems

  • Rails 2.0.2
  • Rake
  • Builder
  • UUID Tools
  • Mongrel
  • Highline
  • Net-LDAP
sudo gem rails rake install builder uuidtools mongrel ruby-net-ldap

Non-Gems

  • MySQL
  • Factor
  • Git
  • Java
  • Runit
  • Mongrel Runit

Configure MySQL

The folks at HJK say they use MySQL and it should work with PostgreSQL and sqlite3 as well. We went wtih MySQL.
First create the database iclassify_production

mysqladmin -u root -p  create iclassify_production

Grant it the correct privleges (set yourpass to the password you want to use):

mysql -u root -p iclassify_production
mysql> GRANT ALL ON iclassify_production.* TO 'iclassify'@'localhost' IDENTIFIED BY 'yourpass';

You should have the ruby mysql gem installed

sudo gem install mysql

on the Macintosh OS X Leopard I had to say:

sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

Git

You can install from ubuntu packages

sudo apt-get install git-core

On the Mac Download and install the git OS X package for the Mac from Git OSX Installer on Google Code or

port -uR install git-core 

Java

Java is needed for the Solr package that is bundled in the iClassify distro. It can be installed via apt and/or downloaded from the Sun site. Java is already installed on Mac OS X. 

Runit

Runit is an alternative / addition to the standard /etc/init.d “systemV” init system. I guess the HJK folks like it and seem to have dependencies on it. They say it should work without it, but I haven’t tried putting this together without the Runit/Mongrel_runit dependencies yet.

Some good info and tips on setting up / running runit on various systems can be found at runit - a UNIX init scheme with service supervision

Runit can be safely installed with apt. It will not replace the standard init system.:

sudo apt-get install runit

For the Mac:

port install runit

On the Mac, you’ll have to start the runit system with the command

sudo launchctl load -w /Library/LaunchDaemons/org.macports.runit.plist

iClassify itself

In a directory you want to keep the source of iclassify:

git clone git://git.hjksolutions.com/iclassify iclassify
cd iclassify 

You need to know where you want to install the actual working rails app of iclassify and what user id/group you want to run it under.

The default location and the one we’ll use on Ubuntu is /srv/iclassify and the user id/group is usually the same as the one that runs the apache web services (www-data). Change yourpass to the password used for the iclassify user in MySQL.

sudo rake iclassify:install ICBASE=/srv/iclassify ICUSER=www-data ICGROUP=www-data DBUSER=iclassify DBPASS=yourpass

For the Macintosh:

sudo rake iclassify:install ICBASE=/usr/local/iclassify ICUSER=_www ICGROUP=_www DBUSER=iclassify DBPASS=yourpass

This will create a new iClassify instance in /srv/iclassify, set the right ownership to run iClassify, and set run the migrations to prepare your database instance. I found that I had to run this as root so that it will create the directories properly.

You can test that the iClassify rails app was installed properly by testing it with the built in Rails Server (on the Mac use the /usr/local/iclassify directory and _www user id):

$ cd /srv/iclassify
$ sudo -u www-data env RAILS_ENV=production ./script/server
=> Booting Mongrel (use 'script/server webrick' to force WEBrick)
=> Rails application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with production environment...
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready.  TERM => stop.  USR2 => restart.  INT => stop (no restart).
** Rails signals registered.  HUP => reload (without restart).  It might not work well.
** Mongrel available at 0.0.0.0:3000
** Use CTRL-C to stop.

You can now point your browser to the local instance of iClassify at http://localhost:3000, hit CTRL-C when you are done to terminate the script/server.

Mongrel Runit

You can download the mongrel_runit gem from the Mongrel Runit page at HJK

Then install it with (on the Mac you’ll have to use the /usr/local/iclassify directory instead of /src/iclassify):

For some reason the HJK folks set their runit_service_dir to be /var/service but the runit ubuntu package puts it in /etc/service. So you might want to edit /srv/iclassify/examples/mongrel_runit_iclassify.yml and set runit_service_dir to /etc/service. You can also change the number of mongrels you want to run in that file. Similarly, the DarwinPorts port install of runit expects it to be in /opt/local/var/service. You can change the /srv/iclassify/examples/mongrel_runit_iclassify.yml  or you can make a symbolic link from /opt/local/var/service to /var/service

sudo gem install mongrel_runit-0.2.1.gem
sudo mkdir /etc/mongrel_runit
sudo cp /srv/iclassify/examples/mongrel_runit_iclassify.yml /etc/mongrel_runit/iclassify.yml
sudo mongrel_runit -c /etc/mongrel_runit/iclassify.yml create 

You should be able to then run the command

mongrel_runit -v status -c /etc/mongrel_runit/iclassify.yml

and see something like (there should be as many lines as you have set for mongrel servers. I changed the iclassify.yml from 5 to 3):

5000: true: run: /etc/sv/mongrel-iclassify-5000: (pid 4403) 119s; run: log: (pid 4402) 119s
5001: true: run: /etc/sv/mongrel-iclassify-5001: (pid 4401) 119s; run: log: (pid 4400) 119s
5002: true: run: /etc/sv/mongrel-iclassify-5002: (pid 4399) 119s; run: log: (pid 4398) 119s

Solr

First create some directories that will be needed for Solr to run its index as the www user (on the Mac replace /srv with /usr/local).

sudo mkdir -p /srv/iclassify/vendor/plugins/acts_as_solr/solr/solr/data/production
sudo chown -R www-data:www-data /srv/iclassify/vendor/plugins/acts_as_solr/solr/solr/data/

You can then test it with the command:

sudo -u www-data env RAILS_ENV=production rake solr:start

It should start and run with no errors.

You can stop it if you want with:

sudo -u www-data env RAILS_ENV=production rake solr:stop

Then set up runit to run it automatically (use /usr/local instead of /srv on the Mac and /var/service or whatevever your system uses for runit service dir if not on ubuntu and using /etc/service):

sudo mkdir -p /etc/sv/iclassify-solr/log/main
sudo cp /srv/iclassify/examples/solr-run /etc/sv/iclassify-solr/run
sudo cp /srv/iclassify/examples/solr-log /etc/sv/iclassify-solr/log/run
sudo chmod a+x /etc/sv/iclassify-solr/run /etc/sv/iclassify-solr/log/run

The following will start the solr process immediately as well as in the future reboots

sudo ln -s /etc/sv/iclassify-solr /etc/service 

Apache

iClassify is best configured as a virtual host under Apache, running with SSL and mod_proxy_balancer. Follow the proper steps for configuring your platforms Apache to use mod_ssl,  mod_proxy_balance r and mod_rewrite. Create a virtual host config which resembles the following (works with Mac and Ubuntu, On the Mac just change the refs to /srv to /usr/local and the EXAMPLE.com to your domain in any case)

<VirtualHost *:443>
  DocumentRoot /srv/iclassify/public
  LimitRequestBody 8388608
  ServerName iclassify.EXAMPLE.COM
  ServerAlias iclassify
  <Directory />
    Options FollowSymLinks
    AllowOverride None
  </Directory>

  <Location /server-status>
    SetHandler server-status
    Order Deny,Allow
    Deny from all
    Allow from 127.0.0.1 192.168.0.0/255.255.0.0
  </Location>

  <Proxy balancer://iclassify>
    BalancerMember http://localhost:5000
    BalancerMember http://localhost:5001
    BalancerMember http://localhost:5002
    BalancerMember http://localhost:5003
  </Proxy>

  LogLevel info
  ErrorLog /var/log/apache2/iclassify-error.log
  CustomLog /var/log/apache2/iclassify-access.log combined

  RewriteEngine On
  RewriteLog /var/log/apache2/iclassify-rewrite.log
  RewriteLogLevel 0
  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
  RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
  RewriteCond %{SCRIPT_FILENAME} !maintenance.html
  RewriteRule ^.*$ /system/maintenance.html [L]
  RewriteRule ^/server-status$ /server-status$1 [L]

  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
  RequestHeader set X_FORWARDED_PROTO 'https'
  RewriteRule ^/(.*)$ balancer://iclassify%{REQUEST_URI} [P,QSA,L]
  ProxyPassReverse / balancer://iclassify
  SetEnv proxy-nokeepalive 1

  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/iclassify.crt
  SSLCertificateKeyFile /etc/apache2/ssl/iclassify.key

  BrowserMatch ".*MSIE.*" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0
</VirtualHost>

<VirtualHost *:80>
  DocumentRoot /srv/iclassify/public
  LimitRequestBody 8388608
  ServerName iclassify.EXAMPLE.COM
  ServerAlias iclassify

  RewriteEngine On
  RewriteCond %{HTTPS} !=on
  RewriteRule ^/(.*) https://%{SERVER_NAME}/ [R,L]
</VirtualHost>

Basic instructions for setting up ssl certificates can be found at Just Samuels blog post HOWTO: Create a self-signed (wildcard) SSL certificate

Take the resulting hosts.cert and copy it to /etc/apache2/ssl/iclassify.crt and hosts.key to /etc/apache2/ssl/iclassify.key (or whereever you put your ssl keys and make sure the SSLCertificateKeyFile and SSLCertificateFile are set the same in your vhosts conf file.

Conclusion

That should get you up and running with iClassify. In a future post I will install Puppet and then figure out how to use these together to deploy to Amazon EC2.

Hadoop, HDFS and Hbase on Ubuntu & Macintosh Leopard

Hadoop and Map / Reduce are all the rage now days, so we figure we should be using it too.

Hbase is an implementation of Google’s Bigtable. Its built on top of the Hadoop File System (HDFS).

Its trivial to install it as a standalone on top of a filesystem, but I had some difficulty getting it working on top of HDFS in the “Pseudo-Distributed” mode.

Follow the Instructions

I set up Hadoop with no problems following the instructions on the Hadoop sitefor Pseudo-Distributed Operation which runs Hbase on top of HDFS but everything runs on one server (I.E. Its configured pretty much like a cluster but all the pieces are on the same server). Another helpful set of instructions are at Running Hadoop On Ubuntu Linux (Single-Node Cluster).

I followed the HBase installation instructions also for Pseudo-Distributed Operation.

A few things to be aware of:

  • Make sure that the Hadoop version and the Hbase major version numbers are the same
    (I used Hadoop 0.18.2 and Hbase 0.18.1)
  • Make sure that the Hadoop, Hbase trees as well as the directories and files that hold the hdfs filesystem are owned by hadoop:hadoop (You have to create the user and group)
  • No need to disable ipv6 as some sites said

You can download the Hadoop tar file from http://www.apache.org/dyn/closer.cgi/hadoop/core/ and the Hbase tar file from http://www.apache.org/dyn/closer.cgi/hadoop/hbase/
They are also available as git repositories via:

git clone git://git.apache.org/hadoop.git
git clone git://git.apache.org/hbase.git

You can track a particular branch with the command (We’re stuck at hadoop 0.19.1 / hbase 0.19.0:

cd hadoop
git branch --track release-0.19.1 origin/tags/release-0.19.1
git checkout release-0.19.1
cd ../hbase
git branch --track 0.19.0 origin/tags/0.19.0
git checkout 0.19.0

Then in each directory build things. As far as I can tell you just need to use the default ant build. But you can build the jar also:

cd ../hadoop
ant
ant jar
cd ../hbase
ant
ant jar

Biggest Problem I Had

The thing that took the longest time to get right was when I wanted to access Hbase from other hosts. You would think you could put the DNS Fully Qualified Domain Name (FQDN) in the config file. Turns out that by default, the Hadoop tools don’t seem to use the host’s DNS resolver and just what is in /etc/hosts (as far as I can tell). So you have to use the IP address in the config file.

I believe there are ways to configure around this but I haven’t found it yet.

Configuration Examples

File System Layout

I untarred the distributions into /usr/local/pkgs and made symbolic links to /usr/local/hadoop and /usr/local/hbase as well as created the directory where Hadoop/HDFS will use for storage.

For Ubuntu:

sudo addgroup hadoop
sudo adduser --ingroup hadoop hadoop

For Mac:

Create a Home Directory

mkdir /Users/_hadoop

Find an unused groupid by seeing what ids are already in use:

sudo dscl . -list /Groups PrimaryGroupID | cut -c 32-34 | sort -rn

Then find an unused userid by seeing what userid’s are in use:

sudo dscl . -list /Users UniqueID | cut -c 20-22 | sort -rn

Pick a number that is in neither list. In our case we will use 402 for both the userid and groupid for _hadoop (Mac OS X has an underscore in front of daemon user/group names. We will also

sudo dscl . -create /Groups/_hadoop PrimaryGroupID 402
sudo dscl . -append /Groups/_hadoop RecordName hadoop

Take the Value of dsAttrTypeStandard:PrimaryGroupID in this case 500, and use it as the groupid in the following command:

sudo dscl . -create /Users/_hadoop UniqueID 402
sudo dscl . -create /Users/_hadoop RealName "Hadoop Service"
sudo dscl . -create /Users/_hadoop PrimaryGroupID 402
sudo dscl . -create /Users/_hadoop NFSHomeDirectory /Users/_hadoop
sudo dscl . -append /Users/_hadoop RecordName hadoop

For both Ubuntu and Mac (Note that the Mac will end up having a user/group id of _hadoop)

cd /usr/local/pkgs
tar xzf hadoop-0.18.2.tar.gz
tar xzf hbase-0.18.1.tar.gz

cd ..
ln -s /usr/local/pkgs/hadoop-0.18.2 hadoop
ln -s /usr/local/pkgs/hbase-0.18.1 hbase
mkdir /var/hadoop_datastore
chown -R hadoop:hadoop hadoop/ hbase/ /var/hadoop_datastore /Users/_hadoop

Hadoop Config files

The following are all in /usr/local/hadoop/conf

hadoop-env.sh

Need to set the JAVA_HOME variable. I installed java 6 via synoptic. You can also install it with:

apt-get install sun-java6-jdk

The Macintosh is a easy if you have a Intel Core 2 Dual (the Intel Core Dual doesn’t count). Apple is only supporting Java 1.6 on their 64 bit processors. If you have a 32 bit processor like the first generation Macbook Pro 17″ or first generation MacMini, or you have a PPC see Tech Tip: How to Set Up JDK 6 and JavaFX on 32-bit Intel Macs

So my config is (only the things I changed, the rest was left as is):

...
# The java implementation to use.  Required.
# export JAVA_HOME=/usr/lib/j2sdk1.5-sun
 export JAVA_HOME=/usr/lib/jvm/java-6-sun
...

For the Macintosh:

export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/Current

hadoop-site.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!-- Put site-specific property overrides in this file. -->
<configuration>
<property>
  <name>hadoop.tmp.dir</name>
  <value>/var/hadoop_datastore/hadoop-${user.name}</value>
  <description>A base for other temporary directories.</description>
</property>

<property>
  <name>fs.default.name</name>
  <value>hdfs://localhost:54310</value>
  <description>The name of the default file system.  A URI whose
  scheme and authority determine the FileSystem implementation.  The
  uri's scheme determines the config property (fs.SCHEME.impl) naming
  the FileSystem implementation class.  The uri's authority is used to
  determine the host, port, etc. for a filesystem.</description>
</property>

<property>
  <name>mapred.job.tracker</name>
  <value>localhost:54311</value>
  <description>The host and port that the MapReduce job tracker runs
  at.  If "local", then jobs are run in-process as a single map
  and reduce task.
  </description>
</property>

<property>
  <name>dfs.replication</name>
  <value>1</value>
  <description>Default block replication.
  The actual number of replications can be specified when the file is created.
  The default is used if replication is not specified in create time.
  </description>
</property>
<!-- As per note in http://mail-archives.apache.org/mod_mbox/hadoop-hbase-user/200810.mbox/<C20126171.post@talk.nabble.com> -->
<property>
  <name>dfs.datanode.socket.write.timeout</name>
  <value>0</value>
</property>

<property>
   <name>dfs.datanode.max.xcievers</name>
   <value>1023</value>
</property>
</configuration>

HBase Config Files

The following are all in /usr/local/hbase/conf

hbase-env.sh

Again, just need to set up JAVA_HOME:

...
# The java implementation to use.  Required.
# export JAVA_HOME=/usr/lib/j2sdk1.5-sun
export JAVA_HOME=/usr/lib/jvm/java-6-sun
...

For the Macintosh:

export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/Current

hbase-site.xml

Here is where I wanted to give a FQDN for the host that is the hbase.master, but had to use an IP address instead.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://localhost:54310/hbase</value>
    <description>The directory shared by region servers.
    Should be fully-qualified to include the filesystem to use.
    E.g: hdfs://NAMENODE_SERVER:PORT/HBASE_ROOTDIR
    </description>
  </property>

  <property>
    <name>hbase.master</name>
    <value>192.168.10.50:60000</value>
    <description>The host and port that the HBase master runs at.
    </description>
  </property>
</configuration>

Formatting the Name Node

You must do this as the same user as will be running the daemon (hadoop)

su hadoop -s /bin/sh -c /usr/local/hadoop/bin/hadoop namenode -format

on the Mac:

/usr/bin/su _hadoop /usr/local/hadoop/bin/hadoop namenode -format

Setup passphraseless ssh

Now check that you can ssh to the localhost without a passphrase:

su - hadoop
ssh localhost

If you cannot ssh to localhost without a passphrase, execute the following commands (as haddop):

$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

Ubuntu /etc/init.d style startup scripts

I scoured the InterTubes for example hadoop/hbase startup scripts and found absolutely none! I ended up creating a minimal one that is so far only suited for the Pseudo-Distributed Operation mode as it just calls the start-all / stop-all scripts.

/etc/init.d/hadoop

Create the place it will put its startup logs

mkdir /var/log/hadoop

Create /etc/init.d/hadoop with the following:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          hadoop services
# Required-Start:    $network
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Description:       Hadoop services
# Short-Description: Enable Hadoop services including hdfs
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HADOOP_BIN=/usr/local/hadoop/bin
NAME=hadoop
DESC=hadoop
USER=hadoop
ROTATE_SUFFIX=
test -x $HADOOP_BIN || exit 0
RETVAL=0
set -e
cd /

start_hadoop () {
    set +e
    su $USER -s /bin/sh -c $HADOOP_BIN/start-all.sh > /var/log/hadoop/startup_log
    case "$?" in
      0)
        echo SUCCESS
        RETVAL=0
        ;;
      1)
        echo TIMEOUT - check /var/log/hadoop/startup_log
        RETVAL=1
        ;;
      *)
        echo FAILED - check /var/log/hadoop/startup_log
        RETVAL=1
        ;;
    esac
    set -e
}

stop_hadoop () {
    set +e
    if [ $RETVAL = 0 ] ; then
        su $USER -s /bin/sh -c $HADOOP_BIN/stop-all.sh > /var/log/hadoop/shutdown_log
        RETVAL=$?
        if [ $RETVAL != 0 ] ; then
            echo FAILED - check /var/log/hadoop/shutdown_log
        fi
    else
        echo No nodes running
        RETVAL=0
    fi
    set -e
}

restart_hadoop() {
    stop_hadoop
    start_hadoop
}

case "$1" in
    start)
        echo -n "Starting $DESC: "
        start_hadoop
        echo "$NAME."
        ;;
    stop)
        echo -n "Stopping $DESC: "
        stop_hadoop
        echo "$NAME."
        ;;
    force-reload|restart)
        echo -n "Restarting $DESC: "
        restart_hadoop
        echo "$NAME."
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|force-reload}" >&2
        RETVAL=1
        ;;
esac
exit $RETVAL

/etc/init.d/hbase

Create the place it will put its startup logs

mkdir /var/log/hbase

Create /etc/init.d/hbase with the following:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          hbase services
# Required-Start:    $network
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Description:       Hbase services
# Short-Description: Enable Hbase services including hdfs
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HBASE_BIN=/usr/local/hbase/bin
NAME=hbase
DESC=hbase
USER=hadoop
ROTATE_SUFFIX=
test -x $HBASE_BIN || exit 0
RETVAL=0
set -e
cd /

start_hbase () {
    set +e
    su $USER -s /bin/sh -c $HBASE_BIN/start-hbase.sh > /var/log/hbase/startup_log
    case "$?" in
      0)
        echo SUCCESS
        RETVAL=0
        ;;
      1)
        echo TIMEOUT - check /var/log/hbase/startup_log
        RETVAL=1
        ;;
      *)
        echo FAILED - check /var/log/hbase/startup_log
        RETVAL=1
        ;;
    esac
    set -e
}

stop_hbase () {
    set +e
    if [ $RETVAL = 0 ] ; then
        su $USER -s /bin/sh -c $HBASE_BIN/stop-hbase.sh > /var/log/hbase/shutdown_log
        RETVAL=$?
        if [ $RETVAL != 0 ] ; then
            echo FAILED - check /var/log/hbase/shutdown_log
        fi
    else
        echo No nodes running
        RETVAL=0
    fi
    set -e
}

restart_hbase() {
    stop_hbase
    start_hbase
}

case "$1" in
    start)
        echo -n "Starting $DESC: "
        start_hbase
        echo "$NAME."
        ;;
    stop)
        echo -n "Stopping $DESC: "
        stop_hbase
        echo "$NAME."
        ;;
    force-reload|restart)
        echo -n "Restarting $DESC: "
        restart_hbase
        echo "$NAME."
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|force-reload}" >&2
        RETVAL=1
        ;;
esac
exit $RETVAL

Set up the init system

This assumes you put the above init files in /etc/init.d

chmod +x /etc/init.d/{hbase,hadoop}
update-rc.d hadoop defaults
update-rc.d hbase defaults 25

You can now start / stop hadoop by saying:

/etc/init.d/hadoop start
/etc/init.d/hadoop stop

And similarly with hbase

/etc/init.d/hbase start
/etc/init.d/hbase stop

Make sure you start hadoop before hbase and stop hbase before you stop hadoop

Macintosh launchd style startup

Starting proceses on Macintosh Leopard is pretty easy with lauchd/launchctl.

For hadoop, create a file /Library/LaunchAgents/com.yourdomain.hadoop.plist with the following content (replace yourdomain with the domain you want to use for this class of apps):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>GroupName</key>
    <string>_hadoop</string>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>com.yourdomain.hadoop</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/hadoop/bin/start-all.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>ServiceDescription</key>
    <string>Hadoop Process</string>
    <key>UserName</key>
    <string>_hadoop</string>
</dict>
</plist>

And for hbase, /Library/LaunchAgents/com.yourdomain.hbase.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>GroupName</key>
	<string>_hadoop</string>
	<key>KeepAlive</key>
	<true/>
	<key>Label</key>
	<string>com.ibd.hbase</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/local/hbase/bin/start-hbase.sh</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
	<key>UserName</key>
	<string>_hadoop</string>
</dict>
</plist>

Set the owner to root and the mode to 644:

chown root /Library/LaunchAgents/com.yourdomain.hadoop.plist /Library/LaunchAgents/com.yourdomain.hbase.plist
chmod 644 /Library/LaunchAgents/com.yourdomain.hadoop.plist /Library/LaunchAgents/com.yourdomain.hbase.plist

The next time you restart, it should start hbase and hadoop. You can also start them manually with the commands:

sudo launchctl load /Library/LaunchAgents/com.yourdomain.hadoop.plist
sudo launchctl load /Library/LaunchAgents/com.yourdomain.hbase.plist

Conclusion

You should now be able to see the HBase web interface at http://<your domain name>:60010

If you have problems check /var/log/{hbase,hadoop}/startup_log as well as /usr/local/hadoop/logs/hadoop-hadoop-namenode-yourhostname.log and /usr/local/hbase/logs/hbase-hadoop-master-yourhostname.log

The error messages are pretty poor. (Ie useless as far as I could tell when tracking down the FQDN/IP Address problem). But better than nothing.

I will post an update when I deploy a Full Cluster.

Deploying RabbitMQ and Stomp on Ubuntu

Install rabbitmq via synaptic

Make sure that the erlang package is installed

Add a repository from the rabbitmq site

Set up Repository via the Synaptic GUI tool

(http://www.rabbitmq.com/debian/)

Synaptic repository addition

Synaptic repository addition

Set up Repository via command line

Ubuntu Documentation for Managing Repositories via the Command Line

How to use the RabbitMQ Debian repository and available RabbitMQ Debian packages

The repositories are described in /etc/apt/sources.list

So do the following:

sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup

Edit /etc/apt/sources.list and add the following line:

deb http://www.rabbitmq.com/debian/ testing main

Then update the apt-get environment:

wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
sudo apt-key add rabbitmq-signing-key-public.asc
sudo apt-get update

Install the RabbitMQ Server

Set up Repository via the Synaptic GUI tool

Synaptic Erlang Packages

Synaptic Erlang Packages

Set up Repository via command line

sudo apt-get install rabbitmq-server

This should have installed the main portion of the code base in /usr/lib/erlang/lib/rabbitmq_server-1.5.1 (The trailing version number may be different than 1.5.1)

After it installed the server, make sure its stopped

# /etc/init.d/rabbitmq-server stop

Install rabbitmq-stomp

I could not find any ubuntu/debian packages so I installed it from the Mercurial repository. If you don’t already have Mercurial (the hg command) then you can install it with the following command:

apt-get install mercurial

Install the rabbitmq-stomp code

This also will go parallel to where the ubuntu package put the stomp server main code and the rabbit-codegen.

cd /usr/lib/erlang/lib/
hg clone http://hg.rabbitmq.com/rabbitmq-stomp/

Compile the stomp code

Build and test run rabbitmq and stomp via make

cd /usr/lib/erlang/lib/rabbitmq-stomp
make RABBIT_SERVER_SOURCE_ROOT=../rabbitmq_server-1.5.1 all

This should produce an output like:

mkdir -p ebin
erlc -I ../rabbitmq_server-1.5.0/include -I include -o ebin -Wall +debug_info  src/rabbit_stomp.erl
erlc -I ../rabbitmq_server-1.5.0/include -I include -o ebin -Wall +debug_info  src/stomp_frame.erl 

Add a file /etc/default/rabbitmq and Restart rabbitmq_server

You need to tell the main rabbitmq_server to load and run the rabbitmq-stomp stuff when it starts up. You do that by creating this file with the following content:

SERVER_START_ARGS='
  -pa /usr//lib/erlang/lib/rabbitmq-stomp/ebin 
  -rabbit
     stomp_listeners [{"0.0.0.0",61613}]
     extra_startup_steps [{"STOMP-listeners",rabbit_stomp,kickstart,[]}]'

Restart the Rabbitmq_server:

/etc/init.d/rabbitmq_server start

You can do a

ps -ax | grep stomp

and see an erlang process that is running the rabbit-stomp process.

Install ruby stomp client code and test

Install the ruby stomp gems

If you don’t have ruby already installed:

sudo apt-get install ruby
sudo apt-get install rubygems

Then install the ruby stomp gem

sudo gem install stomp

Run the ruby receiver client in one window

ruby /usr/lib/erlang/lib/rabbit-stomp/examples/ruby/cb-receiver.rb

In another window run the ruby sender client

ruby /usr/lib/erlang/lib/rabbit-stomp/examples/ruby/cb-sender.rb

In the receiver window you should see 10,000 test message lines:

...
Test Message number 9998
Test Message number 9999
All Done!

That’s it! Now you can use Stomp

(See later post Updating RabbitMQ and RabbitMQ-Stomp to RabbitMQ 1.5.3)

QuarkRuby: Consume non rails-style REST APIs

It seems that most “RESTful” APIs in the wild are well, pretty wild. They don’t meet the strict requirements of the pure CRUD/REST of ActiveResource.

The article in QuarkRuby:  Consume non rails-style REST APIs shows how to create a nice ruby wrapper around ActiveResource so you can adapt to any arbitrary REST / http interface on the Internet.

Building RabbitMQ on Mac OSX Leopard

At Cinch, we are looking into a high volume, high performance message queuing mechanism for aggregating updates from javascript logging into our data stores. The first one we are investigating is RabbitMQ which seems to have a good rep.

Though we are deploying on Linux, we do all our development on Mac OS X. It turned out that it was a bit more tweaky to get RabbitMQ to install on Mac OS X if we wanted to use the latest version of RabbitMQ and its underlying Erlang Environment.

So this is what we’ve done so far to get it installed.

Instructions Source

The core of this information came from the blog entry of Ben Hood, RabbitMQ contributor How I Install RabbitMQ On OSX

I’ve added a few things that were important in our environment.

Make sure MacPorts bin is before default bin

Your Unix PATH must have the MacPorts bin (/opt/local/bin before /usr/bin or /bin)

Ideally change it in the Mac OS X environment and not just your shell. You can use the RCEnvironment (Environment Variables) System Preference to set/update the PATH Environment variable. Or you can edit ~/.MacOSX/environment.plist file. Make sure that you don’t override this in your .bachrc or .tcshrc shell startup files. Or that you do it properly there as well.

This is mainly needed to make sure that you are using the python and python libraries from MacPorts and not the default Apple Leopard python in /usr/bin. It is also needed for the path to the Erlang binaries.

Install Erlang

* Use MacPorts via command line or Portecus to install Erlang. We did use R12B-5 with hipe, ssl, and smp options.
* Link erl_call into /opt/local/bin

UnixPrompt> sudo ln -s /opt/local/lib/erlang/lib/erl_interface-3.5.9/bin/erl_call /opt/local/bin

Install Mercurial

This is needed to install RabbitMQ from the default branch (this is a stable branch but may be beyond the current release). RabbitMQ 1.4.0 will not work with Erlang/OTP R12B-5. Please use R12B-4 or earlier by default.

Get a Mac Binary package.

Install python simple json

Using MacPorts, you can use the following commands:

UnixPrompt> sudo port install py25-simplejson
UnixPrompt> sudo port install python_select
UnixPrompt> sudo python_select python25

Make sure that you have the right python in your path:

UnixPrompt> which python
/opt/local/bin/python

Get RabbitMQ via mercurial

UnixPrompt> hg clone http://hg.rabbitmq.com/rabbitmq-codegen
UnixPrompt> hg clone http://hg.rabbitmq.com/rabbitmq-server

Build and run the rabbitMQ

UnixPrompt> cd rabbitmq-server
UnixPrompt> make -j run

Should then see something like:

NODE_IP_ADDRESS= NODE_PORT= NODE_ONLY=true LOG_BASE=/tmp  RABBIT_ARGS=" -s rabbit" MNESIA_DIR=/tmp/rabbitmq-rabbit-mnesia ./scripts/rabbitmq-server
   Erlang (BEAM) emulator version 5.6.4 [source] [smp:2] [async-threads:30] [kernel-poll:true]

   Eshell V5.6.4  (abort with ^G)
   (rabbit@xlr8)1> RabbitMQ %%VERSION%% (AMQP 8-0)
   ...
   Logging to "/tmp/rabbit.log"
   SASL logging to "/tmp/rabbit-sasl.log"

   starting database             ...done
   starting core processes       ...done
   starting recovery             ...done
   starting persister            ...done
   starting builtin applications ...done
   starting TCP listeners        ...done

   broker running

You are now up and running!

TBD: Figure out how to integrate it into Mac OS X so its treated as a system service started at bootup.