JBoss Community

enable-openshift-ci: full example using openshift-java-client

modified by Andre Dietisheim in JBoss Tools - View the full document

This wiki entry will show you a complete example using the openshift-java-client. The openshift-java-client is a java library that allows you talk to the OpenShift PaaS programmatically.

This article will develop a command line tool in java, that takes a project on your disk and sets up a jenkins build for it on OpenShift.

The example is hosted on github at https://github.com/adietish/enable-openshift-ci and you may freely reuse, redistribute or modify the code since it's licensed under the Eclipse Public License.

Requirements

  • your project is required to build with maven and has to be committed to a git repository
  • you need an account on OpenShift. (If you have no account yet, you'd have to signup first)
  • you require 3 free application slots (given that you have a default quota of 3 applications).
  • you need to have git available on your command-line (enable-openshift-ci is using it to deploy)

Usage

-p     the project (folder) that we'll enable CI for
-pw   the OpenShift password
-u     the OpenShift user

 

You have to tell enable-openshift-ci where it'll find your project (-p), your OpenShift user (-u) and password (-pw).

An exemplary call using the jar would look the following:

 

java -jar target/enable-openshift-ci-0.0.1-SNAPSHOT-jar-with-dependencies.jar -p <PATH_TO_PROJECT> -a test -u <USER> -pw <PASSWORT>

 

Calling it using maven would look like this:

mvn test -Du=<USER> -Dpw=<PASSWORD> -Dp=<PATH_TO_PROJECT>

 

Given that my project at /home/adietish/git/kitchensink is a maven project and already within a git repository, it will log into my OpenShift account <MYACCOUNT>/<MYPASS>. It will then create an application kitchensink and merge it's initial content into my local proect. It will then create a jenkins application on OpenShift, add a jenkins-client cartridge to the kitchensink application and push the local project to OpenShift. This push will then trigger the build on the jenkins instance.

 

Implementation

Openshift-java-client

First of all enable-openshift-ci requires the openshift-java-client. The client library is available as artifact from maven central. Enable-openshift-ci is a maven project, we can add the openshift-java-client to its classpath by simply using the following snippet in the pom:

 

<dependency>          <groupId>com.openshift</groupId>          <artifactId>openshift-java-client</artifactId>          <version>2.0.0</version></dependency>

 

A few classes

  • Main: Bootstrapping
  • Parameters: Parses, validates and holds the command line parameters
  • OpenShiftCI: Creates the OpenShift CI, pushes your project to it

 

Parameters: Talk to me via command line parameters

To keep the example simple, we'll stick to a GUI-less programm, that you control by command-line arguments. The Parameters class holds all parameters that were given at the command line. It'll check them for validity and offer them for further processing.

What's important in this context is that the Parameters class will ensure that your project exists, that it is a maven project and that it is shared with a git repository.  I used the JCommander library by Cédric Beust. It allows me to annotate instance variables and get the parsing, validation, conversion and usage printing done very easily. For the sake of brevity, I'll skip any further detailled discussion.

OpenShiftCI: I want my CI instance!

The OpenShiftCI class is where it all happens. It'll connect to your OpenShift account, create your Jenkins instance and push your project to it. OpenShiftCI#create looks like this:

 

IUser user = createUser();
IDomain domain = getOrCreateDomain(user);
IApplication application = getOrCreateApplication(project.getName(), domain);
IApplication jenkinsApplication = getOrCreateJenkins(domain);
waitForApplication(jenkinsApplication);
waitForApplication(application);
embedJenkinsClient(application);
ensureQuotaNotReached(domain);
deployToOpenShift(application);

Let's get in touch with OpenShift

Before enable-openshift-ci can manipulate resources on OpenShift, it has to connect to it. It asks the OpenShiftConnectionFactory for a new connection. The first required parameter is the url of the OpenShift PaaS. You may either hard code it or ask the OpenShift configuration for it:

new OpenShiftConfiguration().getLibraServer()

The connection factory also asks for a meaningful client id. We'll use "enable-openshift-ci".

Last but not least, you also have to give it your OpenShift credentials.

 

   String openshiftServer = new OpenShiftConfiguration().getLibraServer();
   IOpenShiftConnection connection = new OpenShiftConnectionFactory().getConnection("enable-openshift-ci", "<user>", "<password>", openshiftServer);

Once you have your connection you can get your user instance which will allow you to create your domain and applications:

 

IUser user = connection.getUser();

 

In enable-openshift-ci you'll find this initizalization in OpenShiftCI#createUser.

 

Now I need a domain

 

All resources on OpenShift are bound to a domain. We therefore have to make sure we have a domain in a first step. We actually check if you have a domain and create one if you dont. OpenShiftCI#getOrCreateDomain:

 

IDomain domain = user.getDefaultDomain();

if (domain == null) {

   domain = user.createDomain(DEFAULT_DOMAIN_NAME);

}

 

Let's get an application for my project

 

We now need an application for the project we want to enable jenkins for. The application will provide us the infrastructure that we need for our application (the git-repository, the application server etc.). Enable-openshift-ci now checks if there's an application with the very same as the project.

 

IApplication application = domain.getApplicationByName(name);

 

If there's already one, it'll check for it's type (the cartridge).

 

ICartridge.JBOSSAS_7.equals(application.getCartridge())

 

Enable-openshift-ci requires a maven aka java project. We therefore need a jbossas-7 application on OpenShift. We therefore fail if the application that we found does not match the required cartridge. If there's no application with the given name yet, we'll create a new one.

 

IApplication application = domain.createApplication(name, ICartridge.JBOSSAS_7);

 

You can have a look at the implementation in OpenShiftCI#getOrCreateApplication to spot all details.

 

 

OpenShift, gimme my CI instance!

 

We now created an application that OpenShift builds whenever we push to it's git repository. The build is executed within the git push. To have a jenkins CI instance doing that work, we'd have to add a jenkins application and connect both. We'll show you how in the upcoming steps:

 

OpenShiftCI#getOrCreateJenkins first checks if there are any jenkins applications within your domain.

 

List<IApplication> jenkinsApplications = domain.getApplicationsByCartridge(ICartridge.JENKINS_14);

if(jenkinsApplications.isEmpty()) {

   ...

 

If it spots an jenkins instance, itll leave this step alone, it wont need another jenkins application. If there's none yet, it'll create a new jenkins-application and print it's url and credentials OpenShift setup for us:

 

IApplication jenkins = domain.createApplication(DEFAULT_JENKINS_NAME, ICartridge.JENKINS_14);

System.out.println(jenkins.getCreationLog());

 

We now have to connect both applications. We have to tell the application for your project to build within our jenkins instance, the one we found or created in the prior step. Before doing so, we have to make sure both applications are reachable and eventually wait for them to become ready:

 

Future<Boolean> applicationAccessible = application.waitForAccessibleAsync(WAIT_TIMEOUT);

if (!applicationAccessible.get()) {

   ...

 

Once they're both ready, we can add the jenkins-cartridge to our project application. It'll tell OpenShift to build my application in the jenkins that is available in the very same domain. Since we eventually reused an existing application, we also check if the application we found already has a jenkins cartridge and only add a fresh one if there's none yet.

The embedded cartridge we get back offers a creation log, that shows at what url the jenkins jobs may be reached at.

 

IEmbeddedCartridge jenkinsClient = application.getEmbeddedCartridge(IEmbeddableCartridge.JENKINS_14);

if (jenkinsClient == null) {

     jenkinsClient = application.addEmbeddableCartridge(IEmbeddableCartridge.JENKINS_14);

     System.out.println(jenkinsClient.getCreationLog());

 

 

And now let's have a build fiest!

 

Enable-openshift-ci now setup all infrastructures that it needed, it can now get over to trigger the build. OpenShift is git based, deploying to OpenShift is git pushing to the git repository of an application. OpenShift builds whenever you push to it. Enable-openshift-ci will therefore operate on the git repo of the local project and push its content to the OpenShift application. This git push to the OpenShift git repo will trigger the build in the jenkins CI on OpenShift.

 

It first makes sure the local git repo has no outstanding modifications and tells the git command line tool on your path to add and commit everything:

 

exec("git add .");

exec("git commit -a -m 'deploying'");

 

It then adds the uri of the application git repo to the local repo:

 

exec("git remote add openshift -f " + application.getGitUrl());

 

And then merges the initial content of this git repo into the local project recursively and then pushes the merged result to the OpenShift application:

 

exec("git merge openshift/master -s recursive -X ours");

exec("git push openshift HEAD -f --progress");

 

 

 

Conclusion

Comment by going to Community

Create a new document in JBoss Tools at Community