fix: show relup status even if no packages installed

This commit is contained in:
Shawn 2024-07-19 11:20:03 +08:00
parent 79b65a28c1
commit 3c8ef35b18
1 changed files with 77 additions and 59 deletions

View File

@ -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} ->