summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Strizhakov <alex.strizhakov@gmail.com>2020-07-16 19:57:27 +0300
committerAlexander Strizhakov <alex.strizhakov@gmail.com>2020-09-24 10:12:02 +0300
commita499ea32f7166e61d9168f8279d484ef74ab77f1 (patch)
tree2886acd623168fbbdf37e8f6d249d20103f90585
parente02101e15c425416975f756aca7f3b058006668d (diff)
split pleroma start into phases
-rw-r--r--lib/mix/pleroma.ex22
-rw-r--r--lib/pleroma/application.ex163
-rw-r--r--lib/pleroma/application/dynamic_supervisor.ex178
-rw-r--r--lib/pleroma/application/hackney_pool_supervisor.ex30
-rw-r--r--lib/pleroma/application/requirements.ex (renamed from lib/pleroma/application_requirements.ex)2
-rw-r--r--lib/pleroma/application/static.ex77
-rw-r--r--lib/pleroma/config/config_db.ex25
-rw-r--r--lib/pleroma/config/environment.ex103
-rw-r--r--lib/pleroma/config/loader.ex8
-rw-r--r--lib/pleroma/config/transfer_task.ex201
-rw-r--r--lib/pleroma/web/admin_api/controllers/admin_api_controller.ex4
-rw-r--r--lib/pleroma/web/admin_api/controllers/config_controller.ex16
-rw-r--r--mix.exs9
-rw-r--r--mix.lock3
-rw-r--r--restarter/lib/pleroma.ex94
-rw-r--r--restarter/lib/restarter.ex8
-rw-r--r--restarter/mix.exs21
-rw-r--r--test/application/requirements_test.exs (renamed from test/application_requirements_test.exs)35
-rw-r--r--test/config/config_db_test.exs19
-rw-r--r--test/config/environment_test.exs (renamed from test/config/transfer_task_test.exs)58
-rw-r--r--test/web/admin_api/controllers/admin_api_controller_test.exs21
-rw-r--r--test/web/admin_api/controllers/config_controller_test.exs15
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
diff --git a/mix.exs b/mix.exs
index 18f748672..0e48bbdea 100644
--- a/mix.exs
+++ b/mix.exs
@@ -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"},
diff --git a/mix.lock b/mix.lock
index adb3f024a..228cb5cbb 100644
--- a/mix.lock
+++ b/mix.lock
@@ -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) == []