Create a md5 hash of two text files which can be to used as property in Maven command on a Windows Jenkins slave

I have to start a Maven build with a md5 hash as parameter:

mvn clean verify -Dchecksum=ea25acae60d51e86993efcc6757b31cd

This hash has to be generated from the contents of two configuration files (A.xml, B.xml)

The build is executed on a Jenkins slave running on Windows. So I have implement a PowerShell script:

$config_a = [IO.File]::ReadAllText("A.xml")
$config_b = [IO.File]::ReadAllText("B.xml")

$enc = [system.Text.Encoding]::UTF8
$data = $enc.GetBytes($config_a+$config_b)

$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash($data)).ToLower().Replace("-", "")

write-host "Calculated Hashsum: " $hash

"CHECKSUM=$hash" | Out-File -Encoding ASCII ".\checksum.properties"

In the Jenkins job the generated properties file is read with the EnvInject Plugin to create the environment variable CHECKSUM.

In the build step ‘Invoke Maven top level’ the Maven build can now be started like this:

clean verify -Dchecksum=$CHECKSUM

Note: without ‘-Encoding ASCII’ the properties file is written as ‘Unicode’. The ‘EnvInject Plugin’ then creates a wrong environment variable and the build fails with:

FATAL: Invalid environment variable name: "ÿþchecksum" java.lang.IllegalArgumentException: Invalid environment variable name: "ÿþCHECKSUM"

How to git fetch without a ssh warning

For monitoring the time it takes to clone one of our repositories from github.com had to get rid of the warning:

Warning: Permanently added 'github.com,192.30.252.129' (RSA) to the list of known hosts

I found the solution in this StackOverflow question:
“Warning: Permanently added to the list of known hosts” message from Git

I just had to add these line to

Display execution time of shell commands in seconds

I first tried using the time utility but failed on converting the result into seconds:

$ { time ls -l >/dev/null; } 2>&1 | grep real | sed -e 's/real//g' | sed -e 's/ //g'
	0m0.006s

Searching the web I found a StackOverflow (Display execution time of shell command with better accuracy) post pointing me to a solution using the bash variable SECONDS

From the Bash Reference Manual:

SECONDS This variable expands to the number of seconds since the shell was started. Assignment to this variable resets the count to the value assigned, and the expanded value becomes the value assigned plus the number of seconds since the assignment.

Example:

$ SECONDS=0; sleep 5; echo "I slept for $SECONDS seconds"

I slept for 5 seconds

Monitor the status of a GitHub Enterprise replica

GitHub Enterprise has a convenient script to see if a GitHub replica is in sync with its primary.

$ ghe-repl-status
OK: mysql replication in sync 
OK: redis replication is in sync 
OK: elasticsearch cluster is in sync 
OK: git data is in sync (124 repos, 0 wikis, 0 gists)

I wanted to use this script to monitor the status of replication with Icinga. So I created a ssh key pair for the user ‘icinga’ on the Icinga server.

$ mkdir -m 0700 -p /etc/icinga2/.ssh
$ chown icinga:icinga /etc/icinga2/.ssh
$ ssh-keygen -t rsa -C "icinga@icinga-server"
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): /etc/icinga2/.ssh/id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /etc/icinga2/.ssh/id_rsa.
Your public key has been saved in /etc/icinga2/.ssh/id_rsa.pub.
The key fingerprint is:
...

I then copied the contents of /etc/icinga2/.ssh/id_rsa.pub to /home/admin/.ssh/authorized_keys on the GitHub replica.

Now I can execute the script on the Icinga server:

$ ssh admin@172.31.14.196 -p 122 -i /etc/icinga2/.ssh/id_rsa ghe-repl-status
OK: mysql replication in sync
OK: redis replication is in sync
OK: elasticsearch cluster is in sync
OK: git data is in sync (124 repos, 0 wikis, 0 gists)
OK: pages data is in sync

The problem is that every other command can be executed as admin user as well which is something I don’t like.

I originally had implemented a much more complicated solution creating some more keys, configuring sudoers and changing one of the scripts of GitHub Enterprise. I posted a request to the GitHub support. They pointed out that the changes I made to the script would be overwritten with each upgrade.
They also pointed me to a nice blog post: Restricting public keys

This blog post describes how to limit what can be executed using a ssh key. So I prepended the key with some options:

command="ghe-repl-status",from="<ip_of_replica>",no-pty,no-agent-forwarding,no-port-forwarding  ssh-rsa ...

Now it doesn’t matter which command is executed. The added options makes sure that only ‘ghe-repl-status’ is executed:

$ ssh admin@172.31.14.196 -p 122 -i /etc/icinga2/.ssh/id_rsa ls /tmp
OK: mysql replication in sync
OK: redis replication is in sync
OK: elasticsearch cluster is in sync
OK: git data is in sync (124 repos, 0 wikis, 0 gists)
OK: pages data is in sync

Install Oracle JDK 8 on CentOS 6.5

Download RPM

jdk-8u5-linux-x64.rpm from http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

$ wget --no-check-certificate --no-cookies --header 'Cookie: oraclelicense=accept-securebackup-cookie' http://download.oracle.com/otn-pub/java/jdk/8u5-b13/jdk-8u5-linux-x64.rpm
$ sudo rpm -ivh jdk-8u5-linux-x64.rpm

Make JDK 8 the default with ‘alternatives’

$ sudo alternatives --install /usr/bin/java java /usr/java/jdk1.8.0_05/jre/bin/java 20000

$ sudo alternatives --install /usr/bin/jar jar /usr/java/jdk1.8.0_05/bin/jar 20000
$ sudo alternatives --install /usr/bin/javac javac /usr/java/jdk1.8.0_05/bin/javac 20000
$ sudo alternatives --install /usr/bin/javaws javaws /usr/java/jdk1.8.0_05/jre/bin/javaws 20000

$ sudo alternatives --config java

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   2           /usr/java/jdk1.8.0_05/jre/bin/java

Enter to keep the current selection[+], or type selection number: 2


$ java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

Bulk change subversion repository URL with jenkins-cli and Groovy code

Create the file changeSvnUrl.groovy with this content:

import hudson.scm.*

// Access to the Hudson Singleton
jenkinsInstance = jenkins.model.Jenkins.instance

// Retrieve all jobs
allJobs = jenkinsInstance.items

svnCredentialsId = "c8xxxee-965c-4cc0-b662-8a5xxx7d41b"

// iterate over jobs with Subversion as SCM
allJobs.each { job ->
    if (job.scm instanceof SubversionSCM) {
        if (job.scm.locations[0].remote.startsWith("http://oldhost/svn")) {
            oldUrl = job.scm.locations[0].remote
            newUrl = oldUrl.replace("http://oldhost/svn", "https://newhost/svn/project")

            println("changing Subversion URL in " + job.name + " from " + oldUrl + " to " + newUrl)

            job.scm = new hudson.scm.SubversionSCM(newUrl)
            job.scm.locations[0] = job.scm.locations[0].withCredentialsId(svnCredentialsId)
        }
    }
}

Execute:

java -jar jenkins-cli.jar -s http://jenkinshost/ groovy changeSvnUrl.groovy

Authenticate jenkins-cli with ssh-key

After adding the public key to your Jenkins user profile you can execute jenkins-cli with your ssh key:

$ java -jar jenkins-cli.jar -s http://hudson.hh.arvm.de/ -i ~/.ssh/jenkins_rsa who-am-i
Authenticated as: clsa1
Authorities:
  jenkins_admin

If you are using cygwin you have to transform the path like this:

java -jar jenkins-cli.jar -s http://hudson.hh.arvm.de/ -i $(cygpath -aw "/cygdrive/c/cygwin64/home/CLSA1/.ssh/jenkins_rsa")

Fastest way to create new versions for projects in Jira

1. using the REST API

curl -i -H "Content-Type: application/json" 
-X POST -d '{"description": "An excellent version",
             "name": "New Version 1",
             "userReleaseDate": "2014-05-23",
             "project": "PROD",
             "archived": false,
             "released": true}' 
-u username:password http://<jira.host>/rest/api/latest/version

2. using Jira CLI from bobswift.atlassian.net

./jira.sh --action addVersion 
          --project PROD 
          --description "Another excellent version" 
          --version "New Version 2" 
          --date "23.05.2014 10:00"

Solved weird problem with executing JMeter tests on Jenkins slaves

After a collegue of mine updated the Java version to 1.7 on our JMeter Jenkins slave (running on CentOS) all JMeter Projects stopped running.
The error message was:

Uncaught Exception java.lang.UnsatisfiedLinkError: /usr/java/jdk1.7.0_45/jre/lib/amd64/xawt/libmawt.so: libXtst.so.6: cannot open shared object file: No such file or directory.

When executed on console it worked.
I fired up a Vagrant VM and added this as Jenkins slave. JMeter worked on this slave also.
So I thought there must be something wrong with the Java installation.

When I searched for the missing library I found the solution:

[--@--]# locate libXtst.so.6
/usr/java/jdk1.6.0_29/jre/lib/amd64/xawt/libXtst.so.6
/usr/lib/libXtst.so.6
/usr/lib/libXtst.so.6.1.0

[--@--]# ll
/usr/java/jdk1.6.0_29/jre/lib/amd64/xawt/libXtst.so.6
lrwxrwxrwx 1 root root 10 Jul 16 2012
/usr/java/jdk1.6.0_29/jre/lib/amd64/xawt/libXtst.so.6 -> libmawt.so

The solution was to create a symbolic link:

[--@--]# cd /usr/java/jdk1.7.0_45/jre/lib/amd64/xawt/
[--@--]# ln -s libmawt.so libXtst.so.6