Cameron Stokes's Blog

Using Gradle to Build CoffeeScript

Here’s a simple Gradle script for building and cleaning CoffeeScript with two tasks: coffee and clean.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.gradle.plugins.javascript.coffeescript.CoffeeScriptCompile

apply plugin: 'coffeescript-base'

repositories {
  mavenCentral()
  mavenRepo name: "Gradle", url: "http://repo.gradle.org/gradle/repo"
}

def sourceDir = "src/main/coffeescript"
def buildDir = "src/main/webapp/compiled"

task clean( type: Delete, overwrite: true ) {
  delete buildDir
}

task coffee( type: CoffeeScriptCompile ) {
  source fileTree( sourceDir )
  destinationDir file( buildDir )
}

2012 in Review

My highlights of 2012:

  1. In January, I spent a week with Rhonda (my fiancé at the time) in Japan. Rhonda went to Japan for work and extended her trip a week so I could join. We visited Kyoto, Hiroshima, Nara, and Tokyo.
  2. In March, we lost our dog, Blue, to cancer. He went from seemingly healthy to very sick in the span of 2 weeks. He was 10 years old and my best friend.
  3. In April, five friends and I went to Europe for my bachelor party. We flew to Munich, rented a huge van, and drove over 1800 km, spending time in Munich, Prague, Berlin, Amsterdam, Brugge, and Brussels. Beer was certainly the theme of the trip as we visited many beer bars and breweries including Weihenstephan and Cantillon.
  4. In May, after almost 10 years, I married Rhonda on Hilton Head Island. We had an awesome wedding with all of our closest family and friends. Planning the wedding over 2,000 miles away was difficult but it went off without a hitch. If we could have the same celebration every year, we would.
  5. In June, I went to Bonnaroo Music Festival in Tennessee with friends. It was our 8th year in a row attending and the first year we rented an RV. The RV has now become a requirement for all future visits as it made the festival much easier and more comfortable.
  6. In August, I resigned from InterContinental Hotels Group, my employer for over 9 years, for an opportunity at The Weather Channel. It was a tough decision to leave longtime colleagues and friends, but the move has allowed me to focus on recent interests of mine such as cloud computing, PaaS, devops, and more.
  7. In September, I participated in Tough Mudder and had a blast. I trained for several months leading up to it and it definitely paid off. It would have been excessively tough had I not put in the extra effort preparing for it. I plan on participating in the 2013 Tough Mudder as well.
  8. In November, Rhonda went to Shanghai for work and again we extended her trip to allow for some vacation. I met her in Shanghai and we visited Hangzhou, Tunxi, and Huangshan Mountain. The trip was especially exciting for both of us as we booked our flights on All Nippon Airways so that we could fly on the Boeing 787 Dreamliner - the plane that Rhonda has worked on at Boeing for the past 2 years. In a complete surprise, I was upgraded to business class on the flight over so I was able to truly experience the new plane in all its glory.
  9. Also in November, I turned 30 years old. It happened that I was in Las Vegas at the time for the AWS re: Invent conference and Rhonda surprised me by showing up at my hotel room door at midnight, having taken the late night flight from Seattle to meet me there. A few other friends were also in town for the conference and we had a great time celebrating my birthday with all of them. After Las Vegas, I flew to Chicago to meet a few other friends for the weekend and the celebrations continued there.

In between all of that, I traveled to Atlanta over 10 times and San Francisco a handful of times for work. I flew over 90,000 miles and spent over 2 months away from home. What a year…

Service Issues With Puppet on Amazon Linux - Fixed!

Puppet has been on my list of tools to learn for a while now (and Chef and cfengine and Ansible and …) and I finally had a chance to take it for a spin.

I started with the Puppet Enterprise virtual machine from Puppet Labs and the excellent Learning Puppet series. Soon I had the basics down and decided to try Puppet “in the wild” on Amazon EC2 with an Amazon Linux AMI.

Installing Puppet was as easy as running sudo yum install puppet and setting up a module was just as easy as in the VM, but Puppet wouldn’t start my service as I had instructed. My very basic httpd module looked like this:

1
2
3
4
5
6
7
8
9
10
11
12
class httpd {

  package { 'httpd':
    ensure => installed,
  }

  service { 'httpd':
    ensure => running,
    enable => true,
  }

}

Puppet would enable the httpd service properly with chkconfig, but it would not start it.

I started debugging Puppet with the -d flag and saw this:

1
2
3
4
5
6
7
8
9
10
11
[ec2-user@ip-10-252-3-70 modules]$ sudo puppet apply -de "include httpd"
...
info: Applying configuration version '1345229077'
debug: Service[httpd](provider=redhat): Executing 'ps -ef'
debug: Service[httpd](provider=redhat): PID is 26564
debug: Puppet::Type::Service::ProviderRedhat: Executing '/sbin/chkconfig httpd'
debug: Finishing transaction 70128127580220
debug: Storing state
debug: Stored state in 0.00 seconds
notice: Finished catalog run in 0.07 seconds
[ec2-user@ip-10-252-3-70 modules]$ 

For some reason Puppet wasn’t using the service commands, but was using ps to look for the httpd process and deciding it was running when in fact it wasn’t.

I initially thought it may have been because Puppet wasn’t recognizing Amazon Linux appropriately, but provider=redhat indicated it was. After some googling I found a post on Stack Exchange with the question Why can’t puppet start the dropbox daemon?. It turns out Puppet versions prior to 2.7 don’t use the /etc/init.d/service status command by default and the Puppet version from the Amazon Linux package repository was version 2.6.16. This was explained in the Puppet tutorial (here) but I had glossed over it.

I added hasstatus => true to my module and it worked.

1
2
3
4
5
6
7
8
9
10
11
12
[ec2-user@ip-10-252-3-70 modules]$ sudo puppet apply -de "include httpd"
...
info: Applying configuration version '1345229517'
debug: Service[httpd](provider=redhat): Executing '/sbin/service httpd status'
debug: Puppet::Type::Service::ProviderRedhat: Executing '/sbin/chkconfig httpd'
debug: Service[httpd](provider=redhat): Executing '/sbin/service httpd start'
debug: Puppet::Type::Service::ProviderRedhat: Executing '/sbin/chkconfig httpd'
notice: /Stage[main]/Httpd/Service[httpd]/ensure: ensure changed 'stopped' to 'running'
debug: Finishing transaction 70256658307520
debug: Storing state
debug: Stored state in 0.00 seconds
notice: Finished catalog run in 0.25 seconds

My module now looks like this and successfully installs and starts httpd on Amazon Linux.

1
2
3
4
5
6
7
8
9
10
11
12
13
class httpd {

  package { 'httpd':
    ensure => installed,
  }

  service { 'httpd':
    ensure => running,
    enable => true,
    hasstatus => true,   # <--- The fix.
  }

}

Overriding Hibernate in a Grails Application

I was working on a proof of concept application recently in which I needed to use an internal middleware library to access some backend services. As I usually do, I jumped to Grails for my POC and worked to pull in our middleware library. After struggling with many other issues unrelated to Grails, I ended up with some incompatibilities between the Hibernate version included in Grails and the Hibernate version in our library. On a whim, I removed the Grails version from the packaged application and was able to get things up and running.

If you need to do remove Hibernate from your generated war file, add the following lines to the bottom of your ./application-name/grails-app/conf/BuildConfig.groovy file:

1
2
3
grails.war.resources = { stagingDir ->
  delete( file: "${stagingDir}/WEB-INF/lib/grails-hibernate-2.0.3.jar" )
}

More information on customizing the Grails build can be found here.

Warning!

This can potentially cause other issues in your application as swapping dependency versions can cause other incompatibilities to surface. Having said that, in my case it worked and it may work for you too.

Beer Review: Flying Dog Wild Dog Collaborator Doppelbock

Wild Dog Collaborator Doppelbock is a Doppelbock lager by Flying Dog Brewery in Frederick, Maryland. It was brewed in the Summer of 2007 and released at the Great American Beer Festival that year. As the label states, Collaborator was an “open source beer”. A beer whose recipe was created by the brewery and its fans and released to the public. How cool is that!

Unfortunately, much of the story of how Collaborator came to be is lost. There is no mention of Collaborator on the Flying Dog website and the original Open Source Beer Project website (www.opensourcebeerproject.com) is no longer available. Fortunately there is an archive of the website on the Internet Archive here. From the archive, we can read a bit of the process Flying Dog took in creating the recipe, the artwork, and its release. Following the release the brewery talked of follow-up versions of the doppelbock recipe (v1.1) and a completely new beer (v2.0). It’s at this point that the concept seemed to fade away. The last post on the site was in June of 2008 and the most recent comment from the brewery was in March of 2009 on twitter.

Also worth noting, Flying Dog is the first craft beer I can remember having. I had their Doggie Style Classic Pale Ale at a Taco Mac in Marietta, GA however long ago it was. I remember thinking, “Wow, it’s kind of fruity!” which must have been my naive tongue picking out the Ale qualities of it in contrast to the quantity of Bud Light I had drank before it.

Beer Facts

Name: Wild Dog Collaborator Doppelbock

Brewery: Flying Dog Brewery

Style: Doppelbock Lager

Released: One-Time

Availability: 750ml.

Description:

It may seem like we say this every time we release a Wild Dog beer, but our newest brew really is Flying Dog’s most unique beer to date. Collaborator Doppelbock was created through Flying Dog’s Open Source Beer Project, which gave amateur brewers a chance to give our brewing team recommendations and feedback on the everything from the grain, hops and yeast to the brewing process itself. We combined your feedback and created a unique Doppelbock recipe to brew up and release. Collaborator has a full body with a sweet malt profile and a slight roast character. The complete recipe and printable labels are available for download at www.OpenSourceBeerProject.com. We want to thank everyone who contributed to creating this beer, it truly was a collaboration.

As with their other beers, Collaborator’s artwork is from Ralph Steadman, best known for his work with Hunter S. Thompson. It’s Mr. Steadman’s artwork that first drew me to Flying Dog beers. Their Doggie Style Pale Ale is the beer that turned me on to craft beer many years ago.

Hops: Warrior, Mt. Hood

Malts: 75% Munich Type 1, 9% Munich Type 2, 2% Cara Munich, 2% Cara Amber, and 2% Melanoidin.

Yeast: Wyeast 2206 Bavarian Lager

OG: 19.5° P

FG: 5.0 – 5.5° P

IBUs: 22 – 25

ABV: 8.3%

Tasting

Serving: 750ml. corked and caged bottle into a Frankfurt Mug

Appearance: Dark amber/copper color. Very clear and crisp. Half-inch of off-white head that fell quickly.

Aroma: Very sweet and malty. In a blind “smelling” I would have placed this as a barleywine.

Mouthfeel: Medium mouthfeel. Slightly slick and viscous.

Taste: Not as sweet as it smells, actually kind of dry. Fruity malt flavor also some slight toastiness. No hop presence. Slight oxidation certainly due to its age.

Conclusion

Collaborator is a solid Doppelbock - a style that is dominated by German breweries with few American representations (perhaps rightfully so…). The aroma was intensely sweet and I was happy that intensity did not carry over to the taste. At 8.3% this was a very drinkable beer.

By the time I popped open this beer, it was just over 5 years old. When I purchased this beer I had no intentions of keeping it this long. It ended up in the back of my beer fridge and was subsequently forgotten. From time to time I would dig to the back and find it again, but never found the right time for it. After a few years it seemed too callous to just drink it so I waited for a special occasion.

That special occassion came on a seemingly normal Thursday night. I had made home-made mustard earlier in the week for the first time and wanted to try my hand at home-made pretzels. My wife Rhonda made Wiener Schnitzel and Spätzle for dinner. With our very German dinner and appropriately German beer (though American-made…), we watched The Dark Knight) then saw The Dark Knight Rises at the midnight showing that night.

A lot goes into enjoying a beer: where, when, how, why it’s enjoyed, etc. Of course the beer itself has a great impact on the experience, but the rest of the circumstances can play a significant role as well. In this case, this was a perfect night for this beer and it definitely added to its enjoyment.

Food pairings: German Food of course.

Cellar-able: Yes, but probably past its prime at this point.

Comparable beers: Ayinger Celebrator, Thomas Hooker Liberator, Weihenstephaner Korbinian.

Links