Building GitHub projects with Jenkins, Maven and SonarQube 4.1.1 on OpenShift

Basic installation SonarQube

There are different community-driven sonar cartridges around. There is

  • this one that bases on a Tomcat cartridges and provides SonarQube 3.x and
  • that one that comes with SonarQube 4.0.
  • The most uptodate and flexible one is this, though. It downloads a specific version of SonarQube with each build. At the moment it works with version 4.1.1. I’m still working on getting SonarQube 5 to run on openshift, but haven’t succeeded, yet.

There also is a tutorial that shows how to install SonarQube 3.1.1. It also contains general thoughts on how to bypass OpenShift’s restrictions.

Anyway, to install SonarQube 4.1.1 execute the following steps on your machine:

    1. rhc app create sonar diy-0.1 postgresql-9.2

Make sure to remember the login and passwords!

  1. git rm -r diy .openshift misc README.md
    git remote add upstream -m master https://github.com/worldline/openshift-sonarqube.git
    git pull -s recursive -X theirs upstream master
    git push
    
  2. Login to your SonarQube instance at
    http://sonar-<yourAccount>.rhcloud.com/

    The default login and passwords are admin / admin.
    You might want to change the password right away!

Basic installation Jenkins

A lot of information within this paragraph was taken from here.

  1. Create Jenkins gear with Git-SSH
    rhc create-app jenkins  jenkins-1  "https://cartreflect-claytondev.rhcloud.com/reflect?github=majecek/openshift-community-git-ssh"
  2. Authorize your Jenkins node to communicate with other gears (and with you Git Repository)
    Generate SSH key for your Jenkins node
    SSH to the jenkins node

    ssh-keygen -t rsa -b 4096 -f $OPENSHIFT_DATA_DIR/git-ssh
  3. Add the key to your OpenShift, either
    • via web console
      In SSH console

      cat id_rsa.pub

      then copy and paste the output into web console
      or

    • via rhc
      Download the public key (id_rsa.pub) to your host (e.g. by SFTP) and use the

      rhc sshkey add

      command to authorize the public keys for your OpenShift account.
      If you plan on accessing a private repo or want to allow jenkins committing to your repo (e.g. for generate releases with the maven release plugin) you should also add the key to your repo account. See GitHub Help.

  4. Install Plugins
    Browse to Update Center

    https://jenkins-<yourAccount>.rhcloud.com/pluginManager/advanced

    and hit Check Now (as described here).
    Then go to the Available tab and install

    1. Sonar Plugin,
    2. GitHub plugin,
    3. embeddable-build-status (if you’d like to include those nifty build badges in you README.md).

    While you’re at it, you might as well update the already installed plugins in the Updates tab.
    Then hit Install without restart or Download and install after restart. If necessary, you can restart your app like so

    rhc app restart -a jenkins
  5. Set up maven settings.xml to a writable location.
    • SSH to Jenkins
      mkdir $OPENSHIFT_DATA_DIR/.m2
      echo -e "<settings><localRepository>$OPENSHIFT_DATA_DIR/.m2</localRepository></settings>" > $OPENSHIFT_DATA_DIR/.m2/settings.xml
      
    • Browse to Configure System
      https://jenkins-<yourAccount>.rhcloud.com/configure

      Default settings provider: Settings file in file system
      File path=$OPENSHIFT_DATA_DIR/.m2/settings.xml

  6. Set up main Jenkins node as slave (easy to set up and doesn’t need extra gears).
    Go to Configure System

    https://jenkins-<yourAccount>.rhcloud.com/configure

    and set
    # of executors: 1
    As an alternative, you could also use another gear as dedicated Jenkins slave. To do so, follow the steps described here.

    [EDIT 2015-08-09: As it turned out, memory is too low to run the jenkins master and builds on one node. See my second post on how to introduce a dedicated slave node to this setup]

  7. Setup sonar plugin
    On the Jenkins frontend, go to Configure System

    https://jenkins-<yourAccount>.rhcloud.com/configure
    • Global properties,
      tick Environment variables
      Click Add
      name=SONAR_USER_HOME
      value=$OPENSHIFT_DATA_DIR
      See here for more information.
    • Then set up the plugin itself
      Navigate to Sonar, Sonar installations and set the following
      Name=<be creative>
      Server URL:

      http://sonar-<yourAccount>.rhcloud.com/

      Sonar account login: admin
      Sonar account password: <your pw>, default: admin
      Database URL: jdbc:postgresql://$OPENSHIFT_JENKINS_IP:15555/sonar
      Database login: The admin account that was returned when you first created the sonar application
      Database password: The password that was returned when you first created the sonar application

    • Hit Save

Configure build for a repository

Now lets set up our first build.

  1. Go to
    https://jenkins-<yourAccount>.rhcloud.com/view/All/newJob

    Item name: <your Project name>
    Build a free-style software project (Unfortunately, Maven projects do not work due to OpenShift’s restrictions.)
    Hit OK

  2. On the next Screen
    GitHub project:

    https://github.com/<your user>/<your repo>/

    Source Code Management:

    https://github.com/<your user>/<your repo>.git

    Branch Specifier (blank for ‘any’): origin/master
    Build Triggers: Tick: Build when a change is pushed to GitHub
    Build | Execute Shell

    cd $WORKSPACE
    # Start the actual build
    mvn clean compile test package
    

    Post-build Actions | Add post-build action | Sonar

  3. I’d also recommend the following actions
    Post-build Actions | Add post-build action | Publish JUnit test result report
    Test report XMLs=target/surefire-reports/TEST-.xml*
    Post-build Actions | Add post-build action | E-mail Notification
    Recipients=<your email address>
  4. Hit Apply.
  5. That’s it for the basic build set up. Now for the fun part: We need to find a way for Jenkins to reach sonar’s database.
    We’ll use an SSH tunnel for that.
    Build | Add build step | Execute Shell
    Now enter the following:

    # Make sure Tunnel for Sonar is open
    # Find out IP and port of DB
    OPENSHIFT_POSTGRESQL_DB_HOST_N_PORT=$(ssh -i $OPENSHIFT_DATA_DIR/git-ssh/id_rsa -o "UserKnownHostsFile=$OPENSHIFT_DATA_DIR/git-ssh/known_hosts" <UID>@sonar<yourAccount>.rhcloud.com  '(echo `printenv OPENSHIFT_POSTGRESQL_DB_HOST`:`printenv OPENSHIFT_POSTGRESQL_DB_PORT`)')
    # Open tunnel to DB
    BUILD_ID=dontKillMe nohup ssh -i $OPENSHIFT_DATA_DIR/git-ssh/id_rsa -o "UserKnownHostsFile=$OPENSHIFT_DATA_DIR/git-ssh/known_hosts" -L $OPENSHIFT_JENKINS_IP:15555:$OPENSHIFT_POSTGRESQL_DB_HOST_N_PORT -N <UID>@sonar<yourAccount>.rhcloud.com &
    

    This will tunnel requests from your Jenkins’ local Port 15555 via SSH to your sonar gear, which will forward it to its local PostgreSQL database.
    What is missing is script that explicitly closes the tunnel. But for now I’m just happy that everything is up and running. The tunnel will eventually be closed after a timeout. Let me know if you have any ideas how to improve the tunnel handling.

  6. Finally, press Save and you’re almost good to go.
  7. Before running your first build you should SSH to your Jenkins once more and
    ssh -i $OPENSHIFT_DATA_DIR/git-ssh/id_rsa -o "UserKnownHostsFile=$OPENSHIFT_DATA_DIR/git-ssh/known_hosts" <UID>@sonar<yourAccount>.rhcloud.com

    so the sonar node is added to the list of know hosts.