| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- #!/usr/bin/env bash
- set -euo pipefail
- usage() {
- cat <<EOF
- Run EMQX without building a release (which takes longer time).
- USAGE: $0 [OPTION]
- OPTIONS:
- -h Print this help usage info.
- -p 'emqx' or 'emqx-enterprise', defaults to 'PROFILE' env.
- -c Force recompile, otherwise starts with the already built libs
- in '_build/\$PROFILE/lib/'.
- ENVIRONMENT VARIABLES:
- PROFILE: Overriden by -p option, defaults to 'emqx'.
- EMQX_NODE_NAME: The node name of the EMQX node. Default to emqx@127.0.0.1'.
- EOF
- }
- if [ -n "${DEBUG:-}" ]; then
- set -x
- fi
- export HOCON_ENV_OVERRIDE_PREFIX='EMQX_'
- EMQX_NODE_NAME="${EMQX_NODE_NAME:-emqx@127.0.0.1}"
- PROFILE="${PROFILE:-emqx}"
- FORCE_COMPILE=0
- while getopts ":p:ch" opt; do
- case "${opt}" in
- h)
- usage
- exit 0
- ;;
- p)
- PROFILE="${OPTARG}"
- ;;
- c)
- FORCE_COMPILE=1
- ;;
- \?)
- echo "Invalid option: -$OPTARG" >&2
- exit 1
- ;;
- :)
- echo "Option -$OPTARG requires an argument." >&2
- exit 1
- ;;
- esac
- done
- shift $((OPTIND-1))
- case "${PROFILE}" in
- ce|emqx)
- PROFILE='emqx'
- ;;
- ee|emqx-enterprise)
- PROFILE='emqx-enterprise'
- ;;
- *)
- echo "Unknown profile $PROFILE"
- exit 1
- ;;
- esac
- export PROFILE
- case "${PROFILE}" in
- emqx)
- SCHEMA_MOD='emqx_conf_schema'
- ;;
- emqx-enterprise)
- SCHEMA_MOD='emqx_ee_conf_schema'
- ;;
- esac
- PROJ_ROOT="$(git rev-parse --show-toplevel)"
- cd "$PROJ_ROOT"
- BASE_DIR="_build/dev-run/$PROFILE"
- export EMQX_ETC_DIR="$BASE_DIR/etc"
- export EMQX_DATA_DIR="$BASE_DIR/data"
- export EMQX_LOG_DIR="$BASE_DIR/log"
- CONFIGS_DIR="$EMQX_DATA_DIR/configs"
- COOKIE='emqxsecretcookie'
- mkdir -p "$EMQX_ETC_DIR" "$EMQX_DATA_DIR/patches" "$EMQX_LOG_DIR" "$CONFIGS_DIR"
- ## build compile the profile is it's not compiled yet
- prepare_erl_libs() {
- local profile="$1"
- local libs_dir="_build/${profile}/lib"
- local erl_libs=''
- if [ $FORCE_COMPILE -eq 1 ] || [ ! -d "$libs_dir" ]; then
- make "compile-${PROFILE}"
- else
- echo "Running from code in $libs_dir"
- fi
- for app in "${libs_dir}"/*; do
- erl_libs="${erl_libs}:${app}"
- done
- export ERL_LIBS="$erl_libs"
- }
- ## poorman's mustache templating
- mustache() {
- local name="$1"
- local value="$2"
- local file="$3"
- sed -i "s|{{\s*${name}\s*}}|${value}|g" "$file"
- }
- ## render the merged boot conf file.
- ## the merge action is done before the profile is compiled
- render_hocon_conf() {
- input="apps/emqx_conf/etc/emqx.conf.all"
- output="$EMQX_ETC_DIR/emqx.conf"
- cp "$input" "$output"
- mustache emqx_default_erlang_cookie "$COOKIE" "$output"
- mustache platform_data_dir "${EMQX_DATA_DIR}" "$output"
- mustache platform_log_dir "${EMQX_LOG_DIR}" "$output"
- mustache platform_etc_dir "${EMQX_ETC_DIR}" "$output"
- }
- call_hocon() {
- local in=("$@")
- local args=''
- for arg in "${in[@]}"; do
- if [ -z "$args" ]; then
- args="\"$arg\""
- else
- args="$args, \"$arg\""
- fi
- done
- erl -noshell -eval "{ok, _} = application:ensure_all_started(hocon), ok = hocon_cli:main([$args]), init:stop()."
- }
- # Function to generate app.config and vm.args
- # sets two environment variables CONF_FILE and ARGS_FILE
- generate_app_conf() {
- ## timestamp for each generation
- local NOW_TIME
- NOW_TIME="$(date +'%Y.%m.%d.%H.%M.%S')"
- ## this command populates two files: app.<time>.config and vm.<time>.args
- ## NOTE: the generate command merges environment variables to the base config (emqx.conf),
- ## but does not include the cluster-override.conf and local-override.conf
- ## meaning, certain overrides will not be mapped to app.<time>.config file
- call_hocon -v -t "$NOW_TIME" -s "$SCHEMA_MOD" -c "$EMQX_ETC_DIR"/emqx.conf -d "$EMQX_DATA_DIR"/configs generate
- ## filenames are per-hocon convention
- CONF_FILE="$CONFIGS_DIR/app.$NOW_TIME.config"
- ARGS_FILE="$CONFIGS_DIR/vm.$NOW_TIME.args"
- }
- # apps/emqx/etc/vm.args.cloud
- append_args_file() {
- ## ensure a new line at the end
- echo '' >> "$ARGS_FILE"
- cat <<EOF >> "$ARGS_FILE"
- -name $EMQX_NODE_NAME
- -mnesia dir '"$EMQX_DATA_DIR/mnesia/$EMQX_NODE_NAME"'
- -stdlib restricted_shell emqx_restricted_shell
- +spp true
- +A 4
- +IOt 4
- +SDio 8
- -shutdown_time 30000
- -pa '"$EMQX_DATA_DIR/patches"'
- -mnesia dump_log_write_threshold 5000
- -mnesia dump_log_time_threshold 60000
- -os_mon start_disksup false
- EOF
- }
- # copy cert files and acl.conf to etc
- copy_other_conf_files() {
- cp -r apps/emqx/etc/certs "$EMQX_ETC_DIR"/
- cp apps/emqx_authz/etc/acl.conf "$EMQX_ETC_DIR"/
- }
- is_current_profile_app() {
- local app="$1"
- case "$app" in
- lib-ee*)
- if [ "$PROFILE" = 'emqx-enterprise' ]; then
- return 0
- else
- return 1
- fi
- ;;
- *)
- if [ "$PROFILE" = 'emqx' ]; then
- if [ -f "$app"/BSL.txt ]; then
- return 1
- else
- return 0
- fi
- else
- return 0
- fi
- ;;
- esac
- }
- ## apps to load
- apps_to_load() {
- local apps csl
- apps="$(./scripts/find-apps.sh | xargs)"
- csl=""
- for app in $apps; do
- if ! is_current_profile_app "$app"; then
- continue
- fi
- name="$(basename "$app")"
- if [ -z "$csl" ]; then
- csl="$name"
- else
- csl="$csl,$name"
- fi
- done
- echo "$csl"
- }
- ## Make erl command aware where to load all the beams
- ## this should be done before every erl command
- prepare_erl_libs "$PROFILE"
- render_hocon_conf
- generate_app_conf
- append_args_file
- copy_other_conf_files
- APPS="$(apps_to_load)"
- BOOT_SEQUENCE="
- Apps=[${APPS}],
- ok=lists:foreach(fun application:load/1, Apps),
- io:format(user, \"~nLoaded ~p apps~n\", [length(Apps)]),
- application:ensure_all_started(emqx_machine).
- "
- erl -name "$EMQX_NODE_NAME" \
- -start_epmd false \
- -epmd_module ekka_epmd \
- -proto_dist ekka \
- -args_file "$ARGS_FILE" \
- -config "$CONF_FILE" \
- -s emqx_restricted_shell set_prompt_func \
- -eval "$BOOT_SEQUENCE"
|