Merge pull request #9472 from zmstone/1203-merge-release-50-to-master
1203 merge release 50 to master
This commit is contained in:
commit
16aeba24b7
|
@ -84,14 +84,14 @@ emqx_authn_api {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
authentication_id_move_post {
|
authentication_id_position_put {
|
||||||
desc {
|
desc {
|
||||||
en: """Move authenticator in global authentication chain."""
|
en: """Move authenticator in global authentication chain."""
|
||||||
zh: """更改全局认证链上指定认证器的顺序。"""
|
zh: """更改全局认证链上指定认证器的顺序。"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listeners_listener_id_authentication_id_move_post {
|
listeners_listener_id_authentication_id_position_put {
|
||||||
desc {
|
desc {
|
||||||
en: """Move authenticator in listener authentication chain."""
|
en: """Move authenticator in listener authentication chain."""
|
||||||
zh: """更改监听器认证链上指定认证器的顺序。"""
|
zh: """更改监听器认证链上指定认证器的顺序。"""
|
||||||
|
@ -182,7 +182,6 @@ emqx_authn_api {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
param_user_id {
|
param_user_id {
|
||||||
desc {
|
desc {
|
||||||
en: """User ID."""
|
en: """User ID."""
|
||||||
|
@ -190,6 +189,13 @@ emqx_authn_api {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
param_position {
|
||||||
|
desc {
|
||||||
|
en: """Position of authenticator in chain. Possible values are 'front', 'rear', 'before:{other_authenticator}', 'after:{other_authenticator}'."""
|
||||||
|
zn: """认证者在链中的位置。可能的值是 'front', 'rear', 'before:{other_authenticator}', 'after:{other_authenticator}'"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
like_user_id {
|
like_user_id {
|
||||||
desc {
|
desc {
|
||||||
en: """Fuzzy search user_id (username or clientid)."""
|
en: """Fuzzy search user_id (username or clientid)."""
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
{application, emqx_authn, [
|
{application, emqx_authn, [
|
||||||
{description, "EMQX Authentication"},
|
{description, "EMQX Authentication"},
|
||||||
{vsn, "0.1.9"},
|
{vsn, "0.1.10"},
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_authn_sup, emqx_authn_registry]},
|
{registered, [emqx_authn_sup, emqx_authn_registry]},
|
||||||
{applications, [kernel, stdlib, emqx_resource, ehttpc, epgsql, mysql, jose]},
|
{applications, [kernel, stdlib, emqx_resource, ehttpc, epgsql, mysql, jose]},
|
||||||
|
|
|
@ -55,8 +55,8 @@
|
||||||
listener_authenticators/2,
|
listener_authenticators/2,
|
||||||
listener_authenticator/2,
|
listener_authenticator/2,
|
||||||
listener_authenticator_status/2,
|
listener_authenticator_status/2,
|
||||||
authenticator_move/2,
|
authenticator_position/2,
|
||||||
listener_authenticator_move/2,
|
listener_authenticator_position/2,
|
||||||
authenticator_users/2,
|
authenticator_users/2,
|
||||||
authenticator_user/2,
|
authenticator_user/2,
|
||||||
listener_authenticator_users/2,
|
listener_authenticator_users/2,
|
||||||
|
@ -67,7 +67,6 @@
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
authenticator_examples/0,
|
authenticator_examples/0,
|
||||||
request_move_examples/0,
|
|
||||||
request_user_create_examples/0,
|
request_user_create_examples/0,
|
||||||
request_user_update_examples/0,
|
request_user_update_examples/0,
|
||||||
response_user_examples/0,
|
response_user_examples/0,
|
||||||
|
@ -99,14 +98,14 @@ paths() ->
|
||||||
"/authentication",
|
"/authentication",
|
||||||
"/authentication/:id",
|
"/authentication/:id",
|
||||||
"/authentication/:id/status",
|
"/authentication/:id/status",
|
||||||
"/authentication/:id/move",
|
"/authentication/:id/position/:position",
|
||||||
"/authentication/:id/users",
|
"/authentication/:id/users",
|
||||||
"/authentication/:id/users/:user_id",
|
"/authentication/:id/users/:user_id",
|
||||||
|
|
||||||
"/listeners/:listener_id/authentication",
|
"/listeners/:listener_id/authentication",
|
||||||
"/listeners/:listener_id/authentication/:id",
|
"/listeners/:listener_id/authentication/:id",
|
||||||
"/listeners/:listener_id/authentication/:id/status",
|
"/listeners/:listener_id/authentication/:id/status",
|
||||||
"/listeners/:listener_id/authentication/:id/move",
|
"/listeners/:listener_id/authentication/:id/position/:position",
|
||||||
"/listeners/:listener_id/authentication/:id/users",
|
"/listeners/:listener_id/authentication/:id/users",
|
||||||
"/listeners/:listener_id/authentication/:id/users/:user_id"
|
"/listeners/:listener_id/authentication/:id/users/:user_id"
|
||||||
].
|
].
|
||||||
|
@ -115,7 +114,6 @@ roots() ->
|
||||||
[
|
[
|
||||||
request_user_create,
|
request_user_create,
|
||||||
request_user_update,
|
request_user_update,
|
||||||
request_move,
|
|
||||||
response_user,
|
response_user,
|
||||||
response_users
|
response_users
|
||||||
].
|
].
|
||||||
|
@ -130,8 +128,6 @@ fields(request_user_update) ->
|
||||||
{password, mk(binary(), #{required => true})},
|
{password, mk(binary(), #{required => true})},
|
||||||
{is_superuser, mk(boolean(), #{default => false, required => false})}
|
{is_superuser, mk(boolean(), #{default => false, required => false})}
|
||||||
];
|
];
|
||||||
fields(request_move) ->
|
|
||||||
[{position, mk(binary(), #{required => true})}];
|
|
||||||
fields(response_user) ->
|
fields(response_user) ->
|
||||||
[
|
[
|
||||||
{user_id, mk(binary(), #{required => true})},
|
{user_id, mk(binary(), #{required => true})},
|
||||||
|
@ -321,17 +317,13 @@ schema("/listeners/:listener_id/authentication/:id/status") ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
schema("/authentication/:id/move") ->
|
schema("/authentication/:id/position/:position") ->
|
||||||
#{
|
#{
|
||||||
'operationId' => authenticator_move,
|
'operationId' => authenticator_position,
|
||||||
post => #{
|
put => #{
|
||||||
tags => ?API_TAGS_GLOBAL,
|
tags => ?API_TAGS_GLOBAL,
|
||||||
description => ?DESC(authentication_id_move_post),
|
description => ?DESC(authentication_id_position_put),
|
||||||
parameters => [param_auth_id()],
|
parameters => [param_auth_id(), param_position()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
|
||||||
ref(request_move),
|
|
||||||
request_move_examples()
|
|
||||||
),
|
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"Authenticator moved">>,
|
204 => <<"Authenticator moved">>,
|
||||||
400 => error_codes([?BAD_REQUEST], <<"Bad Request">>),
|
400 => error_codes([?BAD_REQUEST], <<"Bad Request">>),
|
||||||
|
@ -339,17 +331,13 @@ schema("/authentication/:id/move") ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
schema("/listeners/:listener_id/authentication/:id/move") ->
|
schema("/listeners/:listener_id/authentication/:id/position/:position") ->
|
||||||
#{
|
#{
|
||||||
'operationId' => listener_authenticator_move,
|
'operationId' => listener_authenticator_position,
|
||||||
post => #{
|
put => #{
|
||||||
tags => ?API_TAGS_SINGLE,
|
tags => ?API_TAGS_SINGLE,
|
||||||
description => ?DESC(listeners_listener_id_authentication_id_move_post),
|
description => ?DESC(listeners_listener_id_authentication_id_position_put),
|
||||||
parameters => [param_listener_id(), param_auth_id()],
|
parameters => [param_listener_id(), param_auth_id(), param_position()],
|
||||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
|
||||||
ref(request_move),
|
|
||||||
request_move_examples()
|
|
||||||
),
|
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"Authenticator moved">>,
|
204 => <<"Authenticator moved">>,
|
||||||
400 => error_codes([?BAD_REQUEST], <<"Bad Request">>),
|
400 => error_codes([?BAD_REQUEST], <<"Bad Request">>),
|
||||||
|
@ -556,6 +544,17 @@ param_listener_id() ->
|
||||||
})
|
})
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
param_position() ->
|
||||||
|
{
|
||||||
|
position,
|
||||||
|
mk(binary(), #{
|
||||||
|
in => path,
|
||||||
|
desc => ?DESC(param_position),
|
||||||
|
required => true,
|
||||||
|
example => "before:password_based:built_in_database"
|
||||||
|
})
|
||||||
|
}.
|
||||||
|
|
||||||
param_user_id() ->
|
param_user_id() ->
|
||||||
{
|
{
|
||||||
user_id,
|
user_id,
|
||||||
|
@ -662,23 +661,15 @@ listener_authenticator_status(
|
||||||
end
|
end
|
||||||
).
|
).
|
||||||
|
|
||||||
authenticator_move(
|
authenticator_position(
|
||||||
post,
|
put,
|
||||||
#{
|
#{bindings := #{id := AuthenticatorID, position := Position}}
|
||||||
bindings := #{id := AuthenticatorID},
|
|
||||||
body := #{<<"position">> := Position}
|
|
||||||
}
|
|
||||||
) ->
|
) ->
|
||||||
move_authenticator([authentication], ?GLOBAL, AuthenticatorID, Position);
|
move_authenticator([authentication], ?GLOBAL, AuthenticatorID, Position).
|
||||||
authenticator_move(post, #{bindings := #{id := _}, body := _}) ->
|
|
||||||
serialize_error({missing_parameter, position}).
|
|
||||||
|
|
||||||
listener_authenticator_move(
|
listener_authenticator_position(
|
||||||
post,
|
put,
|
||||||
#{
|
#{bindings := #{listener_id := ListenerID, id := AuthenticatorID, position := Position}}
|
||||||
bindings := #{listener_id := ListenerID, id := AuthenticatorID},
|
|
||||||
body := #{<<"position">> := Position}
|
|
||||||
}
|
|
||||||
) ->
|
) ->
|
||||||
with_listener(
|
with_listener(
|
||||||
ListenerID,
|
ListenerID,
|
||||||
|
@ -690,9 +681,7 @@ listener_authenticator_move(
|
||||||
Position
|
Position
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
);
|
).
|
||||||
listener_authenticator_move(post, #{bindings := #{listener_id := _, id := _}, body := _}) ->
|
|
||||||
serialize_error({missing_parameter, position}).
|
|
||||||
|
|
||||||
authenticator_users(post, #{bindings := #{id := AuthenticatorID}, body := UserInfo}) ->
|
authenticator_users(post, #{bindings := #{id := AuthenticatorID}, body := UserInfo}) ->
|
||||||
add_user(?GLOBAL, AuthenticatorID, UserInfo);
|
add_user(?GLOBAL, AuthenticatorID, UserInfo);
|
||||||
|
@ -1475,28 +1464,6 @@ request_user_update_examples() ->
|
||||||
}
|
}
|
||||||
}.
|
}.
|
||||||
|
|
||||||
request_move_examples() ->
|
|
||||||
#{
|
|
||||||
move_to_front => #{
|
|
||||||
summary => <<"Move authenticator to the beginning of the chain">>,
|
|
||||||
value => #{
|
|
||||||
position => <<"front">>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
move_to_rear => #{
|
|
||||||
summary => <<"Move authenticator to the end of the chain">>,
|
|
||||||
value => #{
|
|
||||||
position => <<"rear">>
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'move_before_password_based:built_in_database' => #{
|
|
||||||
summary => <<"Move authenticator to the position preceding some other authenticator">>,
|
|
||||||
value => #{
|
|
||||||
position => <<"before:password_based:built_in_database">>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.
|
|
||||||
|
|
||||||
response_user_examples() ->
|
response_user_examples() ->
|
||||||
#{
|
#{
|
||||||
regular_user => #{
|
regular_user => #{
|
||||||
|
|
|
@ -120,8 +120,8 @@ t_authenticator_users(_) ->
|
||||||
t_authenticator_user(_) ->
|
t_authenticator_user(_) ->
|
||||||
test_authenticator_user([]).
|
test_authenticator_user([]).
|
||||||
|
|
||||||
t_authenticator_move(_) ->
|
t_authenticator_position(_) ->
|
||||||
test_authenticator_move([]).
|
test_authenticator_position([]).
|
||||||
|
|
||||||
t_authenticator_import_users(_) ->
|
t_authenticator_import_users(_) ->
|
||||||
test_authenticator_import_users([]).
|
test_authenticator_import_users([]).
|
||||||
|
@ -138,8 +138,8 @@ t_listener_authenticator_users(_) ->
|
||||||
t_listener_authenticator_user(_) ->
|
t_listener_authenticator_user(_) ->
|
||||||
test_authenticator_user(["listeners", ?TCP_DEFAULT]).
|
test_authenticator_user(["listeners", ?TCP_DEFAULT]).
|
||||||
|
|
||||||
t_listener_authenticator_move(_) ->
|
t_listener_authenticator_position(_) ->
|
||||||
test_authenticator_move(["listeners", ?TCP_DEFAULT]).
|
test_authenticator_position(["listeners", ?TCP_DEFAULT]).
|
||||||
|
|
||||||
t_listener_authenticator_import_users(_) ->
|
t_listener_authenticator_import_users(_) ->
|
||||||
test_authenticator_import_users(["listeners", ?TCP_DEFAULT]).
|
test_authenticator_import_users(["listeners", ?TCP_DEFAULT]).
|
||||||
|
@ -539,7 +539,7 @@ test_authenticator_user(PathPrefix) ->
|
||||||
{ok, 404, _} = request(delete, UsersUri ++ "/u123"),
|
{ok, 404, _} = request(delete, UsersUri ++ "/u123"),
|
||||||
{ok, 204, _} = request(delete, UsersUri ++ "/u1").
|
{ok, 204, _} = request(delete, UsersUri ++ "/u1").
|
||||||
|
|
||||||
test_authenticator_move(PathPrefix) ->
|
test_authenticator_position(PathPrefix) ->
|
||||||
AuthenticatorConfs = [
|
AuthenticatorConfs = [
|
||||||
emqx_authn_test_lib:http_example(),
|
emqx_authn_test_lib:http_example(),
|
||||||
emqx_authn_test_lib:jwt_example(),
|
emqx_authn_test_lib:jwt_example(),
|
||||||
|
@ -569,42 +569,31 @@ test_authenticator_move(PathPrefix) ->
|
||||||
%% Invalid moves
|
%% Invalid moves
|
||||||
|
|
||||||
{ok, 400, _} = request(
|
{ok, 400, _} = request(
|
||||||
post,
|
put,
|
||||||
uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
|
uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "up"])
|
||||||
#{position => <<"up">>}
|
|
||||||
),
|
|
||||||
|
|
||||||
{ok, 400, _} = request(
|
|
||||||
post,
|
|
||||||
uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
|
|
||||||
#{}
|
|
||||||
),
|
),
|
||||||
|
|
||||||
{ok, 404, _} = request(
|
{ok, 404, _} = request(
|
||||||
post,
|
put,
|
||||||
uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
|
uri(PathPrefix ++ [?CONF_NS, "jwt", "position"])
|
||||||
#{position => <<"before:invalid">>}
|
|
||||||
),
|
),
|
||||||
|
|
||||||
{ok, 404, _} = request(
|
{ok, 404, _} = request(
|
||||||
post,
|
put,
|
||||||
uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
|
uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "before:invalid"])
|
||||||
#{position => <<"before:password_based:redis">>}
|
|
||||||
),
|
),
|
||||||
|
|
||||||
{ok, 404, _} = request(
|
{ok, 404, _} = request(
|
||||||
post,
|
put,
|
||||||
uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
|
uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "before:password_based:redis"])
|
||||||
#{position => <<"before:password_based:redis">>}
|
|
||||||
),
|
),
|
||||||
|
|
||||||
%% Valid moves
|
%% Valid moves
|
||||||
|
|
||||||
%% test front
|
%% test front
|
||||||
{ok, 204, _} = request(
|
{ok, 204, _} = request(
|
||||||
post,
|
put,
|
||||||
uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
|
uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "front"])
|
||||||
#{position => <<"front">>}
|
|
||||||
),
|
),
|
||||||
|
|
||||||
?assertAuthenticatorsMatch(
|
?assertAuthenticatorsMatch(
|
||||||
|
@ -618,9 +607,8 @@ test_authenticator_move(PathPrefix) ->
|
||||||
|
|
||||||
%% test rear
|
%% test rear
|
||||||
{ok, 204, _} = request(
|
{ok, 204, _} = request(
|
||||||
post,
|
put,
|
||||||
uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
|
uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "rear"])
|
||||||
#{position => <<"rear">>}
|
|
||||||
),
|
),
|
||||||
|
|
||||||
?assertAuthenticatorsMatch(
|
?assertAuthenticatorsMatch(
|
||||||
|
@ -634,9 +622,8 @@ test_authenticator_move(PathPrefix) ->
|
||||||
|
|
||||||
%% test before
|
%% test before
|
||||||
{ok, 204, _} = request(
|
{ok, 204, _} = request(
|
||||||
post,
|
put,
|
||||||
uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
|
uri(PathPrefix ++ [?CONF_NS, "jwt", "position", "before:password_based:built_in_database"])
|
||||||
#{position => <<"before:password_based:built_in_database">>}
|
|
||||||
),
|
),
|
||||||
|
|
||||||
?assertAuthenticatorsMatch(
|
?assertAuthenticatorsMatch(
|
||||||
|
@ -650,9 +637,16 @@ test_authenticator_move(PathPrefix) ->
|
||||||
|
|
||||||
%% test after
|
%% test after
|
||||||
{ok, 204, _} = request(
|
{ok, 204, _} = request(
|
||||||
post,
|
put,
|
||||||
uri(PathPrefix ++ [?CONF_NS, "password_based%3Abuilt_in_database", "move"]),
|
uri(
|
||||||
#{position => <<"after:password_based:http">>}
|
PathPrefix ++
|
||||||
|
[
|
||||||
|
?CONF_NS,
|
||||||
|
"password_based%3Abuilt_in_database",
|
||||||
|
"position",
|
||||||
|
"after:password_based:http"
|
||||||
|
]
|
||||||
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
?assertAuthenticatorsMatch(
|
?assertAuthenticatorsMatch(
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
- Remove support for setting shared subscriptions using the non-standard `$queue` feature [#9412](https://github.com/emqx/emqx/pull/9412).
|
- Remove support for setting shared subscriptions using the non-standard `$queue` feature [#9412](https://github.com/emqx/emqx/pull/9412).
|
||||||
Shared subscriptions are now part of the MQTT spec. Use `$share` instead.
|
Shared subscriptions are now part of the MQTT spec. Use `$share` instead.
|
||||||
|
|
||||||
- Add `limiter` update API [#9133](https://github.com/emqx/emqx/pull/9133).
|
- Refactor authn API by replacing `POST /authentication/{id}/move` with `PUT /authentication/{id}/position/{position}`. [#9419](https://github.com/emqx/emqx/pull/9419).
|
||||||
|
Same is done for `/listeners/{listener_id}/authentication/id/...`.
|
||||||
|
|
||||||
- Avoid creating temporary zip files when syncing data directory during cluster startup [#9429](https://github.com/emqx/emqx/pull/9429).
|
- Avoid creating temporary zip files when syncing data directory during cluster startup [#9429](https://github.com/emqx/emqx/pull/9429).
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
|
|
||||||
- 通过 `node.global_gc_interval = disabled` 来禁用全局垃圾回收 [#9418](https://github.com/emqx/emqx/pull/9418)。
|
- 通过 `node.global_gc_interval = disabled` 来禁用全局垃圾回收 [#9418](https://github.com/emqx/emqx/pull/9418)。
|
||||||
|
|
||||||
- 删除了老的共享订阅支持方式, 不再使用 `$queue` 前缀 [#9412](https://github.com/emqx/emqx/pull/9412)。
|
|
||||||
共享订阅自 MQTT v5.0 开始已成为协议标准,可以使用 `$share` 前缀代替 `$queue`。
|
|
||||||
|
|
||||||
- 优化命令行实现, 避免输入错误指令时, 产生不必要的原子表消耗 [#9416](https://github.com/emqx/emqx/pull/9416)。
|
- 优化命令行实现, 避免输入错误指令时, 产生不必要的原子表消耗 [#9416](https://github.com/emqx/emqx/pull/9416)。
|
||||||
|
|
||||||
- 支持在 Apple Silicon 架构下编译苹果系统的发行版本 [#9423](https://github.com/emqx/emqx/pull/9423)。
|
- 支持在 Apple Silicon 架构下编译苹果系统的发行版本 [#9423](https://github.com/emqx/emqx/pull/9423)。
|
||||||
|
|
||||||
- 添加 `limiter` 更新 API [#9133](https://github.com/emqx/emqx/pull/9133)。
|
- 删除了老的共享订阅支持方式, 不再使用 `$queue` 前缀 [#9412](https://github.com/emqx/emqx/pull/9412)。
|
||||||
|
共享订阅自 MQTT v5.0 开始已成为协议标准,可以使用 `$share` 前缀代替 `$queue`。
|
||||||
|
|
||||||
|
- 重构认证 API,使用 `PUT /authentication/{id}/position/{position}` 代替了 `POST /authentication/{id}/move` [#9419](https://github.com/emqx/emqx/pull/9419)。
|
||||||
|
|
||||||
- EMQX 集群启动时同步 data 目录不需要在磁盘上产生临时的zip文件 [#9429](https://github.com/emqx/emqx/pull/9429)。
|
- EMQX 集群启动时同步 data 目录不需要在磁盘上产生临时的zip文件 [#9429](https://github.com/emqx/emqx/pull/9429)。
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# v5.0.12
|
||||||
|
|
||||||
|
## Enhancements
|
||||||
|
|
||||||
|
- Add `limiter` update API [#9133](https://github.com/emqx/emqx/pull/9133).
|
||||||
|
|
||||||
|
## Bug fixes
|
|
@ -0,0 +1,7 @@
|
||||||
|
# v5.0.12
|
||||||
|
|
||||||
|
## 增强
|
||||||
|
|
||||||
|
- 添加 `limiter` 更新 API [#9133](https://github.com/emqx/emqx/pull/9133)。
|
||||||
|
|
||||||
|
## 修复
|
|
@ -0,0 +1,35 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ "${DEBUG:-}" = 1 ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ensure dir
|
||||||
|
cd -P -- "$(dirname -- "$0")/../.."
|
||||||
|
|
||||||
|
PROFILE="$1"
|
||||||
|
CHART_FILE="deploy/charts/${PROFILE}/Chart.yaml"
|
||||||
|
|
||||||
|
if [ ! -f "$CHART_FILE" ]; then
|
||||||
|
echo "Chart file $CHART_FILE is not found"
|
||||||
|
echo "Current working dir: $(pwd)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CHART_VSN="$(grep -oE '^version:.*' "$CHART_FILE" | cut -d ':' -f 2 | tr -d ' ')"
|
||||||
|
APP_VSN="$(grep -oE '^appVersion:.*' "$CHART_FILE" | cut -d ':' -f 2 | tr -d ' ')"
|
||||||
|
|
||||||
|
if [ "$CHART_VSN" != "$APP_VSN" ]; then
|
||||||
|
echo "Chart version and app version mismatch in $CHART_FILE"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
PKG_VSN="$(./pkg-vsn.sh "$PROFILE" | cut -d '-' -f 1)"
|
||||||
|
|
||||||
|
if [ "$CHART_VSN" != "$PKG_VSN" ]; then
|
||||||
|
echo "Chart version in $CHART_FILE is not in sync with release version."
|
||||||
|
echo "Chart version: $CHART_VSN"
|
||||||
|
echo "Release version: $PKG_VSN"
|
||||||
|
exit 3
|
||||||
|
fi
|
|
@ -0,0 +1,214 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
## cut a new 5.x release for EMQX (opensource or enterprise).
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ "${DEBUG:-}" = 1 ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ensure dir
|
||||||
|
cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/../.."
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
$0 RELEASE_GIT_TAG [option]
|
||||||
|
RELEASE_GIT_TAG is a 'v*' or 'e*' tag for example:
|
||||||
|
v5.0.12
|
||||||
|
e5.0.0-beta.6
|
||||||
|
|
||||||
|
options:
|
||||||
|
-h|--help: Print this usage.
|
||||||
|
-b|--base: Specify the current release base branch, can be one of
|
||||||
|
release-50
|
||||||
|
NOTE: this option should be used when --dryrun.
|
||||||
|
--dryrun: Do not actually create the git tag.
|
||||||
|
--skip-appup: Skip checking appup
|
||||||
|
Useful when you are sure that appup is already updated'
|
||||||
|
|
||||||
|
NOTE: For 5.0 series the current working branch must be 'release-50' for opensource edition
|
||||||
|
and 'release-e50' for enterprise edition.
|
||||||
|
--.--[ master ]---------------------------.-----------.---
|
||||||
|
\\ /
|
||||||
|
\`---[release-50]----(v5.0.12 | e5.0.0)
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
logerr() {
|
||||||
|
echo "$(tput setaf 1)ERROR: $1$(tput sgr0)"
|
||||||
|
}
|
||||||
|
logmsg() {
|
||||||
|
echo "INFO: $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
TAG="${1:-}"
|
||||||
|
|
||||||
|
case "$TAG" in
|
||||||
|
v*)
|
||||||
|
TAG_PREFIX='v'
|
||||||
|
PROFILE='emqx'
|
||||||
|
SKIP_APPUP='yes'
|
||||||
|
;;
|
||||||
|
e*)
|
||||||
|
TAG_PREFIX='e'
|
||||||
|
PROFILE='emqx-enterprise'
|
||||||
|
SKIP_APPUP='no'
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logerr "Unknown version tag $TAG"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift 1
|
||||||
|
|
||||||
|
DRYRUN='no'
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--skip-appup)
|
||||||
|
shift
|
||||||
|
SKIP_APPUP='yes'
|
||||||
|
;;
|
||||||
|
--dryrun)
|
||||||
|
shift
|
||||||
|
DRYRUN='yes'
|
||||||
|
;;
|
||||||
|
-b|--base)
|
||||||
|
BASE_BR="${2:-}"
|
||||||
|
if [ -z "${BASE_BR}" ]; then
|
||||||
|
logerr "Must specify which base branch"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logerr "Unknown option $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
rel_branch() {
|
||||||
|
local tag="$1"
|
||||||
|
case "$tag" in
|
||||||
|
v5.0.*)
|
||||||
|
echo 'release-50'
|
||||||
|
;;
|
||||||
|
e5.0.*)
|
||||||
|
echo 'release-50'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logerr "Unsupported version tag $TAG"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
## Ensure the current work branch
|
||||||
|
assert_work_branch() {
|
||||||
|
local tag="$1"
|
||||||
|
local release_branch
|
||||||
|
release_branch="$(rel_branch "$tag")"
|
||||||
|
local base_branch
|
||||||
|
base_branch="${BASE_BR:-$(git branch --show-current)}"
|
||||||
|
if [ "$base_branch" != "$release_branch" ]; then
|
||||||
|
logerr "Base branch: $base_branch"
|
||||||
|
logerr "Relase tag must be on the release branch: $release_branch"
|
||||||
|
logerr "or must use -b|--base option to specify which release branch is current branch based on"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
assert_work_branch "$TAG"
|
||||||
|
|
||||||
|
## Ensure no dirty changes
|
||||||
|
assert_not_dirty() {
|
||||||
|
local diff
|
||||||
|
diff="$(git diff --name-only)"
|
||||||
|
if [ -n "$diff" ]; then
|
||||||
|
logerr "Git status is not clean? Changed files:"
|
||||||
|
logerr "$diff"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
assert_not_dirty
|
||||||
|
|
||||||
|
## Assert that the tag is not already created
|
||||||
|
assert_tag_absent() {
|
||||||
|
local tag="$1"
|
||||||
|
## Fail if the tag already exists
|
||||||
|
EXISTING="$(git tag --list "$tag")"
|
||||||
|
if [ -n "$EXISTING" ]; then
|
||||||
|
logerr "$tag already released?"
|
||||||
|
logerr 'This script refuse to force re-tag.'
|
||||||
|
logerr 'If re-tag is intended, you must first delete the tag from both local and remote'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
assert_tag_absent "$TAG"
|
||||||
|
|
||||||
|
PKG_VSN=$(./pkg-vsn.sh "$PROFILE")
|
||||||
|
|
||||||
|
## Assert package version is updated to the tag which is being created
|
||||||
|
assert_release_version() {
|
||||||
|
local tag="$1"
|
||||||
|
# shellcheck disable=SC2001
|
||||||
|
pkg_vsn="$(echo "$PKG_VSN" | sed 's/-g[0-9a-f]\{8\}$//g')"
|
||||||
|
if [ "${TAG_PREFIX}${pkg_vsn}" != "${tag}" ]; then
|
||||||
|
logerr "The release version ($pkg_vsn) is different from the desired git tag."
|
||||||
|
logerr "Update the release version in emqx_release.hrl"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
assert_release_version "$TAG"
|
||||||
|
|
||||||
|
## Check if all upstream branches are merged
|
||||||
|
if [ -z "${BASE_BR:-}" ]; then
|
||||||
|
./scripts/rel/sync-remotes.sh
|
||||||
|
else
|
||||||
|
./scripts/rel/sync-remotes.sh --base "$BASE_BR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Check if the Chart versions are in sync
|
||||||
|
./scripts/rel/check-chart-vsn.sh "$PROFILE"
|
||||||
|
|
||||||
|
## Check if app versions are bumped
|
||||||
|
./scripts/apps-version-check.sh
|
||||||
|
|
||||||
|
## Ensure appup files are updated
|
||||||
|
if [ "$SKIP_APPUP" = 'no' ]; then
|
||||||
|
logmsg "Checking appups"
|
||||||
|
./scripts/update-appup.sh "$PROFILE" --check
|
||||||
|
else
|
||||||
|
logmsg "Skipped checking appup updates"
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Ensure relup paths are updated
|
||||||
|
## TODO: add relup path db
|
||||||
|
#./scripts/relup-base-vsns.escript check-vsn-db "$PKG_VSN" "$RELUP_PATHS"
|
||||||
|
|
||||||
|
## Run some additional checks (e.g. some for enterprise edition only)
|
||||||
|
CHECKS_DIR="./scripts/rel/checks"
|
||||||
|
if [ -d "${CHECKS_DIR}" ]; then
|
||||||
|
CHECKS="$(find "${CHECKS_DIR}" -name "*.sh" -print0 2>/dev/null | xargs -0)"
|
||||||
|
for c in $CHECKS; do
|
||||||
|
logmsg "Executing $c"
|
||||||
|
$c
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$DRYRUN" = 'yes' ]; then
|
||||||
|
logmsg "Release tag is ready to be created with command: git tag $TAG"
|
||||||
|
else
|
||||||
|
git tag "$TAG"
|
||||||
|
logmsg "$TAG is created OK."
|
||||||
|
fi
|
|
@ -0,0 +1,156 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ensure dir
|
||||||
|
cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/../.."
|
||||||
|
|
||||||
|
BASE_BRANCHES=( 'release-50' 'master' )
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
$0 [option]
|
||||||
|
|
||||||
|
options:
|
||||||
|
|
||||||
|
-h|--help:
|
||||||
|
This script works on one of the branches listed in the -b|--base option below.
|
||||||
|
It tries to merge (by default with --ff-only option)
|
||||||
|
upstreams branches for the current working branch.
|
||||||
|
The uppstream branch of the current branch are as below:
|
||||||
|
* release-50: [] # no upstream for 5.0 opensource edition
|
||||||
|
* master: [release-50] # sync release-50 to master
|
||||||
|
|
||||||
|
-b|--base:
|
||||||
|
The base branch of current working branch if currently is not
|
||||||
|
on one of the following branches.
|
||||||
|
${BASE_BRANCHES[@]}
|
||||||
|
|
||||||
|
-i|--interactive:
|
||||||
|
With this option, the script will try to merge upstream
|
||||||
|
branches to local working branch interactively.
|
||||||
|
That is, there will be git prompts to edit commit messages etc.
|
||||||
|
Without this option, the script executes 'git merge' command
|
||||||
|
with '--ff-only' option which conveniently pulls remote
|
||||||
|
updates if there is any, and fails when fast-forward is not possible
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
logerr() {
|
||||||
|
echo "$(tput setaf 1)ERROR: $1$(tput sgr0)"
|
||||||
|
}
|
||||||
|
logwarn() {
|
||||||
|
echo "$(tput setaf 3)WARNING: $1$(tput sgr0)"
|
||||||
|
}
|
||||||
|
|
||||||
|
logmsg() {
|
||||||
|
echo "INFO: $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERACTIVE='no'
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-i|--interactive)
|
||||||
|
shift
|
||||||
|
INTERACTIVE='yes'
|
||||||
|
;;
|
||||||
|
-b|--base)
|
||||||
|
shift
|
||||||
|
BASE_BRANCH="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logerr "Unknown option $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
CURRENT_BRANCH="$(git branch --show-current)"
|
||||||
|
BASE_BRANCH="${BASE_BRANCH:-${CURRENT_BRANCH}}"
|
||||||
|
|
||||||
|
## check if arg1 is one of the elements in arg2-N
|
||||||
|
is_element() {
|
||||||
|
local e match="$1"
|
||||||
|
shift
|
||||||
|
for e in "${@}"; do
|
||||||
|
if [ "$e" = "$match" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! is_element "$BASE_BRANCH" "${BASE_BRANCHES[@]}"; then
|
||||||
|
logerr "Cannot work with branch $BASE_BRANCH"
|
||||||
|
logerr "The base branch must be one of: ${BASE_BRANCHES[*]}"
|
||||||
|
logerr "Change work branch to one of the above."
|
||||||
|
logerr "OR: use -b|--base to specify from which base branch is current working branch created"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Find git remotes to fetch from.
|
||||||
|
##
|
||||||
|
## NOTE: For enterprise, the opensource repo must be added as a remote.
|
||||||
|
## Because not all changes in opensource repo are synced to enterprise repo immediately.
|
||||||
|
##
|
||||||
|
## NOTE: grep -v enterprise here, but why not to match on full repo name 'emqx/emqx.git'?
|
||||||
|
## It's because the git remote does not always end with .git
|
||||||
|
GIT_REMOTE_CE="$(git remote -v | grep 'emqx/emqx' | grep -v enterprise | grep fetch | head -1 | awk '{print $1}' || true)"
|
||||||
|
if [ -z "$GIT_REMOTE_CE" ]; then
|
||||||
|
logerr "Cannot find git remote for emqx/emqx"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
REMOTES=( "${GIT_REMOTE_CE}" )
|
||||||
|
|
||||||
|
## Fetch the remotes
|
||||||
|
for remote in "${REMOTES[@]}"; do
|
||||||
|
logwarn "Fetching from remote=${remote} (force tag sync)."
|
||||||
|
git fetch "$remote" --tags --force
|
||||||
|
done
|
||||||
|
|
||||||
|
logmsg 'Fetched all remotes'
|
||||||
|
|
||||||
|
if [ "$INTERACTIVE" = 'yes' ]; then
|
||||||
|
MERGE_OPTS=''
|
||||||
|
else
|
||||||
|
## Using --ff-only to *check* if the remote is already merged
|
||||||
|
## Also conveniently merged it in case it's *not* merged but can be fast-forwarded
|
||||||
|
## Alternative is to check with 'git merge-base'
|
||||||
|
MERGE_OPTS='--ff-only'
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Get the git remote reference of the given 'release-' or 'main-' branch
|
||||||
|
remote_ref() {
|
||||||
|
local branch="$1"
|
||||||
|
echo -n "${GIT_REMOTE_CE}/${branch} "
|
||||||
|
}
|
||||||
|
|
||||||
|
remote_refs() {
|
||||||
|
local br
|
||||||
|
for br in "${@}"; do
|
||||||
|
remote_ref "$br"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
## Get upstream branches of the given branch
|
||||||
|
upstream_branches() {
|
||||||
|
local base="$1"
|
||||||
|
case "$base" in
|
||||||
|
release-50)
|
||||||
|
remote_ref "$base"
|
||||||
|
;;
|
||||||
|
master)
|
||||||
|
remote_refs "$base" 'release-50'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
for remote_ref in $(upstream_branches "$BASE_BRANCH"); do
|
||||||
|
logmsg "Merging $remote_ref"
|
||||||
|
git merge $MERGE_OPTS "$remote_ref"
|
||||||
|
done
|
Loading…
Reference in New Issue