Wednesday, October 13, 2010

Ritalin for your $PS1

In my last post I shared my colorful but otherwise inert bash prompt. Pedro Melo extended it to integrate __git_ps1 with extra coloring using git status.

Unfortunately this can take a long while on large source trees (git status needs to scan the directory structure), and while smart bash prompts are handy, it can be frustrating if every prompt incurs a delay.

Of course this is annoying for any over zealous $PROMPT_COMMAND, not just git status based ones.

My version of his version has a small trick to add simple but effective throttling:

_update_prompt () {
    if [ -z "$_dumb_prompt" ]; then

        # if $_dumb_prompt isn't set, do something potentially expensive, e.g.:
        git status --porcelain | perl -ne 'exit(1) if /^ /; exit(2) if /^[?]/'

        case "$?" in
             # handle all the normal cases
             ...
             # but also add a case for exit due to SIGINT
             "130" ) _dumb_prompt=1 ;;
        esac
    else
        # in this case the user asked the prompt to be dumbed down
       ...
    fi
}

# helper commands to explicitly change the setting:

dumb_prompt () {
    _dumb_prompt=1
}

smart_prompt () {
    unset _dumb_prompt
}

If the prompt is taking too long to show up I simply hit ^C and my $PROMPT_COMMAND becomes a quicker dumbed down version for the current session.

Tuesday, October 12, 2010

Headless VirtualBox

This being the second time I've set this stuff up, I thought it's worth documenting my VirtualBox development workflow.

A Decent Hacking Environment

The OSX side of my laptop is working pretty smoothly. I've got my stack of tools configured to my liking, from my shell, to my editor, to my documentation browser. I've spent years cargo culting all my dotfiles.

But pick my brain any day and I'll give you a mouthful about Apple and OSX. I also know that there are superior alternatives to most of my software stack.

That said, even if I'm not entirely happy with the setup, I'm definitely content with it, and I have no plans on learning anything new to gain a 3% efficiency in the way I type in text or customize the way I waste time online.

Part of the reason I use OSX is that there is no hope (and therefore no temptation) in trying to fix little annoyances, something that led me to sacrifice countless hours during the brief period of time when I had a fully open source desktop environment.

However, when it comes to installing and configuring various project dependencies (daemons, libraries, etc), OSX can be a real pain compared to a decent Linux distribution.

A Decent Runtime Environment

Disk space is cheap, and virtualization has come along way in recent years, so it really makes a lot more sense to run my code on a superior platform. One image per project also gives me brainless sandboxing, and snapshots mean I can quickly start over when I break everything.

Sweetening the deal even more, I always seem to be surrounded by people who know how to properly maintain a Debian environment much better than I could ever hope to, so I don't even have to think about how to get things right.

Bridging the Gap

In order to make it easy to use both platforms simultaneously, with cheap context switching (on my wetware, that is), I've written a script that acts as my sole entry point to the entire setup.

I don't use the VirtualBox management GUI, and I run the Linux environment completely headless (not just sans X11, without a virtual terminal either).

I hard link the following script in ~/bin, once per VM. To get a shell on a VM called blah, I just type blah into my shell prompt and hit enter:

#!/bin/bash

VM="$( basename "$0" )"

if [ -n "$1" ]; then
    # explicit control of the VM, e.g. `blah stop`
    # useful commands are 'pause', 'resume', 'stop', etc
    case "$1" in
        status) VBoxManage showvminfo "$VM" | grep -i state ;;
        *)      VBoxManage controlvm "$VM" ${1/stop/acpipowerbutton} ;; # much easier to type
    esac
else
    # otherwise just make sure it's up and provide a shell

    # boot the virtual machine in headless mode unless it's already running
    # note that there is a race condition if the machine is in the process of
    # powering down
    VBoxManage showvminfo --machinereadable "$VM" | grep -q 'VMState="running"' || \
    VBoxManage startvm "$VM" -type vrdp;

    # each VM has an SSH config like this:

    # Host $VM
    #     Hostname localhost
    #     Port 2222 # VBoxManage modifyvm "$VM" --natpf1 ...

    # changing ssh port forwarding doesn't require restarting the VM (whereas
    # fiddling with VirtualBox port forwarding does). The following section
    # should probably just be a per VM include, but for my needs it does the
    # job as is.

    # ControlMaster works nicely with a global 'ControlPath /tmp/%r@%h:%p' in
    # my ~/.ssh/config this means the port forwarding stays up no matter how
    # many shells I open and close (unlike ControlMaster auto in the config)

    # this loop quietly waits till sshd is up
    until nc -z localhost 3000 >/dev/null; do
        echo -n "."
        ssh -N -f -q \
            -L 3000:localhost:3000 \
            -o ConnectTimeout=1 \
            -o ControlMaster=yes \
            "$VM" && echo;
    done

    # finally, start a shell
    exec ssh "$VM"
fi

Once I'm in, I also have my code in a mount point under my home directory. I set up a shared folder using VirtualBox's management GUI (installing the VirtualBox guest additions like this). To mount it automatically I've got this in /etc/fstab on the guest OS:

# <file system>  <mount point>               <type>  <options>                       <dump> <pass>
some_dir         /home/nothingmuch/some_dir  vboxsf  uid=nothingmuch,gid=nothingmuch   0      0

I use the same path on the OSX side and the Linux side to minimize confusion. I decided not to mount my entire home directory because I suspect most of my dotfiles aren't that portable, and I'm not really running anything but Perl and services on the debian side.

I use all of my familiar tools on OSX, and instantly run the code on Debian without needing to synchronize anything.

When I'm done, blah stop will shut down the VM cleanly.

Finally, as a bonus, my bash prompt helps keep my confusion to a minimum when sshing all over the place.

Wednesday, October 6, 2010

Hire Me

I'm starting my B.A. at Ben Gurion University (Linguistics & Philosophy), and I'm looking for part time work (1-2 days a week) either telecommuting or in or around Beer Sheva or Tel Aviv.

If you're looking for a developer with strong and diverse technical skills, who is able to work either independently or in a team, feel free to contact me.

My CV is available on my website.

Note that I'm not really looking for contract work unless it may lead to part time employment as a salaried employee, as the overheads of being a freelancer are quite high (both financially and temporally).