Sunday, 8 March 2015

Can my GoCD plugin work with Java 8?

Background

A few weeks back I developed a plugin for the Go Continuous Delivery server software.

My main frustration with trying this on a Mac was that the Go Server installer insisted on locating a Java 6 installation.  A bit of Googling revealed that this can be a non-trivial feature to work around, so I gave up trying to run Go on a Mac and tried things out on my work Linux machine.

I only have a limited amount of time at work to do hobby based development, so I went looking for an alternative solution and found the Sample GoCD VirtualBox based environment.

This is pretty cool and enables me to try things out.

Upgrading Java

For my day to day development I have been programming with Java 8 for almost a year (I know it couldn't be a year yet because it wasn't released until mid-March 2014).

The VirtualBox environment only has Java 7 available, so my plugin development was restricted to the features available pre-Java 8.

During some refactoring of my plugin, I found myself extracting a method because it involve a bit of ugly nesting with a loop and a condition check - I want Java 8's features to filter and forEach instead.

Long story short, the upgrade steps for making the VirtualBox environment use Java 8 instead of Java 7 are as follows


  • Follow the JDK 8 installation instructions:
    • http://www.webupd8.org/2012/09/install-oracle-java-8-in-ubuntu-via-ppa.html
  • Update the go-server and go-agent files under /etc/default to point to the newly installed JDK's home as JAVA_HOME.


I found the location by tracing through some symbolic links, like so:

vagrant@vagrant-ubuntu-trusty-32:/etc/default$ ls -la /usr/bin/java
lrwxrwxrwx 1 root root 22 Jun 14  2014 /usr/bin/java -> /etc/alternatives/java
vagrant@vagrant-ubuntu-trusty-32:/etc/default$ ls -la /etc/alternatives/java
lrwxrwxrwx 1 root root 39 Mar  8 12:33 /etc/alternatives/java -> /usr/lib/jvm/java-8-oracle/jre/bin/java
vagrant@vagrant-ubuntu-trusty-32:/etc/default$ ls -la /usr/lib/jvm/java-8-oracle/jre/bin/java
-rwxr-xr-x 1 root root 5730 Mar  8 12:33 /usr/lib/jvm/java-8-oracle/jre/bin/java
With the config changes in place, a restart of the go-server and go-agent processes should get them to use the Java 8.

Navigating to http://localhost:8153/go/about should show something like:


Where the JVM version confirms that GoCD is indeed running with Java 8.

Now I can replace my refactoring with some Java 8 goodness.

Tuesday, 24 February 2015

Push versus Poll - Cloud Foundry CI plugins

Out of curiosity I recently Google'd what Jenkins plugins are available for Cloud Foundry.

Interestingly - for me at least - the approach the developers have taken is quite different to the direction I approached for the Go CD Cloud Foundry plugin.

While my plugin is focussed on detected when an application has been pushed, the Jenkins plugin supports the process for pushing an application.

So, if you've made it to my github or this blog and you were looking for a plugin for pushing - sorry, my thought process was a little different.

In the interests of shameless self-promotion, here's a link to my github repo:

https://github.com/stephen-souness-springer/springer-gocd-cloudfoundry-plugin

Monday, 23 February 2015

Experimenting with Go Continuous Delivery

If you're working on a Mac you may encounter an annoyance when installing the Go Continuous Delivery server.  It blindly insists on finding a version 6 JVM - even if a compatible later version is available.
After an initial attempt at adjusting the config, and a bit of Googling around I gave up on trying to make it work.
A week or so later I found myself using some spare time at home to develop a plugin on a Mac.  After a couple of days of having to wait until the following day to try out the functionality on my work Linux setup I came across some instructions for installing and using a Vagrant virtual box which contains a fully operational Go server.

http://www.go.cd/2014/09/09/Go-Sample-Virtualbox.html

I haven't used it extensively but it has made plugin development easier for me.

Friday, 20 February 2015

Go CD Cloud Foundry plugin

In February 2015 I developed a Go CD server plugin to enable triggering of builds when a Cloud Foundry application has been deployed.

This post is intended as an introduction to how to use this plugin.

A starting assumption is that you already have the plugin installed on your Go CD server.

Update: Binary jars are available:
https://github.com/stephen-souness-springer/springer-gocd-cloudfoundry-plugin/releases

The source code is also available on Github:
https://github.com/stephen-souness-springer/springer-gocd-cloudfoundry-plugin


Step 1

Navigate to the Package Repositories section of the Admin menu



Add a new repository with your CloudFoundry API credentials.
Update: In version 1.0.1 the password property has changed to be secured - so you won't see it in cleartext the way is is shown here.


To make sure that you have supplied the correct credentials - and confirm that your Go server can connect to Cloud Foundry you can use the Check Connection button before choosing to save the configuration.


You're now ready to include some Cloud Foundry configuration to a build pipeline with your newly available repository.

Step 2



The Check Package button will trigger a check on two levels - first that the supplied credentials can log in, and second that an application exists which starts with the specified App Name.

Step 3

The next step in your pipeline definition depends on what you want to do when a change is detected.  From the example settings above there will be an environment variable called GO_PACKAGE_MYCLOUDFOUNDRYDEV_SERVICEX_LABEL set with the latest matching detected app version.

Friday, 23 January 2015

Assembling a jar to include dependencies with Gradle

How to build a jar containing dependency jars with Gradle

As part of a hack day project at work I have started developing a plugin for use with ThoughtWorks Go CD.

After some initial confusion around how Go Server expects to find the plugin bundled, I realised that a jar file containing a lib folder of jars is the way to make it work.

The example plugins GitHub repository only showed the use of Maven as a project build tool, but I have gotten accustomed to using Gradle - so I need to do a bit of reverse engineering and searching online to find a way to produce a suitable jar to include the managed dependencies of my project.

Without further ado, here is the relevant snippet of Gradle configuration:

jar {
    into('lib') {
        from configurations.runtime
    }
}

This simply creates a lib directory within the generated jar.  The lib directory will contain the various jars that are pulled in by the managed dependencies.  By default this will include transitive dependencies.

This works with Gradle 2.2.1 and I would expect it to work for earlier versions.

Thursday, 15 January 2015

Basic readiness check before developing with micro services - DNS

So, you have your application nicely sliced up into purposeful, self-contained units which can call upon each-other as required - great.

Presuming each of these components is communicating over http, how are you going to deploy them and make them accessible to each other?  Why not use a beautiful Platform As A Service environment - developers can deploy new apps, and manage existing apps to their hearts' content without any assistance from other teams.  Lovely.

Ok, let's presume that your setup has big ambitions and limited IP addresses so you're going to need these applications to have hostnames.  No big deal, and easier to quickly verify what is what.  Who would use IP addresses directly - this is the 21st century!

What if DNS hasn't been set up to cope with some additional load.  It only craps out every other week, but when it does your applications can't reach each other.  Deployments fail, developers get stalled tracking down problems that they haven't caused.  Live demonstrations are now considered risky.

Welcome to my world.  It's the third or fourth time that I've bugged a team that should be able to trace this problem and arrange for it to be fixed (even temporarily).  Their response is that the impact seems to be broader than the single host that the app is currently complained about.  Their recommendation is to update the app's config with IP addresses for a while.

We have a central configuration system, but I don't think it is intended to act as a replacement for an /etc/hosts file.