diff options
author | Alexander Strizhakov <alex.strizhakov@gmail.com> | 2020-07-16 19:57:27 +0300 |
---|---|---|
committer | Alexander Strizhakov <alex.strizhakov@gmail.com> | 2020-09-24 10:12:02 +0300 |
commit | a499ea32f7166e61d9168f8279d484ef74ab77f1 (patch) | |
tree | 2886acd623168fbbdf37e8f6d249d20103f90585 | |
parent | e02101e15c425416975f756aca7f3b058006668d (diff) | |
download | pleroma-a499ea32f7166e61d9168f8279d484ef74ab77f1.tar.gz |
split pleroma start into phases
22 files changed, 513 insertions, 599 deletions
diff --git a/lib/mix/pleroma.ex b/lib/mix/pleroma.ex index 49ba2aae4..7c5322ffe 100644 --- a/lib/mix/pleroma.ex +++ b/lib/mix/pleroma.ex @@ -39,31 +39,23 @@ defmodule Mix.Pleroma do children = [ Pleroma.Repo, - {Pleroma.Config.TransferTask, false}, + %{ + id: :env_updater, + start: {Task, :start_link, [&Pleroma.Config.Environment.load_and_update/0]}, + restart: :temporary + }, Pleroma.Web.Endpoint, {Oban, Pleroma.Config.get(Oban)} ] ++ http_children(adapter) - cachex_children = Enum.map(@cachex_children, &Pleroma.Application.build_cachex(&1, [])) + cachex_children = + Enum.map(@cachex_children, &Pleroma.Application.Static.build_cachex({&1, []})) Supervisor.start_link(children ++ cachex_children, strategy: :one_for_one, name: Pleroma.Supervisor ) - - if Pleroma.Config.get(:env) not in [:test, :benchmark] do - pleroma_rebooted?() - end - end - - defp pleroma_rebooted? do - if Restarter.Pleroma.rebooted?() do - :ok - else - Process.sleep(10) - pleroma_rebooted?() - end end def load_pleroma do diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 00ec79a2a..27ed91554 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -5,8 +5,6 @@ defmodule Pleroma.Application do use Application - import Cachex.Spec - alias Pleroma.Config require Logger @@ -16,6 +14,8 @@ defmodule Pleroma.Application do @repository Mix.Project.config()[:source_url] @env Mix.env() + @type env() :: :test | :benchmark | :dev | :prod + def name, do: @name def version, do: @version def named_version, do: @name <> " " <> @version @@ -53,15 +53,13 @@ defmodule Pleroma.Application do Pleroma.Config.Oban.warn() Config.DeprecationWarnings.warn() Pleroma.Plugs.HTTPSecurityPlug.warn_if_disabled() - Pleroma.ApplicationRequirements.verify!() + Pleroma.Application.Requirements.verify!() setup_instrumenters() load_custom_modules() check_system_commands() Pleroma.Docs.JSON.compile() - adapter = Application.get_env(:tesla, :adapter) - - if adapter == Tesla.Adapter.Gun do + if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Gun do if version = Pleroma.OTPVersion.version() do [major, minor] = version @@ -84,32 +82,32 @@ defmodule Pleroma.Application do end # Define workers and child supervisors to be supervised - children = - [ - Pleroma.Repo, - Config.TransferTask, - Pleroma.Emoji, - Pleroma.Plugs.RateLimiter.Supervisor - ] ++ - cachex_children() ++ - http_children(adapter, @env) ++ - [ - Pleroma.Stats, - Pleroma.JobQueueMonitor, - {Oban, Config.get(Oban)} - ] ++ - task_children(@env) ++ - dont_run_in_test(@env) ++ - chat_child(@env, chat_enabled?()) ++ - [ - Pleroma.Web.Endpoint, - Pleroma.Gopher.Server - ] + children = [ + Pleroma.Repo, + Pleroma.Application.DynamicSupervisor, + {Registry, keys: :duplicate, name: Pleroma.Application.DynamicSupervisor.registry()} + ] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html # for other strategies and supported options - opts = [strategy: :one_for_one, name: Pleroma.Supervisor] - Supervisor.start_link(children, opts) + Supervisor.start_link(children, strategy: :one_for_one, name: Pleroma.Supervisor) + end + + def start_phase(:update_env, :normal, _args) do + # Load and update the environment from the config settings in the database + Pleroma.Config.Environment.load_and_update() + end + + def start_phase(:static_children, :normal, _args) do + # Start static children, + # which don't require any configuration or can be configured in runtime + Pleroma.Application.Static.start_children(@env) + end + + def start_phase(:dynamic_children, :normal, _args) do + # Start dynamic children, + # which require restart after some config changes + Pleroma.Application.DynamicSupervisor.start_children(@env) end def load_custom_modules do @@ -154,113 +152,6 @@ defmodule Pleroma.Application do Pleroma.Web.Endpoint.Instrumenter.setup() end - defp cachex_children do - [ - build_cachex("used_captcha", ttl_interval: seconds_valid_interval()), - build_cachex("user", default_ttl: 25_000, ttl_interval: 1000, limit: 2500), - build_cachex("object", default_ttl: 25_000, ttl_interval: 1000, limit: 2500), - build_cachex("rich_media", default_ttl: :timer.minutes(120), limit: 5000), - build_cachex("scrubber", limit: 2500), - build_cachex("idempotency", expiration: idempotency_expiration(), limit: 2500), - build_cachex("web_resp", limit: 2500), - build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10), - build_cachex("failed_proxy_url", limit: 2500), - build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000) - ] - end - - defp emoji_packs_expiration, - do: expiration(default: :timer.seconds(5 * 60), interval: :timer.seconds(60)) - - defp idempotency_expiration, - do: expiration(default: :timer.seconds(6 * 60 * 60), interval: :timer.seconds(60)) - - defp seconds_valid_interval, - do: :timer.seconds(Config.get!([Pleroma.Captcha, :seconds_valid])) - - @spec build_cachex(String.t(), keyword()) :: map() - def build_cachex(type, opts), - do: %{ - id: String.to_atom("cachex_" <> type), - start: {Cachex, :start_link, [String.to_atom(type <> "_cache"), opts]}, - type: :worker - } - - defp chat_enabled?, do: Config.get([:chat, :enabled]) - - defp dont_run_in_test(env) when env in [:test, :benchmark], do: [] - - defp dont_run_in_test(_) do - [ - {Registry, - [ - name: Pleroma.Web.Streamer.registry(), - keys: :duplicate, - partitions: System.schedulers_online() - ]}, - Pleroma.Web.FedSockets.Supervisor - ] - end - - defp chat_child(_env, true) do - [Pleroma.Web.ChatChannel.ChatChannelState] - end - - defp chat_child(_, _), do: [] - - defp task_children(:test) do - [ - %{ - id: :web_push_init, - start: {Task, :start_link, [&Pleroma.Web.Push.init/0]}, - restart: :temporary - } - ] - end - - defp task_children(_) do - [ - %{ - id: :web_push_init, - start: {Task, :start_link, [&Pleroma.Web.Push.init/0]}, - restart: :temporary - }, - %{ - id: :internal_fetch_init, - start: {Task, :start_link, [&Pleroma.Web.ActivityPub.InternalFetchActor.init/0]}, - restart: :temporary - } - ] - end - - # start hackney and gun pools in tests - defp http_children(_, :test) do - http_children(Tesla.Adapter.Hackney, nil) ++ http_children(Tesla.Adapter.Gun, nil) - end - - defp http_children(Tesla.Adapter.Hackney, _) do - pools = [:federation, :media] - - pools = - if Config.get([Pleroma.Upload, :proxy_remote]) do - [:upload | pools] - else - pools - end - - for pool <- pools do - options = Config.get([:hackney_pools, pool]) - :hackney_pool.child_spec(pool, options) - end - end - - defp http_children(Tesla.Adapter.Gun, _) do - Pleroma.Gun.ConnectionPool.children() ++ - [{Task, &Pleroma.HTTP.AdapterHelper.Gun.limiter_setup/0}] - end - - defp http_children(_, _), do: [] - defp check_system_commands do filters = Config.get([Pleroma.Upload, :filters]) diff --git a/lib/pleroma/application/dynamic_supervisor.ex b/lib/pleroma/application/dynamic_supervisor.ex new file mode 100644 index 000000000..bc56ad0fd --- /dev/null +++ b/lib/pleroma/application/dynamic_supervisor.ex @@ -0,0 +1,178 @@ +# # Pleroma: A lightweight social networking server +# # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# # SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Application.DynamicSupervisor do + use DynamicSupervisor + + @registry Pleroma.Application.DynamicSupervisor.Registry + + @type child() :: + Supervisor.child_spec() + | {module(), term()} + | module() + + def start_link(_), do: DynamicSupervisor.start_link(__MODULE__, :no_arg, name: __MODULE__) + + @impl true + def init(_), do: DynamicSupervisor.init(strategy: :one_for_one) + + @spec registry() :: module() + def registry, do: @registry + + @spec start_child(child()) :: DynamicSupervisor.on_start_child() + def start_child(child), do: DynamicSupervisor.start_child(__MODULE__, child) + + @spec start_children(Pleroma.Application.env()) :: :ok + def start_children(env) do + start_agent() + + [ + Pleroma.Plugs.RateLimiter.Supervisor, + Oban, + Pleroma.Web.Endpoint, + Pleroma.Gopher.Server, + Pleroma.Web.ChatChannel.ChatChannelState, + Pleroma.Web.FedSockets.Supervisor + ] + |> add_http_children(env) + |> add_streamer(env) + |> Enum.each(&start_dynamic_child/1) + end + + defp start_agent do + {:ok, pid} = DynamicSupervisor.start_child(__MODULE__, {Agent, fn -> [] end}) + + Registry.register(@registry, "agent", pid) + end + + defp find_agent do + [{_, pid}] = Registry.lookup(@registry, "agent") + pid + end + + defp add_http_children(children, :test) do + hackney_options = Pleroma.Config.get([:hackney_pools, :federation]) + hackney_pool = :hackney_pool.child_spec(:federation, hackney_options) + [hackney_pool, Pleroma.Pool.Supervisor | children] + end + + defp add_http_children(children, _) do + adapter = Application.get_env(:tesla, :adapter) + + child = + if adapter == Tesla.Adapter.Gun do + Pleroma.Pool.Supervisor + else + Pleroma.Application.HackneyPoolSupervisor + end + + [child | children] + end + + defp add_streamer(children, env) when env in [:test, :benchmark], do: children + defp add_streamer(children, _), do: [Pleroma.Web.StreamerRegistry | children] + + defp start_dynamic_child(child) do + with {:ok, pid} <- DynamicSupervisor.start_child(__MODULE__, spec(child)) do + config_path_mappings() + |> Enum.filter(fn {_key, module} -> child == module end) + |> Enum.each(fn {key, _} -> + Registry.register(@registry, key, pid) + end) + end + end + + defp spec(Oban), do: {Oban, Pleroma.Config.get(Oban)} + + defp spec(Pleroma.Web.StreamerRegistry) do + {Registry, + [ + name: Pleroma.Web.Streamer.registry(), + keys: :duplicate, + partitions: System.schedulers_online() + ]} + end + + defp spec(child), do: child + + defp config_path_mappings do + adapter_module = + if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Gun do + Pleroma.Pool.Supervisor + else + Pleroma.Application.HackneyPoolSupervisor + end + + [ + {{:pleroma, :chat}, Pleroma.Web.ChatChannel.ChatChannelState}, + {{:pleroma, Oban}, Oban}, + {{:pleroma, :rate_limit}, Pleroma.Plugs.RateLimiter.Supervisor}, + {{:pleroma, :streamer}, Pleroma.Web.Streamer.registry()}, + {{:pleroma, :pools}, Pleroma.Pool.Supervisor}, + {{:pleroma, :connections_pool}, Pleroma.Pool.Supervisor}, + {{:pleroma, :hackney_pools}, Pleroma.Application.HackneyPoolSupervisor}, + {{:pleroma, Pleroma.Captcha, [:seconds_valid]}, Pleroma.Web.Endpoint}, + {{:pleroma, Pleroma.Upload, [:proxy_remote]}, adapter_module}, + {{:pleroma, :instance, [:upload_limit]}, Pleroma.Web.Endpoint}, + {{:pleroma, :gopher, [:enabled]}, Pleroma.Gopher.Server}, + {{:pleroma, :fed_sockets, [:enabled]}, Pleroma.Web.Endpoint} + ] + end + + @spec save_need_reboot_paths([Pleroma.ConfigDB.t()]) :: :ok + def save_need_reboot_paths([]), do: :ok + + def save_need_reboot_paths(configs) do + configs + |> Enum.map(&find_path(&1.group, &1.key, &1.value)) + |> Enum.filter(& &1) + |> save_paths() + end + + defp find_path(group, key, value) do + with {path, _} <- + Enum.find(config_path_mappings(), fn + {{g, k}, _} -> + g == group and k == key + + {{g, k, subkeys}, _} -> + Keyword.keyword?(value) and g == group and k == key and + Enum.any?(Keyword.keys(value), &(&1 in subkeys)) + end) do + path + end + end + + defp save_paths([]), do: :ok + + defp save_paths(paths), do: Agent.update(find_agent(), &Enum.uniq(&1 ++ paths)) + + @spec need_reboot?() :: boolean() + def need_reboot?, do: Agent.get(find_agent(), & &1) != [] + + @spec restart_children() :: :ok + def restart_children do + find_agent() + |> Agent.get_and_update(&{&1, []}) + |> Enum.each(&restart_child/1) + end + + defp restart_child(path) do + [{_, pid}] = Registry.lookup(@registry, path) + + # main module can have multiple keys + # first we search for main module + with {_, main_module} <- Enum.find(config_path_mappings(), fn {key, _} -> key == path end) do + DynamicSupervisor.terminate_child(__MODULE__, pid) + # then we search for keys, which depends on this main module + config_path_mappings() + |> Enum.filter(fn {_, module} -> main_module == module end) + |> Enum.each(fn {key, _} -> + Registry.unregister(@registry, key) + end) + + start_dynamic_child(main_module) + end + end +end diff --git a/lib/pleroma/application/hackney_pool_supervisor.ex b/lib/pleroma/application/hackney_pool_supervisor.ex new file mode 100644 index 000000000..3e6c31a9c --- /dev/null +++ b/lib/pleroma/application/hackney_pool_supervisor.ex @@ -0,0 +1,30 @@ +# # Pleroma: A lightweight social networking server +# # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# # SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Application.HackneyPoolSupervisor do + use Supervisor + + def start_link(_) do + Supervisor.start_link(__MODULE__, :no_arg) + end + + def init(_) do + pools = [:federation, :media] + + pools = + if Pleroma.Config.get([Pleroma.Upload, :proxy_remote]) do + [:upload | pools] + else + pools + end + + children = + for pool <- pools do + options = Pleroma.Config.get([:hackney_pools, pool]) + :hackney_pool.child_spec(pool, options) + end + + Supervisor.init(children, strategy: :one_for_one) + end +end diff --git a/lib/pleroma/application_requirements.ex b/lib/pleroma/application/requirements.ex index 16f62b6f5..70e0aade3 100644 --- a/lib/pleroma/application_requirements.ex +++ b/lib/pleroma/application/requirements.ex @@ -2,7 +2,7 @@ # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only -defmodule Pleroma.ApplicationRequirements do +defmodule Pleroma.Application.Requirements do @moduledoc """ The module represents the collection of validations to runs before start server. """ diff --git a/lib/pleroma/application/static.ex b/lib/pleroma/application/static.ex new file mode 100644 index 000000000..56667c22c --- /dev/null +++ b/lib/pleroma/application/static.ex @@ -0,0 +1,77 @@ +# # Pleroma: A lightweight social networking server +# # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# # SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Application.Static do + require Cachex.Spec + + @spec start_children(Pleroma.Application.env()) :: :ok + def start_children(env) do + children = + [ + Pleroma.Emoji, + Pleroma.Stats, + Pleroma.JobQueueMonitor, + %{ + id: :web_push_init, + start: {Task, :start_link, [&Pleroma.Web.Push.init/0]}, + restart: :temporary + } + ] + |> add_cachex_children() + |> add_init_internal_fetch_actor_task(env) + + Enum.each(children, &Pleroma.Application.DynamicSupervisor.start_child/1) + end + + @spec build_cachex({String.t(), keyword()}) :: map() + def build_cachex({type, opts}) do + %{ + id: String.to_atom("cachex_" <> type), + start: {Cachex, :start_link, [String.to_atom(type <> "_cache"), opts]}, + type: :worker + } + end + + defp add_cachex_children(children) do + cachex_children = + [ + {"used_captcha", ttl_interval: seconds_valid_interval()}, + {"user", default_ttl: 25_000, ttl_interval: 1000, limit: 2500}, + {"object", default_ttl: 25_000, ttl_interval: 1000, limit: 2500}, + {"rich_media", default_ttl: :timer.minutes(120), limit: 5000}, + {"scrubber", limit: 2500}, + {"idempotency", expiration: cachex_expiration(6 * 60 * 60, 60), limit: 2500}, + {"web_resp", limit: 2500}, + {"emoji_packs", expiration: cachex_expiration(5 * 60, 60), limit: 10}, + {"failed_proxy_url", limit: 2500}, + {"banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000} + ] + |> Enum.map(&build_cachex/1) + + children ++ cachex_children + end + + defp cachex_expiration(default, interval) do + Cachex.Spec.expiration(default: :timer.seconds(default), interval: :timer.seconds(interval)) + end + + defp seconds_valid_interval do + [Pleroma.Captcha, :seconds_valid] + |> Pleroma.Config.get!() + |> :timer.seconds() + end + + defp add_init_internal_fetch_actor_task(children, :test), do: children + + defp add_init_internal_fetch_actor_task(children, _) do + children ++ + [ + %{ + id: :internal_fetch_init, + start: {Task, :start_link, [&Pleroma.Web.ActivityPub.InternalFetchActor.init/0]}, + restart: :temporary + } + ] + end +end diff --git a/lib/pleroma/config/config_db.ex b/lib/pleroma/config/config_db.ex index e5b7811aa..862c06f0a 100644 --- a/lib/pleroma/config/config_db.ex +++ b/lib/pleroma/config/config_db.ex @@ -379,4 +379,29 @@ defmodule Pleroma.ConfigDB do Regex.match?(~r/^(Pleroma|Phoenix|Tesla|Quack|Ueberauth|Swoosh)\./, string) or string in ["Oban", "Ueberauth", "ExSyslogger"] end + + @spec load_and_merge_with_defaults([t()]) :: [{atom(), atom(), term(), term()}] + def load_and_merge_with_defaults(deleted \\ []) do + (Repo.all(ConfigDB) ++ deleted) + |> Enum.map(&merge_with_defaults/1) + end + + defp merge_with_defaults(%{group: group, key: key, value: value} = setting) do + default = Pleroma.Config.Holder.default_config(group, key) + + merged = + cond do + Ecto.get_meta(setting, :state) == :deleted -> default + can_be_merged?(default, value) -> merge_group(group, key, default, value) + true -> value + end + + {group, key, value, merged} + end + + defp can_be_merged?(val1, val2) when is_list(val1) and is_list(val2) do + Keyword.keyword?(val1) and Keyword.keyword?(val2) + end + + defp can_be_merged?(_, _), do: false end diff --git a/lib/pleroma/config/environment.ex b/lib/pleroma/config/environment.ex new file mode 100644 index 000000000..b8fa18855 --- /dev/null +++ b/lib/pleroma/config/environment.ex @@ -0,0 +1,103 @@ +# # Pleroma: A lightweight social networking server +# # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# # SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Config.Environment do + require Logger + + @spec load_and_update([ConfigDB.t()]) :: :ok + def load_and_update(deleted_settings \\ []) do + if Pleroma.Config.get(:configurable_from_database) do + # We need to restart applications for loaded settings take effect + + {logger_settings, settings} = + Pleroma.ConfigDB.load_and_merge_with_defaults(deleted_settings) + |> Enum.split_with(fn {group, _, _, _} -> group in [:logger, :quack] end) + + logger_settings + |> Enum.sort() + |> Enum.each(&configure_logger/1) + + started_applications = Application.started_applications() + + settings + |> Enum.map(&update/1) + |> Enum.uniq() + |> Enum.reject(&(&1 in [nil, :prometheus, :postgrex])) + |> Enum.each(&restart(started_applications, &1)) + end + + :ok + end + + # change logger configuration in runtime, without restart + defp configure_logger({:quack, key, _, merged}) do + Logger.configure_backend(Quack.Logger, [{key, merged}]) + update(:quack, key, merged) + end + + defp configure_logger({_, :backends, _, merged}) do + # removing current backends + Enum.each(Application.get_env(:logger, :backends), &Logger.remove_backend/1) + + Enum.each(merged, &Logger.add_backend/1) + + update(:logger, :backends, merged) + end + + defp configure_logger({_, key, _, merged}) when key in [:console, :ex_syslogger] do + merged = + if key == :console do + put_in(merged[:format], merged[:format] <> "\n") + else + merged + end + + backend = + if key == :ex_syslogger, + do: {ExSyslogger, :ex_syslogger}, + else: key + + Logger.configure_backend(backend, merged) + update(:logger, key, merged) + end + + defp configure_logger({_, key, _, merged}) do + Logger.configure([{key, merged}]) + update(:logger, key, merged) + end + + defp update({group, key, value, merged}) do + update(group, key, merged) + if group != :pleroma, do: group + rescue + error -> + error_msg = + "updating env causes error, group: #{inspect(group)}, key: #{inspect(key)}, value: #{ + inspect(value) + } error: #{inspect(error)}" + + Logger.warn(error_msg) + + nil + end + + defp update(group, key, nil), do: Application.delete_env(group, key) + defp update(group, key, value), do: Application.put_env(group, key, value) + + defp restart(started_applications, app) do + with {^app, _, _} <- List.keyfind(started_applications, app, 0), + :ok <- Application.stop(app), + :ok <- Application.start(app) do + :ok + else + nil -> + Logger.warn("#{app} is not started.") + + error -> + error + |> inspect() + |> Logger.warn() + end + end +end diff --git a/lib/pleroma/config/loader.ex b/lib/pleroma/config/loader.ex index 64e7de6df..4dd03c9dc 100644 --- a/lib/pleroma/config/loader.ex +++ b/lib/pleroma/config/loader.ex @@ -19,19 +19,13 @@ defmodule Pleroma.Config.Loader do if Code.ensure_loaded?(Config.Reader) do @reader Config.Reader - - def read(path), do: @reader.read!(path) else # support for Elixir less than 1.9 @reader Mix.Config - def read(path) do - path - |> @reader.eval!() - |> elem(0) - end end @spec read(Path.t()) :: keyword() + def read(path), do: @reader.read!(path) @spec merge(keyword(), keyword()) :: keyword() def merge(c1, c2), do: @reader.merge(c1, c2) diff --git a/lib/pleroma/config/transfer_task.ex b/lib/pleroma/config/transfer_task.ex deleted file mode 100644 index a0d7b7d71..000000000 --- a/lib/pleroma/config/transfer_task.ex +++ /dev/null @@ -1,201 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Config.TransferTask do - use Task - - alias Pleroma.Config - alias Pleroma.ConfigDB - alias Pleroma.Repo - - require Logger - - @type env() :: :test | :benchmark | :dev | :prod - - @reboot_time_keys [ - {:pleroma, :hackney_pools}, - {:pleroma, :chat}, - {:pleroma, Oban}, - {:pleroma, :rate_limit}, - {:pleroma, :markup}, - {:pleroma, :streamer}, - {:pleroma, :pools}, - {:pleroma, :connections_pool} - ] - - @reboot_time_subkeys [ - {:pleroma, Pleroma.Captcha, [:seconds_valid]}, - {:pleroma, Pleroma.Upload, [:proxy_remote]}, - {:pleroma, :instance, [:upload_limit]}, - {:pleroma, :gopher, [:enabled]} - ] - - def start_link(restart_pleroma? \\ true) do - load_and_update_env([], restart_pleroma?) - if Config.get(:env) == :test, do: Ecto.Adapters.SQL.Sandbox.checkin(Repo) - :ignore - end - - @spec load_and_update_env([ConfigDB.t()], boolean()) :: :ok - def load_and_update_env(deleted_settings \\ [], restart_pleroma? \\ true) do - with {_, true} <- {:configurable, Config.get(:configurable_from_database)} do - # We need to restart applications for loaded settings take effect - - {logger, other} = - (Repo.all(ConfigDB) ++ deleted_settings) - |> Enum.map(&merge_with_default/1) - |> Enum.split_with(fn {group, _, _, _} -> group in [:logger, :quack] end) - - logger - |> Enum.sort() - |> Enum.each(&configure/1) - - started_applications = Application.started_applications() - - # TODO: some problem with prometheus after restart! - reject = [nil, :prometheus, :postgrex] - - reject = - if restart_pleroma? do - reject - else - [:pleroma | reject] - end - - other - |> Enum.map(&update/1) - |> Enum.uniq() - |> Enum.reject(&(&1 in reject)) - |> maybe_set_pleroma_last() - |> Enum.each(&restart(started_applications, &1, Config.get(:env))) - - :ok - else - {:configurable, false} -> Restarter.Pleroma.rebooted() - end - end - - defp maybe_set_pleroma_last(apps) do - # to be ensured that pleroma will be restarted last - if :pleroma in apps do - apps - |> List.delete(:pleroma) - |> List.insert_at(-1, :pleroma) - else - Restarter.Pleroma.rebooted() - apps - end - end - - defp merge_with_default(%{group: group, key: key, value: value} = setting) do - default = Config.Holder.default_config(group, key) - - merged = - cond do - Ecto.get_meta(setting, :state) == :deleted -> default - can_be_merged?(default, value) -> ConfigDB.merge_group(group, key, default, value) - true -> value - end - - {group, key, value, merged} - end - - # change logger configuration in runtime, without restart - defp configure({:quack, key, _, merged}) do - Logger.configure_backend(Quack.Logger, [{key, merged}]) - :ok = update_env(:quack, key, merged) - end - - defp configure({_, :backends, _, merged}) do - # removing current backends - Enum.each(Application.get_env(:logger, :backends), &Logger.remove_backend/1) - - Enum.each(merged, &Logger.add_backend/1) - - :ok = update_env(:logger, :backends, merged) - end - - defp configure({_, key, _, merged}) when key in [:console, :ex_syslogger] do - merged = - if key == :console do - put_in(merged[:format], merged[:format] <> "\n") - else - merged - end - - backend = - if key == :ex_syslogger, - do: {ExSyslogger, :ex_syslogger}, - else: key - - Logger.configure_backend(backend, merged) - :ok = update_env(:logger, key, merged) - end - - defp configure({_, key, _, merged}) do - Logger.configure([{key, merged}]) - :ok = update_env(:logger, key, merged) - end - - defp update({group, key, value, merged}) do - try do - :ok = update_env(group, key, merged) - - if group != :pleroma or pleroma_need_restart?(group, key, value), do: group - rescue - error -> - error_msg = - "updating env causes error, group: #{inspect(group)}, key: #{inspect(key)}, value: #{ - inspect(value) - } error: #{inspect(error)}" - - Logger.warn(error_msg) - - nil - end - end - - defp update_env(group, key, nil), do: Application.delete_env(group, key) - defp update_env(group, key, value), do: Application.put_env(group, key, value) - - @spec pleroma_need_restart?(atom(), atom(), any()) :: boolean() - def pleroma_need_restart?(group, key, value) do - group_and_key_need_reboot?(group, key) or group_and_subkey_need_reboot?(group, key, value) - end - - defp group_and_key_need_reboot?(group, key) do - Enum.any?(@reboot_time_keys, fn {g, k} -> g == group and k == key end) - end - - defp group_and_subkey_need_reboot?(group, key, value) do - Keyword.keyword?(value) and - Enum.any?(@reboot_time_subkeys, fn {g, k, subkeys} -> - g == group and k == key and - Enum.any?(Keyword.keys(value), &(&1 in subkeys)) - end) - end - - defp restart(_, :pleroma, env), do: Restarter.Pleroma.restart_after_boot(env) - - defp restart(started_applications, app, _) do - with {^app, _, _} <- List.keyfind(started_applications, app, 0), - :ok <- Application.stop(app) do - :ok = Application.start(app) - else - nil -> - Logger.warn("#{app} is not started.") - - error -> - error - |> inspect() - |> Logger.warn() - end - end - - defp can_be_merged?(val1, val2) when is_list(val1) and is_list(val2) do - Keyword.keyword?(val1) and Keyword.keyword?(val2) - end - - defp can_be_merged?(_val1, _val2), do: false -end diff --git a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex index d5713c3dd..ea14894c7 100644 --- a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex @@ -628,14 +628,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do def restart(conn, _params) do with :ok <- configurable_from_database() do - Restarter.Pleroma.restart(Config.get(:env), 50) + Task.start(Pleroma.Application.DynamicSupervisor, :restart_children, []) json(conn, %{}) end end def need_reboot(conn, _params) do - json(conn, %{need_reboot: Restarter.Pleroma.need_reboot?()}) + json(conn, %{need_reboot: Pleroma.Application.DynamicSupervisor.need_reboot?()}) end defp configurable_from_database do diff --git a/lib/pleroma/web/admin_api/controllers/config_controller.ex b/lib/pleroma/web/admin_api/controllers/config_controller.ex index 0df13007f..25086172c 100644 --- a/lib/pleroma/web/admin_api/controllers/config_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/config_controller.ex @@ -34,7 +34,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do render(conn, "index.json", %{ configs: configs, - need_reboot: Restarter.Pleroma.need_reboot?() + need_reboot: Pleroma.Application.DynamicSupervisor.need_reboot?() }) end end @@ -75,7 +75,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do render(conn, "index.json", %{ configs: merged, - need_reboot: Restarter.Pleroma.need_reboot?() + need_reboot: Pleroma.Application.DynamicSupervisor.need_reboot?() }) end end @@ -101,19 +101,13 @@ defmodule Pleroma.Web.AdminAPI.ConfigController do end) |> Enum.split_with(&(Ecto.get_meta(&1, :state) == :deleted)) - Config.TransferTask.load_and_update_env(deleted, false) + Config.Environment.load_and_update(deleted) - if not Restarter.Pleroma.need_reboot?() do - changed_reboot_settings? = - (updated ++ deleted) - |> Enum.any?(&Config.TransferTask.pleroma_need_restart?(&1.group, &1.key, &1.value)) - - if changed_reboot_settings?, do: Restarter.Pleroma.need_reboot() - end + Pleroma.Application.DynamicSupervisor.save_need_reboot_paths(updated ++ deleted) render(conn, "index.json", %{ configs: updated, - need_reboot: Restarter.Pleroma.need_reboot?() + need_reboot: Pleroma.Application.DynamicSupervisor.need_reboot?() }) end end @@ -75,12 +75,10 @@ defmodule Pleroma.Mixfile do extra_applications: [ :logger, :runtime_tools, - :comeonin, - :quack, - :fast_sanitize, - :ssl + :fast_sanitize ], - included_applications: [:ex_syslogger] + included_applications: [:ex_syslogger], + start_phases: [update_env: [], static_children: [], dynamic_children: []] ] end @@ -187,7 +185,6 @@ defmodule Pleroma.Mixfile do {:captcha, git: "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"}, - {:restarter, path: "./restarter"}, {:open_api_spex, git: "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git", ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"}, @@ -1,5 +1,6 @@ %{ "accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm", "11b18c220bcc2eab63b5470c038ef10eb6783bcb1fcdb11aa4137defa5ac1bb8"}, + "auto_linker": {:git, "https://git.pleroma.social/pleroma/auto_linker.git", "95e8188490e97505c56636c1379ffdf036c1fdde", [ref: "95e8188490e97505c56636c1379ffdf036c1fdde"]}, "base62": {:hex, :base62, "1.2.1", "4866763e08555a7b3917064e9eef9194c41667276c51b59de2bc42c6ea65f806", [:mix], [{:custom_base, "~> 0.2.1", [hex: :custom_base, repo: "hexpm", optional: false]}], "hexpm", "3b29948de2013d3f93aa898c884a9dff847e7aec75d9d6d8c1dc4c61c2716c42"}, "base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"}, "bbcode": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/bbcode.git", "f2d267675e9a7e1ad1ea9beb4cc23382762b66c2", [ref: "v0.2.0"]}, @@ -109,7 +110,7 @@ "sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"}, "sweet_xml": {:hex, :sweet_xml, "0.6.6", "fc3e91ec5dd7c787b6195757fbcf0abc670cee1e4172687b45183032221b66b8", [:mix], [], "hexpm", "2e1ec458f892ffa81f9f8386e3f35a1af6db7a7a37748a64478f13163a1f3573"}, - "swoosh": {:hex, :swoosh, "1.0.0", "c547cfc83f30e12d5d1fdcb623d7de2c2e29a5becfc68bf8f42ba4d23d2c2756", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "b3b08e463f876cb6167f7168e9ad99a069a724e124bcee61847e0e1ed13f4a0d"}, + "swoosh": {:hex, :swoosh, "1.0.1", "f005f43d6eebcf727b0678e704a0bef79f9eb6bea40a07732be1945df6d4b1d0", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "53ea118852a42fa1de6e931250879ca0a9d12953cb7c8512e884ecde48627e46"}, "syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"}, "telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"}, "tesla": {:git, "https://github.com/teamon/tesla/", "9f7261ca49f9f901ceb73b60219ad6f8a9f6aa30", [ref: "9f7261ca49f9f901ceb73b60219ad6f8a9f6aa30"]}, diff --git a/restarter/lib/pleroma.ex b/restarter/lib/pleroma.ex deleted file mode 100644 index 149a569ce..000000000 --- a/restarter/lib/pleroma.ex +++ /dev/null @@ -1,94 +0,0 @@ -defmodule Restarter.Pleroma do - use GenServer - - require Logger - - @init_state %{need_reboot: false, rebooted: false, after_boot: false} - - def start_link(_) do - GenServer.start_link(__MODULE__, [], name: __MODULE__) - end - - def init(_), do: {:ok, @init_state} - - def rebooted? do - GenServer.call(__MODULE__, :rebooted?) - end - - def rebooted do - GenServer.cast(__MODULE__, :rebooted) - end - - def need_reboot? do - GenServer.call(__MODULE__, :need_reboot?) - end - - def need_reboot do - GenServer.cast(__MODULE__, :need_reboot) - end - - def refresh do - GenServer.cast(__MODULE__, :refresh) - end - - def restart(env, delay) do - GenServer.cast(__MODULE__, {:restart, env, delay}) - end - - def restart_after_boot(env) do - GenServer.cast(__MODULE__, {:after_boot, env}) - end - - def handle_call(:rebooted?, _from, state) do - {:reply, state[:rebooted], state} - end - - def handle_call(:need_reboot?, _from, state) do - {:reply, state[:need_reboot], state} - end - - def handle_cast(:rebooted, state) do - {:noreply, Map.put(state, :rebooted, true)} - end - - def handle_cast(:need_reboot, %{need_reboot: true} = state), do: {:noreply, state} - - def handle_cast(:need_reboot, state) do - {:noreply, Map.put(state, :need_reboot, true)} - end - - def handle_cast(:refresh, _state) do - {:noreply, @init_state} - end - - def handle_cast({:restart, :test, _}, state) do - Logger.debug("pleroma manually restarted") - {:noreply, Map.put(state, :need_reboot, false)} - end - - def handle_cast({:restart, _, delay}, state) do - Process.sleep(delay) - do_restart(:pleroma) - {:noreply, Map.put(state, :need_reboot, false)} - end - - def handle_cast({:after_boot, _}, %{after_boot: true} = state), do: {:noreply, state} - - def handle_cast({:after_boot, :test}, state) do - Logger.debug("pleroma restarted after boot") - state = %{state | after_boot: true, rebooted: true} - {:noreply, state} - end - - def handle_cast({:after_boot, _}, state) do - do_restart(:pleroma) - state = %{state | after_boot: true, rebooted: true} - {:noreply, state} - end - - defp do_restart(app) do - :ok = Application.ensure_started(app) - :ok = Application.stop(app) - :ok = Application.start(app) - end -end diff --git a/restarter/lib/restarter.ex b/restarter/lib/restarter.ex deleted file mode 100644 index eadd86f89..000000000 --- a/restarter/lib/restarter.ex +++ /dev/null @@ -1,8 +0,0 @@ -defmodule Restarter do - use Application - - def start(_, _) do - opts = [strategy: :one_for_one, name: Restarter.Supervisor] - Supervisor.start_link([Restarter.Pleroma], opts) - end -end diff --git a/restarter/mix.exs b/restarter/mix.exs deleted file mode 100644 index b0908aece..000000000 --- a/restarter/mix.exs +++ /dev/null @@ -1,21 +0,0 @@ -defmodule Restarter.MixProject do - use Mix.Project - - def project do - [ - app: :restarter, - version: "0.1.0", - elixir: "~> 1.8", - start_permanent: Mix.env() == :prod, - deps: deps() - ] - end - - def application do - [ - mod: {Restarter, []} - ] - end - - defp deps, do: [] -end diff --git a/test/application_requirements_test.exs b/test/application/requirements_test.exs index 21d24ddd0..09fbbf20e 100644 --- a/test/application_requirements_test.exs +++ b/test/application/requirements_test.exs @@ -2,11 +2,13 @@ # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only -defmodule Pleroma.ApplicationRequirementsTest do +defmodule Pleroma.Application.RequirementsTest do use Pleroma.DataCase import ExUnit.CaptureLog import Mock + alias Pleroma.Application.Requirements + alias Pleroma.Config alias Pleroma.Repo describe "check_welcome_message_config!/1" do @@ -61,8 +63,7 @@ defmodule Pleroma.ApplicationRequirementsTest do describe "check_rum!" do setup_with_mocks([ - {Pleroma.ApplicationRequirements, [:passthrough], - [check_migrations_applied!: fn _ -> :ok end]} + {Requirements, [:passthrough], [check_migrations_applied!: fn _ -> :ok end]} ]) do :ok end @@ -70,42 +71,42 @@ defmodule Pleroma.ApplicationRequirementsTest do setup do: clear_config([:database, :rum_enabled]) test "raises if rum is enabled and detects unapplied rum migrations" do - Pleroma.Config.put([:database, :rum_enabled], true) + Config.put([:database, :rum_enabled], true) with_mocks([{Repo, [:passthrough], [exists?: fn _, _ -> false end]}]) do - assert_raise Pleroma.ApplicationRequirements.VerifyError, + assert_raise Requirements.VerifyError, "Unapplied RUM Migrations detected", fn -> - capture_log(&Pleroma.ApplicationRequirements.verify!/0) + capture_log(&Requirements.verify!/0) end end end test "raises if rum is disabled and detects rum migrations" do - Pleroma.Config.put([:database, :rum_enabled], false) + Config.put([:database, :rum_enabled], false) with_mocks([{Repo, [:passthrough], [exists?: fn _, _ -> true end]}]) do - assert_raise Pleroma.ApplicationRequirements.VerifyError, + assert_raise Requirements.VerifyError, "RUM Migrations detected", fn -> - capture_log(&Pleroma.ApplicationRequirements.verify!/0) + capture_log(&Requirements.verify!/0) end end end test "doesn't do anything if rum enabled and applied migrations" do - Pleroma.Config.put([:database, :rum_enabled], true) + Config.put([:database, :rum_enabled], true) with_mocks([{Repo, [:passthrough], [exists?: fn _, _ -> true end]}]) do - assert Pleroma.ApplicationRequirements.verify!() == :ok + assert Requirements.verify!() == :ok end end test "doesn't do anything if rum disabled" do - Pleroma.Config.put([:database, :rum_enabled], false) + Config.put([:database, :rum_enabled], false) with_mocks([{Repo, [:passthrough], [exists?: fn _, _ -> false end]}]) do - assert Pleroma.ApplicationRequirements.verify!() == :ok + assert Requirements.verify!() == :ok end end end @@ -130,17 +131,17 @@ defmodule Pleroma.ApplicationRequirementsTest do setup do: clear_config([:i_am_aware_this_may_cause_data_loss, :disable_migration_check]) test "raises if it detects unapplied migrations" do - assert_raise Pleroma.ApplicationRequirements.VerifyError, + assert_raise Requirements.VerifyError, "Unapplied Migrations detected", fn -> - capture_log(&Pleroma.ApplicationRequirements.verify!/0) + capture_log(&Requirements.verify!/0) end end test "doesn't do anything if disabled" do - Pleroma.Config.put([:i_am_aware_this_may_cause_data_loss, :disable_migration_check], true) + Config.put([:i_am_aware_this_may_cause_data_loss, :disable_migration_check], true) - assert :ok == Pleroma.ApplicationRequirements.verify!() + assert :ok == Requirements.verify!() end end end diff --git a/test/config/config_db_test.exs b/test/config/config_db_test.exs index 3895e2cda..bd2f2ba60 100644 --- a/test/config/config_db_test.exs +++ b/test/config/config_db_test.exs @@ -543,4 +543,23 @@ defmodule Pleroma.ConfigDBTest do ] end end + + test "load_and_merge_with_defaults/1" do + assert Pleroma.Config.Holder.default_config(:logger, :console)[:level] == :warn + + {:ok, config} = + ConfigDB.update_or_create(%{group: :logger, key: :console, value: [level: :debug]}) + + assert [{:logger, :console, [level: :debug], merged}] = + ConfigDB.load_and_merge_with_defaults() + + assert merged[:level] == :debug + + {:ok, deleted} = ConfigDB.delete(config) + + assert [{:logger, :console, [level: :debug], merged}] = + ConfigDB.load_and_merge_with_defaults([deleted]) + + assert merged[:level] == :warn + end end diff --git a/test/config/transfer_task_test.exs b/test/config/environment_test.exs index f53829e09..681430c3f 100644 --- a/test/config/transfer_task_test.exs +++ b/test/config/environment_test.exs @@ -1,14 +1,13 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only +# # Pleroma: A lightweight social networking server +# # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# # SPDX-License-Identifier: AGPL-3.0-only -defmodule Pleroma.Config.TransferTaskTest do +defmodule Pleroma.Config.EnvironmentTest do use Pleroma.DataCase - import ExUnit.CaptureLog import Pleroma.Factory - alias Pleroma.Config.TransferTask + alias Pleroma.Config.Environment setup do: clear_config(:configurable_from_database, true) @@ -25,7 +24,7 @@ defmodule Pleroma.Config.TransferTaskTest do insert(:config, group: :postgrex, key: :test_key, value: :value) insert(:config, group: :logger, key: :level, value: :debug) - TransferTask.start_link([]) + Environment.load_and_update() assert Application.get_env(:pleroma, :test_key) == [live: 2, com: 3] assert Application.get_env(:idna, :test_key) == [live: 15, com: 35] @@ -49,7 +48,7 @@ defmodule Pleroma.Config.TransferTaskTest do insert(:config, group: :quack, key: :level, value: :info) insert(:config, group: :quack, key: :meta, value: [:none]) - TransferTask.start_link([]) + Environment.load_and_update() assert Application.get_env(:quack, :level) == :info assert Application.get_env(:quack, :meta) == [:none] @@ -69,52 +68,11 @@ defmodule Pleroma.Config.TransferTaskTest do insert(:config, key: :emoji, value: [groups: [a: 1, b: 2]]) insert(:config, key: :assets, value: [mascots: [a: 1, b: 2]]) - TransferTask.start_link([]) + Environment.load_and_update() emoji_env = Application.get_env(:pleroma, :emoji) assert emoji_env[:groups] == [a: 1, b: 2] assets_env = Application.get_env(:pleroma, :assets) assert assets_env[:mascots] == [a: 1, b: 2] end - - describe "pleroma restart" do - setup do - on_exit(fn -> Restarter.Pleroma.refresh() end) - end - - test "don't restart if no reboot time settings were changed" do - clear_config(:emoji) - insert(:config, key: :emoji, value: [groups: [a: 1, b: 2]]) - - refute String.contains?( - capture_log(fn -> TransferTask.start_link([]) end), - "pleroma restarted" - ) - end - - test "on reboot time key" do - clear_config(:chat) - insert(:config, key: :chat, value: [enabled: false]) - assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted" - end - - test "on reboot time subkey" do - clear_config(Pleroma.Captcha) - insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60]) - assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted" - end - - test "don't restart pleroma on reboot time key and subkey if there is false flag" do - clear_config(:chat) - clear_config(Pleroma.Captcha) - - insert(:config, key: :chat, value: [enabled: false]) - insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60]) - - refute String.contains?( - capture_log(fn -> TransferTask.load_and_update_env([], false) end), - "pleroma restarted" - ) - end - end end diff --git a/test/web/admin_api/controllers/admin_api_controller_test.exs b/test/web/admin_api/controllers/admin_api_controller_test.exs index cba6b43d3..229b262b3 100644 --- a/test/web/admin_api/controllers/admin_api_controller_test.exs +++ b/test/web/admin_api/controllers/admin_api_controller_test.exs @@ -6,7 +6,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do use Pleroma.Web.ConnCase use Oban.Testing, repo: Pleroma.Repo - import ExUnit.CaptureLog import Mock import Pleroma.Factory import Swoosh.TestAssertions @@ -1426,28 +1425,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do setup do: clear_config(:configurable_from_database, true) test "pleroma restarts", %{conn: conn} do - capture_log(fn -> - assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == %{} - end) =~ "pleroma restarted" + assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == %{} - refute Restarter.Pleroma.need_reboot?() + refute Pleroma.Application.DynamicSupervisor.need_reboot?() end end - test "need_reboot flag", %{conn: conn} do - assert conn - |> get("/api/pleroma/admin/need_reboot") - |> json_response(200) == %{"need_reboot" => false} - - Restarter.Pleroma.need_reboot() - - assert conn - |> get("/api/pleroma/admin/need_reboot") - |> json_response(200) == %{"need_reboot" => true} - - on_exit(fn -> Restarter.Pleroma.refresh() end) - end - describe "GET /api/pleroma/admin/users/:nickname/statuses" do setup do user = insert(:user) diff --git a/test/web/admin_api/controllers/config_controller_test.exs b/test/web/admin_api/controllers/config_controller_test.exs index 4e897455f..a4b630dae 100644 --- a/test/web/admin_api/controllers/config_controller_test.exs +++ b/test/web/admin_api/controllers/config_controller_test.exs @@ -187,7 +187,6 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do Application.delete_env(:pleroma, Pleroma.Captcha.NotReal) Application.put_env(:pleroma, :http, http) Application.put_env(:tesla, :adapter, Tesla.Mock) - Restarter.Pleroma.refresh() end) end @@ -408,8 +407,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do end test "saving config which need pleroma reboot", %{conn: conn} do - chat = Config.get(:chat) - on_exit(fn -> Config.put(:chat, chat) end) + clear_config(:chat) assert conn |> put_req_header("content-type", "application/json") @@ -454,8 +452,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do end test "update setting which need reboot, don't change reboot flag until reboot", %{conn: conn} do - chat = Config.get(:chat) - on_exit(fn -> Config.put(:chat, chat) end) + clear_config(:chat) assert conn |> put_req_header("content-type", "application/json") @@ -500,10 +497,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do "need_reboot" => true } - capture_log(fn -> - assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == - %{} - end) =~ "pleroma restarted" + assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == + %{} configs = conn @@ -621,7 +616,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do value: [] ) - Pleroma.Config.TransferTask.load_and_update_env([], false) + Pleroma.Config.Environment.load_and_update() assert Application.get_env(:logger, :backends) == [] |