25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-28 16:34:13 +01:00

Merge branch 'joudinet-master'

This commit is contained in:
Christophe Romain 2017-05-31 18:12:26 +02:00
commit 818d9c8c42

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
# define default configuration # define default configuration
POLL=true POLL=true
@ -10,135 +10,95 @@ FIREWALL_WINDOW=""
ERLANG_NODE=ejabberd@localhost ERLANG_NODE=ejabberd@localhost
# define default environment variables # define default environment variables
SCRIPT_DIR=`cd ${0%/*} && pwd`
ERL={{erl}} ERL={{erl}}
IEX={{bindir}}/iex IEX={{bindir}}/iex
EPMD={{epmd}} EPMD={{epmd}}
INSTALLUSER={{installuser}} INSTALLUSER={{installuser}}
ERL_LIBS={{libdir}}
# check the proper system user is used if defined # check the proper system user is used if defined
if [ "$INSTALLUSER" != "" ] ; then EXEC_CMD="false"
EXEC_CMD="false" if [ -n "$INSTALLUSER" ] ; then
for GID in `id -G`; do if [ $(id -g) -eq $(id -g $INSTALLUSER || echo -1) ] ; then
if [ $GID -eq 0 ] ; then EXEC_CMD="as_current_user"
INSTALLUSER_HOME=$(getent passwd "$INSTALLUSER" | cut -d: -f6) else
if [ -n "$INSTALLUSER_HOME" ] && [ ! -d "$INSTALLUSER_HOME" ] ; then id -Gn | grep -q wheel && EXEC_CMD="as_install_user"
mkdir -p "$INSTALLUSER_HOME"
chown "$INSTALLUSER" "$INSTALLUSER_HOME"
fi
EXEC_CMD="su $INSTALLUSER -c"
fi
done
if [ `id -g` -eq `id -g $INSTALLUSER` ] ; then
EXEC_CMD="bash -c"
fi
if [ "$EXEC_CMD" = "false" ] ; then
echo "This command can only be run by root or the user $INSTALLUSER" >&2
exit 4
fi fi
else else
EXEC_CMD="bash -c" EXEC_CMD="as_current_user"
fi
if [ "$EXEC_CMD" = "false" ] ; then
echo "ERROR: This command can only be run by root or the user $INSTALLUSER" >&2
exit 7
fi fi
# set backward compatibility on command line parameters
set -- $(echo "$*" | sed -e \
"s/--node/-n/;s/--spool/-s/;s/--logs/-l/;\
s/--config/-f/;s/--ctl-config/-c/;s/--config-dir/-d/;\
s/--no-timeout/-t/")
# parse command line parameters # parse command line parameters
declare -a ARGS=() while getopts n:s:l:f:c:d:tx opt; do
while [ $# -ne 0 ] ; do case $opt in
PARAM="$1" n) ERLANG_NODE_ARG=$OPTARG;;
shift s) SPOOL_DIR=$OPTARG;;
case $PARAM in l) LOGS_DIR=$OPTARG;;
--) break ;; f) EJABBERD_CONFIG_PATH=$OPTARG;;
--no-timeout) EJABBERD_NO_TIMEOUT="--no-timeout" ;; c) EJABBERDCTL_CONFIG_PATH=$OPTARG;;
--node) ERLANG_NODE_ARG=$1 ; shift ;; d) ETC_DIR=$OPTARG;;
--config-dir) ETC_DIR="$1" ; shift ;; t) NO_TIMEOUT="--no-timeout";;
--config) EJABBERD_CONFIG_PATH="$1" ; shift ;;
--ctl-config) EJABBERDCTL_CONFIG_PATH="$1" ; shift ;;
--logs) LOGS_DIR="$1" ; shift ;;
--spool) SPOOL_DIR="$1" ; shift ;;
*) ARGS=("${ARGS[@]}" "$PARAM") ;;
esac esac
done done
# keep extra command line parameters for ejabberd
shift $((OPTIND-1))
# Define ejabberd variable if they have not been defined from the command line # define ejabberd variables if not already defined from the command line
if [ "$ETC_DIR" = "" ] ; then : ${ETC_DIR:={{sysconfdir}}/ejabberd}
ETC_DIR={{sysconfdir}}/ejabberd : ${LOGS_DIR:={{localstatedir}}/log/ejabberd}
fi : ${SPOOL_DIR:={{localstatedir}}/lib/ejabberd}
if [ "$EJABBERDCTL_CONFIG_PATH" = "" ] ; then : ${EJABBERD_CONFIG_PATH:="$ETC_DIR"/ejabberd.yml}
EJABBERDCTL_CONFIG_PATH=$ETC_DIR/ejabberdctl.cfg : ${EJABBERDCTL_CONFIG_PATH:="$ETC_DIR"/ejabberdctl.cfg}
fi [ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
if [ -f "$EJABBERDCTL_CONFIG_PATH" ] ; then [ "$ERLANG_NODE_ARG" != "" ] && ERLANG_NODE=$ERLANG_NODE_ARG
. "$EJABBERDCTL_CONFIG_PATH" : ${EJABBERD_DOC_PATH:={{docdir}}}
fi : ${EJABBERD_LOG_PATH:="$LOGS_DIR"/ejabberd.log}
if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then
EJABBERD_CONFIG_PATH=$ETC_DIR/ejabberd.yml
fi
if [ "$LOGS_DIR" = "" ] ; then
LOGS_DIR={{localstatedir}}/log/ejabberd
fi
if [ "$SPOOL_DIR" = "" ] ; then
SPOOL_DIR={{localstatedir}}/lib/ejabberd
fi
if [ "$EJABBERD_DOC_PATH" = "" ] ; then
EJABBERD_DOC_PATH={{docdir}}
fi
if [ "$ERLANG_NODE_ARG" != "" ] ; then
ERLANG_NODE=$ERLANG_NODE_ARG
fi
if [ "{{release}}" != "true" -a "$EJABBERD_BIN_PATH" = "" ] ; then
EJABBERD_BIN_PATH={{libdir}}/ejabberd/priv/bin
fi
EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
DATETIME=`date "+%Y%m%d-%H%M%S"`
ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
ERL_INETRC=$ETC_DIR/inetrc
# define mnesia options
MNESIA_OPTS="-mnesia dir \"\\\"$SPOOL_DIR\\\"\" $MNESIA_OPTIONS"
# define erl parameters # define erl parameters
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS" ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
KERNEL_OPTS=""
if [ "$FIREWALL_WINDOW" != "" ] ; then if [ "$FIREWALL_WINDOW" != "" ] ; then
KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}" ERLANG_OPTS="$ERLANG_OPTS -kernel " \
"inet_dist_listen_min ${FIREWALL_WINDOW%-*} " \
"inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
fi fi
if [ "$INET_DIST_INTERFACE" != "" ] ; then if [ "$INET_DIST_INTERFACE" != "" ] ; then
INET_DIST_INTERFACE2="$(echo $INET_DIST_INTERFACE | sed 's/\./,/g')" INET_DIST_INTERFACE2=$("$ERL" -noshell -eval 'case inet:parse_address("'$INET_DIST_INTERFACE'") of {ok,IP} -> io:format("~p",[IP]); _ -> ok end.' -s erlang halt)
if [ "$INET_DIST_INTERFACE" != "$INET_DIST_INTERFACE2" ] ; then if [ "$INET_DIST_INTERFACE2" != "" ] ; then
INET_DIST_INTERFACE2="{$INET_DIST_INTERFACE2}" ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_use_interface \"$INET_DIST_INTERFACE2\""
fi fi
KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_use_interface \"${INET_DIST_INTERFACE2}\""
fi fi
if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then
NAME="-sname" NAME="-sname"
else else
NAME="-name" NAME="-name"
fi fi
IEXNAME="-$NAME" ERL_LIBS={{libdir}}
ERL_CRASH_DUMP="$LOGS_DIR"/erl_crash_$(date "+%Y%m%d-%H%M%S").dump
ERL_INETRC="$ETC_DIR"/inetrc
# define ejabberd environment parameters # define ejabberd parameters
if [ "$EJABBERD_CONFIG_PATH" != "${EJABBERD_CONFIG_PATH%.yml}" ] ; then rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*://;s/ *//' "$EJABBERD_CONFIG_PATH")
rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH) rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*://;s/ *//' "$EJABBERD_CONFIG_PATH")
rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH) count=$(sed '/^[ ]*log_rotate_count/!d;s/.*://;s/ *//' "$EJABBERD_CONFIG_PATH")
count=$(sed '/^[ ]*log_rotate_count/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH) date=$(sed '/^[ ]*log_rotate_date/!d;s/.*://;s/ *//' "$EJABBERD_CONFIG_PATH")
date=$(sed '/^[ ]*log_rotate_date/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
else
rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
count=$(sed '/^[ ]*log_rotate_count/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
date=$(sed '/^[ ]*log_rotate_date/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
fi
[ -z "$rate" ] || EJABBERD_OPTS="log_rate_limit $rate" [ -z "$rate" ] || EJABBERD_OPTS="log_rate_limit $rate"
[ -z "$rotate" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_size $rotate" [ -z "$rotate" ] || EJABBERD_OPTS="$EJABBERD_OPTS log_rotate_size $rotate"
[ -z "$count" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_count $count" [ -z "$count" ] || EJABBERD_OPTS="$EJABBERD_OPTS log_rotate_count $count"
[ -z "$date" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_date '$date'" [ -z "$date" ] || EJABBERD_OPTS="$EJABBERD_OPTS log_rotate_date '$date'"
[ -z "$EJABBERD_OPTS" ] || EJABBERD_OPTS="-ejabberd ${EJABBERD_OPTS}" [ -z "$EJABBERD_OPTS" ] || EJABBERD_OPTS="-ejabberd $EJABBERD_OPTS"
EJABBERD_OPTS="-mnesia dir \"$SPOOL_DIR\" $MNESIA_OPTIONS $EJABBERD_OPTS -s ejabberd"
[ -d "$SPOOL_DIR" ] || $EXEC_CMD "mkdir -p $SPOOL_DIR"
cd "$SPOOL_DIR"
# export global variables # export global variables
export EJABBERD_CONFIG_PATH export EJABBERD_CONFIG_PATH
export EJABBERD_LOG_PATH export EJABBERD_LOG_PATH
export EJABBERD_BIN_PATH
export EJABBERD_DOC_PATH export EJABBERD_DOC_PATH
export EJABBERD_PID_PATH export EJABBERD_PID_PATH
export ERL_CRASH_DUMP export ERL_CRASH_DUMP
@ -150,116 +110,26 @@ export CONTRIB_MODULES_PATH
export CONTRIB_MODULES_CONF_DIR export CONTRIB_MODULES_CONF_DIR
export ERL_LIBS export ERL_LIBS
shell_escape_str() # run command either directly or via su $INSTALLUSER
exec_cmd()
{ {
if test $# -eq 0; then case $EXEC_CMD in
printf '"" ' as_install_user) su -c '"$0" $@"' "$INSTALLUSER" -- "$@" ;;
else as_current_user) "$@" ;;
shell_escape "$@" esac
fi }
} exec_erl()
{
shell_escape() NODE=$1; shift
{ exec_cmd $ERL $NAME $NODE $ERLANG_OPTS "$@"
local RES=() }
for i in "$@"; do exec_iex()
if test -z "$i"; then {
printf '"" ' NODE=$1; shift
else exec_cmd $IEX -$NAME $NODE --erl "$ERLANG_OPTS" "$@"
printf '%q ' "$i"
fi
done
}
# start server
start()
{
check_start
CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \
-noinput -detached \
$MNESIA_OPTS \
$KERNEL_OPTS \
$EJABBERD_OPTS \
-s ejabberd \
$ERLANG_OPTS \
`shell_escape \"${ARGS[@]}\" \"$@\"`"
$EXEC_CMD "$CMD"
}
# attach to server
debug()
{
debugwarning
NID=$(uid debug)
CMD="`shell_escape \"$ERL\" \"$NAME\" \"$NID\"` \
-remsh $ERLANG_NODE \
-hidden \
$KERNEL_OPTS \
$ERLANG_OPTS \
`shell_escape \"${ARGS[@]}\" \"$@\"`"
$EXEC_CMD "$CMD"
}
# attach to server using Elixir
iexdebug()
{
debugwarning
# Elixir shell is hidden as default
NID=$(uid debug)
CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"$NID\"` \
-remsh $ERLANG_NODE \
--erl `shell_escape \"$KERNEL_OPTS\"` \
--erl `shell_escape \"$ERLANG_OPTS\"` \
--erl `shell_escape \"${ARGS[@]}\"` \
--erl `shell_escape_str \"$@\"`"
$EXEC_CMD "ERL_PATH=\"$ERL\" $CMD"
}
# start interactive server
live()
{
livewarning
CMD="`shell_escape \"$ERL\" \"$NAME\" \"${ERLANG_NODE}\"` \
$MNESIA_OPTS \
$KERNEL_OPTS \
$EJABBERD_OPTS \
-s ejabberd \
$ERLANG_OPTS \
`shell_escape \"${ARGS[@]}\" \"$@\"`"
$EXEC_CMD "$CMD"
}
# start interactive server with Elixir
iexlive()
{
livewarning
echo $@
CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"${ERLANG_NODE}\"` \
--erl \"-mnesia dir \\\"$SPOOL_DIR\\\"\" \
--erl \"`shell_escape \"$KERNEL_OPTS\"`\" \
--erl \"`shell_escape \"$EJABBERD_OPTS\"`\" \
--app ejabberd \
--erl `shell_escape \"$ERLANG_OPTS\"` \
--erl `shell_escape \"${ARGS[@]}\"` \
--erl `shell_escape_str \"$@\"`"
$EXEC_CMD "ERL_PATH=\"$ERL\" $CMD"
}
# start server in the foreground
foreground()
{
check_start
CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \
-noinput \
$MNESIA_OPTS \
$KERNEL_OPTS \
$EJABBERD_OPTS \
-s ejabberd \
$ERLANG_OPTS \
`shell_escape \"${ARGS[@]}\" \"$@\"`"
$EXEC_CMD "$CMD"
} }
# usage
debugwarning() debugwarning()
{ {
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
@ -286,7 +156,6 @@ debugwarning()
livewarning() livewarning()
{ {
check_start
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------" echo "--------------------------------------------------------------------"
echo "" echo ""
@ -308,32 +177,6 @@ livewarning()
fi fi
} }
etop()
{
NID=$(uid top)
$EXEC_CMD "$ERL \
$NAME $NID \
-hidden -s etop -s erlang halt -output text -node $ERLANG_NODE"
}
ping()
{
[ -z "$1" ] && PEER=${ERLANG_NODE} || PEER=$1
if [ "$PEER" = "${PEER%.*}" ] ; then
PING_NAME="-sname"
PING_NODE=$(hostname -s)
else
PING_NAME="-name"
PING_NODE=$(hostname)
fi
NID=$(uid ping ${PING_NODE})
$EXEC_CMD "$ERL \
$PING_NAME $NID \
-hidden $KERNEL_OPTS $ERLANG_OPTS \
-eval 'io:format(\"~p~n\",[net_adm:ping('\"'\"'$PEER'\"'\"')])' \
-s erlang halt -output text -noinput"
}
help() help()
{ {
echo "" echo ""
@ -355,28 +198,27 @@ help()
echo "" echo ""
} }
# common control function # generic erlang node ping feature
ctl() ping()
{ {
NID=$(uid ctl) PEER=${1:-$ERLANG_NODE}
CMD="`shell_escape \"$ERL\" \"$NAME\" \"$NID\"` \ if [ "$PEER" = "${PEER%.*}" ] ; then
-noinput -hidden $KERNEL_OPTS -s ejabberd_ctl \ PING_NAME="-sname"
-extra `shell_escape \"$ERLANG_NODE\"` $EJABBERD_NO_TIMEOUT \ PING_NODE=$(hostname -s)
`shell_escape \"$@\"`" else
$EXEC_CMD "$CMD" PING_NAME="-name"
result=$? PING_NODE=$(hostname)
case $result in fi
2) help;; exec_cmd $ERL $PING_NAME $(uid ping $PING_NODE) $ERLANG_OPTS \
3) help;; -noinput -hidden -eval 'io:format("~p~n",[net_adm:ping('"$PEER"')])' \
*) :;; -s erlang halt -output text
esac
return $result
} }
# dynamic node name helper
uid() uid()
{ {
uuid=$(uuidgen 2>/dev/null) uuid=$(uuidgen 2>/dev/null)
[ -z "$uuid" -a -f /proc/sys/kernel/random/uuid ] && uuid=$(</proc/sys/kernel/random/uuid) [ -z "$uuid" -a -f /proc/sys/kernel/random/uuid ] && uuid=$(cat /proc/sys/kernel/random/uuid)
[ -z "$uuid" ] && uuid=$(printf "%X" $RANDOM$(date +%M%S)$$) [ -z "$uuid" ] && uuid=$(printf "%X" $RANDOM$(date +%M%S)$$)
uuid=${uuid%%-*} uuid=${uuid%%-*}
[ $# -eq 0 ] && echo ${uuid}-${ERLANG_NODE} [ $# -eq 0 ] && echo ${uuid}-${ERLANG_NODE}
@ -391,6 +233,7 @@ stop_epmd()
} }
# make sure node not already running and node name unregistered # make sure node not already running and node name unregistered
# if all ok, ensure runtime directory exists and make it current directory
check_start() check_start()
{ {
"$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && { "$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
@ -407,11 +250,16 @@ check_start()
"$EPMD" -kill >/dev/null "$EPMD" -kill >/dev/null
} }
} }
} || {
cd "$SPOOL_DIR" || {
echo "ERROR: ejabberd can not access directory $SPOOL_DIR"
exit 6
}
} }
} }
# allow sync calls # allow sync calls
wait_for_status() wait_status()
{ {
# args: status try delay # args: status try delay
# return: 0 OK, 1 KO # return: 0 OK, 1 KO
@ -420,27 +268,64 @@ wait_for_status()
while [ $status -ne $1 ] ; do while [ $status -ne $1 ] ; do
sleep $3 sleep $3
timeout=`expr $timeout - 1` timeout=`expr $timeout - 1`
[ $timeout -eq 0 ] && { if [ $timeout -eq 0 ] ; then
status=$1 status=$1
} || { else
ctl status > /dev/null ctl status > /dev/null
status=$? status=$?
} fi
done done
[ $timeout -eq 0 ] && return 1 || return 0 [ $timeout -gt 0 ]
} }
# main handler # main
case "${ARGS[0]}" in case $1 in
'start') start;; start)
'debug') debug;; check_start
'iexdebug') iexdebug;; exec_erl $ERLANG_NODE $EJABBERD_OPTS -noinput -detached
'live') live;; ;;
'iexlive') iexlive;; foreground)
'foreground') foreground;; check_start
'ping'*) ping ${ARGS[1]};; exec_erl $ERLANG_NODE $EJABBERD_OPTS -noinput
'etop') etop;; ;;
'started') wait_for_status 0 30 2;; # wait 30x2s before timeout live)
'stopped') wait_for_status 3 30 2 && stop_epmd;; # wait 30x2s before timeout livewarning
*) ctl "${ARGS[@]}";; check_start
exec_erl $ERLANG_NODE $EJABBERD_OPTS
;;
debug)
debugwarning
exec_erl $(uid debug) -hidden -remsh $ERLANG_NODE
;;
etop)
exec_erl $(uid top) -hidden -node $ERLANG_NODE -s etop \
-s erlang halt -output text
;;
iexdebug)
debugwarning
exec_iex $(uid debug) --remsh "$ERLANG_NODE"
;;
iexlive)
livewarning
exec_iex $ERLANG_NODE --erl "$EJABBERD_OPTS" --app ejabberd
;;
ping)
ping $2
;;
started)
wait_status 0 30 2 # wait 30x2s before timeout
;;
stopped)
wait_status 3 30 2 && stop_epmd # wait 30x2s before timeout
;;
*)
exec_erl $(uid ctl) -hidden -noinput -s ejabberd_ctl \
-extra $ERLANG_NODE $NO_TIMEOUT "$@"
result=$?
case $result in
2|3) help;;
*) :;;
esac
exit $result
;;
esac esac