feat(plugin): add plugin http api
This commit is contained in:
parent
dcc0ff673f
commit
7160bc06b3
|
@ -199,7 +199,7 @@ fields(position) ->
|
||||||
#{
|
#{
|
||||||
desc => """
|
desc => """
|
||||||
Enable auto-boot at position in the boot list, where Position could be
|
Enable auto-boot at position in the boot list, where Position could be
|
||||||
'top', 'bottom', or 'before:other-vsn' to specify a relative position.
|
'top', 'bottom', or 'before:other-vsn', 'after:other-vsn' to specify a relative position.
|
||||||
""",
|
""",
|
||||||
nullable => true
|
nullable => true
|
||||||
})}];
|
})}];
|
||||||
|
@ -227,6 +227,10 @@ move_request_body() ->
|
||||||
move_to_before => #{
|
move_to_before => #{
|
||||||
summary => <<"move plugin before other plugins">>,
|
summary => <<"move plugin before other plugins">>,
|
||||||
value => #{position => <<"before:emqx_plugin_demo-5.1-rc.2">>}
|
value => #{position => <<"before:emqx_plugin_demo-5.1-rc.2">>}
|
||||||
|
},
|
||||||
|
move_to_after => #{
|
||||||
|
summary => <<"move plugin after other plugins">>,
|
||||||
|
value => #{position => <<"after:emqx_plugin_demo-5.1-rc.2">>}
|
||||||
}
|
}
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
@ -354,7 +358,9 @@ return(_, {error, Reason}) ->
|
||||||
parse_position(#{<<"position">> := <<"top">>}, _) -> front;
|
parse_position(#{<<"position">> := <<"top">>}, _) -> front;
|
||||||
parse_position(#{<<"position">> := <<"bottom">>}, _) -> rear;
|
parse_position(#{<<"position">> := <<"bottom">>}, _) -> rear;
|
||||||
parse_position(#{<<"position">> := <<"before:", Name/binary>>}, Name) -> {error, <<"Can't before:self">>};
|
parse_position(#{<<"position">> := <<"before:", Name/binary>>}, Name) -> {error, <<"Can't before:self">>};
|
||||||
|
parse_position(#{<<"position">> := <<"after:", Name/binary>>}, Name) -> {error, <<"Can't after:self">>};
|
||||||
parse_position(#{<<"position">> := <<"before:", Before/binary>>}, _Name) -> {before, binary_to_list(Before)};
|
parse_position(#{<<"position">> := <<"before:", Before/binary>>}, _Name) -> {before, binary_to_list(Before)};
|
||||||
|
parse_position(#{<<"position">> := <<"after:", After/binary>>}, _Name) -> {behind, binary_to_list(After)};
|
||||||
parse_position(Position, _) -> {error, iolist_to_binary(io_lib:format("~p", [Position]))}.
|
parse_position(Position, _) -> {error, iolist_to_binary(io_lib:format("~p", [Position]))}.
|
||||||
|
|
||||||
format_plugins(List) ->
|
format_plugins(List) ->
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
|
|
||||||
-type name_vsn() :: binary() | string(). %% "my_plugin-0.1.0"
|
-type name_vsn() :: binary() | string(). %% "my_plugin-0.1.0"
|
||||||
-type plugin() :: map(). %% the parse result of the JSON info file
|
-type plugin() :: map(). %% the parse result of the JSON info file
|
||||||
-type position() :: no_move | front | rear | {before, name_vsn()}.
|
-type position() :: no_move | front | rear | {before, name_vsn()} | {behind, name_vsn()}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% APIs
|
%% APIs
|
||||||
|
@ -170,7 +170,7 @@ add_new_configured(Configured, front, Item) ->
|
||||||
[Item | Configured];
|
[Item | Configured];
|
||||||
add_new_configured(Configured, rear, Item) ->
|
add_new_configured(Configured, rear, Item) ->
|
||||||
Configured ++ [Item];
|
Configured ++ [Item];
|
||||||
add_new_configured(Configured, {before, NameVsn}, Item) ->
|
add_new_configured(Configured, {Action, NameVsn}, Item) ->
|
||||||
SplitFun = fun(#{name_vsn := Nv}) -> bin(Nv) =/= bin(NameVsn) end,
|
SplitFun = fun(#{name_vsn := Nv}) -> bin(Nv) =/= bin(NameVsn) end,
|
||||||
{Front, Rear} = lists:splitwith(SplitFun, Configured),
|
{Front, Rear} = lists:splitwith(SplitFun, Configured),
|
||||||
Rear =:= [] andalso
|
Rear =:= [] andalso
|
||||||
|
@ -178,7 +178,13 @@ add_new_configured(Configured, {before, NameVsn}, Item) ->
|
||||||
hint => "maybe_install_and_configure",
|
hint => "maybe_install_and_configure",
|
||||||
name_vsn => NameVsn
|
name_vsn => NameVsn
|
||||||
}),
|
}),
|
||||||
Front ++ [Item | Rear].
|
case Action of
|
||||||
|
before -> Front ++ [Item | Rear];
|
||||||
|
behind ->
|
||||||
|
[Anchor | Rear0] = Rear,
|
||||||
|
Front ++ [Anchor, Item | Rear0]
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
%% @doc Delete the package file.
|
%% @doc Delete the package file.
|
||||||
-spec delete_package(name_vsn()) -> ok.
|
-spec delete_package(name_vsn()) -> ok.
|
||||||
|
|
|
@ -115,8 +115,8 @@ t_demo_install_start_stop_uninstall(Config) ->
|
||||||
ok = emqx_plugins:ensure_installed(NameVsn),
|
ok = emqx_plugins:ensure_installed(NameVsn),
|
||||||
%% idempotent
|
%% idempotent
|
||||||
ok = emqx_plugins:ensure_installed(NameVsn),
|
ok = emqx_plugins:ensure_installed(NameVsn),
|
||||||
{ok, Info} = emqx_plugins:read_plugin(NameVsn),
|
{ok, Info} = emqx_plugins:describe(NameVsn),
|
||||||
?assertEqual([Info], emqx_plugins:list()),
|
?assertEqual([maps:without([readme], Info)], emqx_plugins:list()),
|
||||||
%% start
|
%% start
|
||||||
ok = emqx_plugins:ensure_started(NameVsn),
|
ok = emqx_plugins:ensure_started(NameVsn),
|
||||||
ok = assert_app_running(emqx_plugin_template, true),
|
ok = assert_app_running(emqx_plugin_template, true),
|
||||||
|
@ -158,6 +158,39 @@ write_info_file(Config, NameVsn, Content) ->
|
||||||
ok = filelib:ensure_dir(InfoFile),
|
ok = filelib:ensure_dir(InfoFile),
|
||||||
ok = file:write_file(InfoFile, Content).
|
ok = file:write_file(InfoFile, Content).
|
||||||
|
|
||||||
|
t_position({init, Config}) ->
|
||||||
|
Package = build_demo_plugin_package(),
|
||||||
|
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
||||||
|
[{name_vsn, NameVsn} | Config];
|
||||||
|
t_position({'end', _Config}) -> ok;
|
||||||
|
t_position(Config) ->
|
||||||
|
NameVsn = proplists:get_value(name_vsn, Config),
|
||||||
|
ok = emqx_plugins:ensure_installed(NameVsn),
|
||||||
|
ok = emqx_plugins:ensure_enabled(NameVsn),
|
||||||
|
FakeInfo = "name=position, rel_vsn=\"2\", rel_apps=[\"position-9\"],"
|
||||||
|
"description=\"desc fake position app\"",
|
||||||
|
PosApp2 = <<"position-2">>,
|
||||||
|
ok = write_info_file(Config, PosApp2, FakeInfo),
|
||||||
|
%% fake a disabled plugin in config
|
||||||
|
ok = emqx_plugins:ensure_state(PosApp2, {before, NameVsn}, false),
|
||||||
|
ListFun = fun() ->
|
||||||
|
lists:map(fun(
|
||||||
|
#{<<"name">> := Name, <<"rel_vsn">> := Vsn}) ->
|
||||||
|
<<Name/binary, "-", Vsn/binary>>
|
||||||
|
end, emqx_plugins:list())
|
||||||
|
end,
|
||||||
|
?assertEqual([PosApp2, list_to_binary(NameVsn)], ListFun()),
|
||||||
|
emqx_plugins:ensure_enabled(PosApp2, {behind, NameVsn}),
|
||||||
|
?assertEqual([list_to_binary(NameVsn), PosApp2], ListFun()),
|
||||||
|
|
||||||
|
ok = emqx_plugins:ensure_stopped(),
|
||||||
|
ok = emqx_plugins:ensure_disabled(NameVsn),
|
||||||
|
ok = emqx_plugins:ensure_disabled(PosApp2),
|
||||||
|
ok = emqx_plugins:ensure_uninstalled(NameVsn),
|
||||||
|
ok = emqx_plugins:ensure_uninstalled(PosApp2),
|
||||||
|
?assertEqual([], emqx_plugins:list()),
|
||||||
|
ok.
|
||||||
|
|
||||||
t_start_restart_and_stop({init, Config}) ->
|
t_start_restart_and_stop({init, Config}) ->
|
||||||
#{package := Package} = build_demo_plugin_package(),
|
#{package := Package} = build_demo_plugin_package(),
|
||||||
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
NameVsn = filename:basename(Package, ?PACKAGE_SUFFIX),
|
||||||
|
@ -283,12 +316,12 @@ t_bad_info_json(Config) ->
|
||||||
?assertMatch({error, #{error := "bad_info_file",
|
?assertMatch({error, #{error := "bad_info_file",
|
||||||
return := {parse_error, _}
|
return := {parse_error, _}
|
||||||
}},
|
}},
|
||||||
emqx_plugins:read_plugin(NameVsn)),
|
emqx_plugins:describe(NameVsn)),
|
||||||
ok = write_info_file(Config, NameVsn, "{\"bad\": \"obj\"}"),
|
ok = write_info_file(Config, NameVsn, "{\"bad\": \"obj\"}"),
|
||||||
?assertMatch({error, #{error := "bad_info_file_content",
|
?assertMatch({error, #{error := "bad_info_file_content",
|
||||||
mandatory_fields := _
|
mandatory_fields := _
|
||||||
}},
|
}},
|
||||||
emqx_plugins:read_plugin(NameVsn)),
|
emqx_plugins:describe(NameVsn)),
|
||||||
?assertEqual([], emqx_plugins:list()),
|
?assertEqual([], emqx_plugins:list()),
|
||||||
emqx_plugins:purge(NameVsn),
|
emqx_plugins:purge(NameVsn),
|
||||||
ok.
|
ok.
|
||||||
|
|
Loading…
Reference in New Issue