Clean the slaves

In my current project we’re generating jobs for each branch of each project with the help of the Jenkins Job DSL. Branches are created for each feature and bugfix – hotfixes are branched from release branches but these are treated a little differently. Anyway, as you can imagine we tend to have a lot of branches even though we delete them once they’re merged back into the master. Since we also have a lot of different jobs for building/testing/deploying, the amount of jobs explodes quite quickly ;)
Also, to have acceptable job execution times and fast feedback for the developers, we’re using multiple slaves.

Problem

When deleting a job, e.g. because the branch is removed, its workspace on the slave is not deleted. This is a little annoying since it’s wasting a lot of space on the slaves’ disks and in the past required some manual effort to clean them up. Luckily, Jenkins provides some nice APIs :)

Solution

We created a job which is executing a “system groovy script” (important!) and must be run on the Jenkins master. It simply runs through all slaves, checks if their workspace contains a folder which is orphaned and deletes it. And yes, it is as simple as it sounds. Just a few lines of code which are run after the job generation and all orphaned workspaces are removed :mrgreen:

import hudson.model.*
import hudson.node_monitors.*
import jenkins.model.*

for (node in Jenkins.instance.nodes) {
    computer = node.toComputer()
    if (computer.getChannel() == null) {
        continue
    }

    def rootPath = node.getWorkspaceRoot()
    def space = DiskSpaceMonitor.DESCRIPTOR.get(computer)

    println "Checking node ${node.name}..."
    println "Got path ${rootPath} and remaining space ${space}"

    rootPath.list().sort().each { dir ->
        if (!Jenkins.instance.getItem(dir.name)) {
            println "${dir} orphaned. Deleting..."
            dir.deleteRecursive()
        } else {
            println "${dir} still in use. Skipping."
        }
    }
}

Using your MacBook as Jenkins slave and thereby avoid any sleeping

As a requirement in my current project, we have to support IE11 and Safari 9 & 10. Since running Mac OS X virtualized comes with some legal issues, we decided to simply use a MacBookPro (El Capitan) as our Jenkins slave of choice. This works out of the box until the MacBook decides to hibernate, suspend or simply start any energy saving feature Mac OS offers. For normal usage, these are some great features but as a Jenkins slave, they are pretty annoying. So here are some hints you can follow to disable the annoying sleeping features:

At first, simply go to the energy preferences and set them up as shown here:
Energy System Settings

This is not enough though. To disable hibernation, you have to execute the following command:

sudo pmset -a autopoweroff 0

And again, this is not enough, as closing the lid will put the MacBook asleep… Therefore you should install a tool like NoSleep and configure it like this:
nosleep

…but, Apple was pretty busy trying to avoid any kind of energy consuming background task. Since we want to test within Safari, we have to disable Safari’s background sleeping as well. So you have to run the following command:

sudo defaults write com.apple.Safari NSAppSleepDisabled -bool YES

Watch out with running this on your own machine though. Safari will drain your battery from now on ;)

From now on, your device will silently run and wait for work :mrgreen:

Update:

You can also set this globally:

defaults write NSGlobalDomain NSAppSleepDisabled -bool YES

Also, when using Safari for automated tests, you might want to set the following, to prevent Safari from reopening the latest windows:

defaults write com.apple.Safari ApplePersistenceIgnoreState YES

By the way, if you want to be notified for new posts, just sign up with your email address on the right :)

Grails 2.0 & Jenkins

A while ago, I started using Jenkins with a Grails project. Now, we switched over to Grails 2.0 and I had to reconfigure some of the jobs to make them work again as the commands changed a little. For those who don’t feel like searching their way through all that mess, here’s a little how to ;)

After installing Grails 2.0 (and Groovy 1.8 shipped with it) on the server, you have to let Jenkins know about the new Grails version. Therefore you go to the Manage Jenkins menu, open the Configure Jenkins page and add the it to the Grails installations.
Grails installations

Then you have to adapt your jobs to the new command line, means, editing the “Targets” in the job configuration.
UnitSuite

IntegrationSuite

Also, don’t forget about the new way of testing in Grails 2.0. For us it still means a lot of work to switch over!

Enjoy :mrgreen:

Jenkins & HTTP-Auth

Since I’m working on a little project in my sparetime, I’m trying to use some software we’re also using at work and increase my knowledge. Lately I’m playing around with Jenkins and keep on running into small issues for which it’s a pain to find good documentation or howtos. Therefore I’ll start posting some hints on this blog and maybe they’ll be useful for someone else as well :)

The first thing I want to write about just came up recently. We have a casual rootserver for the project and thought it’d be a good idea to secure Jenkins from unauthorized access. Therefore I said I’d take care of it and simply put it behind a running apache2 instance and use HTTP-Auth. It’s not something tough but definitely not as easy as it sounds. After studying some documentation, searching a little and reading some posts on different sites we now have a secured Jenkins running. Finally I came up with the following solution.

In the apache2.conf you have to set up a proxy configuration:

ProxyPass /jenkins http://localhost:8081/jenkins
ProxyPassReverse /jenkins http://localhost:8081/jenkins
ProxyRequests Off

<Proxy http://localhost:8081/jenkins*>
  Order deny,allow
  Allow from all
</Proxy>

<Location /jenkins>
	AuthType basic
	AuthName "Jenkins"
	AuthUserFile "/srv/htpasswd"
	Require valid-user
</Location>

In the Jenkins configuration file /etc/default/jenkins you have to extend the JENKINS_ARGS and add

--prefix=/jenkins --httpListenAddress=127.0.0.1

Also, you got to change the Jenkins URL in the “Manage Jenkins” section of your installation.

Now you can access your Jenkins via http://domain.com/jenkins secured with a common HTTP Auth and something like http://domain.com:8081 does not work anymore ;)

Update
I forgot to say that you have to enable a few apache modules as well:

a2enmod proxy
a2enmod proxy_http

Bulgarisch Essen, Jenkins & Grails, Veer

Gestern Abend war ich zum ersten Mal bulgarisch essen und kann das Restaurant Tangra in der Kapuzinerstraße jedem empfehlen ;)

Nachdem die leichte Erkältung sich nach dem Halbmarathon in eine ausgewachsene verwandelt hat, die ich immer noch nicht 100%ig los bin, war ich in den letzten 2 Wochen etwas außer Gefecht. Trotzdem habe ich neben der Arbeit angefangen mich etwas mit Grails und Jenkins auseinander zu setzen. Dabei auf das Blog Lean Java Engineering gestoßen, welches mir bei ein paar anfänglichen Problemen geholfen hat. Mittlerweile muss ich allerdings gestehen, dass ich das Logging System und die Dependency-Verwaltung von Grails nicht ganz so toll finde, wie sie häufig beschrieben wird. Mal schauen, ob sich meine Meinung ändert, wenn ich es endlich geschafft habe das Dingen richtig zu durchblicken und es das tut, was ich von ihm will ;)

HP VeerAußerdem bin ich seit ein paar Tagen stolzer Besitzer eine HP Veer, der Media Markt um die Ecke hatte erstaunlicher Weise noch ein paar rumliegen :P
Mein Eindruck bisher: WebOS ist echt ein geniales System – kein Wunder, dass alle dort “klauen” – und ein sehr kleines Smartphone hat durchaus Vorteile! Allerdings fehlen mir noch ein paar Apps und ein Upgrade auf WebOS 2.2* könnten sie auch langsam mal rausbringen. Ich will integrierte Skype-Funktionalität!!! :mrgreen: