How to compile 3.3.3 web agents on Linux

Trying to build the web policy agents may be a little frustrating at times, especially because it is generally not that well documented. As part of the 3.3.3 agent release I had the joy of going through the build process of the Linux web agents, so here you go, here are the steps I’ve gone through to build the agents on a freshly installed CentOS 5.10 (32 & 64 bit). For the very keen, I’ve also aggregated all the commands into shell scripts, you can find them at the bottom of this post.

Packages

On an out of the box CentOS 5.10 installation gcc is already installed, but there are some other components you should make sure you have installed before attempting to compile the agents:

  • subversion: To check out the source code of the agents.
  • ant: To perform the build, the agents are using Ant scripts to define the build steps.
  • zlib-devel: Compilation time dependency.
  • gcc-c++: C++ compiler.
  • rpm-build: RPM packages are being generated as part of the build process.
  • gcc44: Building NSS requires a newer GCC than the default one.
  • java-1.6.0-openjdk-devel: JDK to be able to build the agent installers (and run the Ant scripts).

The agent dependencies

The agents rely on the following external libraries:

  • NSS 3.16.3 & NSPR 4.10.6
    On 32 bit the component should be built with:

    make BUILD_OPT=1 NS_USE_GCC=1 NSS_ENABLE_ECC=1 NSDISTMODE="copy" CC="/usr/bin/gcc44 -Wl,-R,'$$ORIGIN/../lib' -Wl,-R,'$$ORIGIN'" nss_build_all

    On 64 bit the command is:

    make USE_64=1 BUILD_OPT=1 NS_USE_GCC=1 NSS_ENABLE_ECC=1 NSDISTMODE="copy" CC="/usr/bin/gcc44 -Wl,-R,'$$ORIGIN/../lib' -Wl,-R,'$$ORIGIN'" nss_build_all
  • PCRE 8.31
    On 32 bit:

    ./configure --with-pic --enable-newline-is-anycrlf --disable-cpp

    On 64 bit:

    CC="gcc -m64" CXX="g++ -m64" ./configure --with-pic --enable-newline-is-anycrlf --disable-cpp
  • libxml2 2.9.1
    On either platform:

    ./configure --prefix=/opt/libxml2 --with-threads --with-pic --without-iconv --without-python --without-readline
  • The header files of various web containers

Once all the libraries are in place, you can run the build on 32 bit:

ant nightly

on 64 bit:

ant nightly -Dbuild.type=64

And here are the shell scripts:
32 bit
64 bit

Systemd is the Cat’s Pyjamas



I have been converting some of the startup scripts for my Open Identity Stack project to use systemd. Systemd is now available on Fedora, CentOS and Redhat - and is coming soon to Debian and Ubuntu (you can actually get it now in Debian testing).

What strikes me is how dead simple it is to create init services that just work.  Here is an example for openidm.service that leverages start/stop scripts that come with OpenIDM:




[Unit]
Description=OpenIDM
After=remote-fs.target nss-lookup.target

[Service]
Type=simple
ExecStart=/opt/ois/openidm/startup.sh
ExecStop=/opt/ois/openidm/shutdown.sh
User=fr
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

* The only tricky thing above is the SuccessExitStatus. For reasons that I do not fully understand, many Java based programs started with shell scripts will use that system exit code.

Copy the above to /etc/systemd/system/openidm.service and you are good to go:

systemctl start openidm.service
systemctl stop openidm.service
systemctl status openidm.service

To see the output use:

journalctl 

Scroll to the end by typing "G"


This service file was dead simple to write, and "it just works". Systemd takes care of tracking the process and any spawned children.

By way of constrast, I will leave you with the old openidm script that I spent considerable time hacking to get the correct start/stop behavior. I could never get this init script to reliably execute the shell scripts that came with OpenIDM.


#!/bin/sh
# chkconfig: 345 95 5
# description: start/stop openidm



# clean up left over pid files if necessary
cleanupPidFile() {
if [ -f $OPENIDM_PID_FILE ]; then
rm -f "$OPENIDM_PID_FILE"
fi
trap - EXIT
exit
}

JAVA_BIN={{java_home}}/bin/java

OPENIDM_HOME={{install_root}}/openidm
OPENIDM_USER={{fr_user}}
OPENIDM_PID_FILE=$OPENIDM_HOME/.openidm.pid
OPENIDM_OPTS="-Xmx1024m -Dfile.encoding=UTF-8"

cd ${OPENIDM_HOME}

# Set JDK Logger config file if it is present and an override has not been issued
if [ -z "$LOGGING_CONFIG" ]; then
if [ -r "$OPENIDM_HOME"/conf/logging.properties ]; then
LOGGING_CONFIG="-Djava.util.logging.config.file=$OPENIDM_HOME/conf/logging.properties"
else
LOGGING_CONFIG="-Dnop"
fi
fi


CLASSPATH="$OPENIDM_HOME/bin/*:$OPENIDM_HOME/framework/*"
START_CMD="nohup $JAVA_BIN $LOGGING_CONFIG $JAVA_OPTS $OPENIDM_OPTS \
-Djava.endorsed.dirs=$JAVA_ENDORSED_DIRS \
-classpath $CLASSPATH \
-Dopenidm.system.server.root=$OPENIDM_HOME \
-Djava.awt.headless=true \
org.forgerock.commons.launcher.Main -c $OPENIDM_HOME/bin/launcher.json > $OPENIDM_HOME/logs/server.out 2>&1 &"
case "${1}" in
start)
su $OPENIDM_USER -c "$START_CMD eval echo \$\! > $OPENIDM_PID_FILE"
exit ${?}
;;
stop)
./shutdown.sh > /dev/null
exit ${?}
;;
restart)
./shutdown.sh > /dev/null
su $OPENIDM_USER -c "$START_CMD eval echo \$\! > $OPENIDM_PID_FILE"
exit ${?}
;;
*)
echo "Usage: openidm { start | stop | restart }"
exit 1
;;


esac

ForgeRock welcomes Chris Lee

ForgeRock Logo Welcome to Chris Lee! Chris joined the ForgeRock documentation team today. Great to have you at ForgeRock, Chris!

Chris comes to us from SN Systems (part of Sony Computer Entertainment Group) where he led the documentation effort for their PlayStation game development tools. He understands what developers are looking for, and is primed to come over to the world of Java and the web. Chris’s previous experience in support and as a website engineer give him a head start understanding the solution space that we address at ForgeRock. And he brings a Microsoft power user’s perspective to our team, which is important for a lot of our readers.

Chris will focus on ForgeRock access management documentation, in particular for OpenAM. This is good news for the ForgeRock access management community.