diff --git a/apps/efka/src/docker/docker_commands.erl b/apps/efka/src/docker/docker_commands.erl index 186dff5..48a7d31 100644 --- a/apps/efka/src/docker/docker_commands.erl +++ b/apps/efka/src/docker/docker_commands.erl @@ -18,16 +18,16 @@ -spec pull_image(Image :: binary(), Callback :: fun((Msg :: any()) -> no_return())) -> ok | {error, Reason :: any()}. pull_image(Image, Callback) when is_binary(Image), is_function(Callback, 1) -> Url = lists:flatten(io_lib:format("/images/create?fromImage=~s", [binary_to_list(Image)])), - docker_http:stream_request(Callback, "POST", Url, undefined, []). + docker_http:stream_request(Callback, "POST", Url, <<>>, []). -spec check_image_exist(Image :: binary()) -> boolean(). check_image_exist(Image) when is_binary(Image) -> - Url = io_lib:format("/images/~s/json", [binary_to_list(Image)]), - case docker_http:request("GET", Url, undefined, []) of + Url = lists:flatten(io_lib:format("/images/~s/json", [binary_to_list(Image)])), + case docker_http:request("GET", Url, <<"">>, []) of {ok, 200, _Headers, Resp} -> M = catch jiffy:decode(Resp, [return_maps]), is_map(M) andalso maps:is_key(<<"Id">>, M); - {ok, _, _Headers, _Error} -> + _ -> false end. @@ -46,13 +46,19 @@ create_container(ContainerName, ContainerDir, Config) when is_binary(ContainerNa display_options(Options), Body = iolist_to_binary(jiffy:encode(Options, [force_utf8])), + true = is_binary(Body), + Headers = [ {<<"Content-Type">>, <<"application/json">>} ], case docker_http:request("POST", Url, Body, Headers) of {ok, 201, _Headers, Resp} -> - #{<<"Id">> := ContainerId} = jiffy:decode(Resp, [return_maps]), - {ok, ContainerId}; + case catch jiffy:decode(Resp, [return_maps]) of + #{<<"Id">> := ContainerId} when is_binary(ContainerId) -> + {ok, ContainerId}; + _ -> + {error, Resp} + end; {ok, _StatusCode, _, ErrorResp} -> case catch jiffy:decode(ErrorResp, [return_maps]) of #{<<"message">> := Msg} -> @@ -88,7 +94,7 @@ start_container(ContainerName) when is_binary(ContainerName) -> Headers = [ {<<"Content-Type">>, <<"application/json">>} ], - case docker_http:request("POST", Url, undefined, Headers) of + case docker_http:request("POST", Url, <<>>, Headers) of {ok, 204, _Headers, _} -> ok; {ok, 304, _Headers, _} -> @@ -99,7 +105,9 @@ start_container(ContainerName) when is_binary(ContainerName) -> {error, Msg}; _ -> {error, ErrorResp} - end + end; + {error, Reason} -> + {error, Reason} end. -spec stop_container(ContainerName :: binary()) -> ok | {error, Reason :: binary()}. @@ -108,7 +116,7 @@ stop_container(ContainerName) when is_binary(ContainerName) -> Headers = [ {<<"Content-Type">>, <<"application/json">>} ], - case docker_http:request("POST", Url, undefined, Headers) of + case docker_http:request("POST", Url, <<>>, Headers) of {ok, 204, _Headers, _} -> ok; {ok, 304, _Headers, _} -> @@ -119,7 +127,9 @@ stop_container(ContainerName) when is_binary(ContainerName) -> {error, Msg}; _ -> {error, ErrorResp} - end + end; + {error, Reason} -> + {error, Reason} end. -spec kill_container(ContainerName :: binary()) -> ok | {error, Reason :: binary()}. @@ -128,7 +138,7 @@ kill_container(ContainerName) when is_binary(ContainerName) -> Headers = [ {<<"Content-Type">>, <<"application/json">>} ], - case docker_http:request("POST", Url, undefined, Headers) of + case docker_http:request("POST", Url, <<>>, Headers) of {ok, 204, _Headers, _} -> ok; {ok, _StatusCode, _Header, ErrorResp} -> @@ -137,7 +147,9 @@ kill_container(ContainerName) when is_binary(ContainerName) -> {error, Msg}; _ -> {error, ErrorResp} - end + end; + {error, Reason} -> + {error, Reason} end. -spec remove_container(ContainerName :: binary()) -> ok | {error, Reason :: binary()}. @@ -146,7 +158,7 @@ remove_container(ContainerName) when is_binary(ContainerName) -> Headers = [ {<<"Content-Type">>, <<"application/json">>} ], - case docker_http:request("DELETE", Url, undefined, Headers) of + case docker_http:request("DELETE", Url, <<>>, Headers) of {ok, 204, _Headers, _} -> ok; {ok, 304, _Headers, _} -> @@ -157,7 +169,9 @@ remove_container(ContainerName) when is_binary(ContainerName) -> {error, Msg}; _ -> {error, ErrorResp} - end + end; + {error, Reason} -> + {error, Reason} end. -spec get_containers() -> {ok, Containers :: [map()]} | {error, Reason :: binary()}. @@ -166,7 +180,7 @@ get_containers() -> Headers = [ {<<"Content-Type">>, <<"application/json">>} ], - case docker_http:request("GET", Url, undefined, Headers) of + case docker_http:request("GET", Url, <<>>, Headers) of {ok, 200, _Headers, ContainersBin} -> Containers = jiffy:decode(ContainersBin, [return_maps]), {ok, Containers}; @@ -176,7 +190,9 @@ get_containers() -> {error, Msg}; _ -> {error, ErrorResp} - end + end; + {error, Reason} -> + {error, Reason} end. -spec inspect_container(ContainerId :: binary()) -> {ok, Json :: map()} | {error, Error :: any()}. @@ -185,7 +201,7 @@ inspect_container(ContainerId) when is_binary(ContainerId) -> Headers = [ {<<"Content-Type">>, <<"application/json">>} ], - case docker_http:request("GET", Url, undefined, Headers) of + case docker_http:request("GET", Url, <<>>, Headers) of {ok, 200, _Headers, Resp} -> Json = jiffy:decode(Resp, [return_maps]), {ok, Json}; @@ -195,7 +211,9 @@ inspect_container(ContainerId) when is_binary(ContainerId) -> {error, Msg}; _ -> {error, ErrorResp} - end + end; + {error, Reason} -> + {error, Reason} end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -206,7 +224,7 @@ inspect_container(ContainerId) when is_binary(ContainerId) -> build_options(ContainerName, Config) when is_binary(ContainerName), is_map(Config) -> %% 容器名称作为环境变量,注入到运行时环境中 Envs0 = maps:get(<<"envs">>, Config, []), - Envs = [<<"CONTAINER_NAME=", ContainerName>>|Envs0], + Envs = [<<"CONTAINER_NAME=", ContainerName/binary>>|Envs0], #{ <<"Image">> => maps:get(<<"image">>, Config, <<>>), <<"Cmd">> => maps:get(<<"command">>, Config, []), diff --git a/apps/efka/src/docker/docker_http.erl b/apps/efka/src/docker/docker_http.erl index ecc049c..02babba 100644 --- a/apps/efka/src/docker/docker_http.erl +++ b/apps/efka/src/docker/docker_http.erl @@ -10,10 +10,14 @@ request(Method, Path, Body, Headers) when is_list(Method), is_list(Path), is_bin %% 使用 gun:open/2 + {local, Path} 方式 case gun:open_unix(SocketPath, #{}) of {ok, ConnPid} -> - {ok, http} = gun:await_up(ConnPid), - %% 发送 HTTP 请求 - StreamRef = gun:request(ConnPid, Method, Path, Headers, Body), - receive_response(ConnPid, StreamRef); + case gun:await_up(ConnPid) of + {ok, _} -> + %% 发送 HTTP 请求 + StreamRef = gun:request(ConnPid, Method, Path, Headers, Body), + receive_response(ConnPid, StreamRef); + {error, Reason} -> + {error, Reason} + end; {error, Reason} -> {error, Reason} end. @@ -41,20 +45,19 @@ receive_body(ConnPid, StreamRef, Status, Headers, Acc) -> end. %% 通过 Unix Socket 调用 Docker API --spec stream_request(Callback :: any(), Method :: iolist(), Path :: string(), Body :: binary() | undefined, Headers :: list()) -> ok | {error, Reason :: any()}. -stream_request(Callback, Method, Path, Body, Headers) when is_list(Method); is_binary(Method), is_list(Path), is_binary(Body), is_list(Headers) -> +-spec stream_request(Callback :: any(), Method :: string(), Path :: string(), Body :: binary(), Headers :: list()) -> ok | {error, Reason :: any()}. +stream_request(Callback, Method, Path, Body, Headers) when is_list(Method), is_list(Path), is_binary(Body), is_list(Headers) -> SocketPath = "/var/run/docker.sock", case gun:open_unix(SocketPath, #{}) of {ok, ConnPid} -> - {ok, http} = gun:await_up(ConnPid), - %% 如果 Body 是 undefined,就用 <<>> 代替 - BodyBin = case Body of - undefined -> <<>>; - B when is_binary(B) -> B - end, - %% 发送 HTTP 请求 - StreamRef = gun:request(ConnPid, Method, Path, Headers, BodyBin), - receive_response(Callback, ConnPid, StreamRef); + case gun:await_up(ConnPid) of + {ok, _} -> + %% 发送 HTTP 请求 + StreamRef = gun:request(ConnPid, Method, Path, Headers, Body), + receive_response(Callback, ConnPid, StreamRef); + {error, Reason} -> + {error, Reason} + end; {error, Reason} -> Callback({error, Reason}), {error, Reason}