Partilhar via


My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 3

My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 1 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 2 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 3 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 4 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 5 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 6 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 7 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 8 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 9 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 10 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 11 Click Here
My Take on an Azure Open Source Cross-Platform DevOps Toolkit–Part 12 Click Here

Jenkins Pipelines Need to Track State – Hello Relational Databases

The previous two posts got us all set up to start the main work.

This post is about:

(1) Managing state in the pipeline
(2) The MySQL database to store state
(3) Downloading all the assets: (1) Python code (2) Dockerfile (3) httpservice – the app
(4) Details about the http-based service we are deploying (MySQL data, the unit test, the MVC architecture)

Managing State in the Pipeline – If the Pipeline Breaks, then what?

A core challenge is storing and tracking state. If the pipeline breaks somewhere, it needs to stop and notify the dev team that someone broke the build. All subsequent Python scripts must stop executing.

There's a few things you need to get done obviously based on the prior posts. I'm going to assume the you've followed the instructions in the last post.

As you saw in Part 2, we setup MySQL for this purpose.

Let’s now create a database and a table

For the moment, to keep things simple, go ahead and create a database along with the table called, "messages." As the pipeline executes, we will track state in the messages table. As explained previously, a persistent, centrally available persistent store is important.

Using a persistent store to control pipeline workflow

In later posts you will see how this data store is used. When a specific step in the pipeline executes, . The first task is to verify that the pipeline is still functioning correctly. If it failed in a previous pipeline step, then we need to stop processing. Ideally, we will notify the developer who broke the build. And as each step successfully executes, we also need to store that in a persistent way.

Here is what it should look like:

image001
Figure 1: Configuring your MySQL database

Periodic Build - How will our pipeline begin execution

There are two general approaches to kicking off the pipeline. The first approach is to leverage web hooks. The way web hooks work is that as soon a developer checks in code to github, github will call into your Jenkins server to notify that the github repo got updated.

At that point, Jenkins will begin the downloading of the code repo to begin the pipeline.

Stephen Connolly writes, "Jenkins (and in fact any CI systems) works best when builds are triggered after each and every commit. That provides you, the developer, with the most instant feedback possible. That, in turn, means you get fix(es) to the problems you introduced before you leave the context of what you were working on."

https://www.cloudbees.com/blog/better-integration-between-jenkins-and-github-github-jenkins-plugin

The Jenkins GitHub plugin

I spent a fair bit of time trying to get the Jenkins pipeline to execute when someone committed the code to Github. However, I was able to get Github to issue a post command to Jenkins. And with respect to Jenkins, I was able to receive this post command. But I was unable to execute the pipeline once I received the notification from Github.   Several hours later I just gave up.

Instead I opted for a periodic build until I revisit this later.

Below you can see my httpservice pipeline project. It will essentially execute the httpservice pipeline every five minutes.

image002

Figure 2: Setting a Pipeline build to execute every 5 minutes

Viewing the Pipeline Output

After 5 minutes, you will see this. Notice for our pipeline that the build history shows one job. I can double-click on this job and see the console output.

image003

Figure 3: We created a new Jenkins Pipeline called httpservice

Read about Pipeline here

https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md

We can see that are simplistic pipeline did in fact show, "Hello World." We had clicked Build now then viewed the build job's console output.

image004

Figure 4: Looking at the output of our primitive pipeline

Our pipeline is pretty much empty right now. What we need to do is execute a bunch of Python code and really define out pipeline.

Where does all the python code come from, including the Dockerfile?

So how do we get Python code available to execute in our pipeline?

The answer is simple. We need to put on our lower Python code in a Github repo.

Kick off by downloading our DevOps pipeline code written Python

This is the first step the pipeline will execute will be to do a git clone or git pull to bring in the necessary files to execute the pipeline. In the graphic below this means we need to clone devops.

image005

Figure 5: What our pipeline will look like when we are done. But not ALL the steps - yet

Here you can see that I am downloading my DevOps repo. As you can see from the diagram above, it contains all the Python code I need to execute my pipeline. It also includes the Dockerfile.

You can also see that after initializing the pipeline state (line 7), I am downloading my httpservice (line 8).

Special Note about SSH

The one thing that you should improve is not to pass in the username and password, but rather rely on SSH keys.

Notice that on line 2 below a passing username and password for this private repo. I did this for simplicity.

Downloading all our assets that need to be built and tested

This python script (GitCloneHttpService.py) does the trick, using subprocess. It downloads my enter code repo of httpservice.

Remember, httpservice is our core project that we will now explain below.

image006

Figure 6: Python script that downloads our core project (httpservice)

The httpservice project

This is a simple project. It is an http-based service that returns json data that comes from a MySQL database. In my case I used Eclipse/Spring to build out this project. It has just one method to call that returns JSON data.

Essentially, a user queries a database through a web endpoint.

If the user goes to https://host_address/azurecourse, a method gets called: GetAzureCourse() .

image008

Figure 7: Our core project (httpservice)

Notice that GetAzureCourse() takes a string coursetitle that ends up being used in the where clause. Notice the default value for title (if none is passed) is "esos."

You can pass your own CourseTitle like this:

https://host_address/azurecourse?coursetitle=Mesos

image009

Figure 8: A view of the model of our MVC App as well as the courses table to which it maps

The unit test

The point of all this is that unit tests get automated into the build pipeline before deployment takes place. That is why we are doing all of this work.

Notice the test class below. We essentially validate that a restful call returns "Mesos" based on the query. It is part of the Eclipse/Spring project.

This is the unit test - a simple one

Notice the unit test simply verifies that the call to the database succeeds and that the appropriate string comes back.

image011

Figure 9: The Unit Test

If the endpoint https://host_address/azurecourse is hit, then the courseTitle in the JSON code that comes back should be Mesos.

image010

Figure 10: Notice the default parameter for GetAzureCourse()

Conclusion

This post brought up a few key topics:

(1) Managing state in the pipeline
(2) The MySQL database to store state
(3) Downloading all the assets: (1) Python code (2) Dockerfile (3) httpservice – the app
(4) Details about the http-based service we are deploying (MySQL data, the unit test, the MVC architecture)

.

Comments

  • Anonymous
    January 05, 2017
    Thanks guys, I'm really enjoying this series.About not being able to trigger a build from a web hook. I noticed that you must manually build a Pipeline job at least once, after that the web hook trigger works; see my blog: https://www.code-partners.com/gotcha-with-jenkins-pipeline-as-code/ Another possible cause is that your Pipeline script invokes git using the shell (sh git ) instead of the Pipeline DSL (git ).
    • Anonymous
      January 27, 2017
      Thanks. Yes, I need to circle back to this. I also heard that cross-site scripting causes this.
  • Anonymous
    January 27, 2017
    Hi, great series of posts !Any chance to get access to your GitHub repo for following along ?Thanks !
    • Anonymous
      January 27, 2017
      Yes, I will. I need to scrub out passwords and secrets, etc. Thanks for reading.