Thursday, June 26, 2014

Ruby on Rails gem: Uninitialized Constant (class name)

I was working on a Ruby on Rails project earlier, and ran into a really frustrating issue regarding gems.

I added the influxdb gem to my Gemfile, did a bundle install, saw it installed successfully, then tried to use it in an ApplicationController.  No luck!  Over and over it was acting like the gem wasn't installed (Uninitialized Constant error ApplicationController::InfluxDB when trying to reference the class defined in the gem).

When I ran the same code using the rails console, it worked fine, which lead me to believe it was some problem with bundler or the environments.

It turns out the solution was simply to restart the apache/ngnix/whatever server! "service apache2 restart" in my case. Whew!

Saturday, March 22, 2014

CrashPlan and JunOS Pulse conflict

I spent an hour or so today trying to get CrashPlan working on my linux machine.  The software installed just fine, and the backup engine appeared to start fine as well:

$ sudo service crashplan start    
Starting CrashPlan Engine ... Using standard startup
OK

However, the desktop portion of the CrashPlan software kept saying that it was "Unable to connect to the backup engine, retry?".  Weird.  So I checked to see if the server was actually listening on the port it's supposed to be listening on:

$ netstat -ln | grep 4243
$

Nope.  So it must not be starting up as "OK" as it claims.  Digging through some of the logs (specifically /usr/local/crashplan/log/service.log.0) I found this gem that shows up just before the service automatically shuts down:

[03.22.14 22:05:04.511 WARN    main                 com.backup42.service.CPService          ] >>>>> CPService is already listening on 0.0.0.0:4242 <<<<<

Wait, wat?  Something (it thinks it's itself, but that's not the case) is already bound to port 4242.  Netstat shows who actually is bound to that port:

$ sudo netstat -anp | grep 4242 
tcp  0 0 127.0.0.1:4242  0.0.0.0:*        LISTEN      11466/ncsvc
tcp  0 0 127.0.0.1:45982 127.0.0.1:4242   ESTABLISHED 11466/ncsvc
tcp  0 0 127.0.0.1:4242  127.0.0.1:45982  ESTABLISHED 11466/ncsvc

ncsvc!  That's the Juniper VPN software (aka JunOS Pulse).  Well that's no good, I'm almost always connected to the VPN.  Luckily, CrashPlan lets you configure the port that the server uses to something other than 4242!

The fix that made it work happily ever after was simply modifying a line in /usr/local/crashplan/conf/my.service.xml:

Change:
 <location>0.0.0.0:4242</location>
To a port that isn't already in use:
 <location>0.0.0.0:4244</location>

Now the CrashPlanEngine portion of the software runs smoothly even when I'm on the VPN!


Sunday, March 17, 2013

Apache mod_vhost_alias VirtualDocumentRoot per second level domain name

I wanted to have a virtual document root for each second level domain name (example.com, f85.net, abc.net, etc...), with subdomain virtual document roots located underneath the main domain name.

For example:

         f85.net --> /var/www/f85.net/f85.net
     www.f85.net --> /var/www/f85.net/www.f85.net 
www.news.f85.net --> /var/www/f85.net/www.news.f85.net 
 www.example.com --> /var/www/example.com/www.example.com 
 abc.sub.pri.com --> /var/www/pri.com/abc.sub.pri.com

And so on, so that each primary domain (that gets registered with a registrar) has its own folder in /var/www.

The problem was, everything that I was trying was failing to give the desired results, because I didn't fully understand how the 'Directory Name Interpolation' was working (how Apache turns the configured VirtualDocumentRoot string into a string that represents a discrete folder each time a file is accessed.

What ended up working was:

VirtualDocumentRoot /var/www/%-2.0.%-1/%0
VirtualScriptAlias  /var/www/%-2.0.%-1/%0/cgi-bin/

I'll break this down in pieces to explain how it's working:

/var/www/%-2.0.%-1/%0
This highlighted piece is the folder that holds all of the domains.  It never changes.


/var/www/%-2.0.%-1/%0
This highlighted piece references the second value from the right of the fully qualified domain name (FQDN).  For example, in the URL "http://www.f85.net", this will give us "f85".  When you use the - symbol, Apache starts counting from the right (so "%-1" would yield "net", and "%-3" would yield "www").  The ".0" following "%-2" is also important.  Although it doesn't technically do anything ("%-2" == "%-2.0"), it allows us to add the next item without errors.


/var/www/%-2.0.%-1/%0

This highlighted piece is a dot, plain and simple (up to and including this highlighted piece, we would have "/var/www/f85.").  The reason I wanted to dedicate a paragraph to it is because it gave me the most trouble.  The first thing I tried was combining "%-2" with a period ("%-2.") Logically this would give us "f85.", right? Nope!  When Apache sees this period following a "%-2" (or any other "%x"), it expects another number after the dot, as described in the Directory Name Interpolation section of mod_vhost_alias.  This second number is used to select a single character out of the first number's text (for the "www.f85.net" example, "%-2.1" would represent the character "f".  We can use the number 0 here ("%-2.0") to tell Apache to select the entire value and not some specific character, which allows Apache to finish parsing this "%x" phrase so that we can add our "." and have it actually represent a period without breaking anything!



/var/www/%-2.0.%-1/%0
This highlighted piece is the first value from the right of the FQDN ("net", in our "www.f85.net" example).  Pretty straightforward.  Up to and including this piece, we now have "/var/www/f85.net".  So far so good, just one last piece.

/var/www/%-2.0.%-1/%0
This highlighted piece represents the entire FQDN (with a forward slash in front of it).  Up to and including this piece, we're done!  We have "/var/www/f85.net/www.f85.net".

Now, this is definitely not the first way I tried to do this, but it's the only way that I've found to work consistently across sub-domains of various depths.  Please let me know in the comments if you see a problem with this method or have a better idea!!