93 lines
3.4 KiB
Erlang
93 lines
3.4 KiB
Erlang
%%%-------------------------------------------------------------------
|
|
%%% @author anlicheng
|
|
%%% @copyright (C) 2026, <COMPANY>
|
|
%%% @doc
|
|
%%%
|
|
%%% @end
|
|
%%% Created : 20. 4月 2026
|
|
%%%-------------------------------------------------------------------
|
|
-module(docker_deploy_manager).
|
|
-author("anlicheng").
|
|
-include("message_pb.hrl").
|
|
|
|
-behaviour(gen_server).
|
|
|
|
%% API
|
|
-export([start_link/0, deploy/2]).
|
|
|
|
%% gen_server callbacks
|
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
|
|
|
-define(SERVER, ?MODULE).
|
|
|
|
-record(state, {
|
|
root_dir :: string(),
|
|
task_map = #{}
|
|
}).
|
|
|
|
%%%===================================================================
|
|
%%% API
|
|
%%%===================================================================
|
|
|
|
-spec start_link() -> {ok, pid()} | ignore | {error, term()}.
|
|
start_link() ->
|
|
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
|
|
|
|
-spec deploy(integer(), message_pb:'ContainerDeployParams'()) -> ok | {error, binary()}.
|
|
deploy(TaskId, Params) when is_integer(TaskId), is_record(Params, 'ContainerDeployParams') ->
|
|
gen_server:call(?SERVER, {deploy, TaskId, Params}).
|
|
|
|
%%%===================================================================
|
|
%%% gen_server callbacks
|
|
%%%===================================================================
|
|
|
|
-spec init(list()) -> {ok, #state{}}.
|
|
init([]) ->
|
|
erlang:process_flag(trap_exit, true),
|
|
{ok, RootDir} = application:get_env(efka, root_dir),
|
|
{ok, #state{root_dir = RootDir}}.
|
|
|
|
-spec handle_call(term(), {pid(), term()}, #state{}) -> {reply, term(), #state{}}.
|
|
handle_call({deploy, TaskId, Params = #'ContainerDeployParams'{
|
|
container_name = ContainerName,
|
|
container_dir = ContainerDir0
|
|
}}, _From, State = #state{root_dir = RootDir, task_map = TaskMap}) ->
|
|
{ok, ContainerDir} = docker_helper:ensure_container_dir(RootDir, ContainerName, ContainerDir0),
|
|
{ok, {TaskPid, _Ref}} = docker_deployer:start_monitor(TaskId, ContainerDir, Params),
|
|
logger:debug("[docker_deploy_manager] start deploy task_id: ~p, params: ~p", [TaskId, Params]),
|
|
{reply, ok, State#state{task_map = maps:put(TaskPid, TaskId, TaskMap)}};
|
|
handle_call(_Request, _From, State) ->
|
|
{reply, ok, State}.
|
|
|
|
-spec handle_cast(term(), #state{}) -> {noreply, #state{}}.
|
|
handle_cast(_Request, State) ->
|
|
{noreply, State}.
|
|
|
|
-spec handle_info(term(), #state{}) -> {noreply, #state{}}.
|
|
handle_info({'DOWN', _Ref, process, TaskPid, Reason}, State = #state{task_map = TaskMap}) ->
|
|
case maps:take(TaskPid, TaskMap) of
|
|
error ->
|
|
{noreply, State};
|
|
{TaskId, NTaskMap} ->
|
|
case Reason of
|
|
normal ->
|
|
logger:debug("[docker_deploy_manager] task_id: ~p, exit normal", [TaskId]);
|
|
Error0 ->
|
|
Error = iolist_to_binary(io_lib:format("~p", [Error0])),
|
|
docker_task_reporter:stream(TaskId, <<"error">>, <<"任务失败: "/utf8, Error/binary>>),
|
|
docker_task_reporter:close(TaskId, <<"task exited">>),
|
|
logger:notice("[docker_deploy_manager] task_id: ~p, exit with error: ~p", [TaskId, Error])
|
|
end,
|
|
{noreply, State#state{task_map = NTaskMap}}
|
|
end;
|
|
handle_info(_Info, State) ->
|
|
{noreply, State}.
|
|
|
|
-spec terminate(term(), #state{}) -> ok.
|
|
terminate(_Reason, _State) ->
|
|
ok.
|
|
|
|
-spec code_change(term(), #state{}, term()) -> {ok, #state{}}.
|
|
code_change(_OldVsn, State, _Extra) ->
|
|
{ok, State}.
|