Sunday, May 3, 2009

Cruise and Ubuntu System Wide Environment Settings

I discovered a strange little problem the other day. I just completed my install of ThoughtWorks Cruise on a server running Ubuntu 8.04 LTS. In case you haven't heard of it, Cruise is a continuous integration and release management system. Everything appeared to be running correctly; so I proceeded to setup a pipeline for an Android project I was working on.

Android uses Ant to build and manage a project outside an IDE such as Eclipse. This looked like a no brainer using Cruise's <ant> task. I had Ant 1.7.1 installed with the following lines in my server's /etc/environment file:
ANDROID_HOME=/opt/android-sdk-linux_x86-1.5_r1
ANT_HOME=/opt/apache-ant-1.7.1
JAVA_HOME=/opt/jdk1.6.0_10

PATH="/opt/android-sdk-linux_x86-1.5_r1/tools:/opt/apache-ant-1.7.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games"
Nothing wrong here, I ran:
su cruise
env
...
ANDROID_HOME=/opt/android-sdk-linux_x86-1.5_r1
ANT_HOME=/opt/apache-ant-1.7.1
JAVA_HOME=/opt/jdk1.6.0_10
PATH=/opt/android-sdk-linux_x86-1.5_r1/tools:/opt/apache-ant-1.7.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games
...
The output above looked fine. Running the following looked good as well:
which ant
/opt/apache-ant-1.7.1/bin/ant
When I triggered my pipeline, it failed. Cruise was not finding the ant executable. I tested the pipeline using the <exec> task with the full path to my ant executable and everything worked as expected. I still couldn't figure out why Cruise couldn't locate ant. It should be on the path and therefore accessible. I posted my problem on the ThoughtWorks Cruise forum and received the following reply from Derek Yang:

We investigated this issue according to your description. We found something that might explain why it doesn't work properly for you.

You mentioned that the path is configured in /etc/environment. This might not help because Cruise launches the agent process with the --login option to ensure that the cruise user will start up in its own environment context (This is specified in /etc/init.d/cruise-agent). The environment settings in /etc/environment will not be picked up automatically in this process.

One solution is to change the PATH setting in /etc/profile, and restart cruise agent (/etc/init.d/cruise-agent restart). That way the newly updated environment settings can be applied automatically for the cruise user. We double checked this in a simulated environment and verified it works.


That was it, problem solved. I didn't test with the --login option, doh! I went back and made the following changes to /etc/environment:
ANDROID_HOME=/opt/android-sdk-linux_x86-1.5_r1
ANT_HOME=/opt/apache-ant-1.7.1
JAVA_HOME=/opt/jdk1.6.0_10

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games"
Added the following to the end of /etc/profile:
export PATH="$JAVA_HOME/bin:$ANT_HOME/bin:$ANDROID_HOME/tools:$PATH"
Re-started the Cruise agent process:
/etc/init.d/cruise-agent restart
I logged back into Cruise and triggered my pipeline. Success!! I hope my experience saves someone from making this silly mistake.