This commit is contained in:
anlicheng 2025-09-16 15:22:52 +08:00
parent 46bf7e8fcc
commit 737f5dce00
2 changed files with 39 additions and 24 deletions

View File

@ -11,7 +11,7 @@
%% API %% API
-export([pull_image/1, check_image_exist/1]). -export([pull_image/1, check_image_exist/1]).
-export([create_container/2]). -export([create_container/3, check_container_exist/1]).
-spec pull_image(Image :: binary()) -> ok | {error, Reason :: any()}. -spec pull_image(Image :: binary()) -> ok | {error, Reason :: any()}.
pull_image(Image) when is_binary(Image) -> pull_image(Image) when is_binary(Image) ->
@ -34,8 +34,8 @@ pull_image(Image) when is_binary(Image) ->
{error, <<"exec command startup failed">>} {error, <<"exec command startup failed">>}
end. end.
-spec create_container(ContainerDir :: string(), Config :: map()) -> ok | {error, Reason :: any()}. -spec create_container(ContainerName :: binary(), ContainerDir :: string(), Config :: map()) -> ok | {error, Reason :: any()}.
create_container(ContainerDir, Config) when is_map(Config) -> create_container(ContainerName, ContainerDir, Config) when is_binary(ContainerName), is_list(ContainerDir), is_map(Config) ->
Image = maps:get(<<"image">>, Config), Image = maps:get(<<"image">>, Config),
Cmd = maps:get(<<"command">>, Config, []), Cmd = maps:get(<<"command">>, Config, []),
@ -49,7 +49,7 @@ create_container(ContainerDir, Config) when is_map(Config) ->
%% todo {stderr_to_stdout, true} %% todo {stderr_to_stdout, true}
PortSettings = [stream, exit_status, use_stdio, binary], PortSettings = [stream, exit_status, use_stdio, binary],
ExecCmd = "docker create " ++ binary_to_list(CreateArgs), ExecCmd = "docker create --name " ++ binary_to_list(ContainerName) ++ " " ++ binary_to_list(CreateArgs),
lager:debug("create_container cmd : ~p", [ExecCmd]), lager:debug("create_container cmd : ~p", [ExecCmd]),
case catch erlang:open_port({spawn, ExecCmd}, PortSettings) of case catch erlang:open_port({spawn, ExecCmd}, PortSettings) of
Port when is_port(Port) -> Port when is_port(Port) ->
@ -85,6 +85,23 @@ check_image_exist(Image) when is_binary(Image) ->
false false
end. end.
-spec check_container_exist(ContainerName :: binary()) -> boolean().
check_container_exist(ContainerName) when is_binary(ContainerName) ->
PortSettings = [stream, exit_status, use_stdio, binary],
ExecCmd = "docker inspect --type=container " ++ binary_to_list(ContainerName) ++ " >/dev/null 2>&1",
lager:debug("check_container_exist cmd : ~p", [ExecCmd]),
case catch erlang:open_port({spawn, ExecCmd}, PortSettings) of
Port when is_port(Port) ->
case gather_output(Port) of
{0, _} ->
true;
{_ExitCode, _Error} ->
false
end;
_Error ->
false
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% helper methods %%% helper methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -120,7 +137,6 @@ starts_with(Binary, Prefix) when is_binary(Binary), is_binary(Prefix) ->
%% %%
build_options(Config) -> build_options(Config) ->
lists:flatten([ lists:flatten([
build_name(Config),
build_entrypoint(Config), build_entrypoint(Config),
build_ports(Config), build_ports(Config),
build_expose(Config), build_expose(Config),
@ -145,12 +161,6 @@ build_options(Config) ->
build_healthcheck(Config) build_healthcheck(Config)
]). ]).
build_name(Config) ->
case maps:get(<<"container_name">>, Config, undefined) of
undefined -> [];
Name -> [<<"--name">>, Name]
end.
build_entrypoint(Config) -> build_entrypoint(Config) ->
case maps:get(<<"entrypoint">>, Config, []) of case maps:get(<<"entrypoint">>, Config, []) of
[] -> []; [] -> [];
@ -170,7 +180,7 @@ build_volumes(Config) ->
lists:map(fun(V) -> [<<"-v">>, V] end, Vols). lists:map(fun(V) -> [<<"-v">>, V] end, Vols).
build_env(Config) -> build_env(Config) ->
Envs = maps:get(<<"environment">>, Config, []), Envs = maps:get(<<"envs">>, Config, []),
lists:map(fun(E) -> [<<"-e">>, E] end, Envs). lists:map(fun(E) -> [<<"-e">>, E] end, Envs).
build_env_file(Config) -> build_env_file(Config) ->

View File

@ -25,8 +25,7 @@
-record(state, { -record(state, {
root_dir :: string(), root_dir :: string(),
task_id :: integer(), task_id :: integer(),
image_url :: binary(), config = #{}
args = [] :: list()
}). }).
test() -> test() ->
@ -35,7 +34,7 @@ test() ->
<<"container_name">> => <<"my_nginx">>, <<"container_name">> => <<"my_nginx">>,
<<"command">> => [<<"nginx">>,<<"-g">>,<<"daemon off;">>], <<"command">> => [<<"nginx">>,<<"-g">>,<<"daemon off;">>],
<<"entrypoint">> => [<<"/docker-entrypoint.sh">>], <<"entrypoint">> => [<<"/docker-entrypoint.sh">>],
<<"environment">> => [<<"ENV1=val1">>, <<"ENV2=val2">>], <<"envs">> => [<<"ENV1=val1">>, <<"ENV2=val2">>],
<<"env_file">> => [<<"./env.list">>], <<"env_file">> => [<<"./env.list">>],
<<"ports">> => [<<"8080:80">>, <<"443:443">>], <<"ports">> => [<<"8080:80">>, <<"443:443">>],
<<"expose">> => [<<"80">>, <<"443">>], <<"expose">> => [<<"80">>, <<"443">>],
@ -96,8 +95,8 @@ start_link(TaskId, RootDir, Config) when is_integer(TaskId), is_list(RootDir), i
-spec(init(Args :: term()) -> -spec(init(Args :: term()) ->
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} | {ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
{stop, Reason :: term()} | ignore). {stop, Reason :: term()} | ignore).
init([TaskId, RootDir, ImageUrl, Args]) -> init([TaskId, RootDir, Config]) ->
{ok, #state{task_id = TaskId, root_dir = RootDir, image_url = ImageUrl, args = Args}}. {ok, #state{task_id = TaskId, root_dir = RootDir, config = Config}}.
%% @private %% @private
%% @doc Handling call messages %% @doc Handling call messages
@ -118,8 +117,8 @@ handle_call(_Request, _From, State = #state{}) ->
{noreply, NewState :: #state{}} | {noreply, NewState :: #state{}} |
{noreply, NewState :: #state{}, timeout() | hibernate} | {noreply, NewState :: #state{}, timeout() | hibernate} |
{stop, Reason :: term(), NewState :: #state{}}). {stop, Reason :: term(), NewState :: #state{}}).
handle_cast(deploy, State = #state{task_id = TaskId, root_dir = RootDir, image_url = ImageUrl, args = Args}) -> handle_cast(deploy, State = #state{task_id = TaskId, root_dir = RootDir, config = Config}) ->
do_deploy(TaskId, RootDir, ImageUrl, Args), do_deploy(TaskId, RootDir, Config),
{stop, normal, State}; {stop, normal, State};
handle_cast(_Request, State) -> handle_cast(_Request, State) ->
{stop, normal, State}. {stop, normal, State}.
@ -180,11 +179,16 @@ do_deploy(TaskId, RootDir, Config) when is_integer(TaskId), is_list(RootDir), is
maybe_create_env_file(ContainerDir, maps:get(<<"envs">>, Config, [])), maybe_create_env_file(ContainerDir, maps:get(<<"envs">>, Config, [])),
%% , : "/etc/容器名称/" %% , : "/etc/容器名称/"
case efka_docker_command:create_container(ContainerDir, Config) of case efka_docker_command:check_container_exist(ContainerName) of
ok -> true ->
ok; {error, <<"container exist">>};
{error, Reason} -> false ->
{error, Reason} case efka_docker_command:create_container(ContainerName, ContainerDir, Config) of
ok ->
ok;
{error, Reason} ->
{error, Reason}
end
end; end;
{error, Reason} -> {error, Reason} ->
{error, Reason} {error, Reason}
@ -202,6 +206,7 @@ try_pull_image(Image) when is_binary(Image) ->
maybe_create_env_file(_ContainerDir, []) -> maybe_create_env_file(_ContainerDir, []) ->
ok; ok;
maybe_create_env_file(ContainerDir, Envs) when is_list(Envs)-> maybe_create_env_file(ContainerDir, Envs) when is_list(Envs)->
lager:debug("envs: ~p", [Envs]),
TargetFile = ContainerDir ++ "env", TargetFile = ContainerDir ++ "env",
{ok, IoDevice} = file:open(TargetFile, [write, binary]), {ok, IoDevice} = file:open(TargetFile, [write, binary]),
lists:foreach(fun(Env) -> file:write(IoDevice, <<Env/binary, $\n>>) end, Envs), lists:foreach(fun(Env) -> file:write(IoDevice, <<Env/binary, $\n>>) end, Envs),