Наступила очередная пятница, день можно сказать почти выходной, и я решил создать свой блог, в котором намереваюсь рассказывать о воплощении своих бредовых идей...
Не долго думая решил рассказать об одной такой. Зародилась как то у меня идея прикрутить к проекту, над которым в данный момент работаю, continuous integration tool под названием Cruise Control. Прочитал все за и против, решил, это как раз то, что мне надо. Осталось дело за малым - установка и настройка, ох и поворочался я с этим...
Итак, что мы имеем? Сервер на базе debian lenny с установленным tomcat 5.5, проект, лежащий в репозитории под управлением subversion и собирающийся при помощи maven2.
Для начала скачаем последнюю версию с офф. сайта
Распаковываем в /opt/cruisecontrol.
Затем я пошел дальше и решил немного изменить структуру всего этого счастья:
/opt/cruisecontrol/lib - наши либы, как было, так и оставил
/opt/cruisecontrol/webapps - веб проекты, не трогал
/opt/cruisecontrol/bin - сюда перенес скрипт запуска cruisecontrol.sh
/etc/cruisecontrol - настройки, cruisecontrol.xml dashboard.xml log4j.xml
/var/cache/cruisecontrol - папка используемая нашим веб приложением
/var/log/cruisecontrol - логи
/var/spool/cruisecontrol - все, что относится к нашим проектам
/var/spool/cruisecontrol/projects - рабочие папки проектов
/var/spool/cruisecontrol/artifacts - собранные артефакты
/var/spool/cruisecontrol/logs - логи сборки
Заменил содержимое cruisecontrol.sh
#!/bin/sh
basename=`basename $0`
function usage() {
exit 1
}
# The root of the CruiseControl directory. The key requirement is that this is the parent
# directory of CruiseControl's lib and dist directories.
if [ -z "$CCDIR" ]; then
CCDIR=/opt/cruisecontrol
fi
LIBDIR=$CCDIR/lib
temp=`getopt -o "" -a --long "port:,webport:,rmiport:,configfile:,log:,classpath:,basedir:,dashboardurl:,daemon,jetty" -n $basename -- "$@"`
if [ $? != 0 ]; then
usage
fi
eval set -- "$temp"
while [ "$1" != "--" ]; do
case "$1" in
--configfile)
configfile=$2
shift 2
;;
--jmxport|--port)
port=$2
shift 2
;;
--classpath)
CRUISE_PATH="$CRUISE_PATH:$2"
shift 2
;;
--log)
log=$2
shift 2
;;
--basedir)
basedir=$2
shift 2
;;
--dashboardurl)
dashboardurl=$2
shift 2
;;
--daemon)
daemon=true
shift 1
;;
--jetty)
jetty=true
shift 1
;;
--webport)
webport=$2
shift 2
;;
--rmiport)
rmiport=$2
shift 2
;;
*)
usage
;;
esac
done
# create the CruiseControl arguments (configfile, port)
[ -z "$configfile" ] && usage
CRUISE_OPTS="-configfile $configfile"
[ -n "$log" ] && CRUISE_OPTS="$CRUISE_OPTS -log4jconfig $log"
[ -n "$port" ] && CRUISE_OPTS="$CRUISE_OPTS -jmxport $port"
[ -n "$rmiport" ] && CRUISE_OPTS="$CRUISE_OPTS -rmiport $rmiport"
[ -n "$dashboardurl" ] && CRUISE_OPTS="$CRUISE_OPTS -dashboardurl $dashboardurl"
JAVA_OPTIONS="$JAVA_OPTIONS -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder -Dcc.library.dir=$LIBDIR"
# choose the JVM executable
JAVA_CMD="java"
[ -n "$JAVA_HOME" ] && JAVA_CMD="$JAVA_HOME/bin/java"
LAUNCHER="$LIBDIR/cruisecontrol-launcher.jar"
# if necessary, change to the base directory
[ -n "$basedir" ] && cd $basedir
if [ -n "$jetty" ]; then
JAVA_OPTIONS="$JAVA_OPTIONS -Djetty.logs=/var/log/cruisecontrol"
# CRUISE_MAIN=CruiseControlWithJetty
[ -n $webport ] && CRUISE_OPTS="$CRUISE_OPTS -webport $webport"
fi
EXEC="$JAVA_CMD $JAVA_OPTIONS -jar $LAUNCHER $@ $CRUISE_OPTS"
if [ -n "$daemon" ]; then
default_outputfile="/var/log/cruisecontrol/cruisecontrol.out"
if [ -z "$CRUISE_OUTPUTFILE" ]; then
CRUISE_OUTPUTFILE=$default_outputfile
fi
if [ ! -w "$CRUISE_OUTPUTFILE" ]; then
echo "$CRUISE_OUTPUTFILE isn't writable, output redirected to /dev/null"
CRUISE_OUTPUTFILE="/dev/null"
fi
echo $EXEC >> "$CRUISE_OUTPUTFILE"
$EXEC 2>&1 >> "$CRUISE_OUTPUTFILE" &
if [ -z "$CRUISE_PIDFILE" ]; then
CRUISE_PIDFILE="/var/run/cruisecontrol.pid"
fi
if [ -w "$CRUISE_PIDFILE" ]; then
echo $! > "$CRUISE_PIDFILE"
else
echo "$CRUISE_PIDFILE isn't writable, the JVM pid is $!"
fi
else
exec $EXEC
fi
]]>
Создал пользователя и привилегии на папки:
adduser --system --home /var/spool/cruisecontrol --no-create-home --ingroup nogroup --disabled-password --shell /bin/false ccontrol
chown ccontrol:adm -hR /var/log/cruisecontrol /var/spool/cruisecontrol
chown tomcat55:adm -hR /var/cache/cruisecontrol
chmod -R 755 /var/log/cruisecontrol /var/spool/cruisecontrol
chmod -R 775 /var/cache/cruisecontrol
ln -s /opt/cruisecontrol/bin/cruisecontrol /usr/bin/cruisecontrol
Для автоматического запуска нашего гиганта добавил файлы /etc/default/cruisecontrol и /etc/init.d/cruisecontrol следующего содержания:
#
# /etc/default/cruisecontrol
#
# Run CruiseControl as this user ID (default: ccontrol)
#
# Set this to an empty string to prevent CruiseControl from starting
# automatically. Think to stop CruiseControl before setting an empty string ;o)
#
# CRUISE_USER="root"
# Port used for the JMX Http Console
#CRUISE_PORT=8000
# To activate Jetty support
#CRUISE_JETTY=true
# Port used by the embedded Jetty server (if CRUISE_JETTY is true)
#CRUISE_JETTYPORT=8080
# CRUISE_RMIPORT
# Port used by the MBeanServer RMIConnector
# defaults: disabled
#CRUISE_RMIPORT=1099
CRUISE_DASHBOARD="http://localhost:8180/dashboard"
# The home directory of the Java development kit (JDK).
#JAVA_HOME="/usr/local/j2sdk1.3.1"
#JAVA_HOME="/usr/local/j2sdk1.4.0"
# JVM options
#JAVA_OPTIONS="-Xmx512m"
# Arguments to pass to the CruiseControl script
#CRUISE_OPTS=""
#
# Clean options
# used by /etc/cron.daily/cruisecontrol
#
# CRUISE_CLEANCACHE
# Max days to keep the cache (/var/cache/cruisecontrol) files
# defaults: 7
#CRUISE_CLEANCACHE=7
# CRUISE_CLEANLOGS
# Max days to keep the logs (/var/spool/cruisecontrol/logs) files
# defaults: none
#CRUISE_CLEANLOGS=7
#! /bin/sh -e
#
# /etc/init.d/cruisecontrol -- startup script for the CruiseControl engine
#
# Writed by Alban Peignier.
# Based on the tomcat4 init script
PATH=/usr/bin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=cruisecontrol
DESC="CruiseControl loop engine"
DAEMON=/usr/bin/$NAME
# The following variables can be overwritten in /etc/default/cruisecontrol
# Run CruiseControl as this user ID (default: ccontrol)
# Set this to an empty string to prevent CruiseControl from starting automatically
CRUISE_USER=ccontrol
CRUISE_PORT=8000
CRUISE_JETTYPORT=8080
# Arguments to pass to the Java virtual machine (JVM)
CRUISE_OPTS=""
# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not
# defined in /etc/default/cruisecontrol)
JDK_DIRS=`ls -d /usr/lib/jvm/* /usr/lib/j2sdk* /usr/lib/j2re* 2> /dev/null || true`
# End of variables that can be overwritten in /etc/default/cruisecontrol
# overwrite settings from default file
if [ -f /etc/default/cruisecontrol ]; then
. /etc/default/cruisecontrol
fi
test -f $DAEMON || exit 0
function check_for_no_start() {
if [ -z "$CRUISE_USER" ]; then
echo "Not starting/stopping $DESC as configured (CRUISE_USER is"
echo "empty in /etc/default/cruisecontrol)."
exit 0
fi
}
# Look for the right JVM to use
for jdir in $JDK_DIRS; do
if [ -d "$jdir" -a -z "${JAVA_HOME}" ]; then
JAVA_HOME="$jdir"
fi
done
export JAVA_HOME
if [ -z "$JAVA_HOME" ]; then
echo "Could not start $DESC because no Java Development Kit"
echo "(JDK) was found. Please download and install JDK 1.3 or higher and set"
echo "JAVA_HOME in /etc/default/cruisecontrol to the JDK's installation directory."
exit 0
fi
[ -n "$JAVA_OPTIONS" ] && export JAVA_OPTIONS
CRUISE_OPTS="$CRUISE_OPTS -configfile /etc/cruisecontrol/cruisecontrol.xml"
CRUISE_OPTS="$CRUISE_OPTS -port $CRUISE_PORT"
CRUISE_OPTS="$CRUISE_OPTS -log file:/etc/cruisecontrol/log4j.xml"
CRUISE_OPTS="$CRUISE_OPTS -basedir /var/spool/cruisecontrol"
CRUISE_OPTS="$CRUISE_OPTS -daemon"
if [ "$CRUISE_JETTY" = "true" ]; then
CRUISE_OPTS="$CRUISE_OPTS -jetty -webport $CRUISE_JETTYPORT"
fi
if [ -n "$CRUISE_RMIPORT" ]; then
CRUISE_OPTS="$CRUISE_OPTS -rmiport $CRUISE_RMIPORT"
fi
if [ -n "$CRUISE_DASHBOARD" ]; then
CRUISE_OPTS="$CRUISE_OPTS -dashboardurl $CRUISE_DASHBOARD"
fi
export CRUISE_OPTS
# Define other required variables
LOGDIR="/var/log/cruisecontrol"
CRUISE_PIDFILE="/var/run/$NAME.pid"
CRUISE_OUTPUTFILE=$LOGDIR/cruisecontrol.out
export CRUISE_PIDFILE CRUISE_OUTPUTFILE
case "$1" in
start)
check_for_no_start
echo -n "Starting $DESC: "
touch "$CRUISE_PIDFILE" "$LOGDIR/cruisecontrol.out" || true
chown --dereference "$CRUISE_USER" "$CRUISE_PIDFILE" "$LOGDIR" \
"$LOGDIR/cruisecontrol.out" || true
if start-stop-daemon --test --start --pidfile "$CRUISE_PIDFILE" \
--user $CRUISE_USER --startas "$JAVA_HOME/bin/java" \
>/dev/null; then
# -p preserves the environment (for $JAVA_HOME etc.)
# -s is required because cruisecontrol's login shell is /bin/false
su -p -s /bin/sh $CRUISE_USER \
-c "\"$DAEMON\" $CRUISE_OPTS" \
>>"$LOGDIR/cruisecontrol.out" 2>&1
echo "$NAME."
else
echo "(already running)."
fi
;;
stop)
echo -n "Stopping $DESC: "
if start-stop-daemon --test --start --pidfile "$CRUISE_PIDFILE" \
--startas "$JAVA_HOME/bin/java" \
>/dev/null; then
echo "(not running)."
else
stop_options=""
if [ -n "$CRUISE_USER" ]; then
stop_options="--user $CRUISE_USER"
fi
start-stop-daemon --stop --oknodo --quiet \
--pidfile "$CRUISE_PIDFILE" $stop_options
rm -f "$CRUISE_PIDFILE"
echo "$NAME."
fi
;;
restart|force-reload)
check_for_no_start
$0 stop
sleep 1
$0 start
;;
*)
#echo "Usage: /etc/init.d/cruisecontrol {start|stop|restart|reload|force-reload}" >&2
echo "Usage: /etc/init.d/cruisecontrol {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
Далее
update-rc.d cruisecontrol defaults
invoke-rc.d cruisecontrol start
Теперь запуск Cruise Control будет автоматическим. Но чего то не хватает... Веб приложение! Для того, чтобы все заработало как надо, необходимо немного подправить некоторые настройки. Итак, /opt/cruisecontrol/webapps/cruisecontrol/WEB-INF/web.xml, находим и правим параметры:
- cacheRoot на /var/cache/cruisecontrol
- logDir на /var/spool/cruisecontrol/logs
- rootDir на /var/spool/cruisecontrol/artifacts
Теперь настроим dashboard. Лезем в /etc/default/tomcat5.5 правим
JAVA_OPTS="-Ddashboard.config=/etc/cruisecontrol/dashboard.xml"
/etc/cruisecontrol/dashboard.xml
<buildloop logsdir="/var/spool/cruisecontrol/logs" artifactsdir="/var/spool/cruisecontrol/artifacts"/>
CC готов к работе! Осталось настроить проекты, но об этом в другой раз...