Friday, September 6, 2013

Tunneling SSH over SSH

Here's the problem.  Let's say your network is locked down so that a server called loqued only accept connections from a single host called trapdoor.  You could constantly ssh to trapdoor and then to loqued, but it's sometimes nice to abstract this away.  Here's how:

ssh zera@trapdoor -L 9000:loqued:22 -fN
ssh -p 9000 zera@localhost

Saturday, March 2, 2013

Installing Solr on Ubuntu 12.04

These instructions were created on a fresh Ubuntu 12.04 install.  The only problems I ran into were permission-related.  Here goes the obvious part, update and install Tomcat and Java:

$sudo apt-get update
$sudo apt-get install tomcat6
$sudo apt-get install openjdk-6-jdk

Grab the Solr from a mirror:

$curl -O

Now setup Solr, assuming Solr will be installed under /home/solr and the directory exists (make an account called solr if you want).

$sudo cp solr-4.1.0/dist/solr-4.1.0.war /home/solr
$sudo cp -R solr-4.1.0/example/solr/*/home/solr
$sudo mkdir /home/solr/collection1/data /home/solr/collection1/lib
$sudo chmod 770 /home/solr/collection1/data
$sudo chgrp tomcat6 /home/solr/collection1/data

The data /home/solr/collection1/data directory contains all the data for the Solr index.

Last, setup Tomcat by adding a single file:

$sudo vi /etc/tomcat6/Catalina/localhost/solr.xml
<?xml version="1.0" encoding="utf-8"?>
<Context docBase="/home/solr/solr-4.1.0.war" debug="0" crossContext="true">
  <Environment name="solr/home" type="java.lang.String" value="/home/solr" override="true"/>

$sudo /etc/init.d/tomcat6 restart

Navigate to localhost:8080/solr to see a slick UI.

If you run into problems, ensure the tomcat6 account can read all Solr files and has full permission to the data directory.

Saturday, December 22, 2012

A short tutorial on RVM

RVM is the equivalent of Python's virtualenvs.  Here's how to get started.

First, install RVM from with these instructions.

Workflow is as follows, where some_name is a token name for your environment and some_software is rails for example:

rvm gemset create some_name
rvm gemset use some_name
gem install some_software .gems
rvm gemset export some_name
RVM  can import a Gemfile thusly:
rvm gemset import some_name.gems

Thursday, November 22, 2012

Zombie Movies

I was almost eleven-years-old when I saw my first zombie movie.  The movie was Return of the Night of the Living Dead, featuring sexualized punk rockers, death, and the military in no particular order.  I was scared for the next year ... or 25.

The zombies struck a chord of dissonance in my mind.  They were unlike the other monsters I had known.  The zombie obeys no rules for one -- no fear of God, full moon, silver bullets, garlic.  My young Catholic-trained mind couldn't reconcile that zombies didn't fear a cross or a church.  They were manmade and the byproduct of a radiation, an obvious code word for nuclear war.

My subconscious reasoned thusly: if radiation creates zombies and I don't understand radiation then there is no known reason not to believe a zombie is possible.  So I rode my bike home extra fast, planning my zombie-avoidance and defense strategy in case my suburban neighbors become infected.

I feared my neighbors.  Civilization was a threat.

In the original Night of the Living Dead (1968), the hero is a black man named Ben.  Ben is the only capable character, and the only character who isn't paralyzed with fear or paranoia.  But his entire life has been the night of dead.  The masses have passed laws against him and actively tried to destroy him.  His entire life has been training for the night of the living dead.  He's shot dead by the white militiamen  at the end of the movie, "mistaken" for a zombie.  The viewer is left to construct what would have happened had he not been murdered.  Would he be allowed to join the militia?  How would the militiamen respond to a sole black survivor?

I'm a big fan of Civilization and  Its Discontents.  The premise is the dichotomy between the individual's desire for freedom and civilization's desire for order.  The individual surrenders freedom in exchange for civilization's benefit -- a 9 to 5 for not dying during childbirth.  The zombie apocalypse represents the collapse of the individual and civilization contract.  Civilization turns against its members.  The rescue message from Dawn of the Dead is obvious: ALIVE INSIDE painted on the roof of a mall and symbolizing the individual's struggle against civilization.  The survivors grotesquely resume their former lives in the comfort of consumerism.  But the zombies are attracted to the mall as well, drawn by the shadows of their former existence.  We feel we are the ones who are alive inside and the others are the zombies.

Another film to mention is REC (the Spanish version).  The outbreak in REC seems to be caused by a possession rather than a scientifically knowable fact. REC also takes place in a quarantine, rather than civilization as a whole.  The characters are pitted against each other and the undead.  REC is a good scary zombie movie, but lacks the overt social commentary of american zombie movies.

Wednesday, November 14, 2012

Python Virtualenvs

There are very few things I'm willing to say I hate in public, but I hate managing packages.  Fortunately Python makes this really easy.  Here's how.

First, get pip.  If you're on Ubuntu, do:

$ apt-get install pip

On Mac do (requires setuptools):

$ curl -O
$ gunzip -c pip*.tar.gz | tar xvf -
$ cd pip-1.2.1/
$ sudo python install

Second, get virtualenvwrapper.  Here's how:

$ pip install virtualenvwrapper

Third, start using you virtualenvs.  Here's how you make a virtualenv for you project called my_project:

$ which
$ source $(which
$ mkvirtualenv my_project

Notice your prompt will change.  Add the FQP to your profile if you want.  Next leave your virtualenv:

$ deactivate

Now reactivate:

$ workon my_project

Last, and here's the awesome part.  Install software into your virtualenv:

$ workon my_project
$ pip install django
$ pip install django-celery

But you'll also want to be able to recreate this virtualenv on another machine, so create a requirements.txt file using pip freeze:

$ pip freeze > requirements.txt

Alright, now your coworker needs to workon this project.  You coworker would checkout the repo and:

$ mkvirtualenv my_project
$ pip install -r requirements.txt

Oh, and one more piece of awesomeness: you can add git repos to requirements.txt, which is very useful if there's a bug fix not yet on pypi:


Tuesday, August 21, 2012

Random thoughts

37 signals drives me insane.  Reading this post almost ruined my day.  Having graduated from one of the most pretentious fine art institutions in the country, I can safely say that a lot of people see themselves at the top of this pyramid.  The problem with self-identifying at the top of such a hierarchy is that it leads to an insidious self-awareness.  I can almost certainly guarantee you, nobody will read your code and think it is beautiful because nobody will give a shit about your code. It's computer code, not poetry.

Twitter freaks me out.  One of the fundamental principals of Newspeak was the inability to express meaningful thoughts.  Twitter is a highly digestible format for a particular kind of reader.  There must be a self-satisfaction in knowing everyone agrees with you and you agree with them.  Scares the life out of me, but I still think Twitter is awesome.

PHK's a Generation Lost in the Bazaar is a good read.  However, the issues he claims are problems will continue to grow (especially since hardware tends to compensate for wasted cycles).  A coworker of mine described programming as mastering confusion rather than understanding processes.  There's a coherent thought here somewhere ... but the kind of personality rewarded by the cathedral tends to be less qualified than the personality rewarded by the bazaar.  What I mean is that the cathedral produces incompetent dictators.  Second, the world is undergoing a technology blitz now so it's better to be wrong than nothing at all.

Saturday, August 4, 2012

backbone.js & couchdb

This blog post is about some code I wrote to solve a problem.  I didn't care for the existing solutions, but I now think that I don't care for the problem.

My initial interest in backbone was as a tool to quickly prototype UI couchapps.  Specifically I wanted an easy way to modify collections of documents in CouchDB on a web page.  Unfortunately, that wasn't as easy as I expected.  So here's some of what I learned thus far.

Using jshint or jslint will save time.  I've spent hours debugging JavaScript in the browser (which is less painful thanks to Firebug and Chrome) and hours debugging JavaScript in PhoneGap projects.  Debugging syntax mistakes in a chromeless browser over ADB is a nightmare.

Writing test cases for async code is a nightmare.  Qunit sucks for async testing, but is a great tool otherwise (haven't tried jasmine yet).  The right solution is to test with node (specifically using mocha).  So, I had to learn a little about node and here's the magic.

setup(function(done) {

The setup function takes a parameter called done, which indicates setup contains async code and is also a callback to indicate the async code is complete.

Separate a ReSTful interface into components.  Don't make one giant method for everything, separate create/read/update/delete into methods invoked from sync: 

    Couch.Model.prototype.sync = function(method, model, opts) { 
        if (debug); 
        switch (method) { 
        case "read": 
            return, model, opts); 
        case "create": 
            return, model, opts); 
        case "update": 
            return, model, opts); 
        case "delete": 
            return, model, opts); 
This is good practice for server side code too.  Separate the storage layer from API so that the storage layer can be used outside the API.  The reason I mention this is that most Backbone users will probably implement server side ReST views rather than Backbone.sync.

Why are id and rev sometime prefaced with an _?  Seriously, why is there an _ sometimes?

99% of all applications require a server-side controller with record read access.