- Logger: default log level changed from `warn` to `info`.
- Config mix task `migrate_to_db` truncates `config` table before migrating the config file.
- Default to `prepare: :unnamed` in the database configuration.
+ - Instance stats are now loaded on startup instead of being empty until next hourly job.
<details>
<summary>API Changes</summary>
- User settings: Add _This account is a_ option.
- A new users admin digest email
- OAuth: admin scopes support (relevant setting: `[:auth, :enforce_oauth_admin_scope_usage]`).
+- New HTTP adapter [gun](https://github.com/ninenines/gun). Gun adapter requires minimum OTP version of 22.2 otherwise Pleroma won’t start. For hackney OTP update is not required.
- Add an option `authorized_fetch_mode` to require HTTP signatures for AP fetches.
- ActivityPub: support for `replies` collection (output for outgoing federation & fetching on incoming federation).
- Mix task to refresh counter cache (`mix pleroma.refresh_counter_cache`)
- On failure: `Not found`
- On success: JSON array of instance's latest statuses
+ ## `GET /api/pleroma/admin/statuses`
+
+ ### Retrives all latest statuses
+
+ - Params:
+ - *optional* `page_size`: number of statuses to return (default is `20`)
+ - *optional* `local_only`: excludes remote statuses
+ - *optional* `godmode`: `true`/`false` – allows to see private statuses
+ - *optional* `with_reblogs`: `true`/`false` – allows to see reblogs (default is false)
+ - Response:
+ - On failure: `Not found`
+ - On success: JSON array of user's latest statuses
+
## `POST /api/pleroma/admin/relay`
### Follow a Relay
Most of the settings will be applied in `runtime`, this means that you don't need to restart the instance. But some settings are applied in `compile time` and require a reboot of the instance, such as:
- all settings inside these keys:
- `:hackney_pools`
+ - `:connections_pool`
+ - `:pools`
- `:chat`
- partially settings inside these keys:
- `:seconds_valid` in `Pleroma.Captcha`
{:pleroma, Oban},
{:pleroma, :rate_limit},
{:pleroma, :markup},
- {:plerome, :streamer}
+ {:pleroma, :streamer},
+ {:pleroma, :pools},
+ {:pleroma, :connections_pool},
+ {:tesla, :adapter}
]
@reboot_time_subkeys [
@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),
+ with {:configurable, true} <-
+ {:configurable, 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
if :pleroma in applications do
List.delete(applications, :pleroma) ++ [:pleroma]
else
+ Restarter.Pleroma.rebooted()
applications
end
Enum.each(applications, &restart(started_applications, &1, Pleroma.Config.get(:env)))
:ok
+ else
+ {:configurable, false} -> Restarter.Pleroma.rebooted()
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(:tesla, _, _, _), do: :pleroma
+
+ 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
+ end
+
defp merge_and_update(setting) do
try do
key = ConfigDB.from_string(setting.key)
:ok = update_env(group, key, merged_value)
- if group != :logger do
- 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
- 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
+ group_for_restart(group, key, value, merged_value)
rescue
error ->
error_msg =
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, %{need_reboot?: false}}
+ 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?)
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}
+ {:reply, state[:need_reboot], state}
end
- def handle_cast(:refresh, _state) do
- {:noreply, %{need_reboot?: false}}
+ 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, %{need_reboot: true} = state), do: {:noreply, state}
def handle_cast(:need_reboot, state) do
- {:noreply, Map.put(state, :need_reboot?, true)}
+ {: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.warn("pleroma restarted")
+ Logger.debug("pleroma manually restarted")
- {:noreply, Map.put(state, :need_reboot?, false)}
+ {: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)}
+ {: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.warn("pleroma restarted")
+ Logger.debug("pleroma restarted after boot")
- {:noreply, Map.put(state, :after_boot, true)}
+ state = %{state | after_boot: true, rebooted: true}
+ {:noreply, state}
end
def handle_cast({:after_boot, _}, state) do
do_restart(:pleroma)
- {:noreply, Map.put(state, :after_boot, true)}
+ state = %{state | after_boot: true, rebooted: true}
+ {:noreply, state}
end
defp do_restart(app) do
"@#{admin.nickname} deleted status ##{id}"
end
- test "returns error when status is not exist", %{conn: conn} do
+ test "returns 404 when the status does not exist", %{conn: conn} do
conn = delete(conn, "/api/pleroma/admin/statuses/test")
- assert json_response(conn, :bad_request) == "Could not delete"
+ assert json_response(conn, :not_found) == "Not found"
end
end
"value" => "Tesla.Adapter.Httpc",
"db" => [":adapter"]
}
- ]
+ ],
+ "need_reboot" => true
}
end
%{"tuple" => [":seconds_valid", 60]},
%{"tuple" => [":path", ""]},
%{"tuple" => [":key1", nil]},
- %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
%{"tuple" => [":regex1", "~r/https:\/\/example.com/"]},
%{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]},
%{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]},
%{"tuple" => [":seconds_valid", 60]},
%{"tuple" => [":path", ""]},
%{"tuple" => [":key1", nil]},
- %{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
%{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]},
%{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]},
%{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]},
":seconds_valid",
":path",
":key1",
- ":partial_chain",
":regex1",
":regex2",
":regex3",
"value" => "Tesla.Adapter.Httpc",
"db" => [":adapter"]
}
- ]
+ ],
+ "need_reboot" => true
}
end