Compare commits
2 Commits
425981b7e2
...
616cad6daf
| Author | SHA1 | Date | |
|---|---|---|---|
| 616cad6daf | |||
| cea9fff718 |
@ -63,6 +63,8 @@ handle_request("POST", "/container/push_config", _,
|
|||||||
handle_request("POST", "/container/deploy", _, #{<<"uuid">> := UUID, <<"task_id">> := TaskId, <<"config">> := Config})
|
handle_request("POST", "/container/deploy", _, #{<<"uuid">> := UUID, <<"task_id">> := TaskId, <<"config">> := Config})
|
||||||
when is_binary(UUID), is_integer(TaskId), is_map(Config) ->
|
when is_binary(UUID), is_integer(TaskId), is_map(Config) ->
|
||||||
|
|
||||||
|
case validate_config(Config) of
|
||||||
|
ok ->
|
||||||
case iot_host:get_pid(UUID) of
|
case iot_host:get_pid(UUID) of
|
||||||
undefined ->
|
undefined ->
|
||||||
{ok, 200, iot_util:json_error(404, <<"host not found">>)};
|
{ok, 200, iot_util:json_error(404, <<"host not found">>)};
|
||||||
@ -79,6 +81,10 @@ handle_request("POST", "/container/deploy", _, #{<<"uuid">> := UUID, <<"task_id"
|
|||||||
{ok, 200, iot_util:json_error(400, Reason)}
|
{ok, 200, iot_util:json_error(400, Reason)}
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
{error, Errors} ->
|
||||||
|
Reason = iolist_to_binary(lists:join(<<"|||">>, Errors)),
|
||||||
|
{ok, 200, iot_util:json_error(400, Reason)}
|
||||||
|
end;
|
||||||
|
|
||||||
%% 启动服务
|
%% 启动服务
|
||||||
handle_request("POST", "/container/start", _, #{<<"uuid">> := UUID, <<"container_name">> := ContainerName}) when is_binary(UUID), is_binary(ContainerName) ->
|
handle_request("POST", "/container/start", _, #{<<"uuid">> := UUID, <<"container_name">> := ContainerName}) when is_binary(UUID), is_binary(ContainerName) ->
|
||||||
@ -180,3 +186,120 @@ handle_request(_, Path, _, _) ->
|
|||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
%% helper methods
|
%% helper methods
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
validate_config(Config) when is_map(Config) ->
|
||||||
|
%% 必选参数
|
||||||
|
Required = [
|
||||||
|
{image, binary},
|
||||||
|
{container_name, binary},
|
||||||
|
{command, {list, binary}},
|
||||||
|
{restart, binary},
|
||||||
|
{privileged, boolean}
|
||||||
|
],
|
||||||
|
|
||||||
|
%% 可选参数(附带默认值)
|
||||||
|
Optional = [
|
||||||
|
{envs, {list, binary}},
|
||||||
|
{ports, {list, binary}},
|
||||||
|
{expose, {list, binary}},
|
||||||
|
{volumes, {list, binary}},
|
||||||
|
{networks, {list, binary}},
|
||||||
|
{labels, {map, {binary, binary}}},
|
||||||
|
{user, binary},
|
||||||
|
{working_dir, binary},
|
||||||
|
{hostname, binary},
|
||||||
|
{cap_add, {list, binary}},
|
||||||
|
{cap_drop, {list, binary}},
|
||||||
|
{devices, {list, binary}},
|
||||||
|
{mem_limit, binary},
|
||||||
|
{mem_reservation, binary},
|
||||||
|
{cpu_shares, integer},
|
||||||
|
{cpus, number},
|
||||||
|
{ulimits, {map, {binary, binary}}},
|
||||||
|
{sysctls, {map, {binary, binary}}},
|
||||||
|
{tmpfs, {list, binary}},
|
||||||
|
{extra_hosts, {list, binary}},
|
||||||
|
{healthcheck, {map, {binary, any}}}
|
||||||
|
],
|
||||||
|
|
||||||
|
Errors1 = check_required(Config, Required),
|
||||||
|
Errors2 = check_optional(Config, Optional),
|
||||||
|
|
||||||
|
Errors = Errors1 ++ Errors2,
|
||||||
|
case Errors of
|
||||||
|
[] ->
|
||||||
|
ok;
|
||||||
|
_ ->
|
||||||
|
{error, lists:map(fun erlang:iolist_to_binary/1, Errors)}
|
||||||
|
end;
|
||||||
|
|
||||||
|
validate_config(_) ->
|
||||||
|
{error, [<<"Config 必须为 map() 类型">>]}.
|
||||||
|
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
%% 校验必选项
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
check_required(Config, Fields) ->
|
||||||
|
lists:foldl(
|
||||||
|
fun({Key, Type}, ErrAcc) ->
|
||||||
|
case maps:get(Key, Config, undefined) of
|
||||||
|
undefined ->
|
||||||
|
[io_lib:format("缺少必选参数: ~p", [Key]) | ErrAcc];
|
||||||
|
Value ->
|
||||||
|
case check_type(Value, Type) of
|
||||||
|
true ->
|
||||||
|
ErrAcc;
|
||||||
|
false ->
|
||||||
|
[io_lib:format("参数 ~p 类型错误,应为 ~p", [Key, Type]) | ErrAcc]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
[], Fields).
|
||||||
|
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
%% 校验可选项(支持默认值填充)
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
check_optional(Config, Fields) ->
|
||||||
|
lists:foldl(
|
||||||
|
fun({Key, Type}, ErrAcc) ->
|
||||||
|
case maps:get(Key, Config, undefined) of
|
||||||
|
undefined ->
|
||||||
|
ErrAcc;
|
||||||
|
Value ->
|
||||||
|
case check_type(Value, Type) of
|
||||||
|
true ->
|
||||||
|
ErrAcc;
|
||||||
|
false ->
|
||||||
|
[io_lib:format("可选参数 ~p 类型错误,应为 ~p", [Key, Type]) | ErrAcc]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
[], Fields).
|
||||||
|
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
%% 类型检查辅助函数(binary版)
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
check_type(Value, binary) ->
|
||||||
|
is_binary(Value);
|
||||||
|
check_type(Value, integer) ->
|
||||||
|
is_integer(Value);
|
||||||
|
check_type(Value, number) ->
|
||||||
|
is_number(Value);
|
||||||
|
check_type(Value, list) when is_list(Value) ->
|
||||||
|
true;
|
||||||
|
check_type(Value, {list, binary}) when is_list(Value) ->
|
||||||
|
lists:all(fun(E) -> is_binary(E) end, Value);
|
||||||
|
check_type(Value, {list, number}) when is_list(Value) ->
|
||||||
|
lists:all(fun(E) -> is_number(E) end, Value);
|
||||||
|
check_type(Value, {list, integer}) when is_list(Value) ->
|
||||||
|
lists:all(fun(E) -> is_integer(E) end, Value);
|
||||||
|
check_type(Value, map) when is_map(Value) ->
|
||||||
|
true;
|
||||||
|
check_type(Value, {map, {binary, binary}}) when is_map(Value) ->
|
||||||
|
lists:all(fun({K, V}) -> is_binary(K) andalso is_binary(V) end, maps:to_list(Value));
|
||||||
|
check_type(Value, {map, {binary, any}}) when is_map(Value) ->
|
||||||
|
lists:all(fun({K, _}) -> is_binary(K) end, maps:to_list(Value));
|
||||||
|
check_type(Value, boolean) ->
|
||||||
|
is_boolean(Value);
|
||||||
|
check_type(_, _) ->
|
||||||
|
false.
|
||||||
@ -23,8 +23,9 @@ init(Req0, Opts) ->
|
|||||||
|
|
||||||
lager:debug("method: ~p, path: ~p, get: ~p", [Method, Path, GetParams]),
|
lager:debug("method: ~p, path: ~p, get: ~p", [Method, Path, GetParams]),
|
||||||
Req1 = cowboy_req:stream_reply(200, #{
|
Req1 = cowboy_req:stream_reply(200, #{
|
||||||
<<"content-type">> => <<"text/event-stream">>,
|
<<"Content-Type">> => <<"text/event-stream">>,
|
||||||
<<"cache-control">> => <<"no-cache">>
|
<<"Cache-Control">> => <<"no-cache">>,
|
||||||
|
<<"Connection">> => <<"keep-alive">>
|
||||||
}, Req0),
|
}, Req0),
|
||||||
|
|
||||||
ok = iot_event_stream_observer:add_listener(self(), TaskId),
|
ok = iot_event_stream_observer:add_listener(self(), TaskId),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user