diff --git a/apps/efka/src/docker/docker_commands.erl b/apps/efka/src/docker/docker_commands.erl index 7f87dc5..486fe37 100644 --- a/apps/efka/src/docker/docker_commands.erl +++ b/apps/efka/src/docker/docker_commands.erl @@ -66,6 +66,7 @@ create_container(ContainerName, ContainerDir, Config) when is_binary(ContainerNa PortSettings = [stream, exit_status, stderr_to_stdout, use_stdio, binary], ExecCmd = "docker create --name " ++ binary_to_list(ContainerName) ++ " " ++ binary_to_list(CreateArgs), lager:debug("create_container cmd : ~p", [ExecCmd]), + case catch erlang:open_port({spawn, ExecCmd}, PortSettings) of Port when is_port(Port) -> case gather_output(Port) of diff --git a/apps/efka/src/docker/docker_http.erl b/apps/efka/src/docker/docker_http.erl new file mode 100644 index 0000000..f122add --- /dev/null +++ b/apps/efka/src/docker/docker_http.erl @@ -0,0 +1,57 @@ +%%% docker_http.erl +-module(docker_http). +-export([request/4]). +-export([test/0]). + +test() -> + try + Path = "/api/detail?user_id=a23147f0-2faa-40fc-b1ae-fa387bc7349f&id=16322", + catch request(get, "/manifest.json", undefined, []) + catch _:Reason:Stack -> + lager:debug("reason: ~p", [Reason]), + lager:debug("stack: ~p", [Stack]) + end. + +%% 通过 Unix Socket 调用 Docker API +-spec request(Method :: atom(), Path :: string(), Body :: binary() | undefined, Headers :: list()) -> + {ok, StatusCode :: integer(), RespBody :: binary()} | {error, any()}. +request(Method, Path, Body, Headers) -> + SocketPath = "/var/run/docker.sock", + %% 使用 gun:open/2 + {local, Path} 方式 + case gun:open("127.0.0.1", 80) of + {ok, ConnPid} -> + {ok, _} = Res = gun:await_up(ConnPid), + lager:debug("gun up: ~p, res: ~p", [ConnPid, Res]), + %% 如果 Body 是 undefined,就用 <<>> 代替 + BodyBin = case Body of + undefined -> <<>>; + B when is_binary(B) -> B + end, + %% 发送 HTTP 请求 + StreamRef = gun:request(ConnPid, <<"GET">>, Path, Headers, BodyBin), + lager:debug("stream is: ~p", [StreamRef]), + receive_response(ConnPid, StreamRef); + {error, Reason} -> + {error, Reason} + end. + +receive_response(ConnPid, StreamRef) -> + receive + {gun_response, ConnPid, StreamRef, nofin, Status, Headers} -> + receive_body(ConnPid, StreamRef, Status, Headers, <<>>); + {gun_down, ConnPid, _, Reason, _} -> + {error, {http_closed, Reason}} + after 5000 -> + {error, timeout11} + end. + +receive_body(ConnPid, StreamRef, Status, Headers, Acc) -> + receive + {gun_data, ConnPid, StreamRef, fin, Data} -> + {ok, Status, Headers, <>}; + {gun_data, ConnPid, StreamRef, nofin, Data} -> + NewAcc = <>, + receive_body(ConnPid, StreamRef, Status, Headers, NewAcc) + after 10000 -> + {error, timeout22} + end. \ No newline at end of file diff --git a/apps/efka/src/efka.app.src b/apps/efka/src/efka.app.src index ff62928..064baa8 100644 --- a/apps/efka/src/efka.app.src +++ b/apps/efka/src/efka.app.src @@ -12,6 +12,8 @@ cowboy, ranch, crypto, + gun, + cowlib, inets, ssl, public_key, diff --git a/rebar.config b/rebar.config index fd44992..55735e9 100644 --- a/rebar.config +++ b/rebar.config @@ -3,6 +3,7 @@ {sync, ".*", {git, "https://github.com/rustyio/sync.git", {branch, "master"}}}, {jiffy, ".*", {git, "https://github.com/davisp/jiffy.git", {tag, "1.1.2"}}}, {cowboy, ".*", {git, "https://github.com/ninenines/cowboy.git", {tag, "2.10.0"}}}, + {gun, ".*", {git, "https://github.com/ninenines/gun.git", {tag, "2.2.0"}}}, {parse_trans, ".*", {git, "https://github.com/uwiger/parse_trans", {tag, "3.0.0"}}}, {lager, ".*", {git,"https://github.com/erlang-lager/lager.git", {tag, "3.9.2"}}} ]}.