X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fpleroma%2Fconfig%2Ftransfer_task.ex;h=4a4c022f06750b3f4f8724c37e2adc09075c8fa1;hb=426f5ee48a09dbf321c013db08cc849c8929d86d;hp=d54f38ee4c022db43703b638a3de24317294474f;hpb=ae78059ff433739b83aaa3ccff9245ace153146d;p=akkoma diff --git a/lib/pleroma/config/transfer_task.ex b/lib/pleroma/config/transfer_task.ex index d54f38ee4..4a4c022f0 100644 --- a/lib/pleroma/config/transfer_task.ex +++ b/lib/pleroma/config/transfer_task.ex @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors +# Copyright © 2017-2020 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Config.TransferTask do @@ -10,6 +10,30 @@ defmodule Pleroma.Config.TransferTask do 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, :email_notifications, [:digest]}, + {:pleroma, :oauth2, [:clean_expired_tokens]}, + {:pleroma, Pleroma.ActivityExpiration, [:enabled]}, + {:pleroma, Pleroma.ScheduledActivity, [:enabled]}, + {:pleroma, :gopher, [:enabled]} + ] + def start_link(_) do load_and_update_env() if Pleroma.Config.get(:env) == :test, do: Ecto.Adapters.SQL.Sandbox.checkin(Repo) @@ -17,49 +41,90 @@ defmodule Pleroma.Config.TransferTask do end @spec load_and_update_env([ConfigDB.t()]) :: :ok | false - def load_and_update_env(deleted \\ []) do - with true <- Pleroma.Config.get(:configurable_from_database), - true <- Ecto.Adapters.SQL.table_exists?(Repo, "config"), - started_applications <- Application.started_applications() do + def load_and_update_env(deleted \\ [], restart_pleroma? \\ true) do + with {_, true} <- {:configurable, Pleroma.Config.get(:configurable_from_database)} do # We need to restart applications for loaded settings take effect in_db = Repo.all(ConfigDB) with_deleted = in_db ++ deleted + # TODO: some problem with prometheus after restart! + reject = [nil, :prometheus] + + reject_for_restart = + if restart_pleroma? do + reject + else + [:pleroma | reject] + end + + started_applications = Application.started_applications() + with_deleted |> Enum.map(&merge_and_update(&1)) |> Enum.uniq() - # TODO: some problem with prometheus after restart! - |> Enum.reject(&(&1 in [:pleroma, nil, :prometheus])) - |> Enum.each(&restart(started_applications, &1)) + |> Enum.reject(&(&1 in reject_for_restart)) + |> maybe_set_pleroma_last() + |> Enum.each(&restart(started_applications, &1, Pleroma.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 group_for_restart(:logger, key, _, merged_value) do + # change logger configuration in runtime, without restart + if Keyword.keyword?(merged_value) and + key not in [:compile_time_application, :backends, :compile_time_purge_matching] do + Logger.configure_backend(key, merged_value) + else + Logger.configure([{key, merged_value}]) + end + + nil + end + + defp group_for_restart(group, _, _, _) when group != :pleroma, do: group + + defp group_for_restart(group, key, value, _) do + if pleroma_need_restart?(group, key, value), do: group + end + defp merge_and_update(setting) do try do key = ConfigDB.from_string(setting.key) group = ConfigDB.from_string(setting.group) default = Pleroma.Config.Holder.config(group, key) - merged_value = merge_value(setting, default, group, key) - - :ok = update_env(group, key, merged_value) + value = ConfigDB.from_binary(setting.value) - if group != :logger do - group - else - # change logger configuration in runtime, without restart - if Keyword.keyword?(merged_value) and - key not in [:compile_time_application, :backends, :compile_time_purge_matching] do - Logger.configure_backend(key, merged_value) + merged_value = + if Ecto.get_meta(setting, :state) == :deleted do + default else - Logger.configure([{key, merged_value}]) + if can_be_merged?(default, value) do + ConfigDB.merge_group(group, key, default, value) + else + value + end end - nil - end + :ok = update_env(group, key, merged_value) + + group_for_restart(group, key, value, merged_value) rescue error -> error_msg = @@ -76,22 +141,29 @@ defmodule Pleroma.Config.TransferTask do end end - defp merge_value(%{__meta__: %{state: :deleted}}, default, _group, _key), do: default + @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 merge_value(setting, default, group, key) do - value = ConfigDB.from_binary(setting.value) + defp group_and_key_need_reboot?(group, key) do + Enum.any?(@reboot_time_keys, fn {g, k} -> g == group and k == key end) + end - if can_be_merged?(default, value) do - ConfigDB.merge_group(group, key, default, value) - else - value - 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 update_env(group, key, nil), do: Application.delete_env(group, key) defp update_env(group, key, value), do: Application.put_env(group, key, value) - defp restart(started_applications, app) do + 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)