8. Support Engineering Group : build-server.shore.mbari.org installation This page last changed on Feb 22, 2011 by kgomes. As a part of the upgrade and configuration of our software development infrastructure at MBARI, we installed a continuous integration server. Here is a diagram of the overall structure of the software development infrastructure. For the build server, the goal was to install Atlassian's Bamboo, Fisheye and Crucible products. In addition, we installed the SeleniumRC server to help in the automatic running of web client unit tests. Here are the steps: Install Java. jpackage-utils was already installed, so I went to java.sun.com and downloaded the jdk-6u23-linux-x64-rpm.bin. I had to run 'chmod a+x jdk-6u23-linux-x64-rpm.bin' to make sure I could execute the package. I then ran './jdk-6u23-linux-x64-rpm.bin' This expanded out to several .rpm files. In order to make sure I don't hit permissions issues, I moved all those files to the /tmp/java directory so I could run the install the rpm files using sudo. Then I ran 'sudo rpm -Uvh jdk-6u23-linux-amd64.rpm' Pat did something here to integrate it into the alternatives as I did not have permissions. The bottom line is that java got installed. I downloaded the Bamboo-3.0 standalone installation from atlassian to my Bamboo folder on my desktop. I downloaded the jtds dist zip file (1.2.5) to the Bamboo folder on my desktop.
   | JTDS is already in Bamboo It turns out the Bamboo install already has jtds 1.2.2 installed so you don't need to do this unless you want to upgrade it.
11. I created the /data/Bamboo directory to house the Bamboo working files and created the /opt/Bamboo to house the application itself. I unzipped and untarred the Bamboo download into the /opt directory which put it into the Bamboo directory I created. I cd'd into /opt/Bamboo/webapp/WEB-INF/classes and then edited the bamboo-init.properties file. In the file I uncommented the bamboo.home line and set it to:
        bamboo.home=/data/Bamboo
20. I then started the server by cd'ing to /opt/Bamboo and running ./bamboo.sh start I then browsed to http://localhost:8085 and was prompted to enter the license key. I took the server ID provided and went to the Atlassian site and entered it as the id for a new license key. I grabbed the generated key and stuck it back into the localhost page asking for it. I then clicked on "Custom Installation" to configure things manually. The only things I changed are below: I changed the name field to "MBARI Bamboo" I changed the Base URL to "http://build-server.shore.mbari.org:8085" I chose an external database and chose Microsoft SQL Server 2005/2008 I set the jdbc url to: jdbc:jtds:sqlserver://equinox.shore.mbari.org:51001/Bamboo;domain=SHORE The user was DB_Collaboration password is well, it just is. Clicked on continue and Bamboo setup the database I then chose to Create a new Bamboo home I used my MBARI username and password for the administration account until I can get it hooked up to Crowd. I then shutdown the Bamboo installation and configured it to use SSL per the instructions here. Cathy setup the SSL keystore in /usr/local/keystore/keystore.jks and I used that in the jetty.xml configuration file. I also had to follow the instructions and edit the bamboo.sh file to use the jetty.xml (it does not by default).
    | Note that I also uncomented these lines in the 8085 port connector which disabled the 8085 port on all but localhost IP addresses to make sure people have to use the SSL connection.
        <Set name="Host">127.0.0.1</Set>
        <Set name="ConfidentialPort">8443</Set>
        <Set name="IntegralPort">8443</Set>
23. 5. I restarted Bamboo to verify that the SSL connection works. I then shutdown the Bamboo installation and followed the instructions here to integrate it with Crowd. Below are the specific things I had to do for our installation In order to keep the default groups of bamboo-admin and bamboo-users out of our LDAP, I created those two groups in the MBARI Crowd directory and then created a bambooadmin account that belongs to both. That meets the requirements of Bamboo and does not force our I.S. group to have to have bamboo-admin and bamboo-user groups in our LDAP. The rest of the configuration was pretty straightforward except for the fact that Crowd is now using SSL and the connection between build-server and crowd was over SSL. This caused much grief as the connection was not trusted so I finally found some instructions on how to get around that here. After I ran the program attached and installed the keystore in the java jre/lib/security directory, all was well and I could authenticate into Bamboo using MBARI's LDAP and MBARI Crowd directory. The last step was to get all this running as a different user. I shutdown bamboo. I then did a 'chown -R root:root /opt/Bamboo' to make sure that the default ownership of all the files was root I did a 'chown -R DB_Collaboration:DB_Collaboration /data/Bamboo' to make sure the DB_Collaboration account owned all the bamboo data. I then went in to the /opt/Bamboo directory and gave ownership of the following files and directories to DB_Collaboration. atlassian-bamboo.log logs /opt/Bamboo (so the bamboo.pid file can be created) I then created the /etc/init.d/bamboo script:
           #!/bin/sh
           # Startup script for bamboo
           #
           # chkconfig: 2345 99 01
           # description: Atlassian Bamboo
           # pidfile: /var/run/bamboo.pid
           . /etc/rc.d/init.d/functions
           BAMBOO_HOME=/data/Bamboo
           BAMBOO_INSTALL=/opt/Bamboo
           BAMBOO_USER=DB_Collaboration
           export BAMBOO_HOME
           NAME=bamboo
           BPID=${BAMBOO_INSTALL}/bamboo.pid
           PID=/var/run/${NAME}.pid
           cd ${BAMBOO_INSTALL}
           if [ _$1 = _condrestart ]; then
           su - ${BAMBOO_USER} -c "
           cd ${BAMBOO_INSTALL} &&
           ${BAMBOO_INSTALL}/bamboo.sh stop &&
           ${BAMBOO_INSTALL}/bamboo.sh start
           "
           else
           su - ${BAMBOO_USER} -c "
           cd ${BAMBOO_INSTALL} &&
           ${BAMBOO_INSTALL}/bamboo.sh $@
           "
           fi
           RC=$?
           if [ -f $BPID ]; then
           cp -- $BPID $PID
           touch /var/lock/subsys/${NAME}
           else
           rm -- $PID /var/lock/subsys/${NAME} 2>/dev/null
           fi
           exit $RC
25. I made it executable by all and changed the ownership to root:root I then ran the following to configure it to start:
        sudo /sbin/chkconfig --add bamboo
        sudo /sbin/chkconfig bamboo on
        sudo /sbin/service bamboo start
26. I then downloaded the selenium rc server jar file, put it in the /opt/selenium directory and created the following script and put it in /etc/init.d/selenium
        #!/bin/sh
        # chkconfig: 2345 99 01
        # description: Selenium RC Service Agent
        . /etc/rc.d/init.d/functions
        scriptFile=$(readlink -fn $(type -p $0))
        scriptDir=$(dirname $scriptFile)

        # This is the directory where selenium is installed
        applDir=/opt/selenium-rc

        # The service names
        serviceName=SeleniumRC
        serviceNameLo=SeleniumRC

        # The group that will be used to run the service
        serviceUser=DB_Collaboration
        serviceGroup=DB_Collaboration

        # This is the process id file
        pidFile=/opt/selenium-rc/selenium.pid

        # This is the log file where messages will be written
        serviceLogFile=/opt/selenium-rc/log/selenium.log

        # The java command to run
        javaCommand=java

        # The arguments to pass to the java command
        javaArgs="-jar selenium-server-standalone-2.0b2.jar"

        # The full java command line
        javaCommandLine="$javaCommand $javaArgs"

        javaCommandLineKeyword=selenium-server-standalone

        # The time to wait for the graceful shutdown to work before sending SIGKILL
        maxShutdownTime=15

        # This is a function to create a file and make it writable by the process group
        function makeFileWritable {
          local filename="$1"
          touch $filename || return 1
          chgrp $serviceGroup $filename || return 1
          chmod g+w $filename || return 1
          return 0;
        }

        # This function checks if the process with the pid that is passed in is running
        function checkProcessIsRunning {
          local pid="$1"
          if [ -z "$pid" -o "$pid" == " " ]; then return 1; fi
          if [ ! -e /proc/$pid ]; then return 1; fi
          return 0;
        }

        # This function checks to see if the process id is the one that we started
        function checkProcessIsOurService {
          local pid="$1"
          if [ "$(ps -p $pid --no-headers -o comm)" != "$javaCommand" ];
          then return 1; fi
          grep -q "$javaCommandLineKeyword" /proc/$pid/cmdline
          if [ $? -ne 0 ]; then return 1; fi
          return 0;
        }

        # This actually starts the service running
        function startServiceProcess {
          cd $applDir || return 1
          rm -f $pidFile
          makeFileWritable $pidFile || return 1
          makeFileWritable $serviceLogFile || return 1
          cmd="nohup $javaCommandLine >>$serviceLogFile 2>&1 & echo \$! >$pidFile"
          sudo -u $serviceUser $SHELL -c "$cmd" || return 1
          # $SHELL -c "$cmd" || return 1
          sleep 0.1
          pid="$(<$pidFile)"
          if checkProcessIsRunning $pid; then :; else
            echo "$serviceName service started, log file $serviceLogFile."
            return 1
          fi
            return 0;
        }

        # This function stops the process
        function stopServiceProcess {
          kill $pid || return 1
          for ((i=0; i<maxShutdownTime*10; i++)); do
            checkProcessIsRunning $pid
            if [ $? -ne 0 ]; then
              rm -f $pidFile
              return 0
            fi
            sleep 0.1
          done
          echo "$serviceName $maxShutdownTime time exceeded, sending SIGKILL"
          kill -s KILL $pid || return 1
          local killWaitTime=15
          for ((i=0; i<killWaitTime*10; i++)); do
            checkProcessIsRunning $pid
            if [ $? -ne 0 ]; then
              rm -f $pidFile
              return 0
            fi
            sleep 0.1
          done
          echo "Error: $serviceName $maxShutdownTime+$killWaitTime seconds past and could not shutdown"
          return 1;
        }

        # This function grabs the process ID
        function getServicePID {
          if [ ! -f $pidFile ]; then return 1; fi
          pid="$(<$pidFile)"
          checkProcessIsRunning $pid || return 1
          checkProcessIsOurService $pid || return 1
          return 0;
        }

        # The function that checks to see if the service is running and if not, starts it
        function startService {
          getServicePID
          if [ $? -eq 0 ]; then echo "$serviceName already running"; return 0; fi
          echo "$serviceName starting"
          startServiceProcess
          if [ $? -ne 0 ]; then return 1; fi
          return 0;
        }

        # This function checks to see if the process is running and if so, calls the function to stop it
        function stopService {
          getServicePID
          if [ $? -ne 0 ]; then echo "$serviceName not running"; return 0; fi
          echo "$serviceName stopping"
          stopServiceProcess
          if [ $? -ne 0 ]; then return 1; fi
          return 0;
        }

        # This function check if the service is running or not
        function checkServiceStatus {
          echo -n "$serviceName appears to be "
          if getServicePID; then
            echo "running."
          else
            echo "stopped."
          fi
          return 0;
        }

        # This is the main function that gets called first
        function main {
          case "$1" in
            start)
              startService
              ;;
            stop)
              stopService
              ;;
            restart)
              stopService && startService
              ;;
            status)
              checkServiceStatus
              ;;
            *)
              echo "Usage: $0 {start|stop|restart|status}"
              exit 1
              ;;
          esac
        }

        # Call the main function and pass in the argument
        main $1
28. I then ran sudo /sbin/chkconfig --add selenium Then sudo /sbin/service selenium start
    | I am having trouble getting it to start on reboot. Works fine from the command line, but not from reboot.
30. 1. I then downloaded maven and ant and unpacked them both to /opt and create /opt/maven and /opt/ant symbolic links to them respectively. I then created two scripts java-dev.csh and java-dev.sh and put them in the /etc/profile.d directory and made them exectuable so that ant and maven were added to the default paths. java-dev.csh
           # Set some Java development environment variables
           setenv JAVA_HOME "/usr/java/latest"
           setenv ANT_HOME "/opt/ant"
           setenv M2_HOME "/opt/maven"

           # Add the ant and maven bins to the path
           setenv PATH "${PATH}:/opt/ant/bin:/opt/maven/bin"
    2. java-dev.sh
           # Some Java development variables
           JAVA_HOME=/usr/java/latest
           ANT_HOME=/opt/ant
           M2_HOME=/opt/maven

           export JAVA_HOME ANT_HOME M2_HOME

           # Add the ant and maven bin directories to the path
           pathmunge /opt/ant/bin
           pathmunge /opt/maven/bin

Document generated by Confluence on Feb 03, 2026 16:22