This is a repost of my post on the CloudBees Developers blog
TL;DR Source control injection attacks are a bigger worry than build tool injection attacks, and if you cannot trust your local filesystem, then you cannot trust anything.
A few exchanges on twitter have prompted me to write a fuller blog post on the subject of Cross-Build Injection (XBI) Attacks.
The idea of XBI is that you trick the developer and replace parts of their code with your code, thereby getting your code to be trusted by the developer.
This is a tail about Jenkins (née Hudson) and Kohsuke’s policy of maintaining backwards compatibility…
Back in 2006 I started working for my previous employer, just a month or two after Peter Reilly started. Initially we were working on the same team. This was a team who’s CI system was a nightly cron job that emailed off a list of failing tests to everyone… obviously Peter and I had many a WTF over that old system… so I convinced our boss that we should put some effort into setting up a proper CI system… Initially this was CruiseControl (as he thought Hudson at version 1.64 was too new and unheard of… go with the old reliable)… but after a couple of pains with the CruiseControl system (monolithic xml config file), we convinced him to switch to Hudson… (I don’t think we ever looked back!)
We recently lost our hudson server due to a multiple disk failure in the RAID array storing our hudson configuration. [5 of the 15 disks died]
So I’ve been looking into a backup script that will allow us to keep a backup of the configuration. We use Maven for most of our builds, so the released artifacts are in our Maven Repository (which is hosted on two servers each with RAID arrays and using DRBD to mirror between the pair, with an rsync to a NAS in another cabinet and we are trying to get an rsych to an off-site storage going as well).
Life gets in the way… but we’re back with our final installment! So where to start, let’s start with a publisher for freestyle builds, then we’ll add a publisher for Maven 2 builds… These will both require some reports to display results, and then finally we’ll need the plugin entry point. But before we get into all that, perhaps I should briefly explain structured form submission support
Hudson uses Stapler as it’s web framework. One of the things that Stapler provides is support for constructing objects from a JSON data model. Basically, if you have a class with a public constructor annotated with @DataBoundConstructor, Stapler will bind fields from a JSON object by matching the field name to the constructor parameter name. If a parameter also has a @DataBoundConstructor, then Stapler will recurse to construct this child object from the child JSON object.
Over on the Maven2 Users list a recent poster asked what CI server was best, and Hudson was the only answer.
Then Jason van Zyl posted this praise for Hudson:
I know from my vantage point Hudson is the only system I will provide commercial support for at Sonatype because the battle is over. Hudson won by making developers lives’ easier. Kohsuke will go to no end to make things easier for users.
In some ways parsing the JavaNCSS results is the least interesting part of developing a Hudson plugin, as once I have implemented the parser, it is available for everyone. For that reason I will focus more on:
best practice techniques for parsing results
common gotchas
designing for extension
First off, we need to analyse the results file format. In the case of JavaNCSS there are multiple ways that the results file can be generated: from the JavaNCSS program directly, from ANT or from Maven. This leads us onto gotcha #1
Ok, life has got in the way and I have not been able to update this series as quickly as I originally intended. In any case, there were a number of bugs in Hudson that I discovered and are now fixed, and there was a good deal of tidy-up needed in order for me to figure out what to do for parts 6 and 7. The good news is that I am getting closer to finishing writing these final two parts. The bad news is that there are a number of corrections to the previous posts (I have put some corrections in-line for parts 4 and 5). This post aims to ensure that, for parts 6 and 7, everyone is able to follow from the same code!
Until now we have been generating classes that collect the results we want to display. We have not hooked into Hudson’s methods of displaying reports. There are essentially four places that we could want to generate reports:
To make matters more confusing, each of these reports usually to implement different classes and need to implement different interfaces:
This is the fourth installment, which covers the two abstract classes that call the Ghostwriter for us. When we implement our plugin we will extend from these two classes. These classes perform the work of calling the Ghostwriter at the appropriate points in the build, the concrete classes that we will develop in Part 5, however have the responsibility of creating a configured Ghostwriter and providing it to the superclass for execution.
In this, the third installment, I will introduce some helper classes that we can use to let Publisher and MavenReporter subcontract the job of creating the build reports. Firstly, we have the Ghostwriter interface. An implementation of a Ghostwriter is the work-horse that writes the build report. Secondly, we have the BuildProxy class. This class is a more general MavenBuildProxy that works for both Maven builds and non-Maven builds. In part 4 we will tie these helpers into the Hudson plugin framework with an AbstractMavenReporterImpl and AbstractPublisherImpl from which we can extend our plugin’s MavenReporter and Publisher.