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

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

Outputting the pipeline state throughout the process - the tooling we will need

This is the first of a couple posts around simply interacting with the MySQL database. As explained previously, the purpose of this database is to track state in the pipeline (and display it). So there's a few scripts that help manage this process, written in Python and explained below.

One of the scripts simply clears out the messages table. We needed to do this at the beginning of each pipeline execution.

The other thing we need to do is output the messages table to the Jenkins console output window. It's very important that we display state of the pipeline as it executes so we can figure out where a breakdown might have occurred in the execution of the pipeline.

So this post is all about interacting with MySQL using Python. One of the extra things that I've added extra is some pretty text boxes around the output, so that the pipeline state would stand out in the sea of the messages that you will see in the Jenkins console output window.

We are still in the early stages of constructing our pipeline. We haven't compiled anything at. We haven't tested anything yet.

We are simply building out the tooling's we will used in the rest of the pipeline.

Every Python script in some way interacts with the persistent store (MySQL).

You can see all this in the diagram below.
snap1

Figure 1: The big picture

The pipeline as it stands now

Let's quickly walk through some of these lines.

  • Line 4
    • Cleanup the directory structure from any previous executions of the pipeline
  • Line 5
    • Download our DevOps toolkit. This includes the docker file and all corresponding Python script.
  • Line 7
    • This is Python script that will initialize the Jenkins database. The Jenkins database is hosted in a MySQL server. Specifically, we will truncate the messages table.
  • Line 8
    • ShowPipelineState.py will simply list out the content of the messages table. This is a very important capability because at any point in time we can see the entire state of our pipeline. Notice that we execute the script at the end of each step in the pipeline.

blog0001

Figure 2: The current state of the pipeline

ClearPipelineState.py

This is a script that executes once at the beginning of the pipeline. The purpose is to clear out any existing messages that might be remaining after the last run of the pipeline. An extension of this capability might be to archive all the previous states

One of the longer term goals I want to explore is analyzing all the output jobs to provide a holistic view of all Jenkins pipeline that may be used in an organization. That's what I am trying to capture this output in some type of structured way, to simplify analysis later.

The code below does something simple. It simply clears out the messages table at the beginning of execution of the pipeline.
blog0002

Figure 3: Python code to clear out the messages table

ShowPipelineState.py

What you are looking at, below is the console output window for my build.

Notice that ShowPipelineBuild.py outputs the contents of the messages table.

Notice the two of the scripts have run with success:

  • RunGradelBuild.md
  • BuildDockerImageFromNewBuild.md

blog0003

Figure 4: Displaying the state of the pipeline in the Jenkins console output window

But success will not always be the case. Your unit tests will not always pass.

Notice below that there was a failure in one of the steps of the pipeline.

Subsequent Python scripts in the pipeline need to avoid doing their work if any errors are discovered earlier in the pipeline execution.

blog0004

Figure 5: Failure in the pipeline be displayed in the Jenkins console output window

Beautifying the output of ShowPipelineState.py

You probably noticed in figures 4 and 5 that the output from the messages table is formatted nicely with a box-like appearance.

I wanted the output to stand out from all the countless other messages being displayed in the Jenkins console output window. The way I achieved that was simply creating an ASCII box around the output. But that required me to write a bit of Python code to figure out how to make it look good, taking into account column width, then generally trying to align it well.

There are a few things you should notice here:

  • On lines 1 and 2 we bring in the necessary packages (pymysql and sortedcontainers)
    • pymysql may require you to do a "pip install..." command at the console of the Jenkins host
  • The method called showData() does all the heavy lifting around calculating column width as well. as well as adding the necessary ASCII characters to create the illusion of a box

There is probably more elegant ways to do what I'm doing but this is working well for a simple solution.

I tried to use some third-party packages to do this, but trying to figure out how they work seemed like more effort than it was worth, compared to just doing something simple for myself.

I did waste some time trying to figure out why the columns coming back from a query change ordered randomly. That's why you see line 23 using a sorted dictionary to make sure that I control column order.
blog0004b

Figure 6: ShowPipelineState.py and class AsciiBox

The rest of ShowPipelineState.py

The next chunk of code is more about the real work of selecting from the messages table and then telling the class above to do the work of showing it formatted.

blog0005

Figure 7: Outputting data from ShowPipelineState.py

Conclusion

We are halfway through building some of the tooling we will need. We are spending some time up front to define the code that interacts with the persistent state store that tracks pipeline execution.

MySQL plays a crucial role in tracking state of execution in the pipeline. All the scripts in the pipeline interact with it to track the execution of the pipeline accurately and in a centrally managed fashion.