Monday, December 12, 2011

Free Chromebook

I'm on a plane at the moment, flying to Chicago. It turns out, Google is promoting its Chromebooks by offering them free for the duration of your flight. You give them your name, email address and swipe a credit card, and you get free use of a Chromebook and on board wi-fi. This is great for two reasons. First, I can entertain myself with cat pictures and rage comics for the three hours it will take me to get to Chicago. Second, I get to play around with a Chromebook.

I've only been using it for about a half an hour, but already I can say I would not buy one of these. The main reason is that it is just not the right device for me. I mean, it's basically a computer that can only run Chrome. Don't get me wrong, Chrome is a great browser, but I just need my computers to be able to do more than that.

I do understand the use case for a computer like this. Let's say you run something like a large customer support call center. The software needs for your call center could easily be filled by web applications. With something like a Chromebook, if a computer craps out on you, IT can just grab another Chromebook off a shelf and your employee can get back to taking calls.

Unfortunately, even if I were in a position where a computer like this were to be useful, I still wouldn't buy a Chromebook. The experience of trying to write this blog post has been little short of infuriating. The hardware simply does not work well, at all. The keyboard regularly registers double key presses, resuultiing in worrds like thesee. The touch pad is not much better. It will often not register your finger movements at all. I suppose it's possible that these computers have seen a lot of miles, and a lot of different people have used them, but it just makes me wonder how long it would be before my own use would result in similar behavior.

One thing this experience has shown me is the appeal of a netbook. I brought my laptop with me on this trip, and I can see where my laptop would just be too big to comfortably use on a plane. It is also quite heavy compared to this. If I were to travel more, I think something like an Eee PC would be a worthwhile investment. But that will have to wait. I think my next purchase is going to be an Android tablet of some flavor so I can read on the train during my morning and evening commute.

Update: I'm waiting for my plane back to San Francisco, and they have the free Chrommebooks again. I'm just writing to confirmm that this CChromebook has the samme problems that the last one had. Ick. Oh, well. The frustration is worth the free wifi.

Friday, October 28, 2011

Damn it, I'm actually going to do it this time

I have dipped my toe in the water of Linux From Scratch (LFS) a couple times before, but I never followed through with it. Well, I'm making another go at it, but this time I intend to follow through. I'm applying to grad schools to study operating systems, and I'm recently unemployed which gives me plenty of free time. I also have two computers to work with, which means I can screw up my LFS system without having to worry about losing important data or access to a computer.

I'm in the middle of step one at the moment. I'm formatting the disks on my tower. I will install Ubuntu 10.04 on the smaller of the two disks, and the larger disk will be where I will build my LFS system.

Saturday, October 8, 2011

pH-kraut

Do you remember using purple cabbage as a pH indicator in grade school science class? I decided to combine that with my hobby of pickling.

As sauerkraut ferments it becomes more acidic, and since purple cabbage is a pH indicator, the sauerkraut should change color. I shredded a head of purple cabbage, mixed it with salt and thyme (yum!) and packed it into a plastic container. I took a picture every evening when I got home from work to see how it had changed.

I had hoped to post the whole series of photos here, but the sauerkraut didn't act as I had expected. The change was dramatic, but it happened too quickly for the series of photos to be of any use. The appearance of the sauerkraut did not change at all, until day 3 when it changed drastically. After that its appearance did not change again.


I will try this experiment again, but will have to change how I photograph the sauerkraut. I plan to set up a camera on a tripod taking pictures several times a minute so I can stitch them together into a time lapse video. Hopefully that will catch the dramatic change in detail, as well as some of the more subtle action like formation of bubbles.

And since I'm already pulling stuff off my camera, here's some dude rocking out on an old busted spinet piano at the MacArthur BART station.


Tuesday, September 13, 2011

Grails events

I couldn't find a complete list of Grails events, so I've tried to compile one. Using various text processing tools, I chewed through all of the Grails scripts in my Grails 1.3.7 installation, and here's what I came up with.
  • AppCfgEnd
  • AppCfgStart
  • AppLoadEnd
  • AppLoadStart
  • CreatedArtefact
  • CreatedFile
  • CreateWarEnd
  • CreateWarStart
  • DocEnd
  • DocSkip
  • DocStart
  • Exiting
  • GenerateControllerEnd
  • GenerateViewsEnd
  • InstallPluginStart
  • IntegrateWithInit
  • PackagePluginEnd
  • PackagePluginStart
  • PackagingEnd
  • PluginLoadEnd
  • PluginLoadStart
  • PluginUninstalled
  • SetClasspath
  • StatsStart
  • StatusError
  • StatusFinal
  • StatusUpdate
  • TestCompileEnd
  • TestCompileStart
  • TestPhaseEnd
  • TestPhasesEnd
  • TestPhasesStart
  • TestPhaseStart
  • TestProduceReports
  • TestSuiteEnd
  • TestSuiteStart
  • WebXmlEnd
  • WebXmlStart
I don't know what all of them do, but it should be easy enough to guess from the name.

Git and empty directories

One minor annoyance I have with Git is that it cannot track empty directories. This is especially annoying if you are working with an application framework, which creates an intricate structure of empty directories.

A common work-around you will see is to create an empty .gitignore file in each empty directory. It's not a very elegant solution, but it gets the job done. The trick is making sure you actually find every empty directory. So, I wrote a simple bash script, gitify.sh, to do it for you.
#!/bin/bash


gitify() {
    if [[ -z $(ls -1A "$1") ]]
    then
        touch "$1/.gitignore"
    else
        for file in "$1"/*
        do
            if [ -d "$file" ]
            then
                gitify "$file"
            fi
        done
    fi
}


rootdir=$(readlink -f .)


gitify $rootdir
Just navigate to the root directory of your Git project, and run the script. It will descend from the working directory into all subdirectories and drop a zero byte .gitignore file in any empty directory it finds. Just git-add all the newly created files and check them in to your repository.

I'm posting this not so much for the benefit of others as for myself. This is probably the fifth time I've written this script, because I keep losing it or deleting it. Maybe now that it's posted on the internet I won't lose it so easily.

Tuesday, May 10, 2011

Groovy on Grails: Serving static files from the root context

Grails is a great platform for web development, but there are certain things that are fairly trivial to do in a production environment that are rather difficult in a development environment. One of those is serving up static files from the root of your host name. These could be anything, like robots.txt or crossdomain.xml. It's simple enough to do this with Tomcat. Simply configure your ROOT context, drop in the files and you're done.

But how do you do this in a development environment? Generally, a developer will use the grails run-app command. This invokes a built-in instance of Jetty, which makes your Grails application available at the URL http://localhost:8080/yourApp/. It's easy enough to serve static files from below the yourApp directory. Simply drop them in the web-app folder in your Grails project, but there isn't any way to serve static files from above this.

The problem is that Grails is not designed to work this way. Many of the solutions I found online try to work against Grails' design, such as hacking at the internals directly, or forcing the configuration to serve everything from the root context. These have potential problems when it comes to things like upgrading Grails, or deploying to production.

Instead, I opted to find an external mechanism to serve these static files. This way the Grails application can remain untethered from the rest of its environment. It doesn't need to be aware of what's going on outside its context, its realm of control. This can be accomplished with Apache and mod_proxy. We can use Apache to serve documents from the root, then we can use mod_proxy to delegate any requests from a subdirectory to the Jetty instance used by Grails.

1. Install Apache httpd 2.2

The specifics of installing httpd are beyond the scope of this blog post. If your operating system has a packaging system (apt-get, yum, etc.), use that. If not, refer to the available Apache documentation.


For the rest of this tutorial, I will be assuming use of a Linux system.

Start httpd.
sudo /sbin/service httpd start
Test that it is installed correctly using a web browser.

2. Create a root directory

Pick a location on your disk where you will keep your static files. This will be the document root for httpd. I will be using /var/grails_root.
mkdir /var/grails_root
touch /var/grails_root/crossdomain.xml
3. Create a VirtualHost in httpd.conf

Open httpd.conf in your favorite text editor.
vim /etc/httpd/conf/httpd.conf
Pick your favorite port, and create a virtual host on that port. I will be using 9090, but any port will do.

Add these lines to httpd.conf
Listen 9090
<VirtualHost *:9090>
    DocumentRoot "/var/grails_root"
    <Directory "/var/grails_root">
        Allow from all
    </Directory>
</VirtualHost>
Restart httpd
sudo /sbin/service httpd restart
Test that you are now able to access the static files in your document root directory. If not, you will need to fix this before moving on to the next step.

4. Enable mod_proxy and mod_proxy_http

You need to load both of these modules. mod_proxy has the base functionality for proxying, and the mod_proxy_xxx modules have information specific to a protocol. They ship standard with httpd 2.2, so you shouldn't need to install anything extra.

Add these lines to httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Now modify the virtual host you set up in the previous step. (You can omit the comments)
<VirtualHost *:9090>
    DocumentRoot "/var/grails_root"
    <Directory "/var/grails_root">
        Allow from all
    </Directory>
# New lines start here
    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    ProxyPass /grailsApp http://your.grails.server:8080/grailsApp
# New lines end here
</VirtualHost>
Restart httpd
sudo /sbin/service httpd restart
Now, you should be able to access both your static files and your Grails app via port 9090.

More information on this can be found here.