1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Mix.Tasks.Pleroma.Config do
10 alias Pleroma.ConfigDB
13 @shortdoc "Manages the location of the config"
14 @moduledoc File.read!("docs/administration/CLI_tasks/config.md")
16 def run(["migrate_to_db"]) do
21 def run(["migrate_from_db" | options]) do
25 OptionParser.parse!(options,
26 strict: [env: :string, delete: :boolean],
34 with true <- Pleroma.Config.get([:configurable_from_database]) do
37 header = config_header()
39 shell_info("#{header}")
44 |> Enum.each(&dump(&1))
46 _ -> configdb_not_enabled()
50 def run(["dump", group, key]) do
51 with true <- Pleroma.Config.get([:configurable_from_database]) do
56 _ -> configdb_not_enabled()
60 def run(["dump", group]) do
61 with true <- Pleroma.Config.get([:configurable_from_database]) do
66 _ -> configdb_not_enabled()
70 def run(["groups"]) do
71 with true <- Pleroma.Config.get([:configurable_from_database]) do
77 |> Enum.map(fn x -> x.group end)
81 if length(groups) > 0 do
82 shell_info("The following configuration groups are set in ConfigDB:\r\n")
83 groups |> Enum.each(fn x -> shell_info("- #{x}") end)
87 _ -> configdb_not_enabled()
91 def run(["keys" | group]) do
92 with true <- Pleroma.Config.get([:configurable_from_database]) do
99 if x.group == group do
105 |> Enum.reject(fn x -> x == nil end)
107 if length(keys) > 0 do
108 shell_info("The following configuration keys under :#{group} are set in ConfigDB:\r\n")
109 keys |> Enum.each(fn x -> shell_info("- #{x}") end)
113 _ -> configdb_not_enabled()
117 def run(["reset"]) do
118 with true <- Pleroma.Config.get([:configurable_from_database]) do
121 if shell_prompt("Are you sure you want to continue?", "n") in ~w(Yn Y y) do
122 Ecto.Adapters.SQL.query!(Repo, "TRUNCATE config;")
123 Ecto.Adapters.SQL.query!(Repo, "ALTER SEQUENCE config_id_seq RESTART;")
125 shell_info("The ConfigDB settings have been removed from the database.")
127 shell_info("No changes made.")
130 _ -> configdb_not_enabled()
134 def run(["delete" | args]) when is_list(args) and length(args) == 2 do
135 with true <- Pleroma.Config.get([:configurable_from_database]) do
140 if shell_prompt("Are you sure you want to continue?", "n") in ~w(Yn Y y) do
143 |> Enum.filter(fn x ->
144 if x.group == group and x.key == key do
149 shell_info("No changes made.")
152 _ -> configdb_not_enabled()
156 @spec migrate_to_db(Path.t() | nil) :: any()
157 def migrate_to_db(file_path \\ nil) do
158 with true <- Pleroma.Config.get([:configurable_from_database]),
159 :ok <- Pleroma.Config.DeprecationWarnings.warn() do
164 if Pleroma.Config.get(:release) do
165 Pleroma.Config.get(:config_path)
167 "config/#{Pleroma.Config.get(:env)}.secret.exs"
171 do_migrate_to_db(config_file)
173 :error -> deprecation_error()
174 _ -> migration_error()
178 defp do_migrate_to_db(config_file) do
179 if File.exists?(config_file) do
180 shell_info("Migrating settings from file: #{Path.expand(config_file)}")
181 Ecto.Adapters.SQL.query!(Repo, "TRUNCATE config;")
182 Ecto.Adapters.SQL.query!(Repo, "ALTER SEQUENCE config_id_seq RESTART;")
191 |> Enum.each(&create(&1, custom_config))
193 shell_info("To migrate settings, you must define custom settings in #{config_file}.")
197 defp create(group, settings) do
199 |> Pleroma.Config.Loader.filter_group(settings)
200 |> Enum.each(fn {key, value} ->
201 {:ok, _} = ConfigDB.update_or_create(%{group: group, key: key, value: value})
203 shell_info("Settings for key #{key} migrated.")
206 shell_info("Settings for group :#{group} migrated.")
209 defp migrate_from_db(opts) do
210 if Pleroma.Config.get([:configurable_from_database]) do
211 env = opts[:env] || Pleroma.Config.get(:env)
214 if Pleroma.Config.get(:release) do
216 |> Pleroma.Config.get()
221 |> Path.join("#{env}.exported_from_db.secret.exs")
223 file = File.open!(config_path, [:write, :utf8])
225 IO.write(file, config_header())
229 |> Enum.each(&write_and_delete(&1, file, opts[:delete]))
231 :ok = File.close(file)
232 System.cmd("mix", ["format", config_path])
235 "Database configuration settings have been exported to config/#{env}.exported_from_db.secret.exs"
242 defp migration_error do
244 "Migration is not allowed in config. You can change this behavior by setting `config :pleroma, configurable_from_database: true`"
248 defp deprecation_error do
249 shell_error("Migration is not allowed until all deprecation warnings have been resolved.")
252 if Code.ensure_loaded?(Config.Reader) do
253 defp config_header, do: "import Config\r\n\r\n"
254 defp read_file(config_file), do: Config.Reader.read_imports!(config_file)
256 defp config_header, do: "use Mix.Config\r\n\r\n"
257 defp read_file(config_file), do: Mix.Config.eval!(config_file)
260 defp write_and_delete(config, file, delete?) do
266 defp write(config, file) do
267 value = inspect(config.value, limit: :infinity)
269 IO.write(file, "config #{inspect(config.group)}, #{inspect(config.key)}, #{value}\r\n\r\n")
274 defp delete(config, true) do
275 {:ok, _} = Repo.delete(config)
276 shell_info("#{config.key} deleted from the ConfigDB.")
279 defp delete(_config, _), do: :ok
281 defp dump(%Pleroma.ConfigDB{} = config) do
282 value = inspect(config.value, limit: :infinity)
284 shell_info("config #{inspect(config.group)}, #{inspect(config.key)}, #{value}\r\n\r\n")
287 defp configdb_not_enabled do
289 "ConfigDB not enabled. Please check the value of :configurable_from_database in your configuration."
293 defp dump_key(group, key) do
294 group = group |> String.to_atom()
295 key = key |> String.to_atom()
299 |> Enum.filter(fn x ->
300 if x.group == group && x.key == key do
306 defp dump_group(group) do
307 group = group |> String.to_atom()
311 |> Enum.filter(fn x ->
312 if x.group == group do