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
-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()}.
pull_image(Image) when is_binary(Image) ->
@ -34,8 +34,8 @@ pull_image(Image) when is_binary(Image) ->
{error, <<"exec command startup failed">>}
end.
-spec create_container(ContainerDir :: string(), Config :: map()) -> ok | {error, Reason :: any()}.
create_container(ContainerDir, Config) when is_map(Config) ->
-spec create_container(ContainerName :: binary(), ContainerDir :: string(), Config :: map()) -> ok | {error, Reason :: any()}.
create_container(ContainerName, ContainerDir, Config) when is_binary(ContainerName), is_list(ContainerDir), is_map(Config) ->
Image = maps:get(<<"image">>, Config),
Cmd = maps:get(<<"command">>, Config, []),
@ -49,7 +49,7 @@ create_container(ContainerDir, Config) when is_map(Config) ->
%% todo {stderr_to_stdout, true}
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]),
case catch erlang:open_port({spawn, ExecCmd}, PortSettings) of
Port when is_port(Port) ->
@ -85,6 +85,23 @@ check_image_exist(Image) when is_binary(Image) ->
false
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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -120,7 +137,6 @@ starts_with(Binary, Prefix) when is_binary(Binary), is_binary(Prefix) ->
%%
build_options(Config) ->
lists:flatten([
build_name(Config),
build_entrypoint(Config),
build_ports(Config),
build_expose(Config),
@ -145,12 +161,6 @@ build_options(Config) ->
build_healthcheck(Config)
]).
build_name(Config) ->
case maps:get(<<"container_name">>, Config, undefined) of
undefined -> [];
Name -> [<<"--name">>, Name]
end.
build_entrypoint(Config) ->
case maps:get(<<"entrypoint">>, Config, []) of
[] -> [];
@ -170,7 +180,7 @@ build_volumes(Config) ->
lists:map(fun(V) -> [<<"-v">>, V] end, Vols).
build_env(Config) ->
Envs = maps:get(<<"environment">>, Config, []),
Envs = maps:get(<<"envs">>, Config, []),
lists:map(fun(E) -> [<<"-e">>, E] end, Envs).
build_env_file(Config) ->

View File

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