Просмотр исходного кода

fix: show relup status even if no packages installed

Shawn 1 год назад
Родитель
Сommit
3c8ef35b18
1 измененных файлов с 77 добавлено и 59 удалено
  1. 77 59
      apps/emqx_management/src/emqx_mgmt_api_relup.erl

+ 77 - 59
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} ->