From 3c8ef35b18507a6d36f81a20934c6dfe91ee736d Mon Sep 17 00:00:00 2001 From: Shawn <506895667@qq.com> Date: Fri, 19 Jul 2024 11:20:03 +0800 Subject: [PATCH] fix: show relup status even if no packages installed --- .../src/emqx_mgmt_api_relup.erl | 136 ++++++++++-------- 1 file changed, 77 insertions(+), 59 deletions(-) diff --git a/apps/emqx_management/src/emqx_mgmt_api_relup.erl b/apps/emqx_management/src/emqx_mgmt_api_relup.erl index 5704de8f4..a31551b6d 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_relup.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_relup.erl @@ -408,33 +408,22 @@ validate_name(Name) -> %%============================================================================== %% HTTP API CallBacks -'/relup/package/upload'(post, #{body := #{<<"plugin">> := Plugin}} = Params) -> - case emqx_plugins:list() of - [] -> - [{FileName, _Bin}] = maps:to_list(maps:without([type], Plugin)), - NameVsn = string:trim(FileName, trailing, ".tar.gz"), - %% we install a relup package as a "hidden" plugin - case emqx_mgmt_api_plugins:upload_install(post, Params) of - {204} -> - case emqx_mgmt_api_plugins_proto_v3:ensure_action(NameVsn, start) of - ok -> - {204}; - {error, Reason} -> - %% try our best to clean up if start failed - _ = emqx_mgmt_api_plugins_proto_v3:delete_package(NameVsn), - return_internal_error(Reason) - end; - ErrResp -> - ErrResp +'/relup/package/upload'(post, #{body := #{<<"plugin">> := UploadBody}} = Params) -> + case assert_relup_pkg_name(UploadBody) of + {ok, NameVsn} -> + case get_installed_packages() of + [] -> + install_as_hidden_plugin(NameVsn, Params); + _ -> + return_bad_request( + << + "Only one relup package can be installed at a time." + "Please delete the existing package first." + >> + ) end; - _ -> - {400, #{ - code => 'BAD_REQUEST', - message => << - "Only one relup package can be installed at a time." - "Please delete the existing package first." - >> - }} + {error, Reason} -> + return_bad_request(Reason) end. '/relup/package'(get, _) -> @@ -449,40 +438,36 @@ validate_name(Name) -> {204}. '/relup/status'(get, _) -> - ?ASSERT_PKG_READY(begin - {[_ | _] = Res, []} = emqx_mgmt_api_relup_proto_v1:get_upgrade_status_from_all_nodes(), - case - lists:filter( - fun - (R) when is_map(R) -> false; - (_) -> true - end, - Res + {[_ | _] = Res, []} = emqx_mgmt_api_relup_proto_v1:get_upgrade_status_from_all_nodes(), + case + lists:filter( + fun + (R) when is_map(R) -> false; + (_) -> true + end, + Res + ) + of + [] -> + {200, Res}; + Filtered -> + return_internal_error( + case hd(Filtered) of + {badrpc, Reason} -> Reason; + Reason -> Reason + end ) - of - [] -> - {200, Res}; - Filtered -> - return_internal_error( - case hd(Filtered) of - {badrpc, Reason} -> Reason; - Reason -> Reason - end - ) - end - end). + end. '/relup/status/:node'(get, #{bindings := #{node := NodeNameStr}}) -> - ?ASSERT_PKG_READY( - emqx_utils_api:with_node( - NodeNameStr, - fun - (Node) when node() =:= Node -> - {200, get_upgrade_status()}; - (Node) when is_atom(Node) -> - {200, emqx_mgmt_api_relup_proto_v1:get_upgrade_status(Node)} - end - ) + emqx_utils_api:with_node( + NodeNameStr, + fun + (Node) when node() =:= Node -> + {200, get_upgrade_status()}; + (Node) when is_atom(Node) -> + {200, emqx_mgmt_api_relup_proto_v1:get_upgrade_status(Node)} + end ). '/relup/upgrade'(post, _) -> @@ -511,16 +496,49 @@ validate_name(Name) -> %%============================================================================== %% Helper functions +install_as_hidden_plugin(NameVsn, Params) -> + case emqx_mgmt_api_plugins:upload_install(post, Params) of + {204} -> + case emqx_mgmt_api_plugins_proto_v3:ensure_action(NameVsn, start) of + ok -> + {204}; + {error, Reason} -> + %% try our best to clean up if start failed + _ = emqx_mgmt_api_plugins_proto_v3:delete_package(NameVsn), + return_internal_error(Reason) + end; + ErrResp -> + ErrResp + end. + +assert_relup_pkg_name(UploadBody) -> + [{FileName, _Bin}] = maps:to_list(maps:without([type], UploadBody)), + case string:split(FileName, "-") of + [?PLUGIN_NAME, _] -> + {ok, string:trim(FileName, trailing, ".tar.gz")}; + _ -> + {error, <<"Invalid relup package name: ", FileName/binary>>} + end. + get_upgrade_status() -> #{ node => node(), role => mria_rlog:role(), live_connections => emqx_cm:get_connected_client_count(), current_vsn => list_to_binary(emqx_release:version()), - status => emqx_relup_main:get_latest_upgrade_status(), - upgrade_history => emqx_relup_main:get_all_upgrade_logs() + status => call_emqx_relup_main(get_latest_upgrade_status, [], idle), + upgrade_history => call_emqx_relup_main(get_all_upgrade_logs, [], []) }. +call_emqx_relup_main(Fun, Args, Default) -> + case erlang:function_exported(emqx_relup_main, Fun, length(Args)) of + true -> + apply(emqx_relup_main, Fun, Args); + false -> + %% relup package is not installed + Default + end. + upgrade_with_targe_vsn(Fun) -> case get_target_vsn() of {ok, TargetVsn} ->