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.

After publicly lecturing me about how the configuration management system should make dirty hacks like this (I'm paraphrasing) possible, they contacted someone who could flush a cache or restart the misbehaving service to solve the problem temporarily.

Sunday, 4 January 2015

Career safety checkpoint

As another year begins, I found myself struggling to get to sleep before the first day back at work.  This wasn't a new experience for me as I seem to recall the same sort of nervousness before the first day back at school as a child.

I consider this time of year to be a bit like travelling between very different timezones - just as I have gotten accustomed to going to bed late and sleeping late the following morning, it's time to adjust back to the work life routine.

One of the many thoughts that occurred to me when I should have been blissfully sleeping was whether my skills are still as relevant to my chosen career in software development.

In the morning I woke up early and decided to have a look at some source code from a system that my current project will be interacting with...

A section of code that particularly stood out to me involved something like 12 branches of if / else checks, where each comparison was against a constant defined earlier in the class, and each outcome also involved another constant.  This could easily be condensed down to two or three lines with one conditional expression by replacing all of the constants with a single Map.

I'm sleeping much better.