Prechádzať zdrojové kódy

feat(boot): make possible to boot on short name

Zaiming Shi 4 rokov pred
rodič
commit
d68589e0cb
4 zmenil súbory, kde vykonal 79 pridanie a 88 odobranie
  1. 3 1
      apps/emqx/src/emqx_schema.erl
  2. 38 53
      bin/emqx
  3. 32 30
      bin/emqx_ctl
  4. 6 4
      bin/nodetool

+ 3 - 1
apps/emqx/src/emqx_schema.erl

@@ -156,7 +156,9 @@ fields("rlog") ->
     ];
 
 fields("node") ->
-    [ {"name", t(string(), "vm_args.-name", "emqx@127.0.0.1", "EMQX_NODE_NAME")}
+    [ {"name", hoconsc:t(string(), #{default => "emqx@127.0.0.1",
+                                     override_env => "EMQX_NODE_NAME"
+                                    })}
     , {"cookie", hoconsc:t(string(), #{mapping => "vm_args.-setcookie",
                                        default => "emqxsecretcookie",
                                        sensitive => true,

+ 38 - 53
bin/emqx

@@ -167,11 +167,6 @@ relx_get_pid() {
     fi
 }
 
-relx_get_nodename() {
-    id="longname$(relx_gen_id)-${NAME}"
-    "$BINDIR/erl" -boot "$REL_DIR/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
@@ -227,6 +222,8 @@ relx_start_command() {
 
 # Function to generate app.config and vm.args
 generate_config() {
+    local name_type="$1"
+    local node_name="$2"
     ## Delete the *.siz files first or it cann't start after
     ## changing the config 'log.rotation.size'
     rm -rf "${RUNNER_LOG_DIR}"/*.siz
@@ -277,6 +274,7 @@ generate_config() {
             fi
         fi
     done
+    echo "$name_type $node_name" >> "$TMP_ARG_FILE"
     ## rename the generated vm.<time>.args file
     mv -f "$TMP_ARG_FILE" "$HOCON_GEN_ARG_FILE"
 
@@ -315,43 +313,43 @@ case "$1" in
         ;;
 esac
 
-
-if [ -z "$NAME_ARG" ]; then
-    NODENAME="${EMQX_NODE_NAME:-}"
-    # compatible with docker entrypoint
-    [ -z "$NODENAME" ] && [ -n "$EMQX_NAME" ] && [ -n "$EMQX_HOST" ] && NODENAME="${EMQX_NAME}@${EMQX_HOST}"
-    if [ -z "$NODENAME" ]; then
-        if [ "$IS_BOOT_COMMAND" = 'no' ]; then
-            # for non-boot commands, inspect vm.<time>.args for node name
-            # shellcheck disable=SC2012,SC2086
-            LATEST_VM_ARGS="$(ls -t $CONFIGS_DIR/vm.*.args | head -1)"
-            if [ -z "$LATEST_VM_ARGS" ]; then
-                echo "For command $1, there is no vm.*.args config file found in $CONFIGS_DIR/"
-                exit 1
-            fi
-            NODENAME="$(grep -E '^-name' "$LATEST_VM_ARGS" | awk '{print $2}')"
-        else
-            # for boot commands, inspect emqx.conf for node name
-            NODENAME="$(call_hocon -s emqx_schema -c "$RUNNER_ETC_DIR"/emqx.conf get node.name | tr -d \")"
-        fi
-    fi
-    if [ -z "$NODENAME" ]; then
-        echoerr "Failed to resolve emqx node name"
-        if [ "$IS_BOOT_COMMAND" = 'yes' ]; then
-            echoerr "Make sure runner has read permission on '$RUNNER_ETC_DIR/emqx.conf'"
+## Possible ways to configure emqx node name:
+## 1. configure node.name in emqx.conf
+## 2. override with environment variable EMQX_NODE_NAME
+## 3. override with environment variable EMQX_NAME and EMQX_HOST (deprecated)
+## Node name is either short-name (without '@'), e.g. 'emqx'
+## or long name (with '@') e.g. 'emqx@example.net' or 'emqx@127.0.0.1'
+NAME="${EMQX_NODE_NAME:-}"
+# to be backward compatible
+[ -n "$EMQX_NAME" ] && [ -n "$EMQX_HOST" ] && NAME="${EMQX_NAME}@${EMQX_HOST}"
+if [ -z "$NAME" ]; then
+    if [ "$IS_BOOT_COMMAND" = 'no' ]; then
+        # for non-boot commands, inspect vm.<time>.args for node name
+        # shellcheck disable=SC2012,SC2086
+        LATEST_VM_ARGS="$(ls -t $CONFIGS_DIR/vm.*.args | head -1)"
+        if [ -z "$LATEST_VM_ARGS" ]; then
+            echoerr "For command $1, there is no vm.*.args file found in $CONFIGS_DIR/"
+            exit 1
         fi
-        echoerr "Maybe override node name with environment variable ENQX_NODE_NAME='name@host.name'"
-        echoerr "or, EMQX_NAME='name' and EMQX_HOST='host.name'"
-        exit 1
+        NAME="$(grep -E '^-s?name' "$LATEST_VM_ARGS" | awk '{print $2}')"
+    else
+        # for boot commands, inspect emqx.conf for node name
+        NAME="$(call_hocon -s emqx_schema -c "$RUNNER_ETC_DIR"/emqx.conf get node.name | tr -d \")"
     fi
-    NAME_ARG="-name ${NODENAME# *}"
 fi
 
-# 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}')"
-NODENAME="$(echo "$NAME" | awk -F'@' '{print $1}')"
-export ESCRIPT_NAME="$NODENAME"
+# force to use 'emqx' short name
+[ -z "$NAME" ] && NAME='emqx'
+
+case "$NAME" in
+    *@*)
+        NAME_TYPE='-name'
+       ;;
+    *)
+        NAME_TYPE='-sname'
+esac
+SHORT_NAME="$(echo "$NAME" | awk -F'@' '{print $1}')"
+export ESCRIPT_NAME="$SHORT_NAME"
 
 PIPE_DIR="${PIPE_DIR:-/$RUNNER_DATA_DIR/${WHOAMI}_erl_pipes/$NAME/}"
 
@@ -384,19 +382,6 @@ fi
 
 cd "$ROOTDIR"
 
-# User can specify an sname without @hostname
-# This will fail when creating remote shell
-# So here we check for @ and add @hostname if missing
-case $NAME in
-    *@*)
-        # Nothing to do
-        ;;
-    *)
-        NAME=$NAME@$(relx_get_nodename)
-        ;;
-esac
-
-# Check the first argument for instructions
 case "$1" in
     start|start_boot)
         # Make sure a node IS not running
@@ -596,7 +581,7 @@ case "$1" in
         fi
 
         #generate app.config and vm.args
-        generate_config
+        generate_config "$NAME_TYPE" "$NAME"
 
         # Setup beam-required vars
         EMU="beam"
@@ -639,7 +624,7 @@ case "$1" in
         export EMQX_LOG__CONSOLE_HANDLER__ENABLE="${EMQX_LOG__CONSOLE_HANDLER__ENABLE:-true}"
 
         #generate app.config and vm.args
-        generate_config
+        generate_config "$NAME_TYPE" "$NAME"
 
         [ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start
         FOREGROUNDOPTIONS="-noshell -noinput +Bd"

+ 32 - 30
bin/emqx_ctl

@@ -8,6 +8,10 @@ ROOT_DIR="$(cd "$(dirname "$(readlink "$0" || echo "$0")")"/..; pwd -P)"
 # shellcheck disable=SC1090
 . "$ROOT_DIR"/releases/emqx_vars
 
+export ROOTDIR="$RUNNER_ROOT_DIR"
+export ERTS_DIR="$ROOTDIR/erts-$ERTS_VSN"
+export BINDIR="$ERTS_DIR/bin"
+
 export RUNNER_ROOT_DIR
 export REL_VSN
 
@@ -27,11 +31,22 @@ else
     EPMD_ARG="-start_epmd true"
 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"
+call_hocon() {
+    export RUNNER_ROOT_DIR
+    export RUNNER_ETC_DIR
+    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" hocon "$@" \
+        || die "ERROR: call_hocon failed: $*" $?
 }
 
+# Support for IPv6 Dist. See: https://github.com/emqtt/emqttd/issues/1460
+PROTO_DIST="$(call_hocon -s emqx_schema -c "$RUNNER_ETC_DIR"/emqx.conf get cluster.proto_dist | tr -d \")"
+if [ -z "$PROTO_DIST" ]; then
+    PROTO_DIST_ARG=""
+else
+    PROTO_DIST_ARG="-proto_dist $PROTO_DIST"
+fi
+
+
 # Control a node
 relx_nodetool() {
     command="$1"; shift
@@ -41,23 +56,22 @@ relx_nodetool() {
                                 -setcookie "$COOKIE" "$command" "$@"
 }
 
-if [ -z "$NAME_ARG" ]; then
-    NODENAME="${EMQX_NODE_NAME:-}"
-    [ -z "$NODENAME" ] && [ -n "$EMQX_NAME" ] && [ -n "$EMQX_HOST" ] && NODENAME="${EMQX_NAME}@${EMQX_HOST}"
-    [ -z "$NODENAME" ] && NODENAME="$(grep -E '^-name' "$LATEST_VM_ARGS" | awk '{print $2}')"
-    if [ -z "$NODENAME" ]; then
-        echoerr "vm.args needs to have a -name parameter."
-        echoerr "  -sname is not supported."
-        echoerr "perhaps you do not have read permissions on $RUNNER_ETC_DIR/emqx.conf"
-        exit 1
-    else
-        NAME_ARG="-name ${NODENAME# *}"
-    fi
+NAME="${EMQX_NODE_NAME:-}"
+[ -n "$EMQX_NAME" ] && [ -n "$EMQX_HOST" ] && NAME="${EMQX_NAME}@${EMQX_HOST}"
+[ -z "$NAME" ] && NAME="$(grep -E '^-s?name' "$LATEST_VM_ARGS" | awk '{print $2}')"
+if [ -z "$NAME" ]; then
+    echoerr "Failed to read node name from $LATEST_VM_ARGS"
+    echoerr "Ensure the node is running and you have permission to read $LATEST_VM_ARGS"
+    exit 1
 fi
 
-# 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}')"
+case "$NAME" in
+    *@*)
+        NAME_TYPE='-name'
+       ;;
+    *)
+        NAME_TYPE='-sname'
+esac
 
 COOKIE="${EMQX_NODE_COOKIE:-}"
 [ -z "$COOKIE" ] && COOKIE="$(grep -E '^-setcookie' "$LATEST_VM_ARGS" | awk '{print $2}')"
@@ -66,18 +80,6 @@ if [ -z "$COOKIE" ]; then
     exit 1
 fi
 
-# Support for IPv6 Dist. See: https://github.com/emqtt/emqttd/issues/1460
-PROTO_DIST=$(grep -E '^[ \t]*cluster.proto_dist[ \t]*=[ \t]*' "$RUNNER_ETC_DIR"/emqx.conf 2> /dev/null | tail -1 | awk -F"= " '{print $NF}')
-if [ -z "$PROTO_DIST" ]; then
-    PROTO_DIST_ARG=""
-else
-    PROTO_DIST_ARG="-proto_dist $PROTO_DIST"
-fi
-
-export ROOTDIR="$RUNNER_ROOT_DIR"
-export ERTS_DIR="$ROOTDIR/erts-$ERTS_VSN"
-export BINDIR="$ERTS_DIR/bin"
 cd "$ROOTDIR"
 
 relx_nodetool rpc emqx_ctl run_command "$@"
-

+ 6 - 4
bin/nodetool

@@ -34,13 +34,13 @@ do(Args) ->
     ok = do_with_halt(Args, "chkconfig", fun chkconfig/1),
     Args1 = do_with_ret(Args, "-name",
                         fun(TargetName) ->
-                                ThisNode = this_node_name(TargetName),
+                                ThisNode = this_node_name(longnames, TargetName),
                                 {ok, _} = net_kernel:start([ThisNode, longnames]),
                                 put(target_node, nodename(TargetName))
                         end),
     Args2 = do_with_ret(Args1, "-sname",
                         fun(TargetName) ->
-                                ThisNode = this_node_name(TargetName),
+                                ThisNode = this_node_name(shortnames, TargetName),
                                 {ok, _} = net_kernel:start([ThisNode, shortnames]),
                                 put(target_node, nodename(TargetName))
                         end),
@@ -209,9 +209,11 @@ nodename(Name) ->
             list_to_atom(lists:concat([Node, "@", Host]))
     end.
 
-this_node_name(Name) ->
+this_node_name(longnames, Name) ->
     [Node, Host] = re:split(Name, "@", [{return, list}, unicode]),
-    list_to_atom(lists:concat(["remsh_maint_", Node, os:getpid(), "@", Host])).
+    list_to_atom(lists:concat(["remsh_maint_", Node, os:getpid(), "@", Host]));
+this_node_name(shortnames, Name) ->
+    list_to_atom(lists:concat(["remsh_maint_", Name, os:getpid()])).
 
 %% For windows???
 create_mnesia_dir(DataDir, NodeName) ->