|
#!/bin/bash |
|
# Copyright (c) 2002-2013 "Neo Technology," |
|
|
|
# Network Engine for Objects in Lund AB [http://neotechnology.com] |
|
# |
|
# This file is part of Neo4j. |
|
# |
|
# Neo4j is free software: you can redistribute it and/or modify |
|
# it under the terms of the GNU General Public License as published by |
|
# the Free Software Foundation, either version 3 of the License, or |
|
# (at your option) any later version. |
|
# |
|
# This program is distributed in the hope that it will be useful, |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
# GNU General Public License for more details. |
|
# |
|
# You should have received a copy of the GNU General Public License |
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
FRIENDLY_NAME="Neo4j Server" |
|
LAUNCHD_NAME="org.neo4j.server" |
|
|
|
function findBaseDirAndCdThere { |
|
# This seems to not be safe to run at any time. If that |
|
# is the case, it should be fixed to be so, if possible. |
|
[ "${NEO4J_HOME}" ] || { |
|
SCRIPT=$0 |
|
STARTD=${PWD} |
|
cd "`dirname "$SCRIPT"`" |
|
SCRIPT=`basename "$SCRIPT"` |
|
|
|
while [ -L "$SCRIPT" ] |
|
do |
|
SCRIPT=$( readlink "$SCRIPT" ) |
|
cd "$(dirname "$SCRIPT")" |
|
SCRIPT=`basename "$SCRIPT"` |
|
done |
|
NEO4J_HOME=`cd $( dirname "$SCRIPT" )/.. && dirs -l +0` |
|
} |
|
NEO4J_INSTANCE=${NEO4J_INSTANCE:-${STARTD}} |
|
NEO4J_CONFIG=${NEO4J_CONFIG:-${NEO4J_INSTANCE}/conf} |
|
NEO4J_LOG=${NEO4J_LOG:-${NEO4J_INSTANCE}/data/log} |
|
|
|
cd "${NEO4J_INSTANCE}" |
|
} |
|
|
|
function parseConfig { |
|
if [ ${BASH_VERSINFO[0]} -eq 3 ] ; then |
|
if [ ${BASH_VERSINFO[1]} -lt 2 ] ; then |
|
getconfigquoted "${NEO4J_CONFIG}/neo4j-wrapper.conf" |
|
getconfigquoted "${NEO4J_CONFIG}/neo4j-server.properties" |
|
return |
|
fi |
|
fi |
|
getconfig "${NEO4J_CONFIG}/neo4j-wrapper.conf" |
|
getconfig "${NEO4J_CONFIG}/neo4j-server.properties" |
|
} |
|
|
|
findBaseDirAndCdThere |
|
|
|
[ -d ${NEO4J_CONFIG} ] || { |
|
rsync -vazu ${NEO4J_HOME}/conf/ ${NEO4J_CONFIG} || { |
|
echo "Can not create config" >&2 |
|
exit ${LINENO} |
|
} |
|
} |
|
|
|
[ -d ${NEO4J_INSTANCE}/data ] || { |
|
mkdir -p ${NEO4J_INSTANCE}/data/{graph.db,log} || { |
|
echo "Can not create instance" >&2 |
|
exit ${LINENO} |
|
} |
|
} |
|
|
|
source ${NEO4J_HOME}/bin/utils |
|
parseConfig |
|
|
|
JAVA_OPTS="${JAVA_OPTS} -Dneo4j.ext.udc.disable=true -server -XX:+DisableExplicitGC ${wrapper_java_additional}" |
|
[ -z "${wrapper_java_initmemory}" ] || JAVA_OPTS="$JAVA_OPTS -Xms${wrapper_java_initmemory}m" |
|
[ -z "${wrapper_java_maxmemory}" ] || JAVA_OPTS="$JAVA_OPTS -Xmx${wrapper_java_maxmemory}m" |
|
|
|
#NEO4J_SERVER_PORT=`( egrep "^org.neo4j.server.webserver.port" $NEO4J_INSTANCE/conf/neo4j-server.properties || echo 7474 ) | sed -e 's/.*=//'` |
|
NEO4J_SERVER_PORT=${org_neo4j_server_webserver_port:=7474} |
|
|
|
LAUNCHD_NAME="${LAUNCHD_NAME}.${NEO4J_SERVER_PORT}" |
|
|
|
HEADLESS=false |
|
|
|
if [ -z "${wrapper_user}" ]; then |
|
NEO4J_USER=`id -un` |
|
else |
|
NEO4J_USER=${wrapper_user} |
|
fi |
|
|
|
# Username to propose for neo4j user, can be overridden by -u USERNAME option |
|
DEFAULT_USER='neo4j' |
|
|
|
SCRIPT_NAME="${NEO4J_HOME}/bin/neo4j" |
|
SERVICE_NAME=${wrapper_ntservice_name:=neo4j-service} |
|
LAUNCHD_DIR=~/Library/LaunchAgents/ |
|
|
|
TIMEOUT=120 |
|
|
|
PID_FILE=${NEO4J_INSTANCE}/data/neo4j-service.pid |
|
buildclasspath() { |
|
# confirm library jars |
|
LIBDIR="$NEO4J_HOME"/lib |
|
if [ ! -e "$LIBDIR" ] ; then |
|
echo "Error: missing Neo4j Library, expected at $LIBDIR" |
|
exit 1 |
|
fi |
|
|
|
# confirm system jars |
|
SYSLIBDIR="$NEO4J_HOME"/system/lib |
|
if [ ! -e "$SYSLIBDIR" ] ; then |
|
echo "Error: missing Neo4j System Library, expected at $SYSLIBDIR" |
|
exit 1 |
|
fi |
|
|
|
ALL_JARS="" |
|
for jar in "$LIBDIR"/*.jar "$SYSLIBDIR"/*.jar ; do |
|
[ -z "$ALL_JARS" ] && ALL_JARS="$jar" || ALL_JARS="$ALL_JARS":"$jar" |
|
done |
|
|
|
# add any plugin jars |
|
for jar in "$NEO4J_HOME"/plugins/*.jar ; do |
|
if [ -e "$jar" ] ; then |
|
ALL_JARS="$ALL_JARS":"$jar" |
|
fi |
|
done |
|
|
|
# add any plugin jars in nested folders |
|
for jar in "$NEO4J_HOME"/plugins/**/*.jar ; do |
|
if [ -e "$jar" ] ; then |
|
ALL_JARS="$ALL_JARS":"$jar" |
|
fi |
|
done |
|
|
|
CLASSPATH=${ALL_JARS} |
|
|
|
# add useful conf stuff to classpath - always a good idea |
|
CLASSPATH="$CLASSPATH":"${NEO4J_CONFIG}" |
|
} |
|
|
|
detectrunning() { |
|
## This could be achieved with filtering using -sTCP:LISTEN but this option is not available |
|
## on lsof v4.78 which is the one bundled with some distros. So we have to do this grep below |
|
newpid=$(lsof -i :$NEO4J_SERVER_PORT -F T -Ts | grep -i "TST=LISTEN" -B1 | head -n1) |
|
newpid=${newpid:1} |
|
} |
|
|
|
startit() { |
|
|
|
detectos |
|
exitonnojava |
|
checkstatus |
|
checklimits |
|
|
|
checkjvmcompatibility |
|
|
|
detectrunning |
|
if [ $newpid ] ; then |
|
echo "Another server-process is running with [$newpid], cannot start a new one. Exiting." |
|
exit 2; |
|
fi |
|
|
|
echo "Using additional JVM arguments: " $JAVA_OPTS |
|
|
|
if [ $DIST_OS = "macosx" ] ; then |
|
getlaunchdpid |
|
if [ $LAUNCHDPID -eq 0 ] ; then |
|
echo "Detected installation in launchd, starting it..." |
|
launchctl start $LAUNCHD_NAME |
|
exit 0 |
|
elif [ $LAUNCHDPID -gt 0 ] ; then |
|
echo "Instance already running via launchd with PID $LAUNCHDPID" |
|
exit 1 |
|
fi |
|
# We fall through here since if there is no launchd install we start manually |
|
fi |
|
|
|
if [ -z $NEO4J_PID ] ; then |
|
printf "Starting $FRIENDLY_NAME..." |
|
|
|
buildclasspath |
|
checkclasspath |
|
checkandrepairenv |
|
|
|
CONSOLE_LOG="$NEO4J_LOG/console.log" |
|
|
|
if [ $UID == 0 ] ; then |
|
su $NEO4J_USER -c "nohup $JAVACMD -cp '$CLASSPATH' $JAVA_OPTS \ |
|
-Dneo4j.home=\"${NEO4J_HOME}\" -Dneo4j.instance=\"${NEO4J_INSTANCE}\" \ |
|
-Dfile.encoding=UTF-8 \ |
|
org.neo4j.server.Bootstrapper >> \"${CONSOLE_LOG}\" 2>&1 & echo \$! > \"$PID_FILE\" " |
|
else |
|
checkwriteaccess |
|
echo "WARNING: not changing user" |
|
$JAVACMD -cp "${CLASSPATH}" $JAVA_OPTS \ |
|
-Dneo4j.home="${NEO4J_HOME}" -Dneo4j.instance="${NEO4J_INSTANCE}" \ |
|
-Dfile.encoding=UTF-8 \ |
|
org.neo4j.server.Bootstrapper >> "${CONSOLE_LOG}" 2>&1 & echo $! > "${PID_FILE}" |
|
fi |
|
|
|
STARTED_PID=$( cat "$PID_FILE" ) |
|
|
|
if [ "$org_neo4j_server_database_mode" = "HA" ] ; then |
|
if kill -0 $STARTED_PID 2>/dev/null ; then |
|
echo "HA instance started in process [$STARTED_PID]. Will be operational once connected to peers. See ${CONSOLE_LOG} for current status." |
|
exit 0 |
|
else |
|
echo "HA instance was unable to start. See ${CONSOLE_LOG}." |
|
rm "$PID_FILE" |
|
exit 1 |
|
fi |
|
fi |
|
|
|
echo -n "process [$STARTED_PID]" |
|
|
|
if [ $WAIT = "true" ] ; then |
|
echo -n "... waiting for server to be ready." |
|
while kill -0 $STARTED_PID 2> /dev/null ; do |
|
## wait for start, pick up the server listening on the port |
|
detectrunning |
|
if [ $newpid ] ; then |
|
break |
|
fi |
|
|
|
printf "." |
|
sleep 1 |
|
done |
|
|
|
if kill -0 $STARTED_PID 2>/dev/null ; then |
|
if [ "$newpid" != "$STARTED_PID" ] ; then |
|
rm "$PID_FILE" |
|
kill -9 $STARTED_PID |
|
echo " Failed to start within $TIMEOUT seconds." |
|
echo "$FRIENDLY_NAME failed to start, please check the logs for details." |
|
echo "If startup is blocked on a long recovery, use '$0 start-no-wait' to give the startup more time." |
|
exit 2 |
|
fi |
|
|
|
echo " OK." |
|
echo "Go to http://localhost:$NEO4J_SERVER_PORT/webadmin/ for administration interface." |
|
exit 0 |
|
fi |
|
|
|
echo " Failed to start within $TIMEOUT seconds." |
|
echo "$FRIENDLY_NAME may have failed to start, please check the logs." |
|
rm "$PID_FILE" |
|
exit 1 |
|
else |
|
echo "...Started the server in the background, returning..." |
|
fi |
|
else |
|
echo "$FRIENDLY_NAME already running with pid $NEO4J_PID" |
|
exit 0 |
|
fi |
|
} |
|
|
|
console() { |
|
|
|
checkstatus |
|
checklimits |
|
|
|
if [ -z $NEO4J_PID ] ; then |
|
echo "Starting $FRIENDLY_NAME console-mode..." |
|
|
|
exitonnojava |
|
buildclasspath |
|
checkwriteaccess |
|
checkandrepairenv |
|
|
|
echo "Using additional JVM arguments: " $JAVA_OPTS |
|
|
|
$JAVACMD -cp "${CLASSPATH}" $JAVA_OPTS \ |
|
-Dneo4j.home="${NEO4J_HOME}" -Dneo4j.instance="${NEO4J_INSTANCE}" \ |
|
-Dfile.encoding=UTF-8 \ |
|
org.neo4j.server.Bootstrapper |
|
|
|
else |
|
echo "$FRIENDLY_NAME already running with pid $NEO4J_PID" |
|
exit 1 |
|
fi |
|
} |
|
|
|
# Modifies neo4j config to set the effective user when running as a service |
|
# usage: modify_user_config <username> [true|false] |
|
# pass in "true" for created to mark that the user was created (instead than pre-existing) |
|
modify_user_config() { |
|
created=${2:-"false"} |
|
if `grep -q "wrapper\.user=" "$NEO4J_INSTANCE/conf/neo4j-wrapper.conf"` ; then |
|
sed -i -e "s/^.*wrapper\.user=.*$/wrapper\.user=$1/" "$NEO4J_INSTANCE/conf/neo4j-wrapper.conf" |
|
else |
|
echo "wrapper.user=$1" >> "$NEO4J_INSTANCE/conf/neo4j-wrapper.conf" |
|
fi |
|
|
|
if `grep -q "wrapper\.user\.created=" "$NEO4J_INSTANCE/conf/neo4j-wrapper.conf"` ; then |
|
sed -i -e "s/^.*wrapper\.user\.created=.*$/wrapper\.user\.created=${created}/" "$NEO4J_INSTANCE/conf/neo4j-wrapper.conf" |
|
else |
|
echo "wrapper.user.created=${created}" >> "$NEO4J_INSTANCE/conf/neo4j-wrapper.conf" |
|
fi |
|
} |
|
|
|
installservice() { |
|
detectos |
|
findjava |
|
selectinittool |
|
if [ ! -x "$JAVACMD" ] ; then |
|
if [[ $HEADLESS == false ]]; then |
|
read -p "It was not possible to determine JAVA_HOME. Do you want to continue with the installation? [yN]" yn |
|
else |
|
yn='y' |
|
fi |
|
case $yn in |
|
[yY]* ) echo "WARNING: Alright, but $FRIENDLY_NAME will fail to launch until Java has been properly installed and configured." |
|
;; |
|
* ) echo "Aborting installation." |
|
exit 1 |
|
;; |
|
esac |
|
fi |
|
|
|
if [[ -d "/etc/init.d" ]]; then |
|
if [[ -e "/etc/init.d/${SERVICE_NAME}" ]]; then |
|
echo "${SERVICE_NAME} already installed." |
|
else |
|
if [ $UID != 0 ] ; then |
|
eval echo 'Must be root to perform this action.' |
|
exit 1 |
|
else |
|
checkstatus |
|
if [ ! -z $NEO4J_PID ] ; then |
|
stopit |
|
fi |
|
if [[ $NEO4J_USER == $wrapper_user ]]; then |
|
default_user=$wrapper_user |
|
else |
|
default_user=$DEFAULT_USER |
|
fi |
|
|
|
if [[ $HEADLESS == false ]]; then |
|
read -p "Graph-like power should be handled carefully. What user should run Neo4j? [$default_user] " proposed_user |
|
fi |
|
proposed_user=${proposed_user:-$default_user} |
|
|
|
if ! `id $proposed_user &> /dev/null` ; then |
|
if [[ $HEADLESS == false ]]; then |
|
read -p "User \"$proposed_user\" does not yet exist. Shall I create the account for you? [Yn]" yn |
|
else |
|
yn="y" |
|
fi |
|
case $yn in |
|
[Nn]* ) echo "WARNING: Alright, but Neo4j will fail to launch until that user has been created." |
|
set_user $proposed_user |
|
;; |
|
* ) create_user $proposed_user |
|
;; |
|
esac |
|
else |
|
modify_user_config $proposed_user |
|
fi |
|
ln -s "${SCRIPT_NAME}" "/etc/init.d/${SERVICE_NAME}" |
|
if [ $INIT_TOOL == 'chkconfig' ]; then |
|
chkconfig --add ${SERVICE_NAME} |
|
else |
|
update-rc.d ${SERVICE_NAME} defaults |
|
fi |
|
chown -R $proposed_user: "$NEO4J_HOME/data" "$NEO4J_HOME/conf" |
|
fi |
|
fi |
|
elif [[ $DIST_OS -eq "macosx" ]] ; then |
|
sed -e "s^NEO4J_INSTANCE^${NEO4J_INSTANCE}^" -e "s^LAUNCHD_NAME^${LAUNCHD_NAME}^" <"${NEO4J_INSTANCE}/bin/org.neo4j.server.plist" >"${LAUNCHD_DIR}/${LAUNCHD_NAME}.plist" |
|
launchctl load -w ${LAUNCHD_DIR}/${LAUNCHD_NAME}.plist |
|
launchctl start ${LAUNCHD_NAME} |
|
else |
|
echo "Sorry, don't know how to install on ${DIST_OS}." |
|
fi |
|
|
|
if [ -x "$JAVACMD" ] ; then |
|
if [[ $DIST_OS -ne "macosx" ]] ; then |
|
startit |
|
fi |
|
fi |
|
} |
|
|
|
showinfo() { |
|
reportstatus |
|
|
|
exitonnojava |
|
buildclasspath |
|
|
|
echo "NEO4J_HOME: $NEO4J_HOME" |
|
echo "NEO4J_SERVER_PORT: $NEO4J_SERVER_PORT" |
|
echo "NEO4J_INSTANCE: $NEO4J_INSTANCE" |
|
echo "JAVA_HOME: $JAVA_HOME" |
|
echo "JAVA_OPTS: $JAVA_OPTS" |
|
echo "CLASSPATH: $CLASSPATH" |
|
} |
|
|
|
# END FUNCTIONS |
|
# BEGIN MAIN |
|
|
|
# Parse option flags |
|
while getopts "u:h" opt; do |
|
case $opt in |
|
h) |
|
echo "Running in headless (-h) mode" >&2 |
|
HEADLESS=true |
|
;; |
|
u) |
|
echo "Installing with user $OPTARG" |
|
DEFAULT_USER=$OPTARG |
|
;; |
|
\?) |
|
echo "Invalid option: -$OPTARG" >&2 |
|
exit 1 |
|
;; |
|
:) |
|
echo "Option -$OPTARG requires an argument." >&2 |
|
exit 1 |
|
;; |
|
esac |
|
done |
|
|
|
case "${!OPTIND}" in |
|
console) |
|
console |
|
exit 0 |
|
;; |
|
|
|
start) |
|
WAIT=true |
|
startit |
|
;; |
|
|
|
start-no-wait) |
|
WAIT=false |
|
startit |
|
exit 0 |
|
;; |
|
|
|
stop) |
|
stopit |
|
exit 0 |
|
;; |
|
|
|
restart) |
|
WAIT=true |
|
stopit |
|
startit |
|
exit 0 |
|
;; |
|
|
|
status) |
|
reportstatus |
|
exit 0 |
|
;; |
|
|
|
info) |
|
showinfo |
|
exit 0 |
|
;; |
|
install) |
|
WAIT=true |
|
installservice |
|
exit 0 |
|
;; |
|
remove) |
|
removeservice |
|
exit 0 |
|
;; |
|
*) |
|
echo "Usage: neo4j { console | start | start-no-wait | stop | restart | status | info | install | remove }" |
|
exit 0;; |
|
|
|
esac |
|
|
|
exit $? |