Posts Tagged ‘hudson’

Keeping passwords secret: Hudson plugin development

A common problem with several Hudson plugins is storing passwords and other sensitive data as plaintext as seen here, here, here, and here. There are more examples than I’d care to list here.

What prompted me to write this is a bug in the email-ext that I just fixed where credentials were being stored in plain text. The solution is so easy there’s no excuse not to do it.

The trick is to use hudson.util.Secret and the usage is dead simple:

public class MyPublisher extends Notifier {

  private Secret password;

  public String getSmtpAuthPassword() {
    return Secret.toString(smtpAuthPassword);
  }

  // ... snip ...

  public static final class DescriptorImpl extends BuildStepDescriptor<Publisher> {
    @Override
    public boolean configure(
                    StaplerRequest req, JSONObject formData) throws FormException {
      password = Secret.fromString(
                          nullify(req.getParameter("mypublisher.auth.password")));
      // ... snip ...
    }
  }
}

For what it’s worth, the docs for this class gives this notice:

Note that since the cryptography relies on hudson.model.Hudson.getSecretKey(), this is not meant as a protection against code running in the same VM, nor against an attacker who has local file system access.

So there you have it, there’s no good reason to not be reasonably secure.

 

Triggering Hudson builds with Mercurial hooks

Mercurial offers a variety of hooks, powerful triggers that can be configured to automatically perform automated tasks after an event occurs in a repository. We can leverage Mercurial’s changegroup hook to make Hudson build a project without polling the version control system for changes. This offers some important advantages and disadvantages.

One advantages of triggering builds after hg push is to decrease the load on the Mercurial server and Hudson itself by not polling every 1-60 minutes and use the server when necessary. Of course the fewer projects you have the less this technique buys you. Another advantage is to lower the feedback loop from Hudson; every minute spent waiting for Hudson to poll Mercurial the longer the feedback loop gets.

There are some important disadvantages to this technique too by introducing additional coupling between your CI server and your version control server (VCS). While Hudson always knows about your VCS now your VCS knows about Hudson. Another disadvantage is most likely you already have Hudson setup to poll Mercurial, so there’s time to configure both ends of the process.

Configuring this Mercurial hook really is easy, just edit the file YOUR_REPO/.hg/hgrc located on your Mercurial server and add the following:

[hooks]
changegroup.hudson = curl http://hudson_url/job/project_name/build?delay=0sec

You will need to change hudson_url to the URL of your Hudson server and project_name to the Hudson project you wish to build.

Be sure to add a file, commit, and push to test your hook. You should see the project instantly added to the build queue.

If your Hudson installation is using security you will need to do things a little differently; see authenticating scripted clients for details. If your job is parameterized you can do that too.

Update 2010-07-14: Mirko has posted a variation to this post that is worthwhile.

 

Hudson Startup Trigger 0.1

Last night I released a trigger for Hudson that allows a build to be triggered when Hudson first starts up. While I don’t have any use for it, it was created in response to HUDSON-3669.

Hopefully someone will be able to make good use of it.

 

Link roundup: Dead fish in the Hudson

Lasso me some links

Lasso me some links

Link roundups are legitimate blog posts, right? It doesn’t matter because I’m going to post it anyhow.

We’ll start with programming-related topics:

Next off to the bizarre sciency stuff:

What is more off-topic than dead salmon? These links:

 

Hudson and the Sonar plugin fail: MavenInstallation NoSuchMethodError

No. Not this Hudson.

No. Not this Hudson.

We ran into an interesting and less than informative error when configuring Maven with our Hudson installation. Maven worked great, as expected, but the Sonar plugin stopped working and were causing builds to fail.

The error message wasn’t terribly helpful:


FATAL: hudson.tasks.Maven$MavenInstallation.forNode(Lhudson/model/Node;Lhudson/model/TaskListener;)Lhudson/tasks/Maven$MavenInstallation;
java.lang.NoSuchMethodError: hudson.tasks.Maven$MavenInstallation.forNode(Lhudson/model/Node;Lhudson/model/TaskListener;)Lhudson/tasks/Maven$MavenInstallation;
at hudson.plugins.sonar.SonarPublisher.getMavenInstallationForSonar(SonarPublisher.java:204)
at hudson.plugins.sonar.SonarPublisher.executeSonar(SonarPublisher.java:213)
at hudson.plugins.sonar.SonarPublisher.perform(SonarPublisher.java:177)
at hudson.model.AbstractBuild$AbstractRunner.performAllBuildStep(AbstractBuild.java:372)
at hudson.model.AbstractBuild$AbstractRunner.performAllBuildStep(AbstractBuild.java:360)
at hudson.model.Build$RunnerImpl.post2(Build.java:183)
at hudson.model.AbstractBuild$AbstractRunner.post(AbstractBuild.java:345)
at hudson.model.Run.run(Run.java:943)
at hudson.model.Build.run(Build.java:112)
at hudson.model.ResourceController.execute(ResourceController.java:93)
at hudson.model.Executor.run(Executor.java:119)

A little Googling, I found just two hits.

One result was helpful in which it said the Sonar plugin is compatible with Hudson 1.306+. Currently we’re running 1.303. We’re not exactly far behind, but apparently far enough behind.

Backing up Hudson

While there is a backup plugin for Hudson. The plugin would be ideal, but in case just installing the plugin screws something up, best do a manual backup.

The easiest way to manually backup Hudson is to just copy your Hudson working directory. However, space is limited for us, so a backup that was more selected was necessary. This script seemed to backup the most important configuration files (it wouldn’t make for a pretty recovery, but it’d work):

#/bin/sh

cp $HUDSON_HOME/*.jar $NEWHUDSON_HOME/
cp $HUDSON_HOME/*.xml $NEWHUDSON_HOME/
cp -r $HUDSON_HOME/plugins $NEWHUDSON_HOME
for job in $HUDSON_HOME/jobs/*; do
        echo "Processing $job"
        mkdir -p "$NEWHUDSON_HOME/jobs/$job"
        cp "$job/config.xml" "$NEWHUDSON_HOME/jobs/$job/config.xml"
done
All aboard!

All aboard!

All aboard the fail boat

The upgrade appeared to go well, but after manually starting the Windows service, I get an error. Amusingly, the hudson.err.log showed some slight inconsistencies:

Jul 27, 2009 2:38:03 PM hudson.model.UpdateCenter$DownloadJob run
INFO: Installation successful: hudson.war
Invalid or corrupt jarfile C:\hudson\hudson.war

Hudson the Butler can’t make up his mind; it’s claiming success before imploding on itself.

Hudson recuperated

Skimming around and very annoyed my butler had blatantly lied to me, I noticed hudson.war was sitting at only 2 MB. Yah, that can’t be right.

Luckily the fix was easy: Hudson was successfully fixed by manually downloading the newest hudson.war and replacing the messed up version.

It turns out I really did not need to backup Hudson. Though naturally if I hadn’t backed up Hudson I will have needed my backup!

Upgrading to Hudson 1.317 solved the mysterious java.lang.NoSuchMethodError error. I would not have thought configuring a Maven installation rather than using Hudson’s default would cause issues. Go figure.