From 822a4f9f73e12484b4b33b8ed8e0672d3bc161c8 Mon Sep 17 00:00:00 2001 From: "Zaiming (Stone) Shi" Date: Tue, 5 Apr 2022 15:41:01 +0200 Subject: [PATCH] feat: parameterise EMQX_ETC_DIR both at build time and at runtime --- apps/emqx/src/emqx.erl | 28 +++++++++++++++++-- apps/emqx/src/emqx_tls_lib.erl | 2 +- apps/emqx_exhook/src/emqx_exhook_api.erl | 11 ++++---- apps/emqx_gateway/src/emqx_gateway_api.erl | 4 +-- .../src/emqx_gateway_api_listeners.erl | 18 ++++++------ apps/emqx_gateway/src/emqx_gateway_schema.erl | 2 +- .../emqx_plugin_libs/src/emqx_plugin_libs.erl | 1 - bin/emqx | 7 +++++ bin/emqx.cmd | 1 + build | 2 ++ 10 files changed, 55 insertions(+), 21 deletions(-) diff --git a/apps/emqx/src/emqx.erl b/apps/emqx/src/emqx.erl index c31ba3d6d..2c3f4d1c5 100644 --- a/apps/emqx/src/emqx.erl +++ b/apps/emqx/src/emqx.erl @@ -69,7 +69,9 @@ remove_config/2, reset_config/2, data_dir/0, - certs_dir/0 + etc_file/1, + cert_file/1, + mutable_certs_dir/0 ]). -define(APP, ?MODULE). @@ -253,8 +255,30 @@ reset_config([RootName | _] = KeyPath, Opts) -> Error end. +%% @doc Returns the data directory which is set at boot time. data_dir() -> application:get_env(emqx, data_dir, "data"). -certs_dir() -> +%% @doc Returns the directory for user uploaded certificates. +mutable_certs_dir() -> filename:join([data_dir(), certs]). + +%% @doc Returns the absolute path for a PEM certificate file +%% which is installed or provisioned by sysadmin in $EMQX_ETC_DIR/certs. +cert_file(SubPath) -> + filename:join([etc_dir(), "certs", SubPath]). + +%% @doc Returns the absolute path for a file in EMQX's etc dir. +%% i.e. for rpm and deb installation, it's /etc/emqx/ +%% for other installation, it's /etc/ +etc_file(SubPath) -> + filename:join([etc_dir(), SubPath]). + +etc_dir() -> + %% EMQX_ETC_DIR is inherited from RUNNER_ETC_DIR which is set at package build time. + %% when it's not set, it's most likely when running test cases. + Env = os:getenv("EMQX_ETC_DIR"), + case Env =:= "" orelse Env =:= false of + true -> "etc"; + false -> Env + end. diff --git a/apps/emqx/src/emqx_tls_lib.erl b/apps/emqx/src/emqx_tls_lib.erl index f6fba3bfc..9b049f74f 100644 --- a/apps/emqx/src/emqx_tls_lib.erl +++ b/apps/emqx/src/emqx_tls_lib.erl @@ -389,7 +389,7 @@ pem_file_name(Dir, Key, Pem) -> <> = crypto:hash(md5, Pem), Suffix = hex_str(CK), FileName = binary:replace(Key, <<"file">>, <<"-", Suffix/binary>>), - filename:join([emqx:certs_dir(), Dir, FileName]). + filename:join([emqx:mutable_certs_dir(), Dir, FileName]). hex_str(Bin) -> iolist_to_binary([io_lib:format("~2.16.0b", [X]) || <> <= Bin]). diff --git a/apps/emqx_exhook/src/emqx_exhook_api.erl b/apps/emqx_exhook/src/emqx_exhook_api.erl index bd4cb62e6..2a3ae8c84 100644 --- a/apps/emqx_exhook/src/emqx_exhook_api.erl +++ b/apps/emqx_exhook/src/emqx_exhook_api.erl @@ -171,6 +171,11 @@ params_server_name_in_path() -> ]. server_conf_schema() -> + SSL = #{ enable => false + , cacertfile => emqx:cert_file(<<"cacert.pem">>) + , certfile => emqx:cert_file(<<"cert.pem">>) + , keyfile => emqx:cert_file(<<"key.pem">>) + }, schema_with_example(ref(server_config), #{ name => "default" , enable => true @@ -179,11 +184,7 @@ server_conf_schema() -> , failed_action => deny , auto_reconnect => "60s" , pool_size => 8 - , ssl => #{ enable => false - , cacertfile => <<"{{ platform_etc_dir }}/certs/cacert.pem">> - , certfile => <<"{{ platform_etc_dir }}/certs/cert.pem">> - , keyfile => <<"{{ platform_etc_dir }}/certs/key.pem">> - } + , ssl => SSL }). %%-------------------------------------------------------------------- diff --git a/apps/emqx_gateway/src/emqx_gateway_api.erl b/apps/emqx_gateway/src/emqx_gateway_api.erl index c69b8e13a..771a2879c 100644 --- a/apps/emqx_gateway/src/emqx_gateway_api.erl +++ b/apps/emqx_gateway/src/emqx_gateway_api.erl @@ -600,7 +600,7 @@ examples_gateway_confs() -> enable_stats => true, idle_timeout => <<"30s">>, mountpoint => <<"lwm2m/">>, - xml_dir => <<"etc/lwm2m_xml">>, + xml_dir => emqx:etc_file(<<"lwm2m_xml">>), lifetime_min => <<"1s">>, lifetime_max => <<"86400s">>, qmode_time_window => <<"22s">>, @@ -719,7 +719,7 @@ examples_update_gateway_confs() -> enable_stats => true, idle_timeout => <<"30s">>, mountpoint => <<"lwm2m2/">>, - xml_dir => <<"etc/lwm2m_xml">>, + xml_dir => emqx:etc_file(<<"lwm2m_xml">>), lifetime_min => <<"1s">>, lifetime_max => <<"86400s">>, qmode_time_window => <<"22s">>, diff --git a/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl b/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl index d5f2c9f20..44d938c60 100644 --- a/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl +++ b/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl @@ -833,9 +833,9 @@ examples_listener() -> <<"tlsv1.1">>, <<"tlsv1">> ], - cacertfile => <<"etc/certs/cacert.pem">>, - certfile => <<"etc/certs/cert.pem">>, - keyfile => <<"etc/certs/key.pem">>, + cacertfile => emqx:cert_file(<<"cacert.pem">>), + certfile => emqx:cert_file(<<"cert.pem">>), + keyfile => emqx:cert_file(<<"key.pem">>), verify => <<"verify_none">>, fail_if_no_peer_cert => false }, @@ -879,9 +879,9 @@ examples_listener() -> dtls => #{ versions => [<<"dtlsv1.2">>, <<"dtlsv1">>], - cacertfile => <<"etc/certs/cacert.pem">>, - certfile => <<"etc/certs/cert.pem">>, - keyfile => <<"etc/certs/key.pem">>, + cacertfile => emqx:cert_file(<<"cacert.pem">>), + certfile => emqx:cert_file(<<"cert.pem">>), + keyfile => emqx:cert_file(<<"key.pem">>), verify => <<"verify_none">>, fail_if_no_peer_cert => false }, @@ -906,9 +906,9 @@ examples_listener() -> dtls => #{ versions => [<<"dtlsv1.2">>, <<"dtlsv1">>], - cacertfile => <<"etc/certs/cacert.pem">>, - certfile => <<"etc/certs/cert.pem">>, - keyfile => <<"etc/certs/key.pem">>, + cacertfile => emqx:cert_file(<<"cacert.pem">>), + certfile => emqx:cert_file(<<"cert.pem">>), + keyfile => emqx:cert_file(<<"key.pem">>), verify => <<"verify_none">>, user_lookup_fun => <<"emqx_tls_psk:lookup">>, ciphers => diff --git a/apps/emqx_gateway/src/emqx_gateway_schema.erl b/apps/emqx_gateway/src/emqx_gateway_schema.erl index 3c28e5328..0f64fecfc 100644 --- a/apps/emqx_gateway/src/emqx_gateway_schema.erl +++ b/apps/emqx_gateway/src/emqx_gateway_schema.erl @@ -290,7 +290,7 @@ fields(lwm2m) -> sc( binary(), #{ - default => "etc/lwm2m_xml", + default => emqx:etc_file("lwm2m_xml"), required => true, desc => "The Directory for LwM2M Resource definition" } diff --git a/apps/emqx_plugin_libs/src/emqx_plugin_libs.erl b/apps/emqx_plugin_libs/src/emqx_plugin_libs.erl index d8cd1ab12..4edc24beb 100644 --- a/apps/emqx_plugin_libs/src/emqx_plugin_libs.erl +++ b/apps/emqx_plugin_libs/src/emqx_plugin_libs.erl @@ -15,4 +15,3 @@ %%-------------------------------------------------------------------- -module(emqx_plugin_libs). - diff --git a/bin/emqx b/bin/emqx index 1cfc36481..6708739c4 100755 --- a/bin/emqx +++ b/bin/emqx @@ -19,6 +19,13 @@ export RUNNER_ETC_DIR export REL_VSN export SCHEMA_MOD +# RUNNER_ETC_DIR is only used at boot time +# EMQX_ETC_DIR is by default RUNNER_ETC_DIR but the absolute path +# it is used at runtime by the emqx program +# so that it won't change even if file:set_cwd is evaluated by EMQX later +EMQX_ETC_DIR="${EMQX_ETC_DIR:-$(cd "$(readlink "$RUNNER_ETC_DIR")"; pwd -P)}" +export EMQX_ETC_DIR + RUNNER_SCRIPT="$RUNNER_BIN_DIR/$REL_NAME" CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}" REL_DIR="$RUNNER_ROOT_DIR/releases/$REL_VSN" diff --git a/bin/emqx.cmd b/bin/emqx.cmd index 0777536e1..e64cae494 100644 --- a/bin/emqx.cmd +++ b/bin/emqx.cmd @@ -48,6 +48,7 @@ @set "RUNNER_ROOT_DIR=%rel_root_dir%" :: hard code etc dir @set "RUNNER_ETC_DIR=%rel_root_dir%\etc" +@set "EMQX_ETC_DIR=%rel_root_dir%\etc" @set "etc_dir=%rel_root_dir%\etc" @set "lib_dir=%rel_root_dir%\lib" @set "emqx_conf=%etc_dir%\emqx.conf" diff --git a/build b/build index e84609b23..421fdd6bd 100755 --- a/build +++ b/build @@ -281,6 +281,8 @@ case "$ARTIFACT" in make_tgz ;; pkg) + # this only affect build artifacts, such as schema doc + export EMQX_ETC_DIR='/etc/emqx/' if [ -z "${PKGERDIR:-}" ]; then log "Skipped making deb/rpm package for $SYSTEM" exit 0