Aug 242012
 

There are times where you want to handle HEAD requests differently than you handle GET requests, Dancer makes that a bit difficult. In an attempt to make things easier in the default case Dancer maps HEAD requests to any matching GET routes.

Here’s a quick snippet for branching off inside a route based on GET vs HEAD:

get '/path/to/thing' => sub {
   my $method = request->method;

   if($method eq 'GET') {
      #handle get request
      return;
   } elsif ($method eq 'HEAD') {
      #handle head request
      return;
   } else {
      #no idea, shouldn't happen
      if(defined $method) {
         print STDERR "bad juju, method of ($method) didn't match GET/HEAD\n";
      } else {
         print STDERR "bad juju, no method defined!\n";
      }
      return;
   }
};
Oct 112010
 

For most applications authentication is a necessary evil and my current project is no exception. I always dread having to write the authentication logic in applications. Some frameworks have OK authentication plugins available but I always finding myself writing some piece of it before it’s over with. I was really hoping to avoid that with rails and thanks to devise I have. It has everything I was looking for and more.

It comes with pre-canned (but modifiable) sign-up, password reminder, login, logout, password change etc… forms. And quite a few feature that put it in a class above most other auth modules I’ve used. Confirmation (click link in email) functionality, OAuth2 support, Token auth, tracks sign-in/ out IP, supports idle timeout, lock outs on excessive failed attempts and can re-enable the account after a timeout period or via email. Way more than I expected for the low low price of free :)

Getting it going was as easy as:

sudo gem install devise
rails generate devise:install
rails generate devise User #creates the user model, you can add extra fields you want to track for the user here

Your now ready to pick your features by editing the User model (or whatever you called it) and doing a db migration. Protecting a controller is incredibly easy, adding this line will ensure an auth’d user before allowing any callbacks:

before_filter :authenticate_user!

If there were a section of the controller you do want accessable to guests you modify the above to look like:

before_filter :authenticate_user! :except => [:index, :faq]

There are a couple of good rails casts on the subject:
Introducing Devise
Customizing Devise

Oct 102010
 

This is one place where rails really shines, the number of tutorials, screen casts, and other educational resources are second to none. I’ve been very impressed with both the quantity and quality of the free information available.

A large number of resources are cataloged here.

Oct 102010
 

I’ve decided to try a new philosophy with this project, simplify my life, outsource the unimportant stuff. Instead of setting up a source repository on a server and configuring a hosting environment for my project I’m letting others do that work so I can concentrate on getting code written.

I’ve done a good bit of searching and have settled on Heroku to do the hosting. They have a free plan that will only support a moderate number of concurrent connections and has very little database storage. But for most web based projects it’s a great plan to dev / test your application. The initial cost when I finish the application will be $15 a month to move from a 5MB database to a 20GB database. There are also some really interesting options for hourly cron or worker queues that I may sign up for. Won’t really have that figured out till I get further into the project.

The idea behind the workers is pretty simple, you need to do some work that the web client shouldn’t have to sit and wait on so you throw it in a work queue and the worker(s) churn through the queue asynchronously. Daily cron is free and would probably suffice for any of my needs initially, even if not it’s only $3 a month for hourly cron.

Time will tell but so far my experience with Heroku has been very positive, the user experience couldn’t be much smoother. Sign up for an account, install the heroku gem, run command to send your public ssh key, create an application, push your code. And if your using a database do your migration.
This is what it takes post sign-up (assuming you already have ssh key, if not one extra command for that):

sudo gem install heroku
heroku keys:add
cd /path/to/rails/app
heroku create APPNAME
git push heroku master
heroku rake db:migrate

Next is a source repository, heroku is very integrated with git so for better or worse that made my decision for me on what technology to use. On this piece I’ll be honest I didn’t do a lot of research and decided to go with Github. I’m essentially using it as an insurance policy in case both my laptop and heroku have some kind of catastrophic failure. Not likely but $7 a month isn’t a huge price to pay to sleep well at night. Also if I ever involve someone else in the project I can easily tie them in. There are alot of options out there so for those that might care more, feel free to do some research. Let me know if you find something better :)

Oct 062010
 

I spend a lot of my time these days writing back end services to process mountains of data across a large number of servers almost entirely written in Perl. I try to pride myself on using the right tool for the job and that means straying away from Perl from time to time. Over the past couple of years I’ve written (excluding Perl):
- Windows services in C#
- Front end touch screen apps in action script (never again, ever, never)
- C code for freeswitch
- A web front end in PHP that I later scrapped when I confirmed that I still dislike PHP
- A touch screen plc application in basic and ladder logic
- A decent bit of JavaScript for front end candy and ajaxy goodness

I’ve also toyed a bit with Objective-J (it just doesn’t feel right to me [yet]) and node.js (see a couple of places where i might pull this out of the tool belt down the road).

All that to say, I am willing to give other things a shot and use what is available / appropriate. I usually fall back to Perl due to the enormous “home field advantage” that CPAN gives you as well as the ability to deliver solutions in a very short period of time.

I haven’t revisited Ruby or Ruby on Rails since it was very new. At that time I disliked a large number of things about Rails and had no other use for Ruby so I moved on.

Rails has now hit 3.0 and I figure it’s time to give it another shot, from what I hear a lot has changed.

My plan is to write a few articles as I go and document my findings so that they might be of use to others that go down this path.

Jan 032009
 

From time to time I find myself needing to treat one class of devices differently than another class of devices as dhcp clients. This becomes very common when dealing with sip phones, different phones need different/conflicting configuration parameters. The typical way to deal with this is to have an entry per device to specify how it will behave. That behavior doesn’t scale very well unless you have an automated system to modify the dhcpd configuration on the fly. It turns out that dhcpd has quite a few advanced features that few people ever stumble upon. I will show you a couple here, there are several more at your disposal that I don’t cover here. I strongly suggest exploring the dhcpd documentation to see what other tools you have at your disposal.

In my example I want to treat Snom IP phones differently than everything else. For those unfamiliar with VoIP phones, most phones on the market today support some form of automatic provisioning. Acquiring their configuration files from a central server, Snom phones need to be told more specifics than say Polycom phones for example. For a polycom phone you point it at the server and it will attempt to retrieve files in it’s defined method. Snom phones give you more flexibility but along with that added complexity for dhcpd configuration.

Here is the dhcpd snippet to deal with this situation:

if binary-to-ascii(16, 32, "", substring(hardware, 0, 4)) = "1000413" {
log(info, "request from snom phone, setting proper options.");
option tftp-server-name "http://pbx1.yourdomain.com:80";
option bootfile-name "/phones/snom/{mac}.htm";
} else {
log(info, "Default case, setting basic tftp option");
option tftp-server-name "pbx1.yourdomain.com";
}

In the example we have some if/else logic the binary-to-ascii function which takes the hardware variable and makes it more user friendly and a substring command that peels off just the part of the string we care about. In my case I am matching on the first six characters of the mac address which is the prefix that has been assigned to Snom. If you need to be more or less specific you would simply modify the substring portion you are looking at. Assignments are made at the 6 character level so this should work for most cases. Some vendors will subdivide their MAC space with different prefixes underneath the 6 characters. If that is the case it would give you the granularity to handle each device class differently.

If you want to research the MAC assignments of vendors you can hop over to the IEEE website and perform look ups or download the entire database of assignments. That website can be found Here.

Note: Devices are not guaranteed to show up as being made by the actual manufacturer. If they use a component in their product manufactured by someone else it may have that vendor’s mac prefix. When working with new device types it’s very important to test and see what MACs they actually have been assigned. Luckily with phones they are typically on the bottom/back or accessible from the menus so you can figure it out before connecting the devices to the network.

Jan 032009
 

This is a pretty quick post but I wanted to throw it out here as it might help somebody. When you start getting into several tables and a large rule base it can get to be a bit difficult to figure out what rule blocked a packet that shouldn’t have gotten through.

Instead of:
IN=eth1 OUT=tun0 SRC=10.2.1.2 DST=10.3.1.6 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=16679 PROTO=ICMP TYPE=0 CODE=0 ID=29120 SEQ=4

Your log entry can have a prefix that you can use as a breadcrumb to get you headed in the right direction for tracking down the over zealous rule. This is done with the log prefix parameter. For example lets say you have a table where you keep all your rules for PBX connectivity you could add a prefix to let you know that chain’s cleanup rule is hosing you. You add the prefix like so:
--log-prefix "[PBX-OUT CLEANUP]"

Now the log entries look like:
[PBX-OUT CLEANUP]IN=eth1 OUT=tun0 SRC=10.2.1.2 DST=10.3.1.6 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=16679 PROTO=ICMP TYPE=0 CODE=0 ID=29120 SEQ=4

In this instance I am adding this to the “cleanup” rule, the last rule in the table that blocks all traffic not specifically allowed above it. You could add a prefix to any rule in a chain or a special prefix to any rule to help you better troubleshoot unexpected behavior. This definitely comes in handy on firewalls you might touch a couple times a year.

Aug 112008
 

Sun Volume Manager, or SVM for short, allows you to do software raid in instances where you don’t have hardware capable of doing the job. You will find that the more expensive the Sun hardware gets, the less chance it will have any kind of hardware raid. So this will become a critical tool on your most critical servers. This is a quick example of how to setup mirroring of the root disk while the system is online, although it will require a reboot to finish the process.

This walk-through assumes you have two disks c0t0d0 and c0t1d0 that you want to mirror the root volume which is on slice 0. I also am assuming you have a small slice located at slice 3 on both disks for the metadevice database. Adjust the following according to your actual setup.

First you need to create the metadevice database which keeps track of your raid configuration, if you don’t already have one:

#when you initially create the database you have to force the addition of database copies
#this creates two copies of the database on the first drives slice 3
metadb -a -f -c2 c0t0d0s3

#now create the redundant copies on the second drive
metadb -a -c2 c0t1d0s3

Now that you have the database you need to configure the sub-mirrors (the volumes you are mirroring) and the metadevice which you will mount.

#run with a -f to create the stripe of the first (live) root volume
#this creates a submirror named d11 of the root volume
metainit -f d11 1 1 c0t0d0s0

#create the second submirror (the one you will be mirroring to)
metainit d12 1 1 c0t1d0s0

#now create the metadevice that you will mount
metainit d10 -m d11

You have now created the mirror, it’s time to tell the OS to use that mirror next time it comes up, this is done as follows:

metaroot d10

At this point it’s time to reboot the system to begin using the mirror device

#flush the filesystems buffers
lockfs -fa

reboot

After the system comes up there is one final step, you told the system about d11 which d10 is a metadevice for. Currently d12 is not related to d11 or d10 in any way, you need to add d12 into the mirror

metattach d10 d12

Now you should be able to sleep easier knowing you have a redundant boot device, in a later article I will cover how to have your system boot off of the secondary device automatically in the case of a drive failure. It is important for you to record (somewhere off of the system) the devices in play so that if you have to do a recovery down the road you have the information you need. You should also keep a copy of the partition tables for good measure.

Jul 182008
 

This is probably going to be my shortest technical post ever, Solaris definitely gets management of one thing right, multipathing. It does almost all the work for you, run stmsboot -e answer a couple of questions and it will reboot the system, it will come up, discover all paths and update your vfstab with the multipath version then reboot again, done.