%% @author Marc Worrell %% @copyright 2009 Marc Worrell %% @doc Start/stop functions for Zotonic %% Copyright 2009 Marc Worrell %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. -module(zotonic). -author('Marc Worrell '). -export([start/0, start/1, stop/0, stop/1, ping/0, status/0, status/1, update/0, update/1, run_tests/0, ensure_started/1]). -compile([{parse_transform, lager_transform}]). -define(MIN_OTP_VERSION, "R14B03"). ensure_started(App) -> case application:start(App) of ok -> ok; {error, {not_started, Dep}} -> case ensure_started(Dep) of ok -> ensure_started(App); Error -> Error end; {error, {already_started, App}} -> ok; {error, Reason} -> Reason end. %% @spec start() -> ok %% @doc Start the zotonic server. start() -> start([]). %% @spec start(_Args) -> ok %% @doc Start the zotonic server. start(_Args) -> test_erlang_version(), zotonic_deps:ensure(), case ensure_started(zotonic) of ok -> ok; Error -> Message = if is_tuple(Error) -> string:join([z_convert:to_list(E) || E <- tuple_to_list(Error)], ": "); is_list(Error) -> Error; true -> z_convert:to_list(Error) end, lager:error("Zotonic failed to start application: ~s~n", [Message]), init:stop() end. %% @spec stop() -> ok %% @doc Stop the zotonic server. stop() -> Res = application:stop(zotonic), application:stop(eiconv), application:stop(mnesia), application:stop(lager), application:stop(webzmachine), application:stop(crypto), Res. %% @spec stop([Node]) -> void() %% @doc Stop a zotonic server on a specific node stop([Node]) -> io:format("Stopping:~p~n",[Node]), case net_adm:ping(Node) of pong -> rpc:cast(Node, init, stop, []); pang -> io:format("There is no node with this name~n") end, init:stop(). %% @doc Just returns 'pong'; used by shell scripts to determine if node is alive. ping() -> pong. %% @spec status() -> ok %% @doc Print the status of the current node. status() -> status([node()]). %% @spec status([node()]) -> ok %% @doc Get server status. Prints the state of sites running. status([Node]) -> [io:format("~-20s- ~s~n", [Site, Status]) || [Site,Status|_] <- rpc:call(Node, z_sites_manager, get_sites_status, [])], ok. %% @spec update() -> ok %% @doc Update the server. Compiles and loads any new code, flushes caches and rescans all modules. update() -> z:m(), ok. %% @spec update([Node]) -> ok %% @doc Update the server on a specific node with new code on disk and flush the caches. update([Node]) -> io:format("Update:~p~n",[Node]), case net_adm:ping(Node) of pong -> rpc:cast(Node, zotonic, update, []); pang -> io:format("There is no node with this name~n") end, init:stop(). test_erlang_version() -> Version = erlang:system_info(otp_release), if Version < ?MIN_OTP_VERSION -> lager:error("Zotonic needs at least Erlang release ~p; this is ~p", [?MIN_OTP_VERSION, Version]), erlang:exit({minimal_otp_version, ?MIN_OTP_VERSION}); true -> ok end. run_tests() -> z_media_preview_tests:test().