| #! /bin/sh -e |
| |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| |
| BACKGROUND=false |
| DEFAULT_CONFIG_DIR=%localconfdir%/default.d |
| DEFAULT_CONFIG_FILE=%localconfdir%/%defaultini% |
| ERL_OS_MON_OPTIONS="-os_mon \ |
| start_memsup false \ |
| start_cpu_sup false \ |
| disk_space_check_interval 1 \ |
| disk_almost_full_threshold 1" |
| ERL_START_OPTIONS="$ERL_OS_MON_OPTIONS -sasl errlog_type error +K true +A 4" |
| HEART_BEAT_TIMEOUT=11 |
| HEART_COMMAND="%bindir%/%couchdb_command_name% -k" |
| INTERACTIVE=false |
| KILL=false |
| PLUGINS_DIR=%locallibdir%/plugins |
| LOCAL_CONFIG_DIR=%localconfdir%/local.d |
| LOCAL_CONFIG_FILE=%localconfdir%/%localini% |
| PID_FILE=%localstatedir%/run/couchdb/couchdb.pid |
| RECURSED=false |
| RESET_CONFIG=true |
| RESPAWN_TIMEOUT=0 |
| SCRIPT_ERROR=1 |
| SCRIPT_OK=0 |
| SHUTDOWN=false |
| STDERR_FILE=couchdb.stderr |
| STDOUT_FILE=couchdb.stdout |
| |
| print_arguments="" |
| start_arguments="" |
| background_start_arguments="" |
| |
| basename=`basename $0` |
| |
| display_version () { |
| cat << EOF |
| $basename - %package_name% %version% |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); you may not use |
| this file except in compliance with the License. You may obtain a copy of the |
| License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software distributed |
| under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR |
| CONDITIONS OF ANY KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations under the License. |
| |
| EOF |
| } |
| |
| display_help () { |
| cat << EOF |
| Usage: $basename [OPTION] |
| |
| The $basename command runs the %package_name% server. |
| |
| Erlang is called with: |
| |
| $ERL_START_OPTIONS |
| |
| Erlang inherits the environment of this command. |
| |
| You can override these options using the environment: |
| |
| ERL_AFLAGS, ERL_FLAGS, ERL_ZFLAGS |
| |
| See erl(1) for more information about the environment variables. |
| |
| The exit status is 0 for success or 1 for failure. |
| |
| Options: |
| |
| -h display a short help message and exit |
| -V display version information and exit |
| -a FILE add configuration FILE to chain |
| -A DIR add configuration DIR to chain |
| -n reset configuration file chain (including system default) |
| -c print configuration file chain and exit |
| -i use the interactive Erlang shell |
| -b spawn as a background process |
| -p FILE set the background PID FILE (overrides system default) |
| -r SECONDS respawn background process after SECONDS (defaults to no respawn) |
| -o FILE redirect background stdout to FILE (defaults to $STDOUT_FILE) |
| -e FILE redirect background stderr to FILE (defaults to $STDERR_FILE) |
| -s display the status of the background process |
| -k kill the background process, will respawn if needed |
| -d shutdown the background process |
| |
| Report bugs at <%bug_uri%>. |
| EOF |
| } |
| |
| display_error () { |
| if test -n "$1"; then |
| echo $1 >&2 |
| fi |
| echo >&2 |
| echo "Try \`"$basename" -h' for more information." >&2 |
| false |
| } |
| |
| _get_pid () { |
| if test -f $PID_FILE; then |
| PID=`cat $PID_FILE` |
| fi |
| echo $PID |
| } |
| |
| _add_config_file () { |
| if test -z "$print_arguments"; then |
| print_arguments="$1" |
| else |
| print_arguments="`cat <<EOF |
| $print_arguments |
| $1 |
| EOF |
| `" |
| fi |
| start_arguments="$start_arguments $1" |
| background_start_arguments="$background_start_arguments -a $1" |
| } |
| |
| _add_config_dir () { |
| for file in "$1"/*.ini; do |
| if [ -r "$file" ]; then |
| _add_config_file "$file" |
| fi |
| done |
| } |
| |
| _add_erlang_config () { |
| if [ -r "$1" ]; then |
| ERL_START_OPTIONS="$ERL_START_OPTIONS -config '$1'" |
| fi |
| } |
| |
| _load_config () { |
| _add_config_file "$DEFAULT_CONFIG_FILE" |
| _add_config_dir "$DEFAULT_CONFIG_DIR" |
| # We initialize plugins here to get the desired default config load order |
| _find_plugins |
| _add_config_file "$LOCAL_CONFIG_FILE" |
| _add_config_dir "$LOCAL_CONFIG_DIR" |
| if [ "$COUCHDB_ADDITIONAL_CONFIG_FILE" != '' ] |
| then |
| _add_config_file "$COUCHDB_ADDITIONAL_CONFIG_FILE" |
| fi |
| } |
| |
| _reset_config () { |
| print_arguments="" |
| start_arguments="" |
| background_start_arguments="-n" |
| } |
| |
| _print_config () { |
| cat <<EOF |
| $print_arguments |
| EOF |
| } |
| |
| check_status () { |
| PID=`_get_pid` |
| if test -n "$PID"; then |
| if kill -0 $PID 2> /dev/null; then |
| echo "Apache CouchDB is running as process $PID, time to relax." |
| return $SCRIPT_OK |
| else |
| echo >&2 << EOF |
| Apache CouchDB is not running but a stale PID file exists: $PID_FILE |
| EOF |
| fi |
| else |
| echo "Apache CouchDB is not running." >&2 |
| fi |
| return $SCRIPT_ERROR |
| } |
| |
| check_environment () { |
| if test "$BACKGROUND" != "true"; then |
| return |
| fi |
| touch $PID_FILE 2> /dev/null || true |
| touch $STDOUT_FILE 2> /dev/null || true |
| touch $STDERR_FILE 2> /dev/null || true |
| message_prefix="Apache CouchDB needs write permission on the" |
| if test ! -w $PID_FILE; then |
| echo "$message_prefix PID file: $PID_FILE" >&2 |
| false |
| fi |
| if test ! -w $STDOUT_FILE; then |
| echo "$message_prefix STDOUT file: $STDOUT_FILE" >&2 |
| false |
| fi |
| if test ! -w $STDERR_FILE; then |
| echo "$message_prefix STDERR file: $STDERR_FILE" >&2 |
| false |
| fi |
| message_prefix="Apache CouchDB needs a regular" |
| if test `echo 2> /dev/null >> $PID_FILE; echo $?` -gt 0; then |
| echo "$message_prefix PID file: $PID_FILE" >&2 |
| false |
| fi |
| if test `echo 2> /dev/null >> $STDOUT_FILE; echo $?` -gt 0; then |
| echo "$message_prefix STDOUT file: $STDOUT_FILE" >&2 |
| false |
| fi |
| if test `echo 2> /dev/null >> $STDERR_FILE; echo $?` -gt 0; then |
| echo "$message_prefix STDERR file: $STDERR_FILE" >&2 |
| false |
| fi |
| } |
| |
| _find_plugins () { |
| # Find plugins and add them to the Erlang path and load their default |
| # configurations. This should be called from _load_config. |
| if test -d "$PLUGINS_DIR"; then |
| for plugin in "$PLUGINS_DIR"/*; do |
| if echo "$COUCH_PLUGIN_BLACKLIST" | grep "$plugin" > /dev/null 2> /dev/null; then |
| : # Do not use this plugin. |
| else |
| if echo "$ERL_ZFLAGS" | grep "$plugin/ebin" > /dev/null 2> /dev/null; then |
| : # It's already loaded. |
| else |
| ERL_ZFLAGS="$ERL_ZFLAGS -pz '$plugin/ebin'" |
| fi |
| _add_config_dir "$plugin/priv/default.d" |
| _add_erlang_config "$plugin/priv/couch_plugin.config" |
| fi |
| done |
| export ERL_ZFLAGS |
| fi |
| } |
| |
| start_couchdb () { |
| if test ! "$RECURSED" = "true"; then |
| if check_status 2> /dev/null; then |
| exit |
| fi |
| check_environment |
| fi |
| interactive_option="+Bd -noinput" |
| if test "$INTERACTIVE" = "true"; then |
| interactive_option="" |
| fi |
| if test "$BACKGROUND" = "true"; then |
| touch $PID_FILE |
| interactive_option="+Bd -noinput" |
| fi |
| |
| command="%ERL% $interactive_option $ERL_START_OPTIONS \ |
| -env ERL_LIBS $ERL_LIBS:%localerlanglibdir% -couch_ini $start_arguments -s couch" |
| if test "$BACKGROUND" = "true" -a "$RECURSED" = "false"; then |
| $0 $background_start_arguments -b -r $RESPAWN_TIMEOUT -p $PID_FILE \ |
| -o $STDOUT_FILE -e $STDERR_FILE -R & |
| echo "Apache CouchDB has started, time to relax." |
| else |
| if test "$RECURSED" = "true"; then |
| while true; do |
| export HEART_COMMAND |
| export HEART_BEAT_TIMEOUT |
| `eval $command -pidfile $PID_FILE -heart \ |
| >> $STDOUT_FILE 2>> $STDERR_FILE` || true |
| PID=`_get_pid` |
| if test -n "$PID"; then |
| if kill -0 $PID 2> /dev/null; then |
| return $SCRIPT_ERROR |
| fi |
| else |
| return $SCRIPT_OK |
| fi |
| if test "$RESPAWN_TIMEOUT" = "0"; then |
| return $SCRIPT_OK |
| fi |
| if test "$RESPAWN_TIMEOUT" != "1"; then |
| plural_ending="s" |
| fi |
| cat << EOF |
| Apache CouchDB crashed, restarting in $RESPAWN_TIMEOUT second$plural_ending. |
| EOF |
| sleep $RESPAWN_TIMEOUT |
| done |
| else |
| eval exec $command |
| fi |
| fi |
| } |
| |
| stop_couchdb () { |
| PID=`_get_pid` |
| STOP_TIMEOUT=60 |
| if test -n "$PID"; then |
| if kill -0 $PID 2> /dev/null; then |
| if kill -TERM $PID 2> /dev/null; then |
| count=0 |
| while kill -0 $PID 2> /dev/null; do |
| if [ $count -ge $STOP_TIMEOUT ]; then |
| echo "Apache CouchDB failed to shutdown." |
| return $SCRIPT_ERROR |
| else |
| count=$[count+1] |
| sleep 1 |
| fi |
| done |
| if test "$1" = "false"; then |
| echo "Apache CouchDB has been shutdown." |
| else |
| echo "Apache CouchDB has been killed." |
| fi |
| return $SCRIPT_OK |
| else |
| echo "Apache CouchDB could not be killed." >&2 |
| return $SCRIPT_ERROR |
| fi |
| if test "$1" = "false"; then |
| echo "Stale PID file exists but Apache CouchDB is not running." |
| else |
| echo "Stale PID file existed but Apache CouchDB is not running." |
| fi |
| fi |
| else |
| echo "Apache CouchDB is not running." |
| fi |
| } |
| |
| parse_script_option_list () { |
| _load_config |
| set +e |
| options=`getopt hVa:A:ncibp:r:Ro:e:skd $@` |
| if test ! $? -eq 0; then |
| display_error |
| fi |
| set -e |
| eval set -- $options |
| while [ $# -gt 0 ]; do |
| case "$1" in |
| -h) shift; display_help; exit;; |
| -V) shift; display_version; exit;; |
| -a) shift; _add_config_file "$1"; shift;; |
| -A) shift; _add_config_dir "$1"; shift;; |
| -n) shift; _reset_config;; |
| -c) shift; _print_config; exit;; |
| -i) shift; INTERACTIVE=true;; |
| -b) shift; BACKGROUND=true;; |
| -r) shift; RESPAWN_TIMEOUT=$1; shift;; |
| -R) shift; RECURSED=true;; |
| -p) shift; PID_FILE=$1; shift;; |
| -o) shift; STDOUT_FILE=$1; shift;; |
| -e) shift; STDERR_FILE=$1; shift;; |
| -s) shift; check_status; exit;; |
| -k) shift; KILL=true;; |
| -d) shift; SHUTDOWN=true;; |
| --) shift; break;; |
| *) display_error "Unknown option: $1" >&2;; |
| esac |
| done |
| if test "$KILL" = "true" -o "$SHUTDOWN" = "true"; then |
| stop_couchdb $KILL |
| else |
| start_couchdb |
| fi |
| } |
| |
| parse_script_option_list $@ |