#!/bin/ksh93 # OpenGrok Wrapper (initial setup and cron job updating) for Glassfish OG_DIR=${.sh.file}; OG_DIR=${OG_DIR%/*/*}; [[ $OG_DIR == ${.sh.file} ]] && OG_DIR=$PWD export LC_CTYPE="de_DE.UTF-8" LANG="$LC_CTYPE" typeset -ft $(typeset +f) # Initialize the environment for opengrok with reasonable defaults. SetupEnv() { # REQUIRED: Glassfish domain directory to use GF_DOMAINDIR="${GF_DOMAINDIR:-/data/glassfish/src}" # The owner of the glassfish directory GF_OWNER="webservd:webservd" # Configuration Address (host:port in conf/web.xml) WEBAPP_CONFIG="${WEBAPP_CONFIG:-localhost:2424}" # REQUIRED: Full Path to Java Installation Root JAVA_HOME="${JAVA_HOME:-/usr/jdk/instances/jdk1.7.0}" # Enable remote debugging for the current indexer #JAVA_DEBUG="-agentlib:jdwp=transport=dt_socket,server=y,address=8010,suspend=y" #JAVA_OPTS="-server -Xmx2048m" JAVA_OPTS=${JAVA_OPTS:-"-Xmx2048m"} # REQUIRED: Full Path to Exuberant CTags EXUBERANT_CTAGS="${EXUBERANT_CTAGS:-/usr/bin/etags}" # REQUIRED: OpenGrok's working directory OG_WORK_DIR="${OG_WORK_DIR:-/data/opengrok}" # file with read only configuration - a temp workaround for bug #327 # see https://defect.opensolaris.org/bz/show_bug.cgi?id=327 #READ_XML_CONFIG= # How deep should scanning for repos go (default: 3 dirs from SRC_ROOT) #OG_SCAN_DEPTH=3 # Enable Projects: every dir in SRC_ROOT is considered a separate project #OG_PROJECTS=1 # Disable History Cache for (remote) Repositories (CVS or SVN). # Can be very time demanding, uncomment if not needed. #OG_NOREMOTE_REPOS=1 # Disable Scan for repositories. Uncomment if needed. #OG_NOSCAN_REPOS=1 # Set Maximum Indexed Words Per File (default: unlimited). # Note, that you might run out of memory, then either increase JVM memory # as noted in JAVA_OPTS, or set this limit (if you don't mind opengrok not # indexing the rest of the file, once the limit is reached) #OG_MAX_WORDS=100000 # Store the history cache in Java DB (derby) instead of file system # (gzipped xml files). #OG_DERBY=1 # Use the Derby as embedded DB (instead of an external one, which defaults # to localhost:1527). To be able to selectively tune DB and application, # this is not recommended. #OG_DERBY_EMBEDDED=1 # Disable wildcard prefix search query support. Uncomment if needed. #OG_NOWPREFIX=1 # Ignore these patterns as names of files or directories. # Add for each pattern a '-i' and enclose patterns with special characters # like ! or * in single quotes and escape special shell characters. #OG_IGNORE="-i dummy -i dummy2" # Web Site Look & Feel {default|offwhite|polished}. #OG_SKIN="default" # Suppress Progress and Warnings Messages #OG_NON_INTERACTIVE=1 # Enable Verbose Mode in opengrok.jar #OG_VERBOSE=1 # Shows progress in % of working through project. It's good to have verbose # Mode enabled too, cost of this is one more traversal of the project # before indexing it #OG_PROGRESS=1 # Replace a tab in the source code by the given number of spaces. # It might be needed because most web browsers always expand a tab character # to 8 space characters and thus screws up its appearance. Default: 0, i.e. # do not expand tabs - let the browser do, what it wants. #OG_TABS=4 # ------ usually one does not need to touch remaining stuff ------ # REQUIRED (deploy): Glassfish WAR Target Directory OG_WAR_DST="${OG_WAR_DST:-${GF_DOMAINDIR}/autodeploy}" # REQUIRED (deploy): Web Archive of OpenGrok (Distribution Location). OG_WAR_SRC="${OG_WAR_SRC:-${OG_DIR}/lib/source.war}" # REQUIRED: Source Code/Repository Root # (your source code or the root of all repositories) SRC_ROOT="${SRC_ROOT:-${OG_WORK_DIR}/source}" # REQUIRED: OpenGrok Generate Data Root (for Lucene index and hypertext # cross-references). This area is rebuilt by "update". DATA_ROOT="${DATA_ROOT:-${OG_WORK_DIR}/data}" # User Provided Source Path to Description Mapping (Tab Separated Value) # The user maintained source of the generated EftarFile file. PATH_DESC="${PATH_DESC:-${OG_WORK_DIR}/etc/paths.tsv}" # REQUIRED: XML Configuration (the config used by Web/GUI interfaces) XML_CONFIG="${XML_CONFIG:-${OG_WORK_DIR}/etc/configuration.xml}" # REQUIRED: Logger Configuration LOG_CONFIG_FILE="${LOG_CONFIG_FILE:-logging.properties}" LOG_CONFIG_PATH="${LOG_CONFIG_PATH:-$OG_WORK_DIR/etc/$LOG_CONFIG_FILE}" # template to use to create $LOG_CONFIG_PATH when it is n/a LOG_CONFIG_SRC="${LOG_CONFIG_SRC:-${OG_DIR}/doc/logging.properties}" # REQUIRED: Java Archive of OpenGrok (Installation Location) OG_JAR="${OG_JAR:-${OG_DIR}/lib/opengrok.jar}" # Full Path to History Utilities HG="${HG:-${ Which hg; }}" CVS="${CVS:-${ Which cvs; }}" SVN="${SVN:-${ Which svn; }}" SCCS="${SCCS:-${ Which sccs; }}" CLEARCASE="${CLEARCASE:-${ Which cleartool; }}" GIT="${GIT:-${ Which git; }}" P4="${P4:-${ Which p4; }}" MTN="${MTN:-${ Which mtn; }}" BZR="${BZR:-${ Which bzr; }}" # The user configuration directory to be used by svn (equivalent to # svn's --config-dir option). If not set, svn will use its builtin default. #SVN_CONFIG_DIR= # EftarFile == An Extremely Fast Tagged Attribute Read-only File System EFTAR_UPDATE="${EFTAR_UPDATE:-org.opensolaris.opengrok.web.EftarFile}" # HARDCODED: Generated EftarFile (See web/*.jsp) EFTAR_OUTPUT_FILE="${EFTAR_OUTPUT_FILE:-${DATA_ROOT}/index/dtags.eftar}" } # # Helper Functions # Progress() { [[ -z $OG_NON_INTERACTIVE ]] && print "${@}" } Warning() { [[ -z $OG_NON_INTERACTIVE ]] && print -u2 "WARNING: ${@}" } Error() { print -u2 "ERROR: ${@}" } FatalError() { print -u2 "\nFATAL: ${@} - Aborting!" ${DO} exit 2 } # # Helper Functions - Autodetection of Runtime Environment # Which() { whence -p $1 2>/dev/null } LoadInstanceConfiguration() { if [[ -n $1 ]]; then if [[ -r $1 ]]; then PROPFILE="$1" Progress "Loading $PROPFILE ..." source "$PROPFILE" [[ ${PROPFILE#/} == $PROPFILE ]] && PROPFILE="$PWD/$PROPFILE" else FatalError "Unable to load $1" fi else Progress "Using default settings ..." fi } checkJava() { # REQUIRED: Java Virtual Machine export JAVA_HOME if [[ -z $JAVA_HOME ]]; then if [[ -n $JAVA && -x $JAVA ]]; then : else JAVA=${ Which java; } fi if [[ -n $JAVA && -x $JAVA ]]; then JAVA_HOME=${JAVA%/*} JAVA_HOME=${JAVA%/*} else FatalError "java not found." fi fi JAVA="${JAVA:-$JAVA_HOME/bin/java}" } ValidateConfiguration() { checkJava JAR="${JAR:-$JAVA_HOME/bin/jar}" unset VERBOSE QUIET PROGRESS DERBY_HISTORY_CACHE SCAN_DEPTH READ_XML_CONF \ ENABLE_PROJECTS SKIN IGNORE_PATTERNS MAX_INDEXED_WORDS EMBEDDED TABS [[ -n $OG_VERBOSE ]] && VERBOSE="-v" && QUIET="" [[ -n $OG_PROGRESS ]] && PROGRESS="-C" [[ -n $OG_DERBY ]] && DERBY_HISTORY_CACHE="-D" [[ -n $OG_SCAN_DEPTH ]] && SCAN_DEPTH="-z${OG_SCAN_DEPTH}" [[ -n $OG_PROJECTS ]] && ENABLE_PROJECTS="-P" [[ -n $OG_IGNORE ]] && IGNORE_PATTERNS="-i $OG_IGNORE" [[ -n $OG_MAX_WORDS ]] && MAX_INDEXED_WORDS="-m $OG_MAX_WORDS" [[ $OG_DERBY_EMBEDDED == "1" ]] && EMBEDDED="-j embedded" [[ -n $OG_TABS ]] && TABS="-t $OG_TABS" LOG_PROPERTIES="-Djava.util.logging.config.file=${LOG_CONFIG_PATH}" if [[ $WEBAPP_CONFIG =~ (none|-) ]]; then : else WEBAPP_CONFIG_ADDRESS="-U "${WEBAPP_CONFIG:-"localhost:2424"} fi # We should not set properties to the empty string PROPERTIES="\ ${HG:+-Dorg.opensolaris.opengrok.history.Mercurial=$HG} \ ${CVS:+-Dorg.opensolaris.opengrok.history.cvs=$CVS} \ ${SVN:+-Dorg.opensolaris.opengrok.history.Subversion=$SVN} \ ${SCCS:+-Dorg.opensolaris.opengrok.history.SCCS=$SCCS} \ ${CLEARCASE:+-Dorg.opensolaris.opengrok.history.ClearCase=$CLEARCASE} \ ${GIT:+-Dorg.opensolaris.opengrok.history.git=$GIT} \ ${P4:+-Dorg.opensolaris.opengrok.history.Perforce=$P4} \ ${MTN:+-Dorg.opensolaris.opengrok.history.Monotone=$MTN} \ ${BZR:+-Dorg.opensolaris.opengrok.history.Bazaar=$BZR} \ " [[ -n $SVN_CONFIG_DIR ]] && PROPERTIES+=" -Dorg.opensolaris.opengrok.history.Subversion.configdir=$SVN_CONFIG_DIR" [[ -n $READ_XML_CONFIG && -r $READ_XML_CONFIG ]] && \ READ_XML_CONF="-R $READ_XML_CONFIG" LEADING_WILDCARD="-a on" [[ -n $OG_NOWPREFIX ]] && LEADING_WILDCARD="" REMOTE_REPOSITORIES="-r on" [[ -n $OG_NOREMOTE_REPOS ]] && REMOTE_REPOSITORIES="" SCAN_FOR_REPOSITORY="-S" [[ -n $OG_NOSCAN_REPOS ]] && SCAN_FOR_REPOSITORY="" if [[ -n $OG_SKIN ]]; then case "$OG_SKIN" in default) SKIN="-L default" ;; offwhite) SKIN="-L offwhite" ;; polished) SKIN="-L polished" ;; *) Warning "Invalid OG_SKIN ignored!" ;; esac fi if [[ ! -x $EXUBERANT_CTAGS ]]; then FatalError "Missing Dependent Application - Exuberant CTags" fi if [[ ! -d $SRC_ROOT ]]; then FatalError "OpenGrok Source Path $SRC_ROOT doesn't exist" fi if [[ -n $QUIET && -n $VERBOSE ]]; then Warning "Both Quiet and Verbose Mode Enabled - Choosing Verbose" QUIET="" VERBOSE="-v" fi dlib="lib/derbyclient.jar" if [[ -n $OG_DERBY && ! -r $OG_DIR/lib/$dlib ]]; then if [[ -n "$AS_HOME" && -r $AS_HOME/javadb/$dlib ]]; then ${DO} ln -s "$AS_HOME/javadb/$dlib" "$OG_DIR/lib/$dlib" || \ print -u2 "\n\nExecute the following command as root:\n" \ "ln -s $AS_HOME/javadb/$dlib $OG_DIR/lib/$dlib\n" elif [[ -r /opt/SUNWjavadb/$dlib ]]; then ${DO} ln -s /opt/SUNWjavadb/$dlib "$OG_DIR/lib/$dlib" || \ print -u2 "\n\nExecute the following command as root:\n" \ "ln -s /opt/SUNWjavadb/$dlib $OG_DIR/lib/$dlib\n" else FatalError "$OG_DIR/lib/$dlib not found!" fi fi } CreateRuntimeRequirements() { if [[ ! -d $DATA_ROOT ]]; then Warning "OpenGrok generated data path $DATA_ROOT doesn't exist" Progress " Attempting to create generated data directory ... " ${DO} mkdir -p "$DATA_ROOT" || \ FatalError "OpenGrok data path $DATA_ROOT doesn't exist" fi if [[ ! -d $OG_WORK_DIR/etc ]]; then Warning "OpenGrok generated etc path $OG_WORK_DIR/etc doesn't exist" Progress " Attempting to create generated etc directory ... " ${DO} mkdir -p "$OG_WORK_DIR/etc" || \ FatalError "OpenGrok etc path $OG_WORK_DIR/etc doesn't exist" fi if [[ -n $LOG_CONFIG_PATH && ! -f $LOG_CONFIG_PATH ]]; then Progress " Creating default $LOG_CONFIG_PATH ... " if [[ ! -f $LOG_CONFIG_SRC ]]; then Warning "Can't find distribution logging configuration" \ "($LOG_CONFIG_SRC) to install as default " \ "logging configuration ($LOG_CONFIG_PATH)" else ${DO} grep -v java.util.logging.FileHandler.pattern \ "$LOG_CONFIG_SRC" | sed -e '/^\.level *=/ s,=.*,=INFO,' \ > "$LOG_CONFIG_PATH" ${DO} grep java.util.logging.FileHandler.pattern \ "$LOG_CONFIG_SRC" | sed -e \ "s|opengrok%g.%u.log|${OG_WORK_DIR}/log/opengrok%g.%u.log|g" \ >> "$LOG_CONFIG_PATH" [[ ! -d $OG_WORK_DIR/log ]] && ${DO} mkdir "$OG_WORK_DIR/log" fi fi if [[ -n $OG_DERBY && $OG_DERBY_EMBEDDED == "1" ]]; then if [[ ! -d $OG_WORK_DIR/derby ]]; then Warning "OpenGrok generated derby path $OG_WORK_DIR/derby doesn't exist" Progress " Attempting to create generated derby directory ... " ${DO} mkdir -p "$OG_WORK_DIR/derby" || exit 1 fi LSI=( ${ ls -ld "$OG_WORK_DIR/derby"; } ) if [[ ${LSI[2]} != ${GF_OWNER%:*} ]]; then FatalError "Please 'chown ${GF_OWNER%:*} $OG_WORK_DIR/derby'" fi fi } StdInvocation() { print ${DO} ${JAVA} ${JAVA_OPTS} ${PROPERTIES} \ ${LOG_PROPERTIES} \ ${JAVA_DEBUG} \ -jar ${OG_JAR} \ ${IGNORE_PATTERNS} ${ENABLE_PROJECTS} \ ${DERBY_HISTORY_CACHE} ${EMBEDDED} \ ${SCAN_FOR_REPOSITORY} ${REMOTE_REPOSITORIES} \ ${SCAN_DEPTH} \ ${VERBOSE} ${QUIET} \ ${PROGRESS} \ ${EXUBERANT_CTAGS:+-c} ${EXUBERANT_CTAGS} \ ${MAX_INDEXED_WORDS} ${SKIN} ${LEADING_WILDCARD} ${TABS} \ ${READ_XML_CONF} \ -W ${XML_CONFIG} \ ${WEBAPP_CONFIG_ADDRESS} \ -s ${SRC_ROOT} -d ${DATA_ROOT} \ "${@}" } UpdateDescriptionCache() { # An update program for EftarFile # Usage: inputFile [inputFile ...] outputFile if [[ -n $PATH_DESC && -s $PATH_DESC ]]; then ${DO} ${JAVA} -classpath ${OG_JAR} \ ${EFTAR_UPDATE} ${PATH_DESC} ${EFTAR_OUTPUT_FILE} fi } OpenGrokUsage() { print -u2 "Options for opengrok.jar:\n" ${DO} ${JAVA} ${JAVA_OPTS} -jar ${OG_JAR} '-?' } DeployWar() { if [[ ! -f $OG_WAR_SRC ]]; then FatalError "Missing Web Application Archive $OG_WAR_SRC" fi if [[ ! -d $OG_WAR_DST ]]; then FatalError "Missing Deployment Directory $OG_WAR_DST" fi Progress "Installing $OG_WAR_SRC to $OG_WAR_DST ..." if [[ -n $PROPFILE ]]; then REPLACE_SRC="${PROPFILE%/*}" [[ $REPLACE_SRC == ${PROPFILE} ]] && REPLACE_SRC=$PWD REPLACE_SRC+="/replace" [[ ! -d $REPLACE_SRC ]] && REPLACE_SRC="" fi REPLACE_OG="" [[ $OG_WORK_DIR != /var/opengrok ]] && REPLACE_OG="y" RES= if [[ -n $REPLACE_OG || -n $REPLACE_SRC ]]; then [[ -n $JAR && ! -x $JAR ]] && JAR=${ Which jar; } if [[ -z $JAR ]]; then PACK=${ Which zip; } ; UNPACK=${ Which unzip; } [[ -z $PACK || -z $UNPACK ]] && FatalError "Neither jar nor zip/unzip found." PACKARGS="-ur" ; UNPACKARGS="" else PACK="$JAR" ; UNPACK="$JAR" PACKARGS="uf" ; UNPACKARGS="xf" fi ATMPDIR=${ /usr/bin/mktemp -d; } [[ -z $ATMPDIR ]] && FatalError "Unable to create temp file" OLDPWD=$PWD ${DO} cp "$OG_WAR_SRC" "$ATMPDIR/source.war" ${DO} cd "$ATMPDIR" FILES="" if [[ -n $REPLACE_OG ]]; then ${DO} ${UNPACK} ${UNPACKARGS} source.war WEB-INF/web.xml FILES="WEB-INF/web.xml" ${DO} ${UNPACK} ${UNPACKARGS} source.war WEB-INF/lib/opengrok.jar ${DO} ${UNPACK} ${UNPACKARGS} WEB-INF/lib/opengrok.jar \ org/opensolaris/opengrok/management/oga.properties ${DO} gsed -i -e "s|/var/opengrok|$OG_WORK_DIR|" WEB-INF/web.xml \ org/opensolaris/opengrok/management/oga.properties ${DO} ${PACK} ${PACKARGS} WEB-INF/lib/opengrok.jar \ org/opensolaris/opengrok/management/oga.properties FILES="$FILES WEB-INF/lib/opengrok.jar" cp WEB-INF/lib/opengrok.jar "$OG_JAR" fi if [[ -n $REPLACE_SRC ]]; then RFILES=( $( cd $REPLACE_SRC; find . -type f -print | \ sed -e 's,^./,,' ) ) if (( ${#RFILES[@]} > 0 )); then ( cd $REPLACE_SRC; print "${RFILES[@]}" | tr ' ' '\n' | \ cpio -puvmd $ATMPDIR ) FILES+=" ${RFILES[@]}" fi fi ${DO} ${PACK} ${PACKARGS} source.war $FILES chmod 644 source.war ${DO} cp source.war "$OG_WAR_DST/source.war" RES=$? cd "$OLDPWD" ${DO} rm -rf "$ATMPDIR" else ${DO} cp "$OG_WAR_SRC" "$OG_WAR_DST/source.war" RES=$? fi #chown $GF_OWNER "$OG_WAR_DST/source.war" (( $RES != 0 )) && FatalError "Web Application Installation FAILED" Progress Progress "Start your Glassfish application server, if it is not already" Progress "running, or wait until it loads the just installed web application." HOST=${ hostname; } ; [[ -z $HOST ]] && HOST=localhost PORT=":${AS_PORT_HTTP}"; [[ $PORT == ":80" || $PORT == ":" ]] && PORT="" Progress Progress "OpenGrok should be available via http://${HOST}${PORT}/source/" Progress } # Main Program Usage() { PROG="${0##*/}" print -u2 "\nUsage:\n\ $PROG [-h] [-c file] [-q|v] [-p] [-s dir] [-d dir] [-u] [-n] cmd [args]\n\n\ Options:\n\ -h .. print this help and exit.\n\ -c file .. configuration file to read. Gets sourced in immediately and\n\ it may overwrite other cmd line options or values configured\n\ might be overwritten by cmd line options, which follow this\n\ one. So cmd line option order is important. The config file\n\ should obey bourne shell syntax and only overwrite intended\n\ environment variables.\n\ -s dir .. Use the given directory dir as SRC_ROOT.\n\ -d dir .. Use the given directory dir as DATA_ROOT.\n\ -q .. Run quietly (disables verbose).\n\ -v .. Run verbose.\n\ -p .. Show progress in percent.\n\ -u .. Do not inform the web application about config changes.\n\ -n .. Experimental: Dry run, i.e. show, what gets executed.\n\ cmd .. deploy:\n\ Deploys the opengrok source.war to the Glassfish domain\n\ directory.\n\ undeploy:\n\ Undeploy the opengrok source.war\n\ derby:\n\ Enables the Java DB system service (smf).\n\ update:\n\ Index the related source directories and update database.\n\ usage:\n\ Display opengrok usage.\n\ list:\n\ Display a list of all repository pathes.\n\ zap [directory ...]:\n\ Clear revision history cache for the given repository pathes.\n\ vars:\n\ List all default vars incl. description used by this script\n\ args .. any command line arguments the indexer understands. See also:\n\ $PROG -c ~/src/opengrok.rc usage OR http://src.opensolaris.org/source/xref/opengrok/trunk/src/org/opensolaris/opengrok/index/Indexer.java#cmd " exit 1 } doPrint() { print "$@" } listVars() { if [[ ! -r $0 ]]; then FatalError "Unable to find myself." fi awk '/^SetupEnv/ { getline; while ( $1 != "}" ) { print ; getline }; exit 0 }' $0 } OG_LOADED= while getopts "hc:qvps:d:un" option ; do case "$option" in h) Usage ;; q) QUIET="-q" ; VERBOSE="" ;; c) LoadInstanceConfiguration "${OPTARG}" ; OG_LOADED=1 ;; s) SRC_ROOT="${OPTARG}" ;; d) DATA_ROOT="${OPTARG}" ;; v) OG_VERBOSE=1 ;; p) OG_PROGRESS=1 ;; u) WEBAPP_CONFIG="none" ;; n) typeset -n DO=doPrint esac done shift $((OPTIND-1)) [[ $OG_LOADED != 1 ]] && LoadInstanceConfiguration (( $# == 0 )) && Usage SetupEnv CMD="$1" shift case "$CMD" in undeploy) ValidateConfiguration ${DO} rm -f "$OG_WAR_DST/source.war" ;; deploy) ValidateConfiguration DeployWar ;; derby) ValidateConfiguration CreateRuntimeRequirements svcadm enable glassfish/javadb ;; update) ValidateConfiguration CreateRuntimeRequirements StdInvocation -H UpdateDescriptionCache ;; list) ValidateConfiguration CreateRuntimeRequirements StdInvocation -K ;; zap) ValidateConfiguration CreateRuntimeRequirements if (( $# == 0 )); then StdInvocation -k '*' else TOKILL="" while [[ -n $1 ]]; do TOKILL+=" -k $1" shift done StdInvocation $TOKILL fi ;; reconfigure) ValidateConfiguration CreateRuntimeRequirements SCAN_FOR_REPOSITORY="" StdInvocation -n ;; vars) listVars ; exit 0 ;; usage) checkJava OpenGrokUsage ;; *) Usage ;; esac