Hudson Service script

January 2nd, 2009

Below is the code for startHudson.sh

#!/usr/bin/env bash
# Uncomment the following line if you have OutOfMemoryError errors
# HUDSON_OPTS=”-Xms128m -Xmx256m”

export JAVA_HOME=/usr/java/default
LAUNCHER=hudson.war

EXEC=”$JAVA_HOME/bin/java $HUDSON_OPTS -jar $LAUNCHER $@ ”
echo $EXEC
$JAVA_HOME/bin/java $HUDSON_OPTS -jar “$LAUNCHER” $@ &
echo $! > hudson.pid

Below this is the code for hudson.sh which should then be symlinked into /etc/init.d/hudson , then it should be chkconfig –add hudson to make it a service.

#!/bin/sh
#content of /opt/hudson/default/hudson.sh script
# chkconfig: 345 99 05
# description: Hudson build loop

# Hudson Unix Startup Script Version 1.0
#
# based on http://confluence.public.thoughtworks.org/display/CC/UnixStartupScriptVersion1.x
# adapted for multiple projects
# also based on the file attached to the above page created by Jerome Lacoste

#
# Hudson startup: Startup and kill script for Hudson
#
###################################################################################################
# USER CONFIGURATION
#
# Fill in these values for your Hudson setup

# What user will Hudson run as? The user will need permission to write and modify files
# in the next entries.
HUDSON_USER=hudson

# Where is the HUDSON startup script located?
HUDSON_INSTALL_DIR=/opt/hudson/default

# In what directory is the config.xml file located for HUDSON?
# default: HUDSON_WORK_DIR=$HUDSON_INSTALL_DIR
HUDSON_WORK_DIR=$HUDSON_INSTALL_DIR

# Where will the hudson.log file be located?
# default: HUDSON_LOGFILE_DIR=$HUDSON_INSTALL_DIR
HUDSON_LOGFILE_DIR=$HUDSON_INSTALL_DIR

#######################
# ENVIRONMENT ADDITIONS

# Add environement variables here that are needed
# example:
# export JAVA_HOME=/usr/local/java
#
export JAVA_HOME=/usr/java/default
export JDK_HOME=/usr/java/default
export ANT_HOME=/opt/ant/default
export M2_HOME=/opt/maven/default
export M2=$M2_HOME/bin
export GROOVY_HOME=/opt/groovy/default
export HUDSON_HOME=/opt/hudson/default

# Add path to additional executables needed for project build. See PATH entry below for base config.
# No additional action taken when blank.
PATH_ADDITIONS=

##############################
# Hudson PORT SETTINGS

# Port for application. You can access it by going to http://localhost:8080
# Specify only one either Webport or Securewebport if you want to use https
# default HUDSON_WEBPORT=8080
HUDSON_WEBPORT=8080
HUDSON_SECURE_WEBPORT=

###################################################################################################
# DO NOT MODIFY ENTRIES BELOW THIS LINE

NAME=hudson
DESC=”Hudson - continuous integration build loop”

PATH=/sbin:/usr/sbin:/usr/bin:/bin
# add additions if variable has text defined
if [ -n “$PATH_ADDITIONS” ]; then
PATH=$PATH_ADDITIONS:$PATH
fi
export PATH

HUDSON_DAEMON=$HUDSON_INSTALL_DIR/startHudson.sh

HUDSON_LOG_FILE=$HUDSON_LOGFILE_DIR/hudson.log

if [ -n “$HUDSON_SECURE_WEBPORT” ]; then
HUDSON_COMMAND=”$HUDSON_DAEMON –httpsPort=$HUDSON_SECURE_WEBPORT –webroot=/opt/hudson/default/hudson ”
fi

if [ -n “$HUDSON_WEBPORT” ]; then
HUDSON_COMMAND=”$HUDSON_DAEMON –httpPort=$HUDSON_WEBPORT –webroot=/opt/hudson/default/hudson ”
fi

# does the executable exist?
test -f $HUDSON_DAEMON || (echo “The executable $HUDSON_DAEMON does not exist!” && exit 0)

if [ `id -u` -ne 0 ]; then
echo “Not starting/stopping $DESC, you are not root.”
exit 4
fi

# Get the PID output from the startup script
if [ -f $HUDSON_INSTALL_DIR/hudson.pid ]; then
HUDSON_PID=`cat $HUDSON_INSTALL_DIR/hudson.pid`
else
echo “No hudson.pid file found. HUDSON process may not be controllable from this script!”
fi

case “$1″ in

’start’)
cd $HUDSON_INSTALL_DIR
#echo “HUDSON environtment at startup” > hudson.startup.env
#env >> hudson.startup.env
su $HUDSON_USER -c “/bin/sh -c \”$HUDSON_COMMAND >> $HUDSON_LOG_FILE 2>&1\”" & RETVAL=$?
echo “$NAME started on port ${HUDSON_WEBPORT}”
;;

’stop’)
if [ -n “$HUDSON_PID” ] && ps -p ${HUDSON_PID} > /dev/null ; then
kill -9 ${HUDSON_PID}
$0 status
RETVAL=$?
else
echo “$NAME is not running”
RETVAL=1
fi
;;

’status’)
if [ -n “$HUDSON_PID” ] && ps -p ${HUDSON_PID} > /dev/null ; then
echo $NAME \(pids $HUDSON_PID\) is running
RETVAL=0
else
echo “$NAME is stopped”
RETVAL=1
fi
;;

‘restart’)
$0 stop && $0 start
RETVAL=$?
;;

*)
echo “Usage: $0 { start | stop | status | restart }”
exit 1
;;
esac
#echo ending $0 $$….
exit 0;

Groovy Grails REST service helper

August 23rd, 2008

h4. Quick Tip on Markup Builder example is from a Domain object (Book) that contains enum’s if you have only simple datatypes then “render as XML” works just fine

String toXML() {
StringWriter buffer = new StringWriter()
def xml = new MarkupBuilder(buffer)
xml.book() {
id(this.id)
author(this.authorName)
pagecount(pagecount:this.pagecount)
}
return buffer.toString() + “\\n”
}

Keep in mind that the difference between author and pagecount looks like this in the xml


222
Toddecus

You can see that the pagecount is much more terse but may present challenges on parsing.h4. Quick Tip on parsing say a Rest service that returns the XML above: This assumes you used an XMLSlurper to parse the text into a GPathResult
{code}
static Book fromXML(GPathResult bookXML)
{
def book = new Book()
book.id = Integer.parseInt(bookXML.id.text())
book.author = bookXML.author.text()
book.pagecount = Integer.parseInt(bookXML.pagecount.@pagecount.text())
return book
}
{code}Pay special attention to the use of the “at” symbol to get access to the property on the field as opposed to the field contents.

h4. If you really cared about terse XML in your REST service you might even do this:
{code}
String toXML() {
StringWriter buffer = new StringWriter()
def xml = new MarkupBuilder(buffer)
xml.book(id: this.id, author:this.authorName, pagecount:this.pagecount){}
return buffer.toString() + “\\n”
}
{code}
Which would result in XML like this:
{code}

{code}
doesn’t help much if your domain object contains a set of sub elements though :)

Progression from Jr. Desktop Support to Senior Systems Administrator

August 23rd, 2008

The progression in the IT world looks like this for a system administrator

Desktop Support or Help Desk moving to > Jr. System Administrator - Great
place to take this step is at a hosting company working in the NOC or a
large university or large corporation that have subtle nuances of levels of
sytem administrators. Together with installing Linux and configuring it at
home Red Hat and at least One OTHER distribution. RHT is a great starter
certification on the UNIX path. MCSE is good on the windows path (easier
but will pay less in the long run). Master an Editor on UNIX (VI or don’t
do UNIX!) either textpad or Ultraedit on windows. Learn how HTML, HTTP,
SSL, printers, WiFi, ping, traceroute, nslookup (dig), ifconfig or win
equivalent. Master TCP/IP, DHCP, and

Jr. Systems moving to >> Mid Systems
Must learn at least competent level on the OTHER flavor for example if you
are now a UNIX guy, then learn how to make it talk to windows. Add to that
at least all the basic configurations of a Mail program (Exchage or
Postfix/Qmail). Know backwards and forwards DNS, HTTP, and learn a SHELL
scripting language. (KSH, SH, Windows PowerShell), learn to setup backups
and cron jobs. Learn how to read logs. Know Syslog and setup at least one
monitoring system. Learn file sharing Samba, NFS, windows etc… And how to
manage this. (Active Directory or Open Directory, or LDAP) Implement a
single sign on. SSH Keys & other two factor authentication. Learn VOIP and
setup and configure phones. MUST master time management, organization, and
prioritization to make it to the Mid level of systems administration.

Mid >> Senior Systems
Must setup and configure at least one flavor of SAN, must learn CISCO IOS at
a basic level, configure a firewall, know what a VLAN is, and master a
scripting language. Must be able to configure either IIS or Apache. Must
Learn basic SQL. Learn a second more advanced scripting language ( Perl,
Groovy, Ruby) Support one Major application server, database or ERP server.
Must learn to ment

Off Topic How to use LVM in CENTOS to add a second hard drive

May 1st, 2008

The current instructions on LVM howto are sparse and generally suck. So after some figuring here are the steps to add a second hard drive. (Not doing anything complicated like striping or adding to volume groups, etc..) Just plain old vanilla add a second hard drive to my server.

You’ll find this command handy to see what your current boot drive is setup for:

pvdisplay

The newDrive is not there! Ok how do I get it there?

Run :

lvmdiskscan

I see it but it does not say “LVM Physical volume” the way my boot drive does. How do I know which one is the new drive? (I don’t have a precise answer but I can say that /dev/hd?? and the size of the drive should help. Remember 200 GB for me looked like [186.31 GB] example of my boot drive results below

/dev/hda2 [ 74.43 GB] LVM physical volume

/dev/hdd1 [ 186.31 GB]

Now I found mine was named /dev/hdd1 so do the next two commands

pvcreate /dev/hdd1

dd if=/dev/zero of=/dev/diskname bs=1k count=1

Now lets see where we are at:

pvdisplay

Drive now there but no Volume Group or size information

next step is to create the Physical Volume Group possible names: testvg, vg, or in my case VolGroup01

vgcreate VolGroup01 /dev/hdd1

Now how are we doing:

pvdisplay

Now all the information is there and in volume group!

Now to create one of these Logical Volume things. Where did the -l size come from? Read “Total PE” from pvdisplay. Now choose a Logical Volume arbitrary name e.g. LogVol01, or lvg, or data. I chose opt because that was where I was going to mount it.

lvcreate -l 47694 VolGroup01 -n opt

Now we have a Logical volume group, lets format the disk and lay down a file system. I am assuming you would like some form of journaled file system for example ext3 :) the -j means journal it, without the -j you get an ext2.

mke2fs -j /dev/VolGroup01/opt

Now that the filesystem is in place lets try mounting the logical volume. Be sure to choose a place that doesn’t have data in it. I like /opt or /data for example

mount /dev/VolGroup01/opt /opt

df -k

Whahoo! Victory! now I can set /opt as the directory for mysql or Oracle to dump it’s data and go to town. One last thing. So I can shut the machine down and have it mount automagically when it comes back up. Go add the following line to /etc/fstab

vi /etc/fstab
/dev/
VolGroup01/opt /opt ext3 defaults 1 1

Better Web App — Better Late than Never

April 3rd, 2008

18 months ago Mr. Park, Mr. Bukoski and I were faced with the task of a software engineering capstone project. Foolishly, I enrolled these two fine gentlemen in the idea that we might write a simple, 3 Tier, and Enterprise class website in all of the currently available Web Application Technology Platforms, and if we did all this painstaking work, we might get published therefore setting us up for future academic success. Alas, after 6 months of hard work and 9 months of waiting for me to get this published, I have surrendered to the call of modern publishing: a CMS’ed website and Blog. This site represents an earnest, fraught with peril and assumptions attempt to create an objective tool to evaluate Web Application Technology Platforms. You will have to be the judge of our success or failure. We graduated from Arizona State University W.P. Carey School of Business with our MBA’s and Ed and Anthony even went on to complete their Master’s in Engineering. If you ever have an opportunity to work with these two unassuming and brilliant individuals I highly recommend it!

Sincerely,

Todd R. Ellermann, MBA