relx
This commit is contained in:
parent
3e77773d04
commit
710890dd22
|
@ -7,8 +7,6 @@ deps
|
||||||
erl_crash.dump
|
erl_crash.dump
|
||||||
ebin
|
ebin
|
||||||
!ebin/.placeholder
|
!ebin/.placeholder
|
||||||
rel/emqttd
|
|
||||||
rel/emqttd*
|
|
||||||
.concrete/DEV_MODE
|
.concrete/DEV_MODE
|
||||||
.rebar
|
.rebar
|
||||||
test/ebin/*.beam
|
test/ebin/*.beam
|
||||||
|
@ -28,3 +26,4 @@ logs
|
||||||
ct.coverdata
|
ct.coverdata
|
||||||
.idea/
|
.idea/
|
||||||
emqttd.iml
|
emqttd.iml
|
||||||
|
_rel/
|
||||||
|
|
606
bin/emqttd
606
bin/emqttd
|
@ -2,46 +2,21 @@
|
||||||
# -*- tab-width:4;indent-tabs-mode:nil -*-
|
# -*- tab-width:4;indent-tabs-mode:nil -*-
|
||||||
# ex: ts=4 sw=4 et
|
# ex: ts=4 sw=4 et
|
||||||
|
|
||||||
# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is.
|
set -e
|
||||||
if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then
|
|
||||||
POSIX_SHELL="true"
|
|
||||||
export POSIX_SHELL
|
|
||||||
# To support 'whoami' add /usr/ucb to path
|
|
||||||
PATH=/usr/ucb:$PATH
|
|
||||||
export PATH
|
|
||||||
exec /usr/bin/ksh $0 "$@"
|
|
||||||
fi
|
|
||||||
unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well
|
|
||||||
|
|
||||||
RUNNER_SCRIPT_DIR={{runner_script_dir}}
|
SCRIPT=$(readlink $0 || true)
|
||||||
RUNNER_SCRIPT=${0##*/}
|
if [ -z $SCRIPT ]; then
|
||||||
|
SCRIPT=$0
|
||||||
RUNNER_BASE_DIR={{runner_base_dir}}
|
fi;
|
||||||
RUNNER_ETC_DIR={{runner_etc_dir}}
|
SCRIPT_DIR="$(cd `dirname "$SCRIPT"` && pwd -P)"
|
||||||
RUNNER_LIB_DIR={{platform_lib_dir}}
|
RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||||
RUNNER_LOG_DIR={{runner_log_dir}}
|
REL_NAME="emqttd"
|
||||||
RUNNER_DATA_DIR=$RUNNER_BASE_DIR/data
|
REL_VSN="{{ rel_vsn }}"
|
||||||
RUNNER_PLUGINS_DIR=$RUNNER_BASE_DIR/plugins
|
ERTS_VSN="{{ erts_vsn }}"
|
||||||
|
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
|
||||||
# Note the trailing slash on $PIPE_DIR/
|
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
|
||||||
PIPE_DIR={{pipe_dir}}
|
ERL_OPTS="{{ erl_opts }}"
|
||||||
RUNNER_USER={{runner_user}}
|
RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}"
|
||||||
PLATFORM_DATA_DIR={{platform_data_dir}}
|
|
||||||
SSL_DIST_CONFIG=$PLATFORM_DATA_DIR/ssl_distribution.args_file
|
|
||||||
RIAK_VERSION="git"
|
|
||||||
|
|
||||||
WHOAMI=$(whoami)
|
|
||||||
|
|
||||||
# Make sure this script is running as the appropriate user
|
|
||||||
if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then
|
|
||||||
type sudo > /dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Attempting to restart script through sudo -H -u $RUNNER_USER" >&2
|
|
||||||
exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Warn the user if ulimit -n is less than 1024
|
# Warn the user if ulimit -n is less than 1024
|
||||||
ULIMIT_F=`ulimit -n`
|
ULIMIT_F=`ulimit -n`
|
||||||
|
@ -51,153 +26,231 @@ if [ "$ULIMIT_F" -lt 1024 ]; then
|
||||||
echo "!!!!"
|
echo "!!!!"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make sure CWD is set to runner base dir
|
find_erts_dir() {
|
||||||
cd $RUNNER_BASE_DIR
|
__erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
|
||||||
|
if [ -d "$__erts_dir" ]; then
|
||||||
|
ERTS_DIR="$__erts_dir";
|
||||||
|
ROOTDIR="$RELEASE_ROOT_DIR"
|
||||||
|
else
|
||||||
|
__erl="$(which erl)"
|
||||||
|
code="io:format(\"~s\", [code:root_dir()]), halt()."
|
||||||
|
__erl_root="$("$__erl" -noshell -eval "$code")"
|
||||||
|
ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
|
||||||
|
ROOTDIR="$__erl_root"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get node pid
|
||||||
|
relx_get_pid() {
|
||||||
|
if output="$(relx_nodetool rpcterms os getpid)"
|
||||||
|
then
|
||||||
|
echo "$output" | sed -e 's/"//g'
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "$output"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
relx_get_nodename() {
|
||||||
|
id="longname$(relx_gen_id)-${NAME}"
|
||||||
|
"$BINDIR/erl" -boot start_clean -eval '[Host] = tl(string:tokens(atom_to_list(node()),"@")), io:format("~s~n", [Host]), halt()' -noshell ${NAME_TYPE} $id
|
||||||
|
}
|
||||||
|
|
||||||
|
# Connect to a remote node
|
||||||
|
relx_rem_sh() {
|
||||||
|
# Generate a unique id used to allow multiple remsh to the same node
|
||||||
|
# transparently
|
||||||
|
id="remsh$(relx_gen_id)-${NAME}"
|
||||||
|
|
||||||
|
# Get the node's ticktime so that we use the same thing.
|
||||||
|
TICKTIME="$(relx_nodetool rpcterms net_kernel get_net_ticktime)"
|
||||||
|
|
||||||
|
# Setup remote shell command to control node
|
||||||
|
exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \
|
||||||
|
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
|
||||||
|
-setcookie "$COOKIE" -hidden -kernel net_ticktime $TICKTIME
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate a random id
|
||||||
|
relx_gen_id() {
|
||||||
|
od -t x -N 4 /dev/urandom | head -n1 | awk '{print $2}'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Control a node
|
||||||
|
relx_nodetool() {
|
||||||
|
command="$1"; shift
|
||||||
|
|
||||||
|
"$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
|
||||||
|
-setcookie "$COOKIE" "$command" $@
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run an escript in the node's environment
|
||||||
|
relx_escript() {
|
||||||
|
shift; scriptpath="$1"; shift
|
||||||
|
export RELEASE_ROOT_DIR
|
||||||
|
|
||||||
|
"$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@
|
||||||
|
}
|
||||||
|
|
||||||
|
# Output a start command for the last argument of run_erl
|
||||||
|
relx_start_command() {
|
||||||
|
printf "exec \"%s\" \"%s\"" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \
|
||||||
|
"$START_OPTION"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Use $CWD/vm.args if exists, otherwise releases/VSN/vm.args
|
||||||
|
if [ -z "$VMARGS_PATH" ]; then
|
||||||
|
if [ -f "$RELEASE_ROOT_DIR/vm.args" ]; then
|
||||||
|
VMARGS_PATH="$RELEASE_ROOT_DIR/vm.args"
|
||||||
|
else
|
||||||
|
VMARGS_PATH="$REL_DIR/vm.args"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
orig_vmargs_path="$VMARGS_PATH.orig"
|
||||||
|
if [ $RELX_REPLACE_OS_VARS ]; then
|
||||||
|
#Make sure we don't break dev mode by keeping the symbolic link to
|
||||||
|
#the user's vm.args
|
||||||
|
if [ ! -L "$orig_vmargs_path" ]; then
|
||||||
|
#we're in copy mode, rename the vm.args file to vm.args.orig
|
||||||
|
mv "$VMARGS_PATH" "$orig_vmargs_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$orig_vmargs_path" > "$VMARGS_PATH"
|
||||||
|
else
|
||||||
|
#We don't need to replace env. vars, just rename the
|
||||||
|
#symlink vm.args.orig to vm.args, and keep it as a
|
||||||
|
#symlink.
|
||||||
|
if [ -L "$orig_vmargs_path" ]; then
|
||||||
|
mv "$orig_vmargs_path" "$VMARGS_PATH"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Make sure log directory exists
|
# Make sure log directory exists
|
||||||
mkdir -p $RUNNER_LOG_DIR
|
mkdir -p "$RUNNER_LOG_DIR"
|
||||||
|
|
||||||
# Make sure the data directory exists
|
# Use $CWD/sys.config if exists, otherwise releases/VSN/sys.config
|
||||||
mkdir -p $PLATFORM_DATA_DIR
|
if [ -z "$RELX_CONFIG_PATH" ]; then
|
||||||
|
if [ -f "$RELEASE_ROOT_DIR/sys.config" ]; then
|
||||||
|
RELX_CONFIG_PATH="$RELEASE_ROOT_DIR/sys.config"
|
||||||
|
else
|
||||||
|
RELX_CONFIG_PATH="$REL_DIR/sys.config"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Warn the user if they don't have write permissions on the log dir
|
orig_relx_config_path="$RELX_CONFIG_PATH.orig"
|
||||||
if [ ! -w $RUNNER_LOG_DIR ]; then
|
if [ $RELX_REPLACE_OS_VARS ]; then
|
||||||
echo "!!!!"
|
#Make sure we don't break dev mode by keeping the symbolic link to
|
||||||
echo "!!!! WARNING: $RUNNER_LOG_DIR not writable; logs and crash dumps unavailable."
|
#the user's sys.config
|
||||||
echo "!!!!"
|
if [ ! -L "$orig_relx_config_path" ]; then
|
||||||
|
#We're in copy mode, rename sys.config to sys.config.orig
|
||||||
|
mv "$RELX_CONFIG_PATH" "$orig_relx_config_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$orig_relx_config_path" > "$RELX_CONFIG_PATH"
|
||||||
|
else
|
||||||
|
#We don't need to replace env. vars, just rename the
|
||||||
|
#symlink sys.config.orig to sys.config. Keep it as
|
||||||
|
#a symlink.
|
||||||
|
if [ -L "$orig_relx_config_path" ]; then
|
||||||
|
mv "$orig_relx_config_path" "$RELX_CONFIG_PATH"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Extract the target node name from node.args
|
# Extract the target node name from node.args
|
||||||
NAME_ARG=`egrep '^\-s?name' $RUNNER_ETC_DIR/vm.args`
|
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true)
|
||||||
if [ -z "$NAME_ARG" ]; then
|
if [ -z "$NAME_ARG" ]; then
|
||||||
echo "vm.args needs to have either -name or -sname parameter."
|
echo "vm.args needs to have either -name or -sname parameter."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
NODE_NAME=${NAME_ARG##* }
|
|
||||||
|
# Extract the name type and name from the NAME_ARG for REMSH
|
||||||
|
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
|
||||||
|
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"
|
||||||
|
|
||||||
|
PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}"
|
||||||
|
|
||||||
# Extract the target cookie
|
# Extract the target cookie
|
||||||
COOKIE_ARG=`grep '^\-setcookie' $RUNNER_ETC_DIR/vm.args`
|
COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)"
|
||||||
if [ -z "$COOKIE_ARG" ]; then
|
if [ -z "$COOKIE_ARG" ]; then
|
||||||
echo "vm.args needs to have a -setcookie parameter."
|
echo "vm.args needs to have a -setcookie parameter."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Identify the script name
|
# Extract cookie name from COOKIE_ARG
|
||||||
SCRIPT=`basename $0`
|
COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
|
||||||
|
|
||||||
# Parse out release and erts info
|
find_erts_dir
|
||||||
START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
|
export ROOTDIR="$RELEASE_ROOT_DIR"
|
||||||
ERTS_VSN=${START_ERL% *}
|
export BINDIR="$ERTS_DIR/bin"
|
||||||
APP_VSN=${START_ERL#* }
|
export EMU="beam"
|
||||||
|
export PROGNAME="erl"
|
||||||
|
export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH"
|
||||||
|
ERTS_LIB_DIR="$ERTS_DIR/../lib"
|
||||||
|
MNESIA_DATA_DIR="$ROOTDIR/data/mnesia/$NAME"
|
||||||
|
|
||||||
# Add ERTS bin dir to our path
|
cd "$ROOTDIR"
|
||||||
ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
|
|
||||||
|
|
||||||
# Setup command to control the node
|
# User can specify an sname without @hostname
|
||||||
NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
|
# This will fail when creating remote shell
|
||||||
NODETOOL_LITE="$ERTS_PATH/escript $ERTS_PATH/nodetool"
|
# So here we check for @ and add @hostname if missing
|
||||||
|
case $NAME in
|
||||||
# Common functions
|
*@*)
|
||||||
|
# Nothing to do
|
||||||
# Ping node without allowing nodetool to take stdin
|
;;
|
||||||
ping_node() {
|
*)
|
||||||
$NODETOOL ping < /dev/null
|
NAME=$NAME@$(relx_get_nodename)
|
||||||
}
|
;;
|
||||||
|
esac
|
||||||
# Set the PID global variable, return 1 on error
|
|
||||||
get_pid() {
|
|
||||||
PID=`$NODETOOL getpid < /dev/null`
|
|
||||||
ES=$?
|
|
||||||
if [ "$ES" -ne 0 ]; then
|
|
||||||
echo "Node is not running!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# don't allow empty or init pid's
|
|
||||||
if [ -z $PID ] || [ "$PID" -le 1 ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Scrape out SSL distribution config info from vm.args into $SSL_DIST_CONFIG
|
|
||||||
rm -f $SSL_DIST_CONFIG
|
|
||||||
sed -n '/Begin SSL distribution items/,/End SSL distribution items/p' \
|
|
||||||
$RUNNER_ETC_DIR/vm.args > $SSL_DIST_CONFIG
|
|
||||||
|
|
||||||
# Check the first argument for instructions
|
# Check the first argument for instructions
|
||||||
case "$1" in
|
case "$1" in
|
||||||
start)
|
start|start_boot)
|
||||||
# Make sure there is not already a node running
|
|
||||||
RES=`ping_node`
|
|
||||||
if [ "$RES" = "pong" ]; then
|
|
||||||
echo "Node is already running!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Sanity check the emqttd.config file
|
|
||||||
RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/emqttd.config`
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error reading $RUNNER_ETC_DIR/emqttd.config"
|
|
||||||
echo $RES
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
HEART_COMMAND="$RUNNER_SCRIPT_DIR/$SCRIPT start"
|
|
||||||
export HEART_COMMAND
|
|
||||||
mkdir -p $PIPE_DIR
|
|
||||||
$ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR \
|
|
||||||
"exec $RUNNER_SCRIPT_DIR/$SCRIPT console" 2>&1
|
|
||||||
|
|
||||||
# Wait for the node to come up. We can't just ping it because
|
# Make sure there is not already a node running
|
||||||
# distributed erlang comes up for a second before emqttd crashes
|
#RES=`$NODETOOL ping`
|
||||||
# (eg. in the case of an unwriteable disk). Once the node comes
|
#if [ "$RES" = "pong" ]; then
|
||||||
# up we check for the node watcher process. If that's running
|
# echo "Node is already running!"
|
||||||
# then we assume things are good enough. This will at least let
|
# exit 1
|
||||||
# the user know when emqttd is crashing right after startup.
|
#fi
|
||||||
WAIT=${WAIT_FOR_ERLANG:-15}
|
# Save this for later.
|
||||||
while [ $WAIT -gt 0 ]; do
|
CMD=$1
|
||||||
WAIT=`expr $WAIT - 1`
|
case "$1" in
|
||||||
sleep 1
|
start)
|
||||||
RES=`ping_node`
|
shift
|
||||||
if [ "$?" -ne 0 ]; then
|
START_OPTION="console"
|
||||||
continue
|
HEART_OPTION="start"
|
||||||
fi
|
;;
|
||||||
echo "emqttd is started successfully!"
|
start_boot)
|
||||||
exit 0
|
shift
|
||||||
done
|
START_OPTION="console_boot"
|
||||||
echo "emqttd failed to start within ${WAIT_FOR_ERLANG:-15} seconds,"
|
HEART_OPTION="start_boot"
|
||||||
echo "see the output of 'emqttd console' for more information."
|
;;
|
||||||
echo "If you want to wait longer, set the environment variable"
|
esac
|
||||||
echo "WAIT_FOR_ERLANG to the number of seconds to wait."
|
RUN_PARAM="$@"
|
||||||
exit 1
|
|
||||||
|
# Set arguments for the heart command
|
||||||
|
set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION"
|
||||||
|
[ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM"
|
||||||
|
|
||||||
|
# Export the HEART_COMMAND
|
||||||
|
HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD"
|
||||||
|
export HEART_COMMAND
|
||||||
|
|
||||||
|
mkdir -p "$PIPE_DIR"
|
||||||
|
|
||||||
|
"$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \
|
||||||
|
"$(relx_start_command)"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
stop)
|
stop)
|
||||||
UNAME_S=`uname -s`
|
|
||||||
case $UNAME_S in
|
|
||||||
Darwin)
|
|
||||||
# Make sure we explicitly set this because iTerm.app doesn't for
|
|
||||||
# some reason.
|
|
||||||
COMMAND_MODE=unix2003
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Get the PID from nodetool
|
|
||||||
get_pid
|
|
||||||
GPR=$?
|
|
||||||
if [ "$GPR" -ne 0 ] || [ -z $PID ]; then
|
|
||||||
exit $GPR
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Tell nodetool to initiate a stop
|
|
||||||
$NODETOOL stop
|
|
||||||
ES=$?
|
|
||||||
if [ "$ES" -ne 0 ]; then
|
|
||||||
exit $ES
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Wait for the node to completely stop...
|
# Wait for the node to completely stop...
|
||||||
while `kill -s 0 $PID 2>/dev/null`;
|
PID="$(relx_get_pid)"
|
||||||
|
if ! relx_nodetool "stop"; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
while $(kill -s 0 "$PID" 2>/dev/null);
|
||||||
do
|
do
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
@ -205,117 +258,214 @@ case "$1" in
|
||||||
|
|
||||||
restart)
|
restart)
|
||||||
## Restart the VM without exiting the process
|
## Restart the VM without exiting the process
|
||||||
$NODETOOL restart
|
if ! relx_nodetool "restart"; then
|
||||||
ES=$?
|
exit 1
|
||||||
if [ "$ES" -ne 0 ]; then
|
|
||||||
exit $ES
|
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
reboot)
|
reboot)
|
||||||
## Restart the VM completely (uses heart to restart it)
|
## Restart the VM completely (uses heart to restart it)
|
||||||
$NODETOOL reboot
|
if ! relx_nodetool "reboot"; then
|
||||||
ES=$?
|
exit 1
|
||||||
if [ "$ES" -ne 0 ]; then
|
fi
|
||||||
exit $ES
|
;;
|
||||||
|
|
||||||
|
pid)
|
||||||
|
## Get the VM's pid
|
||||||
|
if ! relx_get_pid; then
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
ping)
|
ping)
|
||||||
## See if the VM is alive
|
## See if the VM is alive
|
||||||
ping_node
|
if ! relx_nodetool "ping"; then
|
||||||
ES=$?
|
exit 1
|
||||||
if [ "$ES" -ne 0 ]; then
|
fi
|
||||||
exit $ES
|
;;
|
||||||
|
|
||||||
|
escript)
|
||||||
|
## Run an escript under the node's environment
|
||||||
|
if ! relx_escript $@; then
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
attach)
|
attach)
|
||||||
if [ "$2" = "-f" ]; then
|
# Make sure a node IS running
|
||||||
echo "Forcing connection..."
|
if ! relx_nodetool "ping" > /dev/null; then
|
||||||
else
|
|
||||||
# Make sure a node is running
|
|
||||||
RES=`ping_node`
|
|
||||||
ES=$?
|
|
||||||
if [ "$ES" -ne 0 ]; then
|
|
||||||
echo "Node is not running!"
|
echo "Node is not running!"
|
||||||
exit $ES
|
exit 1
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
shift
|
shift
|
||||||
exec $ERTS_PATH/to_erl $PIPE_DIR
|
exec "$BINDIR/to_erl" "$PIPE_DIR"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
remote_console)
|
||||||
|
# Make sure a node IS running
|
||||||
|
if ! relx_nodetool "ping" > /dev/null; then
|
||||||
|
echo "Node is not running!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
shift
|
||||||
|
relx_rem_sh
|
||||||
|
;;
|
||||||
|
|
||||||
|
upgrade|downgrade|install)
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo "Missing package argument"
|
||||||
|
echo "Usage: $REL_NAME $1 {package base name}"
|
||||||
|
echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure a node IS running
|
||||||
|
if ! relx_nodetool "ping" > /dev/null; then
|
||||||
|
echo "Node is not running!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
|
||||||
|
"install" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
|
||||||
|
;;
|
||||||
|
|
||||||
|
unpack)
|
||||||
|
if [ -z "$2" ]; then
|
||||||
|
echo "Missing package argument"
|
||||||
|
echo "Usage: $REL_NAME $1 {package base name}"
|
||||||
|
echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure a node IS running
|
||||||
|
if ! relx_nodetool "ping" > /dev/null; then
|
||||||
|
echo "Node is not running!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
|
||||||
|
"unpack" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
|
||||||
|
;;
|
||||||
|
|
||||||
|
console|console_clean|console_boot)
|
||||||
|
# .boot file typically just $REL_NAME (ie, the app name)
|
||||||
|
# however, for debugging, sometimes start_clean.boot is useful.
|
||||||
|
# For e.g. 'setup', one may even want to name another boot script.
|
||||||
|
case "$1" in
|
||||||
console)
|
console)
|
||||||
RES=`ping_node`
|
if [ -f "$REL_DIR/$REL_NAME.boot" ]; then
|
||||||
if [ "$RES" = "pong" ]; then
|
BOOTFILE="$REL_DIR/$REL_NAME"
|
||||||
echo "Node is already running - use '$SCRIPT attach' instead"
|
else
|
||||||
exit 1
|
BOOTFILE="$REL_DIR/start"
|
||||||
fi
|
|
||||||
# Sanity check the emqttd.config file
|
|
||||||
RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/emqttd.config`
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error reading $RUNNER_ETC_DIR/emqttd.config"
|
|
||||||
echo $RES
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
;;
|
||||||
|
console_clean)
|
||||||
|
BOOTFILE="$ROOTDIR/bin/start_clean"
|
||||||
|
;;
|
||||||
|
console_boot)
|
||||||
|
shift
|
||||||
|
BOOTFILE="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
# Setup beam-required vars
|
# Setup beam-required vars
|
||||||
ROOTDIR=$RUNNER_BASE_DIR
|
EMU="beam"
|
||||||
ERL_LIBS=$ROOTDIR/plugins
|
PROGNAME="${0#*/}"
|
||||||
BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
|
|
||||||
EMU=beam
|
|
||||||
PROGNAME=`echo $0 | sed 's/.*\///'`
|
|
||||||
# Setup Mnesia Dir
|
|
||||||
MNESIA_DIR="$RUNNER_DATA_DIR/mnesia/$NODE_NAME"
|
|
||||||
CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$SCRIPT \
|
|
||||||
-embedded -config $RUNNER_ETC_DIR/emqttd.config \
|
|
||||||
-pa $RUNNER_LIB_DIR/basho-patches \
|
|
||||||
-mnesia dir "\"${MNESIA_DIR}\"" \
|
|
||||||
-args_file $RUNNER_ETC_DIR/vm.args -- ${1+"$@"}"
|
|
||||||
export EMU
|
export EMU
|
||||||
export ROOTDIR
|
|
||||||
export ERL_LIBS
|
|
||||||
export BINDIR
|
|
||||||
export PROGNAME
|
export PROGNAME
|
||||||
|
|
||||||
|
# Store passed arguments since they will be erased by `set`
|
||||||
|
ARGS="$@"
|
||||||
|
|
||||||
|
# Build an array of arguments to pass to exec later on
|
||||||
|
# Build it here because this command will be used for logging.
|
||||||
|
set -- "$BINDIR/erlexec" -boot "$BOOTFILE" -mode "$CODE_LOADING_MODE" \
|
||||||
|
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
|
||||||
|
-config "$RELX_CONFIG_PATH" \
|
||||||
|
-mnesia dir "\"${MNESIA_DATA_DIR}\"" \
|
||||||
|
-args_file "$VMARGS_PATH"
|
||||||
|
|
||||||
# Dump environment info for logging purposes
|
# Dump environment info for logging purposes
|
||||||
echo "Exec: $CMD"
|
echo "Exec: $@" -- ${1+$ARGS}
|
||||||
echo "Root: $ROOTDIR"
|
echo "Root: $ROOTDIR"
|
||||||
|
|
||||||
# Log the startup
|
# Log the startup
|
||||||
logger -t "$SCRIPT[$$]" "Starting up"
|
echo "$RELEASE_ROOT_DIR"
|
||||||
|
logger -t "$REL_NAME[$$]" "Starting up"
|
||||||
|
|
||||||
# Start the VM
|
# Start the VM
|
||||||
exec $CMD
|
exec "$@" -- ${1+$ARGS}
|
||||||
;;
|
;;
|
||||||
chkconfig)
|
|
||||||
RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/emqttd.config`
|
foreground)
|
||||||
if [ $? != 0 ]; then
|
# start up the release in the foreground for use by runit
|
||||||
echo "Error reading $RUNNER_ETC_DIR/emqttd.config"
|
# or other supervision services
|
||||||
echo $RES
|
|
||||||
|
[ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start
|
||||||
|
FOREGROUNDOPTIONS="-noshell -noinput +Bd"
|
||||||
|
|
||||||
|
# Setup beam-required vars
|
||||||
|
EMU=beam
|
||||||
|
PROGNAME="${0#*/}"
|
||||||
|
|
||||||
|
export EMU
|
||||||
|
export PROGNAME
|
||||||
|
|
||||||
|
# Store passed arguments since they will be erased by `set`
|
||||||
|
ARGS="$@"
|
||||||
|
|
||||||
|
# Build an array of arguments to pass to exec later on
|
||||||
|
# Build it here because this command will be used for logging.
|
||||||
|
set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \
|
||||||
|
-boot "$REL_DIR/$BOOTFILE" -mode "$CODE_LOADING_MODE" -config "$RELX_CONFIG_PATH" \
|
||||||
|
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
|
||||||
|
-mnesia dir "\"${MNESIA_DATA_DIR}\"" \
|
||||||
|
-args_file "$VMARGS_PATH"
|
||||||
|
|
||||||
|
# Dump environment info for logging purposes
|
||||||
|
echo "Exec: $@" -- ${1+$ARGS}
|
||||||
|
echo "Root: $ROOTDIR"
|
||||||
|
|
||||||
|
# Start the VM
|
||||||
|
exec "$@" -- ${1+$ARGS}
|
||||||
|
;;
|
||||||
|
rpc)
|
||||||
|
# Make sure a node IS running
|
||||||
|
if ! relx_nodetool "ping" > /dev/null; then
|
||||||
|
echo "Node is not running!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "config is OK"
|
|
||||||
;;
|
|
||||||
escript)
|
|
||||||
shift
|
shift
|
||||||
$ERTS_PATH/escript "$@"
|
|
||||||
|
relx_nodetool rpc $@
|
||||||
;;
|
;;
|
||||||
version)
|
rpcterms)
|
||||||
echo $RIAK_VERSION
|
# Make sure a node IS running
|
||||||
;;
|
if ! relx_nodetool "ping" > /dev/null; then
|
||||||
getpid)
|
echo "Node is not running!"
|
||||||
# Get the PID from nodetool
|
exit 1
|
||||||
get_pid
|
|
||||||
ES=$?
|
|
||||||
if [ "$ES" -ne 0 ] || [ -z $PID ]; then
|
|
||||||
exit $ES
|
|
||||||
fi
|
fi
|
||||||
echo $PID
|
|
||||||
|
shift
|
||||||
|
|
||||||
|
relx_nodetool rpcterms $@
|
||||||
|
;;
|
||||||
|
eval)
|
||||||
|
# Make sure a node IS running
|
||||||
|
if ! relx_nodetool "ping" > /dev/null; then
|
||||||
|
echo "Node is not running!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
shift
|
||||||
|
relx_nodetool "eval" $@
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|attach|chkconfig|escript|version|getpid}"
|
echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|escript|rpc|rpcterms|eval}"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
124
bin/emqttd_ctl
124
bin/emqttd_ctl
|
@ -2,90 +2,82 @@
|
||||||
# -*- tab-width:4;indent-tabs-mode:nil -*-
|
# -*- tab-width:4;indent-tabs-mode:nil -*-
|
||||||
# ex: ts=4 sw=4 et
|
# ex: ts=4 sw=4 et
|
||||||
|
|
||||||
# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is.
|
set -e
|
||||||
if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then
|
|
||||||
POSIX_SHELL="true"
|
|
||||||
export POSIX_SHELL
|
|
||||||
# To support 'whoami' add /usr/ucb to path
|
|
||||||
PATH=/usr/ucb:$PATH
|
|
||||||
export PATH
|
|
||||||
exec /usr/bin/ksh $0 "$@"
|
|
||||||
fi
|
|
||||||
unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well
|
|
||||||
|
|
||||||
RUNNER_SCRIPT_DIR={{runner_script_dir}}
|
SCRIPT=$(readlink $0 || true)
|
||||||
RUNNER_SCRIPT=${0##*/}
|
if [ -z $SCRIPT ]; then
|
||||||
|
SCRIPT=$0
|
||||||
|
fi;
|
||||||
|
SCRIPT_DIR="$(cd `dirname "$SCRIPT"` && pwd -P)"
|
||||||
|
RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||||
|
REL_NAME="emqttd"
|
||||||
|
REL_VSN="{{ rel_vsn }}"
|
||||||
|
ERTS_VSN="{{ erts_vsn }}"
|
||||||
|
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
|
||||||
|
ERL_OPTS="{{ erl_opts }}"
|
||||||
|
RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}"
|
||||||
|
|
||||||
RUNNER_BASE_DIR={{runner_base_dir}}
|
find_erts_dir() {
|
||||||
RUNNER_ETC_DIR={{runner_etc_dir}}
|
__erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
|
||||||
RUNNER_LIB_DIR={{platform_lib_dir}}
|
if [ -d "$__erts_dir" ]; then
|
||||||
RUNNER_LOG_DIR={{runner_log_dir}}
|
ERTS_DIR="$__erts_dir";
|
||||||
RUNNER_USER={{runner_user}}
|
ROOTDIR="$RELEASE_ROOT_DIR"
|
||||||
|
else
|
||||||
WHOAMI=$(whoami)
|
__erl="$(which erl)"
|
||||||
|
code="io:format(\"~s\", [code:root_dir()]), halt()."
|
||||||
# Make sure this script is running as the appropriate user
|
__erl_root="$("$__erl" -noshell -eval "$code")"
|
||||||
if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then
|
ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
|
||||||
type sudo > /dev/null 2>&1
|
ROOTDIR="$__erl_root"
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
echo "Attempting to restart script through sudo -H -u $RUNNER_USER" >&2
|
}
|
||||||
exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make sure CWD is set to runner base dir
|
relx_get_nodename() {
|
||||||
cd $RUNNER_BASE_DIR
|
id="longname$(relx_gen_id)-${NAME}"
|
||||||
|
"$BINDIR/erl" -boot start_clean -eval '[Host] = tl(string:tokens(atom_to_list(node()),"@")), io:format("~s~n", [Host]), halt()' -noshell ${NAME_TYPE} $id
|
||||||
|
}
|
||||||
|
|
||||||
|
# Control a node
|
||||||
|
relx_nodetool() {
|
||||||
|
command="$1"; shift
|
||||||
|
|
||||||
|
"$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
|
||||||
|
-setcookie "$COOKIE" "$command" $@
|
||||||
|
}
|
||||||
|
|
||||||
|
# Use $CWD/vm.args if exists, otherwise releases/VSN/vm.args
|
||||||
|
if [ -z "$VMARGS_PATH" ]; then
|
||||||
|
if [ -f "$RELEASE_ROOT_DIR/vm.args" ]; then
|
||||||
|
VMARGS_PATH="$RELEASE_ROOT_DIR/vm.args"
|
||||||
|
else
|
||||||
|
VMARGS_PATH="$REL_DIR/vm.args"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Extract the target node name from node.args
|
# Extract the target node name from node.args
|
||||||
NAME_ARG=`egrep "^ *-s?name" $RUNNER_ETC_DIR/vm.args`
|
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true)
|
||||||
if [ -z "$NAME_ARG" ]; then
|
if [ -z "$NAME_ARG" ]; then
|
||||||
echo "vm.args needs to have either -name or -sname parameter."
|
echo "vm.args needs to have either -name or -sname parameter."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Learn how to specify node name for connection from remote nodes
|
# Extract the name type and name from the NAME_ARG for REMSH
|
||||||
echo "$NAME_ARG" | grep '^-sname' > /dev/null 2>&1
|
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
|
||||||
if [ "X$?" = "X0" ]; then
|
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"
|
||||||
NAME_PARAM="-sname"
|
|
||||||
NAME_HOST=""
|
|
||||||
else
|
|
||||||
NAME_PARAM="-name"
|
|
||||||
echo "$NAME_ARG" | grep '@.*' > /dev/null 2>&1
|
|
||||||
if [ "X$?" = "X0" ]; then
|
|
||||||
NAME_HOST=`echo "${NAME_ARG}" | sed -e 's/.*\(@.*\)$/\1/'`
|
|
||||||
else
|
|
||||||
NAME_HOST=""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract the target cookie
|
# Extract the target cookie
|
||||||
COOKIE_ARG=`grep '\-setcookie' $RUNNER_ETC_DIR/vm.args`
|
COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)"
|
||||||
if [ -z "$COOKIE_ARG" ]; then
|
if [ -z "$COOKIE_ARG" ]; then
|
||||||
echo "vm.args needs to have a -setcookie parameter."
|
echo "vm.args needs to have a -setcookie parameter."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Identify the script name
|
# Extract cookie name from COOKIE_ARG
|
||||||
SCRIPT=`basename $0`
|
COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
|
||||||
|
|
||||||
# Parse out release and erts info
|
find_erts_dir
|
||||||
START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
|
export ROOTDIR="$RELEASE_ROOT_DIR"
|
||||||
ERTS_VSN=${START_ERL% *}
|
export BINDIR="$ERTS_DIR/bin"
|
||||||
APP_VSN=${START_ERL#* }
|
cd "$ROOTDIR"
|
||||||
|
|
||||||
# Add ERTS bin dir to our path
|
relx_nodetool rpc emqttd_ctl run $@
|
||||||
ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
|
|
||||||
|
|
||||||
# Setup command to control the node
|
|
||||||
NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
|
|
||||||
|
|
||||||
RES=`$NODETOOL ping`
|
|
||||||
if [ "$RES" != "pong" ]; then
|
|
||||||
echo "Node is not running!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
$NODETOOL rpc emqttd_ctl run $@
|
|
||||||
|
|
||||||
|
|
117
bin/emqttd_top
117
bin/emqttd_top
|
@ -1,117 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# -*- tab-width:4;indent-tabs-mode:nil -*-
|
|
||||||
# ex: ts=4 sw=4 et
|
|
||||||
|
|
||||||
# /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is.
|
|
||||||
if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then
|
|
||||||
POSIX_SHELL="true"
|
|
||||||
export POSIX_SHELL
|
|
||||||
# To support 'whoami' add /usr/ucb to path
|
|
||||||
PATH=/usr/ucb:$PATH
|
|
||||||
export PATH
|
|
||||||
exec /usr/bin/ksh $0 "$@"
|
|
||||||
fi
|
|
||||||
unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well
|
|
||||||
|
|
||||||
RUNNER_SCRIPT_DIR={{runner_script_dir}}
|
|
||||||
RUNNER_SCRIPT=${0##*/}
|
|
||||||
|
|
||||||
RUNNER_BASE_DIR={{runner_base_dir}}
|
|
||||||
RUNNER_ETC_DIR={{runner_etc_dir}}
|
|
||||||
RUNNER_LIB_DIR={{platform_lib_dir}}
|
|
||||||
RUNNER_USER={{runner_user}}
|
|
||||||
|
|
||||||
WHOAMI=$(whoami)
|
|
||||||
|
|
||||||
# Make sure this script is running as the appropriate user
|
|
||||||
if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then
|
|
||||||
type sudo > /dev/null 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Attempting to restart script through sudo -H -u $RUNNER_USER" >&2
|
|
||||||
exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Make sure CWD is set to runner base dir
|
|
||||||
cd $RUNNER_BASE_DIR
|
|
||||||
|
|
||||||
# Extract the target node name from node.args
|
|
||||||
NAME_ARG=`egrep "^ *-s?name" $RUNNER_ETC_DIR/vm.args`
|
|
||||||
if [ -z "$NAME_ARG" ]; then
|
|
||||||
echo "vm.args needs to have either -name or -sname parameter."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Learn how to specify node name for connection from remote nodes
|
|
||||||
echo "$NAME_ARG" | grep '^-sname' > /dev/null 2>&1
|
|
||||||
if [ "X$?" = "X0" ]; then
|
|
||||||
NAME_PARAM="-sname"
|
|
||||||
NAME_HOST=""
|
|
||||||
else
|
|
||||||
NAME_PARAM="-name"
|
|
||||||
echo "$NAME_ARG" | grep '@.*' > /dev/null 2>&1
|
|
||||||
if [ "X$?" = "X0" ]; then
|
|
||||||
NAME_HOST=`echo "${NAME_ARG}" | sed -e 's/.*\(@.*\)$/\1/'`
|
|
||||||
else
|
|
||||||
NAME_HOST=""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract the target cookie
|
|
||||||
COOKIE_ARG=`grep '\-setcookie' $RUNNER_ETC_DIR/vm.args`
|
|
||||||
if [ -z "$COOKIE_ARG" ]; then
|
|
||||||
echo "vm.args needs to have a -setcookie parameter."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Identify the script name
|
|
||||||
SCRIPT=`basename $0`
|
|
||||||
|
|
||||||
# Parse out release and erts info
|
|
||||||
START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
|
|
||||||
ERTS_VSN=${START_ERL% *}
|
|
||||||
APP_VSN=${START_ERL#* }
|
|
||||||
|
|
||||||
# Add ERTS bin dir to our path
|
|
||||||
ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
|
|
||||||
|
|
||||||
NODE_NAME=${NAME_ARG#* }
|
|
||||||
|
|
||||||
# Setup command to control the node
|
|
||||||
NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
|
|
||||||
|
|
||||||
RES=`$NODETOOL ping`
|
|
||||||
if [ "$RES" != "pong" ]; then
|
|
||||||
echo "Node is not running!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
runtime)
|
|
||||||
SORTBY="runtime"
|
|
||||||
;;
|
|
||||||
reductions)
|
|
||||||
SORTBY="reductions"
|
|
||||||
;;
|
|
||||||
memory)
|
|
||||||
SORTBY="memory"
|
|
||||||
;;
|
|
||||||
msg_q)
|
|
||||||
SORTBY="msg_q"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Usage: $SCRIPT {runtime | reductions | memory | msg_q}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
MYPID=$$
|
|
||||||
ETOP_ARGS="-sort $SORTBY -interval 10 -lines 50 -tracing off"
|
|
||||||
$ERTS_PATH/erl -noshell -noinput \
|
|
||||||
-pa $RUNNER_LIB_DIR/basho-patches \
|
|
||||||
-hidden $NAME_PARAM emqttd_top$MYPID$NAME_HOST $COOKIE_ARG \
|
|
||||||
-s etop -s erlang halt -output text \
|
|
||||||
-node $NODE_NAME $ETOP_ARGS
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
#!/usr/bin/env escript
|
|
||||||
%%! -noshell -noinput
|
|
||||||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
|
||||||
%% ex: ft=erlang ts=4 sw=4 et
|
|
||||||
|
|
||||||
-define(TIMEOUT, 60000).
|
|
||||||
-define(INFO(Fmt,Args), io:format(Fmt,Args)).
|
|
||||||
|
|
||||||
main([NodeName, Cookie, ReleasePackage]) ->
|
|
||||||
TargetNode = start_distribution(NodeName, Cookie),
|
|
||||||
{ok, Vsn} = rpc:call(TargetNode, release_handler, unpack_release,
|
|
||||||
[ReleasePackage], ?TIMEOUT),
|
|
||||||
?INFO("Unpacked Release ~p~n", [Vsn]),
|
|
||||||
{ok, OtherVsn, Desc} = rpc:call(TargetNode, release_handler,
|
|
||||||
check_install_release, [Vsn], ?TIMEOUT),
|
|
||||||
{ok, OtherVsn, Desc} = rpc:call(TargetNode, release_handler,
|
|
||||||
install_release, [Vsn], ?TIMEOUT),
|
|
||||||
?INFO("Installed Release ~p~n", [Vsn]),
|
|
||||||
ok = rpc:call(TargetNode, release_handler, make_permanent, [Vsn], ?TIMEOUT),
|
|
||||||
?INFO("Made Release ~p Permanent~n", [Vsn]);
|
|
||||||
main(_) ->
|
|
||||||
init:stop(1).
|
|
||||||
|
|
||||||
start_distribution(NodeName, Cookie) ->
|
|
||||||
MyNode = make_script_node(NodeName),
|
|
||||||
{ok, _Pid} = net_kernel:start([MyNode, shortnames]),
|
|
||||||
erlang:set_cookie(node(), list_to_atom(Cookie)),
|
|
||||||
TargetNode = make_target_node(NodeName),
|
|
||||||
case {net_kernel:hidden_connect_node(TargetNode),
|
|
||||||
net_adm:ping(TargetNode)} of
|
|
||||||
{true, pong} ->
|
|
||||||
ok;
|
|
||||||
{_, pang} ->
|
|
||||||
io:format("Node ~p not responding to pings.\n", [TargetNode]),
|
|
||||||
init:stop(1)
|
|
||||||
end,
|
|
||||||
TargetNode.
|
|
||||||
|
|
||||||
make_target_node(Node) ->
|
|
||||||
[_, Host] = string:tokens(atom_to_list(node()), "@"),
|
|
||||||
list_to_atom(lists:concat([Node, "@", Host])).
|
|
||||||
|
|
||||||
make_script_node(Node) ->
|
|
||||||
list_to_atom(lists:concat([Node, "_upgrader_", os:getpid()])).
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
#!/usr/bin/env escript
|
||||||
|
%%! -noshell -noinput
|
||||||
|
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||||
|
%% ex: ft=erlang ts=4 sw=4 et
|
||||||
|
|
||||||
|
-define(TIMEOUT, 300000).
|
||||||
|
-define(INFO(Fmt,Args), io:format(Fmt,Args)).
|
||||||
|
|
||||||
|
%% Unpack or upgrade to a new tar.gz release
|
||||||
|
main(["unpack", RelName, NameTypeArg, NodeName, Cookie, VersionArg]) ->
|
||||||
|
TargetNode = start_distribution(NodeName, NameTypeArg, Cookie),
|
||||||
|
WhichReleases = which_releases(TargetNode),
|
||||||
|
Version = parse_version(VersionArg),
|
||||||
|
case proplists:get_value(Version, WhichReleases) of
|
||||||
|
undefined ->
|
||||||
|
%% not installed, so unpack tarball:
|
||||||
|
?INFO("Release ~s not found, attempting to unpack releases/~s/~s.tar.gz~n",[Version,Version,RelName]),
|
||||||
|
ReleasePackage = Version ++ "/" ++ RelName,
|
||||||
|
case rpc:call(TargetNode, release_handler, unpack_release,
|
||||||
|
[ReleasePackage], ?TIMEOUT) of
|
||||||
|
{ok, Vsn} ->
|
||||||
|
?INFO("Unpacked successfully: ~p~n", [Vsn]);
|
||||||
|
{error, UnpackReason} ->
|
||||||
|
print_existing_versions(TargetNode),
|
||||||
|
?INFO("Unpack failed: ~p~n",[UnpackReason]),
|
||||||
|
erlang:halt(2)
|
||||||
|
end;
|
||||||
|
old ->
|
||||||
|
%% no need to unpack, has been installed previously
|
||||||
|
?INFO("Release ~s is marked old, switching to it.~n",[Version]);
|
||||||
|
unpacked ->
|
||||||
|
?INFO("Release ~s is already unpacked, now installing.~n",[Version]);
|
||||||
|
current ->
|
||||||
|
?INFO("Release ~s is already installed and current. Making permanent.~n",[Version]);
|
||||||
|
permanent ->
|
||||||
|
?INFO("Release ~s is already installed, and set permanent.~n",[Version])
|
||||||
|
end;
|
||||||
|
main(["install", RelName, NameTypeArg, NodeName, Cookie, VersionArg]) ->
|
||||||
|
TargetNode = start_distribution(NodeName, NameTypeArg, Cookie),
|
||||||
|
WhichReleases = which_releases(TargetNode),
|
||||||
|
Version = parse_version(VersionArg),
|
||||||
|
case proplists:get_value(Version, WhichReleases) of
|
||||||
|
undefined ->
|
||||||
|
%% not installed, so unpack tarball:
|
||||||
|
?INFO("Release ~s not found, attempting to unpack releases/~s/~s.tar.gz~n",[Version,Version,RelName]),
|
||||||
|
ReleasePackage = Version ++ "/" ++ RelName,
|
||||||
|
case rpc:call(TargetNode, release_handler, unpack_release,
|
||||||
|
[ReleasePackage], ?TIMEOUT) of
|
||||||
|
{ok, Vsn} ->
|
||||||
|
?INFO("Unpacked successfully: ~p~n", [Vsn]),
|
||||||
|
install_and_permafy(TargetNode, RelName, Vsn);
|
||||||
|
{error, UnpackReason} ->
|
||||||
|
print_existing_versions(TargetNode),
|
||||||
|
?INFO("Unpack failed: ~p~n",[UnpackReason]),
|
||||||
|
erlang:halt(2)
|
||||||
|
end;
|
||||||
|
old ->
|
||||||
|
%% no need to unpack, has been installed previously
|
||||||
|
?INFO("Release ~s is marked old, switching to it.~n",[Version]),
|
||||||
|
install_and_permafy(TargetNode, RelName, Version);
|
||||||
|
unpacked ->
|
||||||
|
?INFO("Release ~s is already unpacked, now installing.~n",[Version]),
|
||||||
|
install_and_permafy(TargetNode, RelName, Version);
|
||||||
|
current -> %% installed and in-use, just needs to be permanent
|
||||||
|
?INFO("Release ~s is already installed and current. Making permanent.~n",[Version]),
|
||||||
|
permafy(TargetNode, RelName, Version);
|
||||||
|
permanent ->
|
||||||
|
?INFO("Release ~s is already installed, and set permanent.~n",[Version])
|
||||||
|
end;
|
||||||
|
main(_) ->
|
||||||
|
erlang:halt(1).
|
||||||
|
|
||||||
|
parse_version(V) when is_list(V) ->
|
||||||
|
hd(string:tokens(V,"/")).
|
||||||
|
|
||||||
|
install_and_permafy(TargetNode, RelName, Vsn) ->
|
||||||
|
case rpc:call(TargetNode, release_handler, check_install_release, [Vsn], ?TIMEOUT) of
|
||||||
|
{ok, _OtherVsn, _Desc} ->
|
||||||
|
ok;
|
||||||
|
{error, Reason} ->
|
||||||
|
?INFO("ERROR: release_handler:check_install_release failed: ~p~n",[Reason]),
|
||||||
|
erlang:halt(3)
|
||||||
|
end,
|
||||||
|
case rpc:call(TargetNode, release_handler, install_release, [Vsn], ?TIMEOUT) of
|
||||||
|
{ok, _, _} ->
|
||||||
|
?INFO("Installed Release: ~s~n", [Vsn]),
|
||||||
|
permafy(TargetNode, RelName, Vsn),
|
||||||
|
ok;
|
||||||
|
{error, {no_such_release, Vsn}} ->
|
||||||
|
VerList =
|
||||||
|
iolist_to_binary(
|
||||||
|
[io_lib:format("* ~s\t~s~n",[V,S]) || {V,S} <- which_releases(TargetNode)]),
|
||||||
|
?INFO("Installed versions:~n~s", [VerList]),
|
||||||
|
?INFO("ERROR: Unable to revert to '~s' - not installed.~n", [Vsn]),
|
||||||
|
erlang:halt(2)
|
||||||
|
end.
|
||||||
|
|
||||||
|
permafy(TargetNode, RelName, Vsn) ->
|
||||||
|
ok = rpc:call(TargetNode, release_handler, make_permanent, [Vsn], ?TIMEOUT),
|
||||||
|
file:copy(filename:join(["bin", RelName++"-"++Vsn]),
|
||||||
|
filename:join(["bin", RelName])),
|
||||||
|
?INFO("Made release permanent: ~p~n", [Vsn]),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
which_releases(TargetNode) ->
|
||||||
|
R = rpc:call(TargetNode, release_handler, which_releases, [], ?TIMEOUT),
|
||||||
|
[ {V, S} || {_,V,_, S} <- R ].
|
||||||
|
|
||||||
|
print_existing_versions(TargetNode) ->
|
||||||
|
VerList = iolist_to_binary([
|
||||||
|
io_lib:format("* ~s\t~s~n",[V,S])
|
||||||
|
|| {V,S} <- which_releases(TargetNode) ]),
|
||||||
|
?INFO("Installed versions:~n~s", [VerList]).
|
||||||
|
|
||||||
|
start_distribution(NodeName, NameTypeArg, Cookie) ->
|
||||||
|
MyNode = make_script_node(NodeName),
|
||||||
|
{ok, _Pid} = net_kernel:start([MyNode, get_name_type(NameTypeArg)]),
|
||||||
|
erlang:set_cookie(node(), list_to_atom(Cookie)),
|
||||||
|
TargetNode = list_to_atom(NodeName),
|
||||||
|
case {net_kernel:connect_node(TargetNode),
|
||||||
|
net_adm:ping(TargetNode)} of
|
||||||
|
{true, pong} ->
|
||||||
|
ok;
|
||||||
|
{_, pang} ->
|
||||||
|
io:format("Node ~p not responding to pings.\n", [TargetNode]),
|
||||||
|
erlang:halt(1)
|
||||||
|
end,
|
||||||
|
{ok, Cwd} = file:get_cwd(),
|
||||||
|
ok = rpc:call(TargetNode, file, set_cwd, [Cwd], ?TIMEOUT),
|
||||||
|
TargetNode.
|
||||||
|
|
||||||
|
make_script_node(Node) ->
|
||||||
|
[Name, Host] = string:tokens(Node, "@"),
|
||||||
|
list_to_atom(lists:concat([Name, "_upgrader_", os:getpid(), "@", Host])).
|
||||||
|
|
||||||
|
%% get name type from arg
|
||||||
|
get_name_type(NameTypeArg) ->
|
||||||
|
case NameTypeArg of
|
||||||
|
"-sname" ->
|
||||||
|
shortnames;
|
||||||
|
_ ->
|
||||||
|
longnames
|
||||||
|
end.
|
44
bin/nodetool
44
bin/nodetool
|
@ -1,5 +1,4 @@
|
||||||
#!/usr/bin/env escript
|
#!/usr/bin/env escript
|
||||||
|
|
||||||
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||||
%% ex: ft=erlang ts=4 sw=4 et
|
%% ex: ft=erlang ts=4 sw=4 et
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
@ -38,8 +37,8 @@ main(Args) ->
|
||||||
{error, {Line, Mod, Term}} ->
|
{error, {Line, Mod, Term}} ->
|
||||||
io:format(standard_error, ["Error on line ", file:format_error({Line, Mod, Term}), "\n"], []),
|
io:format(standard_error, ["Error on line ", file:format_error({Line, Mod, Term}), "\n"], []),
|
||||||
halt(1);
|
halt(1);
|
||||||
{error, R} ->
|
{error, Error} ->
|
||||||
io:format(standard_error, ["Error reading config file: ", file:format_error(R), "\n"], []),
|
io:format(standard_error, ["Error reading config file: ", file:format_error(Error), "\n"], []),
|
||||||
halt(1)
|
halt(1)
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
|
@ -94,20 +93,48 @@ main(Args) ->
|
||||||
end;
|
end;
|
||||||
["rpcterms", Module, Function, ArgsAsString] ->
|
["rpcterms", Module, Function, ArgsAsString] ->
|
||||||
case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
|
case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function),
|
||||||
consult(ArgsAsString), 60000) of
|
consult(lists:flatten(ArgsAsString)), 60000) of
|
||||||
{badrpc, Reason} ->
|
{badrpc, Reason} ->
|
||||||
io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]),
|
io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]),
|
||||||
halt(1);
|
halt(1);
|
||||||
Other ->
|
Other ->
|
||||||
io:format("~p\n", [Other])
|
io:format("~p\n", [Other])
|
||||||
end;
|
end;
|
||||||
|
["eval" | ListOfArgs] ->
|
||||||
|
% shells may process args into more than one, and end up stripping
|
||||||
|
% spaces, so this converts all of that to a single string to parse
|
||||||
|
String = binary_to_list(
|
||||||
|
list_to_binary(
|
||||||
|
string:join(ListOfArgs," ")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
% then just as a convenience to users, if they forgot a trailing
|
||||||
|
% '.' add it for them.
|
||||||
|
Normalized =
|
||||||
|
case lists:reverse(String) of
|
||||||
|
[$. | _] -> String;
|
||||||
|
R -> lists:reverse([$. | R])
|
||||||
|
end,
|
||||||
|
|
||||||
|
% then scan and parse the string
|
||||||
|
{ok, Scanned, _} = erl_scan:string(Normalized),
|
||||||
|
{ok, Parsed } = erl_parse:parse_exprs(Scanned),
|
||||||
|
|
||||||
|
% and evaluate it on the remote node
|
||||||
|
case rpc:call(TargetNode, erl_eval, exprs, [Parsed, [] ]) of
|
||||||
|
{value, Value, _} ->
|
||||||
|
io:format ("~p\n",[Value]);
|
||||||
|
{badrpc, Reason} ->
|
||||||
|
io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]),
|
||||||
|
halt(1)
|
||||||
|
end;
|
||||||
Other ->
|
Other ->
|
||||||
io:format("Other: ~p\n", [Other]),
|
io:format("Other: ~p\n", [Other]),
|
||||||
io:format("Usage: nodetool {chkconfig|getpid|ping|stop|restart|reboot|rpc|rpc_infinity|rpcterms}\n")
|
io:format("Usage: nodetool {chkconfig|getpid|ping|stop|restart|reboot|rpc|rpc_infinity|rpcterms|eval [Terms]} [RPC]\n")
|
||||||
end,
|
end,
|
||||||
net_kernel:stop().
|
net_kernel:stop().
|
||||||
|
|
||||||
|
|
||||||
process_args([], Acc, TargetNode) ->
|
process_args([], Acc, TargetNode) ->
|
||||||
{lists:reverse(Acc), TargetNode};
|
{lists:reverse(Acc), TargetNode};
|
||||||
process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) ->
|
process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) ->
|
||||||
|
@ -126,7 +153,7 @@ process_args([Arg | Rest], Acc, Opts) ->
|
||||||
|
|
||||||
|
|
||||||
start_epmd() ->
|
start_epmd() ->
|
||||||
[] = os:cmd(epmd_path() ++ " -daemon"),
|
[] = os:cmd("\"" ++ epmd_path() ++ "\" -daemon"),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
epmd_path() ->
|
epmd_path() ->
|
||||||
|
@ -163,7 +190,6 @@ append_node_suffix(Name, Suffix) ->
|
||||||
list_to_atom(lists:concat([Node, Suffix, os:getpid()]))
|
list_to_atom(lists:concat([Node, Suffix, os:getpid()]))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% Given a string or binary, parse it into a list of terms, ala file:consult/0
|
%% Given a string or binary, parse it into a list of terms, ala file:consult/0
|
||||||
%%
|
%%
|
||||||
|
@ -188,7 +214,6 @@ consult(Cont, Str, Acc) ->
|
||||||
consult(Cont1, eof, Acc)
|
consult(Cont1, eof, Acc)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
%% Validation functions for checking the emqttd.config
|
%% Validation functions for checking the emqttd.config
|
||||||
%%
|
%%
|
||||||
|
@ -211,4 +236,3 @@ print_issue({warning, Warning}) ->
|
||||||
print_issue({error, Error}) ->
|
print_issue({error, Error}) ->
|
||||||
io:format(standard_error, "Error in emqttd.config: ~s~n", [Error]).
|
io:format(standard_error, "Error in emqttd.config: ~s~n", [Error]).
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,27 @@
|
||||||
|
%%===================================================================
|
||||||
|
%%
|
||||||
|
%% Config file for emqttd 2.0
|
||||||
|
%%
|
||||||
|
%% Erlang Term Syntax:
|
||||||
|
%%
|
||||||
|
%% {}: Tuple, usually {Key, Value}
|
||||||
|
%% []: List, seperated by comma
|
||||||
|
%% %%: comment
|
||||||
|
%%
|
||||||
|
%%===================================================================
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% MQTT Protocol
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% Max ClientId Length Allowed.
|
||||||
|
{mqtt_max_clientid_len, 512}.
|
||||||
|
|
||||||
|
%% Max Packet Size Allowed, 64K by default.
|
||||||
|
{mqtt_max_packet_size, 65536}.
|
||||||
|
|
||||||
|
%% Client Idle Timeout.
|
||||||
|
{mqtt_client_idle_timeout, 30}. % Second
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Authentication
|
%% Authentication
|
||||||
|
@ -11,7 +35,7 @@
|
||||||
{auth, username, [{passwd, "etc/passwd.conf"}, {passwd_hash, plain}]}.
|
{auth, username, [{passwd, "etc/passwd.conf"}, {passwd_hash, plain}]}.
|
||||||
|
|
||||||
%% Authentication with clientId
|
%% Authentication with clientId
|
||||||
{auth, clientid, [{clients, "etc/client.config"}, {password, no}]}.
|
{auth, clientid, [{config, "etc/client.config"}, {password, no}]}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% ACL
|
%% ACL
|
||||||
|
@ -42,20 +66,7 @@
|
||||||
{retained_max_playload_size, 65536}.
|
{retained_max_playload_size, 65536}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% MQTT Protocol
|
%% Session
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
|
|
||||||
%% Max ClientId Length Allowed.
|
|
||||||
{mqtt_max_clientid_len, 512}.
|
|
||||||
|
|
||||||
%% Max Packet Size Allowed, 64K by default.
|
|
||||||
{mqtt_max_packet_size, 65536}.
|
|
||||||
|
|
||||||
%% Socket Idle Timeout.
|
|
||||||
{mqtt_client_idle_timeout, 30}. % Seconds
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%% MQTT Session
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
%% Max number of QoS 1 and 2 messages that can be “inflight” at one time.
|
%% Max number of QoS 1 and 2 messages that can be “inflight” at one time.
|
||||||
|
@ -101,7 +112,13 @@
|
||||||
{queue_qos0, true}.
|
{queue_qos0, true}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Listeners
|
%% Zone
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
{zone, admin, []}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Listener
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
%% Plain MQTT
|
%% Plain MQTT
|
||||||
|
@ -112,6 +129,9 @@
|
||||||
%% Maximum number of concurrent clients
|
%% Maximum number of concurrent clients
|
||||||
{max_clients, 512},
|
{max_clients, 512},
|
||||||
|
|
||||||
|
%% Mount point prefix
|
||||||
|
%% {mount_point, "prefix/"},
|
||||||
|
|
||||||
%% Socket Access Control
|
%% Socket Access Control
|
||||||
{access, [{allow, all}]},
|
{access, [{allow, all}]},
|
||||||
|
|
||||||
|
@ -132,7 +152,7 @@
|
||||||
]}
|
]}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
%% MQTT SSL
|
%% MQTT/SSL
|
||||||
{listener, mqtts, 8883, [
|
{listener, mqtts, 8883, [
|
||||||
%% Size of acceptor pool
|
%% Size of acceptor pool
|
||||||
{acceptors, 4},
|
{acceptors, 4},
|
||||||
|
@ -179,8 +199,12 @@
|
||||||
%% PubSub and Router. Default should be scheduler numbers.
|
%% PubSub and Router. Default should be scheduler numbers.
|
||||||
{pubsub_pool_size, 8}.
|
{pubsub_pool_size, 8}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Routing
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
%% Route aging time(seconds)
|
%% Route aging time(seconds)
|
||||||
{pubsub_routing_age, 5}.
|
{routing_age, 5}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Bridge
|
%% Bridge
|
||||||
|
@ -196,35 +220,22 @@
|
||||||
%% Plugins
|
%% Plugins
|
||||||
%%-------------------------------------------------------------------
|
%%-------------------------------------------------------------------
|
||||||
|
|
||||||
%% Plugins Dir
|
|
||||||
{plugins_dir, "./plugins"}.
|
|
||||||
|
|
||||||
%% File to store loaded plugin names.
|
%% File to store loaded plugin names.
|
||||||
{plugins_loaded_file, "./data/loaded_plugins"}.
|
{plugins_loaded_file, "data/loaded_plugins"}.
|
||||||
|
|
||||||
%%-------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Modules
|
%% Modules
|
||||||
%%-------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
%% Client presence management module. Publish presence messages when client connected or disconnected
|
%% Client presence management module. Publish presence messages when
|
||||||
|
%% client connected or disconnected.
|
||||||
{module, presence, [{qos, 0}]}.
|
{module, presence, [{qos, 0}]}.
|
||||||
|
|
||||||
%% Subscribe topics automatically when client connected
|
%% Subscribe topics automatically when client connected
|
||||||
{module, subscription, [{"$queue/clients/$c", 1}, backend]}.
|
{module, subscription, [{"$queue/clients/$c", 1}, backend]}.
|
||||||
|
|
||||||
%% [Rewrite](https://github.com/emqtt/emqttd/wiki/Rewrite)
|
%% [Rewrite](https://github.com/emqtt/emqttd/wiki/Rewrite)
|
||||||
{module, rewrite, [
|
{module, rewrite, [{config, "etc/rewrite.conf"}]}.
|
||||||
|
|
||||||
%{topic, "x/#", [
|
|
||||||
% {rewrite, "^x/y/(.+)$", "z/y/$1"},
|
|
||||||
% {rewrite, "^x/(.+)$", "y/$1"}
|
|
||||||
%]},
|
|
||||||
|
|
||||||
%{topic, "y/+/z/#", [
|
|
||||||
% {rewrite, "^y/(.+)/z/(.+)$", "y/z/$2"}
|
|
||||||
%]}
|
|
||||||
|
|
||||||
]}.
|
|
||||||
|
|
||||||
%%-------------------------------------------------------------------
|
%%-------------------------------------------------------------------
|
||||||
%% Erlang System Monitor
|
%% Erlang System Monitor
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% [Rewrite](https://github.com/emqtt/emqttd/wiki/Rewrite)
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
%{topic, "x/#", [
|
||||||
|
% {rewrite, "^x/y/(.+)$", "z/y/$1"},
|
||||||
|
% {rewrite, "^x/(.+)$", "y/$1"}
|
||||||
|
%]}.
|
||||||
|
|
||||||
|
%{topic, "y/+/z/#", [
|
||||||
|
% {rewrite, "^y/(.+)/z/(.+)$", "y/z/$2"}
|
||||||
|
%]}.
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
|
||||||
|
%% ex: ft=erlang ts=4 sw=4 et
|
||||||
|
|
||||||
|
%% Platform-specific installation paths
|
||||||
|
{platform_bin_dir, "./bin"}.
|
||||||
|
{platform_data_dir, "./data"}.
|
||||||
|
{platform_etc_dir, "./etc"}.
|
||||||
|
{platform_lib_dir, "./lib"}.
|
||||||
|
{platform_log_dir, "./log"}.
|
||||||
|
|
||||||
|
%%
|
||||||
|
%% bin/emqttd
|
||||||
|
%%
|
||||||
|
%% {runner_script_dir, "$(cd ${0%/*} && pwd)"}.
|
||||||
|
{runner_base_dir, "${RUNNER_SCRIPT_DIR%/*}"}.
|
||||||
|
{runner_etc_dir, "$RUNNER_BASE_DIR/etc"}.
|
||||||
|
{runner_log_dir, "$RUNNER_BASE_DIR/log"}.
|
||||||
|
{pipe_dir, "/tmp/$RUNNER_SCRIPT/"}.
|
||||||
|
{runner_user, ""}.
|
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
{release, {emqttd, "2.0"}, [
|
||||||
|
sasl,
|
||||||
|
os_mon,
|
||||||
|
runtime_tools,
|
||||||
|
{mnesia, load},
|
||||||
|
emqttd
|
||||||
|
]}.
|
||||||
|
|
||||||
|
{include_src, false}.
|
||||||
|
|
||||||
|
{extended_start_script, false}.
|
||||||
|
|
||||||
|
{sys_config, "rel/sys.config"}.
|
||||||
|
|
||||||
|
{vm_args, "rel/vm.args"}.
|
||||||
|
|
||||||
|
{overlay_vars, "./rel/vars.config"}.
|
||||||
|
|
||||||
|
{overlay, [
|
||||||
|
{mkdir, "etc/"},
|
||||||
|
{mkdir, "etc/ssl/"},
|
||||||
|
{mkdir, "data/"},
|
||||||
|
{mkdir, "data/mnesia"},
|
||||||
|
{mkdir, "log/"},
|
||||||
|
{copy, "etc/ssl/ssl.crt", "etc/ssl/ssl.crt"},
|
||||||
|
{copy, "etc/ssl/ssl.key", "etc/ssl/ssl.key"},
|
||||||
|
|
||||||
|
{template, "bin/emqttd", "bin/emqttd"},
|
||||||
|
{template, "bin/emqttd_ctl", "bin/emqttd_ctl"},
|
||||||
|
{copy, "bin/nodetool", "bin/nodetool"},
|
||||||
|
{copy, "bin/nodetool", "erts-\{\{erts_vsn\}\}/bin/nodetool"},
|
||||||
|
{copy, "bin/install_upgrade_escript", "bin/install_upgrade_escript"},
|
||||||
|
|
||||||
|
{template, "etc/acl.conf", "etc/acl.conf"},
|
||||||
|
{template, "etc/client.conf", "etc/client.conf"},
|
||||||
|
{template, "etc/emqttd.conf", "etc/emqttd.conf"},
|
||||||
|
{template, "etc/passwd.conf", "etc/passwd.conf"},
|
||||||
|
{template, "etc/rewrite.conf", "etc/rewrite.conf"}
|
||||||
|
]}.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
{id, "emqttd"},
|
{id, "emqttd"},
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{applications, [kernel, stdlib, gproc, esockd, mochiweb]},
|
{applications, [kernel, stdlib, gproc, esockd, mochiweb, gen_logger, gen_conf]},
|
||||||
{mod, {emqttd_app, []}},
|
{mod, {emqttd_app, []}},
|
||||||
{env, []}
|
{env, []}
|
||||||
]}.
|
]}.
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
%% Client State
|
%% Client State
|
||||||
-record(client_state, {connection, connname, peername, peerhost, peerport,
|
-record(client_state, {connection, connname, peername, peerhost, peerport,
|
||||||
await_recv, conn_state, rate_limit, parser_fun,
|
await_recv, conn_state, rate_limit, parser_fun,
|
||||||
proto_state, packet_opts, keepalive}).
|
proto_state, packet_opts, keepalive, mountpoint}).
|
||||||
|
|
||||||
-define(INFO_KEYS, [peername, peerhost, peerport, await_recv, conn_state]).
|
-define(INFO_KEYS, [peername, peerhost, peerport, await_recv, conn_state]).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue