소스 검색

feat: parameterise EMQX_ETC_DIR

both at build time and at runtime
Zaiming (Stone) Shi 3 년 전
부모
커밋
822a4f9f73

+ 26 - 2
apps/emqx/src/emqx.erl

@@ -69,7 +69,9 @@
     remove_config/2,
     remove_config/2,
     reset_config/2,
     reset_config/2,
     data_dir/0,
     data_dir/0,
-    certs_dir/0
+    etc_file/1,
+    cert_file/1,
+    mutable_certs_dir/0
 ]).
 ]).
 
 
 -define(APP, ?MODULE).
 -define(APP, ?MODULE).
@@ -253,8 +255,30 @@ reset_config([RootName | _] = KeyPath, Opts) ->
             Error
             Error
     end.
     end.
 
 
+%% @doc Returns the data directory which is set at boot time.
 data_dir() ->
 data_dir() ->
     application:get_env(emqx, data_dir, "data").
     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]).
     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 <install_root>/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.

+ 1 - 1
apps/emqx/src/emqx_tls_lib.erl

@@ -389,7 +389,7 @@ pem_file_name(Dir, Key, Pem) ->
     <<CK:8/binary, _/binary>> = crypto:hash(md5, Pem),
     <<CK:8/binary, _/binary>> = crypto:hash(md5, Pem),
     Suffix = hex_str(CK),
     Suffix = hex_str(CK),
     FileName = binary:replace(Key, <<"file">>, <<"-", Suffix/binary>>),
     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) ->
 hex_str(Bin) ->
     iolist_to_binary([io_lib:format("~2.16.0b", [X]) || <<X:8>> <= Bin]).
     iolist_to_binary([io_lib:format("~2.16.0b", [X]) || <<X:8>> <= Bin]).

+ 6 - 5
apps/emqx_exhook/src/emqx_exhook_api.erl

@@ -171,6 +171,11 @@ params_server_name_in_path() ->
     ].
     ].
 
 
 server_conf_schema() ->
 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),
     schema_with_example(ref(server_config),
                         #{ name => "default"
                         #{ name => "default"
                          , enable => true
                          , enable => true
@@ -179,11 +184,7 @@ server_conf_schema() ->
                          , failed_action => deny
                          , failed_action => deny
                          , auto_reconnect => "60s"
                          , auto_reconnect => "60s"
                          , pool_size => 8
                          , 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
                          }).
                          }).
 
 
 %%--------------------------------------------------------------------
 %%--------------------------------------------------------------------

+ 2 - 2
apps/emqx_gateway/src/emqx_gateway_api.erl

@@ -600,7 +600,7 @@ examples_gateway_confs() ->
                         enable_stats => true,
                         enable_stats => true,
                         idle_timeout => <<"30s">>,
                         idle_timeout => <<"30s">>,
                         mountpoint => <<"lwm2m/">>,
                         mountpoint => <<"lwm2m/">>,
-                        xml_dir => <<"etc/lwm2m_xml">>,
+                        xml_dir => emqx:etc_file(<<"lwm2m_xml">>),
                         lifetime_min => <<"1s">>,
                         lifetime_min => <<"1s">>,
                         lifetime_max => <<"86400s">>,
                         lifetime_max => <<"86400s">>,
                         qmode_time_window => <<"22s">>,
                         qmode_time_window => <<"22s">>,
@@ -719,7 +719,7 @@ examples_update_gateway_confs() ->
                         enable_stats => true,
                         enable_stats => true,
                         idle_timeout => <<"30s">>,
                         idle_timeout => <<"30s">>,
                         mountpoint => <<"lwm2m2/">>,
                         mountpoint => <<"lwm2m2/">>,
-                        xml_dir => <<"etc/lwm2m_xml">>,
+                        xml_dir => emqx:etc_file(<<"lwm2m_xml">>),
                         lifetime_min => <<"1s">>,
                         lifetime_min => <<"1s">>,
                         lifetime_max => <<"86400s">>,
                         lifetime_max => <<"86400s">>,
                         qmode_time_window => <<"22s">>,
                         qmode_time_window => <<"22s">>,

+ 9 - 9
apps/emqx_gateway/src/emqx_gateway_api_listeners.erl

@@ -833,9 +833,9 @@ examples_listener() ->
                                     <<"tlsv1.1">>,
                                     <<"tlsv1.1">>,
                                     <<"tlsv1">>
                                     <<"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">>,
                                 verify => <<"verify_none">>,
                                 fail_if_no_peer_cert => false
                                 fail_if_no_peer_cert => false
                             },
                             },
@@ -879,9 +879,9 @@ examples_listener() ->
                         dtls =>
                         dtls =>
                             #{
                             #{
                                 versions => [<<"dtlsv1.2">>, <<"dtlsv1">>],
                                 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">>,
                                 verify => <<"verify_none">>,
                                 fail_if_no_peer_cert => false
                                 fail_if_no_peer_cert => false
                             },
                             },
@@ -906,9 +906,9 @@ examples_listener() ->
                         dtls =>
                         dtls =>
                             #{
                             #{
                                 versions => [<<"dtlsv1.2">>, <<"dtlsv1">>],
                                 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">>,
                                 verify => <<"verify_none">>,
                                 user_lookup_fun => <<"emqx_tls_psk:lookup">>,
                                 user_lookup_fun => <<"emqx_tls_psk:lookup">>,
                                 ciphers =>
                                 ciphers =>

+ 1 - 1
apps/emqx_gateway/src/emqx_gateway_schema.erl

@@ -290,7 +290,7 @@ fields(lwm2m) ->
             sc(
             sc(
                 binary(),
                 binary(),
                 #{
                 #{
-                    default => "etc/lwm2m_xml",
+                    default => emqx:etc_file("lwm2m_xml"),
                     required => true,
                     required => true,
                     desc => "The Directory for LwM2M Resource definition"
                     desc => "The Directory for LwM2M Resource definition"
                 }
                 }

+ 0 - 1
apps/emqx_plugin_libs/src/emqx_plugin_libs.erl

@@ -15,4 +15,3 @@
 %%--------------------------------------------------------------------
 %%--------------------------------------------------------------------
 
 
 -module(emqx_plugin_libs).
 -module(emqx_plugin_libs).
-

+ 7 - 0
bin/emqx

@@ -19,6 +19,13 @@ export RUNNER_ETC_DIR
 export REL_VSN
 export REL_VSN
 export SCHEMA_MOD
 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"
 RUNNER_SCRIPT="$RUNNER_BIN_DIR/$REL_NAME"
 CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
 CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
 REL_DIR="$RUNNER_ROOT_DIR/releases/$REL_VSN"
 REL_DIR="$RUNNER_ROOT_DIR/releases/$REL_VSN"

+ 1 - 0
bin/emqx.cmd

@@ -48,6 +48,7 @@
 @set "RUNNER_ROOT_DIR=%rel_root_dir%"
 @set "RUNNER_ROOT_DIR=%rel_root_dir%"
 :: hard code etc dir
 :: hard code etc dir
 @set "RUNNER_ETC_DIR=%rel_root_dir%\etc"
 @set "RUNNER_ETC_DIR=%rel_root_dir%\etc"
+@set "EMQX_ETC_DIR=%rel_root_dir%\etc"
 @set "etc_dir=%rel_root_dir%\etc"
 @set "etc_dir=%rel_root_dir%\etc"
 @set "lib_dir=%rel_root_dir%\lib"
 @set "lib_dir=%rel_root_dir%\lib"
 @set "emqx_conf=%etc_dir%\emqx.conf"
 @set "emqx_conf=%etc_dir%\emqx.conf"

+ 2 - 0
build

@@ -281,6 +281,8 @@ case "$ARTIFACT" in
         make_tgz
         make_tgz
         ;;
         ;;
     pkg)
     pkg)
+        # this only affect build artifacts, such as schema doc
+        export EMQX_ETC_DIR='/etc/emqx/'
         if [ -z "${PKGERDIR:-}" ]; then
         if [ -z "${PKGERDIR:-}" ]; then
             log "Skipped making deb/rpm package for $SYSTEM"
             log "Skipped making deb/rpm package for $SYSTEM"
             exit 0
             exit 0