Mar 3, 2010

Capistrano & Sunspot in Rails

I've been messing around with Sunspot in Rails lately. One of the issues that I ran into is that the index is stored in the application root's solr directory. That's usually not a big deal, but if you use capistrano, then you know that you end up with a new application directory with each deploy. So how do you handle that?


Well, the proper way is to not rely on the built-in instance of Solr that comes with Sunspot. Instead, you're supposed to treat Solr like MySQL; A component that's independent of your application. As somebody who does not program Java, I found the instructions on doing this strange enough that I decided not to use this route. (And don't bother installing Solr via Ubuntu's packages.. white a nightmare that turns out to be..)

Instead, I created a solr directory in my capistrano shared directory. From there, I create a new symlink via capistrano and restart solr. In case you want to try this method (which again, is not the recommended path, but works in a pinch). Here are the relevant parts of my capistrano recipe.

First, before doing anything, I stop Solr/Sunspot:

  task :before_update_code do
#stop solr:
run "cd #{current_path} && rake sunspot:solr:stop RAILS_ENV=#{rails_env}"
end


Next, I create the hook to run my solr tasks after the crontab and symlinks have been set:

 after "deploy:update_crontab", "deploy:solr:symlink"


Lastly, I create the symlinks and restart Solr:

  namespace :solr do
desc <<-DESC
Symlink in-progress deployment to a shared Solr index.
DESC
task :symlink, :except => { :no_release => true } do
run "ln -nfs #{shared_path}/solr #{current_path}/solr"
run "ls -al #{current_path}/solr/pids/"
run "cd #{current_path} && rake sunspot:solr:start RAILS_ENV=#{rails_env}"
end
end


Anyway, your mileage may vary. It's been fun playing with Sunspot and Solr. They have a great community and nice documentation too.

Read on...

Feb 15, 2010

An (easier) guide to installing Cyanogen 5.0.2 on the Nexus One

A while back I followed this great video tutorial from Android and Me to get root access on my Nexus One. I travel quite a bit and need the USB Tether option in order to handle 'emergency' customer requests.

A few weeks back Google updated the Nexus One to include multi-touch. Unfortunately, having already rooted my N1, I was out of luck when it came to applying the OTA update. Looks like once you start down the unlock/root path you pretty much need to follow it. The XDA forums are helpful but there's a ton of chatter which makes it hard to keep up. Since Android and Me never put out an updated video (hint hint) I thought I'd take a crack at documenting how I updated my N1.


First a caveat:

This worked for me but I am *not* an expert. Follow the advice of people who claim to know what they're doing if they have helpful advice.

Now that we have that clear, here's what I did:

1. Get your files!
Head over to the XDA thread and download the latest Cyanogen Mod, Radio update, and Google Addons. As of this writing, that's version 5.0.2. Be very careful to reconcile the instructions on the thread with what I've written.. if a new version of the Cyanogen mod is up there then this post may be obsolete and harm your phone.

Once you have all 3 files downloaded, plug your N1 into your computer and copy the two zip files to the root of your SD card.

2. Reboot phone & hold down trackball to get into fastboot mode
Once you've got the phone rebooted into fastboot mode, plug it in to your computer via USB. If you're on linux, navigate to the folder where you downloaded the fastboot binary and type

sudo su
./ fastboot devices
./fastboot flash radio /path/to/image.img


Where the /path/to/image.img is the path to the radio image. Note that you might not need to update the radio. But if you're going from the Android and Me "making bacon" version to 5.0.2 then I would.

3. Reboot into Recovery & WIPE
Now that you've got the radio image flashed, reboot the phone (again holding down the trackball) and enter recovery mode. Once there, use the trackball to navigate down to the option that says "Wipe" and then Wipe everything.

4. Apply Cyanogen's mod from the SD card
After wiping your phone, navigate back to the main menu and select the option to apply and update from your sdcard. You should see at least 2 options:

1. update-cm-5.0.2-N1-signed.zip
2. gapps-passion-ERE36B-2-signed

Apply update #1 first

5. Apply the Google additions from the SD Card
Once done with step 4, again navigate back and rechoose the same option to apply an update but this time:

Apply update #2

6. Reboot your phone and cross your fingers.
If it worked the boot up animation should change to blue indicating that you're now using Cyanogen 5.0.2. Congratulations!

7. Go download all the apps & set your stuff up again.
In case you're wondering, my essential apps are: DoggCatcher, Twidroid, Pandora, Shazam, StreamFurious, ConnectBot, and Google Skymap.

More/Troubleshooting...
By the way, the first time I did this, my data connection did not turn on. I've heard that wiping again can help that, but for me a simple reboot was sufficient. I've already donated to Cyanogen and if you also want to contribute to his efforts, go ahead and Buy him a beer
Read on...

Feb 11, 2010

5 things I hate about Google Buzz

Google recently released a new social marketing platform known as Google Buzz. If you have a Gmail account you have probably heard of it. I'm always willing to evaluate and use a technology if it's good, but this time around I find myself resenting a company that I've grown to respect over the years. Here's why:


1. It punishes entrepreneurship.

Like Apple, Google has chosen to rewrite an application that provides functionality they want rather than engage another company to form a partnership. Apple's done it to Delicious Monster and Watson and now Google has done it to FaceBook and Twitter.

In other areas, such as starting a broadband initiative, creating the ChromeOS, or even selling Android phones, Google has taken a defensive position to prevent OS makers, handset makers, or even ISPs from filtering the ads that they depend on for revenue. Face it, if Google ads couldn't be served on the iPhone, on Windows, or to computers connected via Comcast, their valuation would suffer in a hurry.

With Buzz however, they are fighting the possibility that they can't *reach* facebook's site and that Facebook can make their own deals. Nothing Facebook does here is in any way a threat to Google's existing business. It may shift advertising dollars but that's hardly anything any company does not have to deal with, especially in tough economic times. With this attitude, Google should acquire Bathroom stalls and billboards as those are also places that compete with advertising budgets.

The only way I can see this not being awful is if it's an attempt to lower the valuation of either Twitter or Facebook to make an acquisition possible. This is similar to what happened with YouTube and Google's own Video service. But unlike with Google's initial entry into Video...

2. They played a heavy hand

Yeah, they threw Buzz right in our face, didn't they? A HUGE button to opt in with a tiny little link next to it to say no thanks. And suddenly you found yourself following and being followed by a ton of people. That's beyond desperate, it's dishonest. That's no better than sending solicitations by mail that look like invoices in the hopes of tricking unwary people. Google, with their "Don't be Evil" motto, clearly failed here.

3. It doesn't fit in with Google's main goal which is "to organize the world's information and make it universally accessible and useful."

But they're organizing information, right? No.. they're creating information which they then organize. By this argument Google should get into the market of writing Fiction novels and English lit books so they can then organize them. There is a big bright line between organizing information and creating a tool that allows the creation of information. (By the way, this blog is hosted on Blogger which is owned by Google, and if I were them I would not have bothered with purchasing it either.)


4. It hurts productivity at the workplace or reduce's gmail's accessibility

Believe it or not, there are companies out there that block sites like Facebook, Twitter, and eBay. Those companies are now faced with the possibility of having to block mail.google.com or all of google.com. Employees who were once able to check their gmail during the day won't be able to do it in the future because of newly added firewall rules that they feel give them back some productivity from their facebooking, tweeting, chatting, net-surfing workforce. I've already fielded one request to block mail.google.com for a customer as I'm sure are others.

5. It's downright monopolistic

Having a monopoly isn't illegal. Using that monopoly to extend yourself into other areas is. Microsoft has been smacked down dozens of times from bundling apps in Windows because of it. This move by Google is no different. They are using their Gmail base and extending it to develop traction into social networking. Now, Gmail *isn't* a monopoly which is why this is safe, but the general trend here to leverage one product that I like to make me use another one that I didn't ask for, is the exact same behavior.

There are a number of things I *haven't* discussed (privacy, features, etc) as I generally don't have a problem with them. Still, overall I'm incredibly disappointed with this latest move by Google and yes, I hope it fails.

By the way, you can scroll to the bottom of your Gmail and click the tiny tiny link that says "turn off buzz"
Read on...

Feb 10, 2010

Quick Tip: Compiile nginx/passenger with SSL

I recently installed Ruby Enterprise Edition on one of my stacks. While you need to rerun the apache install module there's no word on whether that's necessary if you use Nginx. I thought it better to just recompile rather than just risk it. Problem is that if you need SSL with Nginx the default Phusion installer won't help you unless you choose the advanced route.


Assuming you used the Ubuntu package for Ruby Enterprise Edition:

Step 1: Download nginx, untar it and put it into /tmp/

wget http://nginx.org/download/nginx-0.7.65.tar.gz
sudo mv nginx-0.7.65.tar.gz /tmp
cd /tmp
tar xvzf nginx-0.7.65.tar.gz


Step 2: Run the phusion installer for nginx:
sudo /usr/local/bin/passenger-install-nginx-module


Step 3: When it asks you, choose the advanced option [2]

For the location of nginx, enter the path from Step 1.

--> Where is your Nginx source code located?

/tmp/nginx-0.7.65


Step 4: When it asks you for extra arguments, enter this one for SSL
--> Extra arguments to pass to configure script

--with-http_ssl_module


And then it should happily go about compiling nginx with SSL support. From there it's just a matter of following the instructions the installer gives you!

Read on...

Feb 4, 2010

Quick Tip: Access your Rails Helper from the console

Earlier today I was investigating a problem with some code that worked in development but failed in staging. It all centered around one of my helper methods. Being a bit lazy at the time, I tunneled into the server and dropped into console. But there was a problem.. I couldn't access my helper method from script console.. so what to do?


Luckily, you can pull the helper in fairly easily. In my case I wanted to pull in a TeamsHelper.. I did so using the following command:

helper.extend TeamsHelper


After that, getting to a method in my Teams Helper was straight forward. For example

helper.current_status(Team.first)
=> Active


Read on...

Jan 27, 2010

Install Communigate Pro on Ubuntu Hardy Heron

This is another blog entry from my old site that I'm going to keep around just in case. Will probably write this one up again once a new LTS is out.

I love free software. But, there is something to be said for paid support. When it comes to email, sometimes a robust mail server is just what the doctor ordered. Communigate Pro has been doing the job for large scale ISPs for a while now so back when one of my clients needed a solution I didn't hesitate to recommend it. I've no regrets except for one: the initial install was on a CentOS machine. Nothing against CentOS or Red Hat, but I prefer Debian based distros. And while the CG Pro mail server install instructions exist for Windows, MacOS X, FreeBSD, and many Linux distros, Ubuntu is currently not one of them. Fortunately it turns out it's not that bad to get it going. Here's what you need to do.




Step 1 - Update and upgrade: I bet you didn't see that coming?




sudo apt-get update
sudo apt-get dist-upgrade


Step 2 - Grab needed tools and use 'em: In our case we'll only need alien, an application that converts RPM files into DEB files.


sudo apt-get install alien
sudo alien CGatePro-Linux-5.0-14.x86_64.rpm


As you can see in our example above, I'm assuming that you've downloaded the RPM from Communigate. In my case I'm running version 5.0-14. Your version may vary.



Step 3 - Install: The process for install a deb file is very easy just type this in, replacing the name of the deb with what you generated in Step 2.




sudo dpkg -i cgatepro-linux_5.0-15_amd64.deb


Step 4 - Modify files At this point CG Pro is installed and it will work. But when you first launch it you'll get a bunch of errors like ulimit: 43: Illegal option -u and librt.so.1: cannot open shared object file: No such file or directory. These aren't deal breakers but we should fix them anyway. To do that, pop open your favorite text editor and modify the /etc/init.d/Communigate file. Here are the changes you want to make:




  • Change the first line from #!/bin/sh to #!/bin/bash

  • Change the assumed kernel line to use 2.6.16

  • Change all instances of /var/lock/susbsys/Communigate to /var/lock/Communigate



Step 5 - Launch and default run on boot With that done you'll need to start Communigate, make sure there are no errors and then set it to boot in case your server needs to be restarted.




sudo /etc/init.d Communigate start
sudo update-rc.d Communigate defaults


When you restart your machine, just check that Communigate Pro is running using ps -aux | grep CGServer. Hopefully you'll see all the spawned daemons. There are of course plenty of authorized CG resellers and Stalker themselves gives great support so if something didn't go according to plan you should contact somebody there. Of course my employer could also provide paid support if you need it. :-)


Read on...

Installing Git on a server (Ubuntu or Debian)

I'm shutting down my old blog for good soon.. This is one of the last popular articles from that blog (from July 2008) that is still relevant. I haven't followed these directions in a while but they should still work. YMMV:

There are lots of great instructions out there for using Git so you may not be interested in another one. Mine is no doubt imperfect as well, but I didn't find a front-to-back tutorial for getting rolling with Git on your own centralized server. I ended up cobbling information together from a bunch of sources (which I will list below). Mostly for my own benefit, I'm posting what I learned here. Feel free to ignore or read on as you desire.. By the end of it we'll have installed Git on a server, created a repository on that server, and checked in code from our local machine.










Step 1: Install Git. You'll have to do this ON BOTH YOUR SERVER AND LOCAL MACHINE. If you're running a different OS for your client find and check out instructions for installing git on that OS instead. See this link for OS X if you don't have Mac Ports.




sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install git-core


Step 2: Set up the server. We'll have to do some work on the server. We're going to use Gitosis which needs python and a python setup tool to get running. Grabbing the python setup tool in Debian/Ubuntu will grab all the requirements if you don't already have them:




sudo apt-get install python-setuptools


Step 3: Gitosis. Now it's time to get Gitosis. For the most part I followed the instructions on scie.nti.st, so full credit and many thanks to them. Once you're done with my instructions, I recommend you go visit them and read more details on adding users and some other advanced topics.



From your home directory on your server, create a new directory called src, and from there grab the gitosis code.



mkdir ~/src
cd ~/src
git clone git://eagain.net/gitosis.git


Install it using the python setup tool we grabbed earlier.




cd gitosis
sudo python setup.py install


Step 4: Setup some security. We're next going to add a new user called git. This is the guy that will do all the heavy lifting for us!




sudo adduser \
--system \
--shell /bin/sh \
--gecos 'git version control' \
--group \
--disabled-password \
--home /home/git \
git


IMPORTANT: If you have locked down ssh, don't forget to go into your /etc/ssh/ssh_config file and add git to the list of Allowed Users that can login. That list of users is separated by a space not a comma.



I always encourage the use of public/private key exchange and in the case of gitosis it looks to be required. Generate a key if you haven't already. See instructions for public/private key here. I'm going to assume that from this point on you can access your server from your local machine using a public key exchange!



Next, copy your id_rsa.pub file over to your server somewhere (in our example we're using /tmp) and then run this command:




sudo -H -u git gitosis-init < /tmp/id_rsa.pub


You'll see output like this:




Initialized empty Git repository in ./
Initialized empty Git repository in ./


Others have reported seeing that 3 times but when I did it on Ubuntu Hardy Heron I only saw it twice.



Step 5: Minor permissions tweak. Just in case, let's make sure permissions are set correctly:


sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update


We're now done with the server config! From your local machine, test it out with this:




git clone git@YOUR_SERVER:gitosis-admin.git


If all went well you have a gitosis-admin directory with a gitosis.conf file and keydir directory. We're basically setup now. We just need to create a new repository and push it to the server.



Step 6: Configure gitosis for a new rails project. Use your favorite editor to create a new block under the gitosis one. It should look like this:




[group myrailsapp]
members = vince@urbanpuddle
writable = myrailsapp


A couple of things to watch out in the above block. First, make sure your name matches what's in your public key (that is, open your id_rsa.pub file and see that what the name says. Mine says vince@urbanpuddle so that's what I have above. Yours will be different.) Second, make sure you spell writable correctly!



Once you're done, commit and push the changes up to the server.



 
git commit -a -m "created a new repository!"
git push


What we've basically done in this step is configured gitosis to accept a new repository. We then submitted that new configuration to the server using Git itself. Genius!



Step 7: Put your local code under version control. Now that the myrailsapp project is waiting for us on the server let's go put it under version control on our local machine.




cd myrailsapp
git init


As you may have heard, most of the goodness with git is in a special hidden .git directory at the root of your project. That's pretty cool since it means removing your project from version control is as simple as erasing that directory. Way easier than subversion.. especially if something goes wrong..



If you're a Rails developer you may want to blacklist some things from being under version control. Open up a text editor and create a file called .gitignore in the root of your project directory. Fill it up with this goodness:




.DS_Store
log/*.log
tmp/**/*
config/database.yml
db/*.sqlite3


Thanks to Ryan Bates for the above. If you haven't checked out Railscasts 96 you should do that as well. There's good info on creating empty files in a few empty directories to make sure they're under version control.



Step 7.5: Designate the server as a remote repository. An interim step here is to remote add the files to the server we set up previously. Honestly I'm not sure what's going on here under the covers but it's necessary..




git remote add origin git@YOUR_SERVER:myrailsapp.git


Step 8: Add files and commit! Let's add everything to git, (note the trailing dot) and then push your initial commit to the server.




git add .
git commit -a -m "initial import"
git push origin master:refs/heads/master


Once that's done you're done! You can grab your code from any place that has public key access to your server using this command.




git clone git@YOUR_SERVER:myrailsapp.git


Again, please please go check out this post which was the inspiration for 90% of what you just read. They did a great job and go into more detail in some spots than I did. You'll also likely find questions and answers to any errors you encounter on the way there.



Also, as promised here are some resources:




Last thing, if you're on Debian or Ubuntu and follow the Peepcode, keep in mind you'll need to separately install gitk.




sudo apt-get install gitk

Read on...