⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 release_handler.erl

📁 OTP是开放电信平台的简称
💻 ERL
📖 第 1 页 / 共 5 页
字号:
				       [Script],[NewAppl],[OldAppl]) of	{ok, LowLevelScript} ->	    {ok, NewVsn, LowLevelScript};	{error, _SystoolsRC, Reason} ->	    throw(Reason)    end.downgrade_script(App, OldVsn, OldDir) ->    NewVsn = ensure_running(App),    NewDir = code:lib_dir(App),    {NewVsn, Script} = find_script(App, NewDir, OldVsn, down),    OldAppl = read_app(App, OldVsn, OldDir),    NewAppl = read_app(App, NewVsn, NewDir),    case systools_rc:translate_scripts(dn,				       [Script],[OldAppl],[NewAppl]) of	{ok, LowLevelScript} ->	    {ok, LowLevelScript};	{error, _SystoolsRC, Reason} ->	    throw(Reason)    end.eval_appup_script(App, ToVsn, ToDir, Script) ->    EnvBefore = application_controller:prep_config_change(),    AppSpecL = read_appspec(App, ToDir),    Res = release_handler_1:eval_script(Script,					[], % [AppSpec]					[{App, ToVsn, ToDir}],					[]), % [Opt]    case Res of	{ok, _Unpurged} ->	    application_controller:change_application_data(AppSpecL,[]),	    application_controller:config_change(EnvBefore);	_Res ->	    ignore    end,    Res.ensure_running(App) ->    case lists:keysearch(App, 1, application:which_applications()) of	{value, {_App, _Descr, Vsn}} ->	    Vsn;	false ->	    throw({app_not_running, App})    end.find_script(App, Dir, OldVsn, UpOrDown) ->    Appup = filename:join([Dir, "ebin", atom_to_list(App)++".appup"]),    case file:consult(Appup) of	{ok, [{NewVsn, UpFromScripts, DownToScripts}]} ->	    Scripts = case UpOrDown of			  up -> UpFromScripts;			  down -> DownToScripts		      end,	    case lists:keysearch(OldVsn, 1, Scripts) of		{value, {_OldVsn, Script}} ->		    {NewVsn, Script};		false ->		    throw({version_not_in_appup, OldVsn})	    end;	{error, enoent} ->	    throw(no_appup_found);	{error, Reason} ->	    throw(Reason)    end.read_app(App, Vsn, Dir) ->    AppS = atom_to_list(App),    Path = [filename:join(Dir, "ebin")],    case systools_make:read_application(AppS, Vsn, Path, []) of	{ok, Appl} ->	    Appl;	{error, {not_found, _AppFile}} ->	    throw({no_app_found, Vsn, Dir});	{error, Reason} ->	    throw(Reason)    end.read_appspec(App, Dir) ->    AppS = atom_to_list(App),    Path = [filename:join(Dir, "ebin")],    case file:path_consult(Path, AppS++".app") of	{ok, AppSpecL, _File} ->	    AppSpecL;	{error, Reason} ->	    throw(Reason)    end.				      				         	        %%-----------------------------------------------------------------%% Call-back functions from gen_server%%-----------------------------------------------------------------init([]) ->    {ok, [[Root]]} = init:get_argument(root),    {CliDir, Masters} = is_client(),    ReleaseDir =	case application:get_env(sasl, releases_dir) of	    undefined ->		case os:getenv("RELDIR") of		    false ->			if			    CliDir == false ->				filename:join([Root, "releases"]);			    true ->				filename:join([CliDir, "releases"])			end;		    RELDIR ->			RELDIR		end;	    {ok, Dir} ->		Dir	end,    Releases =	case consult(filename:join(ReleaseDir, "RELEASES"), Masters) of	    {ok, [Term]} ->		transform_release(ReleaseDir, Term, Masters);	    _ ->		{Name, Vsn} = init:script_id(),		[#release{name = Name, vsn = Vsn, status = permanent}]	end,    StartPrg =	case application:get_env(start_prg) of	    {ok, Found2} when is_list(Found2) ->		{do_check, Found2};	    _ ->		{no_check, filename:join([Root, "bin", "start"])}	end,    Static =	case application:get_env(static_emulator) of	    {ok, SFlag} when is_atom(SFlag) -> SFlag;	    _                            -> false	end,    {ok, #state{root = Root, rel_dir = ReleaseDir, releases = Releases,		start_prg = StartPrg, masters = Masters,	        client_dir = CliDir, static_emulator = Static}}.handle_call({unpack_release, ReleaseName}, _From, S)  when S#state.masters == false ->    RelDir = S#state.rel_dir,    case catch do_unpack_release(S#state.root, RelDir,				 ReleaseName, S#state.releases) of	{ok, NewReleases, Vsn} -> 	    clean_release(RelDir, ReleaseName),	    {reply, {ok, Vsn}, S#state{releases = NewReleases}};	{error, Reason}   ->	    {reply, {error, Reason}, S}; 	{'EXIT', Reason} ->	    {reply, {error, Reason}, S}    end;handle_call({unpack_release, _ReleaseName}, _From, S) ->    {reply, {error, client_node}, S};handle_call({check_install_release, Vsn}, _From, S) ->    case catch do_check_install_release(S#state.rel_dir,					Vsn,					S#state.releases,					S#state.masters) of	{ok, CurrentVsn, Descr} -> 	    {reply, {ok, CurrentVsn, Descr}, S};	{error, Reason}   ->	    {reply, {error, Reason}, S}; 	{'EXIT', Reason} ->	    {reply, {error, Reason}, S}    end;handle_call({install_release, Vsn, ErrorAction, Opts}, From, S) ->    NS = resend_sync_nodes(S),    case catch do_install_release(S, Vsn, Opts) of	{ok, NewReleases, CurrentVsn, Descr} -> 	    {reply, {ok, CurrentVsn, Descr}, NS#state{releases=NewReleases}};	{ok, NewReleases, Unpurged, CurrentVsn, Descr} ->	    Timer =		case S#state.timer of		    undefined ->			{ok, Ref} = timer:send_interval(?timeout, timeout),			Ref;		    Ref -> Ref		end,	    NewS = NS#state{releases = NewReleases, unpurged = Unpurged,			    timer = Timer},	    {reply, {ok, CurrentVsn, Descr}, NewS};	{error, Reason}   ->	    {reply, {error, Reason}, NS}; 	{restart_new_emulator, CurrentVsn, Descr} ->	    gen_server:reply(From, {ok, CurrentVsn, Descr}),	    init:reboot(),	    {noreply, NS};	{'EXIT', Reason} ->	    io:format("release_handler:"		      "install_release(Vsn=~p Opts=~p) failed, "		      "Reason=~p~n", [Vsn, Opts, Reason]),	    gen_server:reply(From, {error, Reason}),	    case ErrorAction of		restart ->		    init:restart();		reboot ->		    init:reboot()	    end,	    {noreply, NS}    end;handle_call({make_permanent, Vsn}, _From, S) ->    case catch do_make_permanent(S, Vsn) of	{ok, Releases, Unpurged} ->	    {reply, ok, S#state{releases = Releases, unpurged = Unpurged}};	{error, Reason}   ->	    {reply, {error, Reason}, S}; 	{'EXIT', Reason} ->	    {reply, {error, Reason}, S}    end;handle_call({reboot_old_release, Vsn}, From, S) ->    case catch do_reboot_old_release(S, Vsn) of	ok ->	    gen_server:reply(From, ok),	    init:reboot(),	    {noreply, S};	{error, Reason}   ->	    {reply, {error, Reason}, S}; 	{'EXIT', Reason} ->	    {reply, {error, Reason}, S}    end;handle_call({remove_release, Vsn}, _From, S)  when S#state.masters == false ->    case catch do_remove_release(S#state.root, S#state.rel_dir,				 Vsn, S#state.releases) of	{ok, NewReleases} -> 	    {reply, ok, S#state{releases = NewReleases}};	{error, Reason}   ->	    {reply, {error, Reason}, S}; 	{'EXIT', Reason} ->	    {reply, {error, Reason}, S}    end;handle_call({remove_release, _Vsn}, _From, S) ->    {reply, {error, client_node}, S};handle_call({set_unpacked, RelFile, LibDirs}, _From, S) ->    Root = S#state.root,    case catch do_set_unpacked(Root, S#state.rel_dir, RelFile,			       LibDirs, S#state.releases,			       S#state.masters) of	{ok, NewReleases, Vsn} -> 	    {reply, {ok, Vsn}, S#state{releases = NewReleases}};	{error, Reason}   ->	    {reply, {error, Reason}, S}; 	{'EXIT', Reason} ->	    {reply, {error, Reason}, S}    end;handle_call({set_removed, Vsn}, _From, S) ->    case catch do_set_removed(S#state.rel_dir, Vsn,			      S#state.releases,			      S#state.masters) of	{ok, NewReleases} ->	    {reply, ok, S#state{releases = NewReleases}};	{error, Reason}   ->	    {reply, {error, Reason}, S}; 	{'EXIT', Reason} ->	    {reply, {error, Reason}, S}    end;handle_call({install_file, File, Vsn}, _From, S) ->    Reply = 	case lists:keysearch(Vsn, #release.vsn, S#state.releases) of	    {value, _} ->		Dir = filename:join([S#state.rel_dir, Vsn]),		catch copy_file(File, Dir, S#state.masters);	    _ ->		{error, {no_such_release, Vsn}}	end,    {reply, Reply, S};handle_call(which_releases, _From, S) ->    Reply = lists:map(fun(#release{name = Name, vsn = Vsn, libs = Libs,				   status = Status}) ->			      {Name, Vsn, mk_lib_name(Libs), Status}		      end, S#state.releases),    {reply, Reply, S}.mk_lib_name([{LibName, Vsn, _Dir} | T]) ->    [lists:concat([LibName, "-", Vsn]) | mk_lib_name(T)];mk_lib_name([]) -> [].handle_info(timeout, S) ->    case soft_purge(S#state.unpurged) of	[] ->	    timer:cancel(S#state.timer),	    {noreply, S#state{unpurged = [], timer = undefined}};	Unpurged ->	    {noreply, S#state{unpurged = Unpurged}}    end;handle_info({sync_nodes, Id, Node}, S) ->    PSN = S#state.pre_sync_nodes,    {noreply, S#state{pre_sync_nodes = [{sync_nodes, Id, Node} | PSN]}};handle_info(Msg, State) ->    error_logger:info_msg("release_handler: got unknown message: ~p~n", [Msg]),    {noreply, State}.terminate(_Reason, _State) ->    ok.handle_cast(_Msg, State) ->    {noreply, State}.code_change(_OldVsn, State, _Extra) ->    {ok, State}.%%%-----------------------------------------------------------------%%% Internal functions%%%-----------------------------------------------------------------is_client() ->    case application:get_env(masters) of	{ok, Masters} ->	    Alive = is_alive(),	    case atom_list(Masters) of		true when Alive == true ->		    case application:get_env(client_directory) of			{ok, ClientDir} ->			    case int_list(ClientDir) of				true ->				    {ClientDir, Masters};				_ ->				    exit({bad_parameter, client_directory,					  ClientDir})			    end;			_ ->			    {false, false}		    end;		_ ->		    exit({bad_parameter, masters, Masters})	    end;	_ ->	    {false, false}    end.atom_list([A|T]) when is_atom(A) -> atom_list(T);atom_list([])                    -> true;atom_list(_)                     -> false.int_list([I|T]) when is_integer(I) -> int_list(T);int_list([])                       -> true;int_list(_)                        -> false.resend_sync_nodes(S) ->    lists:foreach(fun(Msg) -> self() ! Msg end, S#state.pre_sync_nodes),    S#state{pre_sync_nodes = []}.soft_purge(Unpurged) ->    lists:filter(fun({Mod, _PostPurgeMethod}) ->			 case code:soft_purge(Mod) of			     true -> false; % No proc left, don't remember Mod			     false -> true  % Still proc left, remember it			 end		 end,		 Unpurged).brutal_purge(Unpurged) ->    lists:filter(fun({Mod, brutal_purge}) -> code:purge(Mod), false;		    (_) -> true		 end,		 Unpurged).%%-----------------------------------------------------------------%% The release package is a RelName.tar.Z (.tar on non unix) file%% with the following contents:%%   - RelName.rel   == {release, {Name, Vsn}, {erts, EVsn}, [lib()]}%%   - <files> according to [lib()]%%   - lib() = {LibName, LibVsn}%% In the Dir, there exists a file called RELEASES, which contains%% a [{Vsn, {erts, EVsn}, {libs, [{LibName, LibVsn, LibDir}]}}].%% Note that RelDir is an absolute directory name !%% Note that this function is not executed by a client%% release_handler.%%-----------------------------------------------------------------do_unpack_release(Root, RelDir, ReleaseName, Releases) ->

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -