DogOnRails, only a smaller piece of a bigger picture.

I noticed that I’ve been referring to DogOnRails a lot in my Ruby Examples (because I don’t like exposing our clients’ code to the outside world if I can avoid it), so I better talk about what it is other than it being an abstract example I use here!

What is Dog On Rails?

DogOnRails is a WifiDog Captive Portal Authentication Server. Unlike the WifiDog server, it is written in Ruby on Rails (hence the name). It originally started out as a small hobby project so I could use it to run on a Linksys WRT54G at my apartment and have it redirect to my Dreamhost account. Then some other people saw that I was working on the project on Google Code and started to help me out with it. Then I started doing this Meraki FreeTheNet stuff, which gave me a new platform to put WifiDog client, and this was the perfect opportunity to de-mystify the whole process.

So, why is it cool?

The original concept of WifiDog is what drew me to it. The original WifiDog project was designed so that Captive Portals, which were only being used by WISPs at the time could be used to display both user-centric and location-centric information to the user so that they would learn more about the area around them. The reason I started working with DogOnRails was because I am able to add more features faster with Rails than I would be able to with PHP, and the fact that I dislike the Smarty Templating Engine, which made adding larger features a major hassle.

There is also the fact that the project seemed to cater more and more to the WISP community than its original purpose, so I felt the server no longer was interesting.

The thing that I like about it is the fact that this allows anyone who can hack Ruby on Rails to add more features onto something that normally would require that you write in C or Shell Script. By moving the authentication off the device, you can do much more with the process than simple authentication, you could redirect the user to what you want to see before they are on their way. And since they’re using YOUR bandwidth anyway. The analogy here is showing a visitor to your house around before they sit down and watch television. It’s not always necessary, but it’s a good courtesy for those who haven’t been to your house before.

Oh yeah, did I mention that it was voted the Best of HackDay 1. I think that bars it from competing in Hack Day 2. I have a whole new killer app for that. :P

So, what features did you add during HackDay?

I added the following features:

  • User-Agent detection for mobile devices
  • GoogleMaps Functionality
  • GoogleEarth Functionality

The User-Agent detection was much easier than I thought. I borrowed Alexei’s iPhone to test the final design, and at the end I was able to get the UserAgent detection to show the view easily, the code looks like this:


user_agent = request.user_agent.downcase
mobile = false

# Mobile Request URI
[ 'iphone' , 'ipod' ].each { |b|
mobile = true if user_agent.include? b
}

The rest is pretty self-explanitory at this point! After that was added, it was just a matter of doing some iPhone-based CSS. I used Facebook as an example of how to do this, and after cursing WebKit/Safari’s existance, I managed to get something that didn’t require a LOT of resizing to get working.

Of course, the following features were added post-hackday:

  • ROBIN/Open-Mesh Update Recieving – (Can’t update settings yet, can get the Mesh status)
  • Improved GoogleMaps Functionality – Looks more like the Merkai Map
  • Per Node Auditing
  • Graphs using gruff
  • MAC Address Blocking
  • Facebook Functionality

That’s right, DogOnRails is now a Facebook application as well. The idea behind this is to encourage people to grow Wifi networks like they would grow their own garden. Make it so that there’s a certain level of pride for having the nodes up and working. It’s very, very early alpha stages, but it exists and it currently looks like this:

Facebook Screen

It needs a lot more polish, but it’s going to be used by the FreeTheNet group in the coming month, and will be the replacement to the Meraki Dashboard that we have been looking it. There will probably be more changes to this, and to other things like this. But, when I refer to DogOnRails, I’m referring to a real app, and not some abstract thing like in a textbook.

And I will keep using it as an example of what to do and what NOT to do for many posts to come.

VLAD the DEPLOYER!

I like simple things, and I’m not squemish when I see an error if I know why that error is true. When I needed to learn how to deploy a Rails app, I first looked at Capistrano. Capistrano looked nice enough, until I heard other people complain about how hard it was to use and how it was a pain the ass.

Then I found Vlad! Vlad the Deployer is a great alternative to the complex Capistrano. I’ve used vlad on every Rails project that I’ve deployed in the last year, and it’s hawt! This will probably sound the same as all the other vlad tutorials, and no I did not get it to not try and run apacheconf, but I will talk about options to turn this off.

First of all, when you install vlad, you need to add the following to your rakefile:


require 'vlad'
Vlad.load

Then you setup a deploy.rb file with the following:


set :application, "dogonrails"
set :user, "bowserj"
set :domain, "#{ user }dogonrails.net"
set :deploy_to, "/var/www/dogonrails"
set :repository, "http://dogonrails.googlecode.com/svn/trunk/dogonrails"
set :web, "nginx"
set :ssh_flags, "-p 31323"

In this case, there are two things that I did differently in my vlad file that aren’t normally done. DogOnRails is hosted on a vm which also hosts many other community sites. This means that I have to specify the port by using the ssh flags. I also changed the server to nginx. However, without an nginx.rb in the lib/vlad/ directory, this is going to run the apache command. A quick and dirty way to get around this as well is to set the web_command


set :web_command, '/dev/null < '

Now the message is supressed. We really don't need to keep restarting nginx when we deploy. It's not leaking memory or breaking the proxy like what Apache does in the scenario that I just described above. (Note: If your vlad or apache process IS doing this, you should probably get that fixed before dealing with deployment woes!) Of course, you'll probably want to create your own tasks in the namespace, and this is exactly like rake:

namespace :vlad do
desc 'Does turnkey stuff'

task :deploy => ['vlad:update', 'vlad:symlink', 'vlad:start']
task :deploy_with_migrations => ['vlad:update', 'vlad:migrate', 'vlad:symlink', 'vlad:start']

desc 'Symlink custom directories'
remote_task :symlink, :roles => :app do
# Do Stuff
end

end

In this case, This task will create and destroy symlinks. I use ugly absolute paths because I don't trust my Rails environment. In hindsight, I really should use the current_directory and shared_directory variables because they can be changed. This is probably a judgement call that you can make.

Anyway, at the end of it all, you'll have to type in your password a bunch of times. You could put your password on the key and send it to the server, but given that most projects have multiple administrators, I think that idea is as good as trying to nail warm jello. This is the downside of vlad, but I like learning complex passwords!

The other big plus is that it can use git! I think that I am becoming stupider and more ugly by using svn! (mostly because Linus says so) not to mention the fact that Google Code has problems with hosting DogOnRails as of late, I will be switching to git soon! Once I have a functioning public git repository, I'll post the results here! I will also try to update this blog more often as well.