X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;ds=inline;f=lib%2Fpleroma%2Fconfig%2Ftransfer_task.ex;h=6c5ba1f95ca040107bcf026c904ed6467e530e3d;hb=5ebffd5224729413e53a55ddda9a1f86224d7d73;hp=00c8790f868516083b9437b378801bfcf578c691;hpb=f01ab6cd29aaae39fef6a95ec8490223fb692499;p=akkoma diff --git a/lib/pleroma/config/transfer_task.ex b/lib/pleroma/config/transfer_task.ex index 00c8790f8..6c5ba1f95 100644 --- a/lib/pleroma/config/transfer_task.ex +++ b/lib/pleroma/config/transfer_task.ex @@ -10,46 +10,95 @@ 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}, + {:plerome, :streamer} + ] + + @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]} + ] + + @reject [nil, :prometheus] + def start_link(_) do load_and_update_env() if Pleroma.Config.get(:env) == :test, do: Ecto.Adapters.SQL.Sandbox.checkin(Repo) :ignore end - def load_and_update_env do + @spec load_and_update_env([ConfigDB.t()]) :: :ok | false + def load_and_update_env(deleted \\ [], restart_pleroma? \\ true) do with true <- Pleroma.Config.get(:configurable_from_database), true <- Ecto.Adapters.SQL.table_exists?(Repo, "config"), started_applications <- Application.started_applications() do # We need to restart applications for loaded settings take effect - ConfigDB - |> Repo.all() - |> Enum.map(&update_env(&1)) - |> Enum.uniq() - # TODO: some problem with prometheus after restart! - |> Enum.reject(&(&1 in [:pleroma, nil, :prometheus])) - |> Enum.each(&restart(started_applications, &1)) + + in_db = Repo.all(ConfigDB) + + with_deleted = in_db ++ deleted + + reject_for_restart = if restart_pleroma?, do: @reject, else: [:pleroma | @reject] + + applications = + with_deleted + |> Enum.map(&merge_and_update(&1)) + |> Enum.uniq() + # TODO: some problem with prometheus after restart! + |> Enum.reject(&(&1 in reject_for_restart)) + + # to be ensured that pleroma will be restarted last + applications = + if :pleroma in applications do + List.delete(applications, :pleroma) ++ [:pleroma] + else + applications + end + + Enum.each(applications, &restart(started_applications, &1, Pleroma.Config.get(:env))) + + :ok end end - defp update_env(setting) do + defp merge_and_update(setting) do try do key = ConfigDB.from_string(setting.key) group = ConfigDB.from_string(setting.group) - value = ConfigDB.from_binary(setting.value) default = Pleroma.Config.Holder.config(group, key) + value = ConfigDB.from_binary(setting.value) merged_value = - if can_be_merged?(default, value) do - ConfigDB.merge_group(group, key, default, value) + if Ecto.get_meta(setting, :state) == :deleted do + default else - value + if can_be_merged?(default, value) do + ConfigDB.merge_group(group, key, default, value) + else + value + end end - :ok = Application.put_env(group, key, merged_value) + :ok = update_env(group, key, merged_value) if group != :logger do - group + if group != :pleroma or pleroma_need_restart?(group, key, value) do + group + end else # change logger configuration in runtime, without restart if Keyword.keyword?(merged_value) and @@ -62,18 +111,46 @@ defmodule Pleroma.Config.TransferTask do nil end rescue - e -> - Logger.warn( - "updating env causes error, group: #{inspect(setting.group)}, key: #{ - inspect(setting.key) - }, value: #{inspect(ConfigDB.from_binary(setting.value))}, error: #{inspect(e)}" - ) + error -> + error_msg = + "updating env causes error, group: " <> + inspect(setting.group) <> + " key: " <> + inspect(setting.key) <> + " value: " <> + inspect(ConfigDB.from_binary(setting.value)) <> " error: " <> inspect(error) + + Logger.warn(error_msg) nil end end - defp restart(started_applications, app) do + @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 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(_, :pleroma, :test), do: Logger.warn("pleroma restarted") + + defp restart(_, :pleroma, _), do: send(Restarter.Pleroma, :after_boot) + + defp restart(started_applications, app, _) do with {^app, _, _} <- List.keyfind(started_applications, app, 0), :ok <- Application.stop(app) do :ok = Application.start(app)