Add initial PGSQL plumbing

This commit is contained in:
Timothée Floure 2022-02-19 10:18:05 +01:00
parent a51b59aa4c
commit 5a5de72e2a
Signed by: tfloure
GPG key ID: 4502C902C00A1E12
10 changed files with 107 additions and 6 deletions

View file

@ -3,5 +3,5 @@ import Config
config :ha_handler,
http_port: 4000,
acme_challenge_path: "acme-challenge",
haproxy_socket: System.get_env("HAPROXY_SOCKET") || "/var/run/haproxy.sock"
haproxy_socket: System.get_env("HAPROXY_SOCKET") || "/var/run/haproxy.sock",
pgsql_instances: []

View file

@ -11,6 +11,8 @@ defmodule HAHandler do
def http_port, do: Application.get_env(@otp_app, :http_port)
def haproxy_socket, do: Application.get_env(@otp_app, :haproxy_socket)
def pgsql_instances, do: Application.get_env(@otp_app, :pgsql_instances, [])
def acme_challenge_path, do: Application.get_env(@otp_app, :acme_challenge_path)
def static_path(), do: Application.app_dir(@otp_app, "priv/static/")

View file

@ -5,12 +5,13 @@ defmodule HAHandler.Application do
use Application
import HAHandler
alias HAHandler
@impl true
def start(_type, _args) do
children = [
{Plug.Cowboy, scheme: :http, plug: HAHandler.Web.Router, options: [port: http_port()]}
{Plug.Cowboy, scheme: :http, plug: HAHandler.Web.Router, options: [port: HAHandler.http_port()]},
{HAHandler.PGSQL.Supervisor, HAHandler.pgsql_instances()}
]
# See https://hexdocs.pm/elixir/Supervisor.html

10
lib/ha_handler/pgsql.ex Normal file
View file

@ -0,0 +1,10 @@
defmodule HAHandler.PGSQL do
@supervisor HAHandler.PGSQL.Supervisor
def status() do
watchers = Supervisor.which_children(@supervisor)
for {_id, pid, _type, _modules} <- watchers do
GenServer.call(pid, :status)
end
end
end

View file

@ -0,0 +1,17 @@
defmodule HAHandler.PGSQL.Supervisor do
use Supervisor
alias HAHandler.PGSQL.Watcher, as: PGSQLWatcher
def start_link(opts) do
Supervisor.start_link(__MODULE__, opts, name: __MODULE__)
end
@impl true
def init(instances) do
children = Enum.map(instances, fn conf -> {PGSQLWatcher, conf} end)
opts = [ strategy: :one_for_one ]
Supervisor.init(children, opts)
end
end

View file

@ -0,0 +1,42 @@
defmodule HAHandler.PGSQL.Watcher do
use GenServer
require Logger
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
@impl true
def init(opts) do
# Starts a Postgrex child but does not means the connection was
# successful.
# TODO: set dbconnections backoff and connect hooks
# See https://github.com/elixir-ecto/db_connection/blob/master/lib/db_connection.ex#L343
{:ok, pid} = Postgrex.start_link(opts)
state = %{
backend: pid,
hostname: Keyword.get(opts, :hostname)
}
{:ok, state}
end
@impl true
def handle_call(:status, _from, %{backend: backend, hostname: hostname} = state) do
result = case Postgrex.query(backend, "SELECT version();", []) do
{:ok, %Postgrex.Result{rows: [[raw_version_string]]}} ->
version = case Regex.run(~r/^PostgreSQL (\d+\.\d+)/, raw_version_string) do
[_, version_number] -> version_number
_ -> "unknown"
end
%{hostname: hostname, version: version, status: "up"}
{:error, %DBConnection.ConnectionError{message: _msg, reason: err}} ->
%{hostname: hostname, version: "unknown", status: err}
_ ->
%{hostname: hostname, version: "unknown", status: "Unhandled error"}
end
{:reply, result, state}
end
end

View file

@ -1,7 +1,7 @@
defmodule HAHandler.Web.Controller do
import Plug.Conn
alias HAHandler.HAProxy
alias HAHandler.{HAProxy, PGSQL}
@templates_dir "lib/ha_handler/web/templates"
@ -22,6 +22,7 @@ defmodule HAHandler.Web.Controller do
assigns = [
haproxy_stats: stats,
pgsql_status: PGSQL.status(),
hostname: hostname,
otp_app: HAHandler.otp_app(),
version: HAHandler.version(),

View file

@ -98,6 +98,29 @@
<% end %>
</tbody>
</table>
<hr />
<h2>PostgreSQL</h2>
<table>
<thead>
<tr>
<th>Hostname</th>
<th>Version</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<%= for entry <- pgsql_status do %>
<tr>
<td><%= entry[:hostname] %></td>
<td><%= entry[:version] %></td>
<td><%= entry[:status] %></td>
</tr>
<% end %>
</tbody>
</table>
</main>
</body>
</html>

View file

@ -26,7 +26,8 @@ defmodule HAHandler.MixProject do
{:plug, "~> 1.12"},
{:plug_cowboy, "~> 2.5"},
{:procket, "~> 0.9"},
{:poison, "~> 5.0"}
{:poison, "~> 5.0"},
{:postgrex, "~> 0.16.1"}
]
end

View file

@ -1,13 +1,17 @@
%{
"afunix": {:git, "https://github.com/tonyrog/afunix.git", "d7baab77d741d49bce08de2aeb28c5f192ab13d8", []},
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
"db_connection": {:hex, :db_connection, "2.4.1", "6411f6e23f1a8b68a82fa3a36366d4881f21f47fc79a9efb8c615e62050219da", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ea36d226ec5999781a9a8ad64e5d8c4454ecedc7a4d643e4832bf08efca01f00"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
"plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"},
"plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"},
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
"poison": {:hex, :poison, "5.0.0", "d2b54589ab4157bbb82ec2050757779bfed724463a544b6e20d79855a9e43b24", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "11dc6117c501b80c62a7594f941d043982a1bd05a1184280c0d9166eb4d8d3fc"},
"postgrex": {:hex, :postgrex, "0.16.1", "f94628a32c571266f53cd1e5fca705e626e2417bf1eee6f868985d14e874160a", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "6b225df32c857b9430619dbe30200a7ae664e23415a771ae9209396ee8eeee64"},
"procket": {:hex, :procket, "0.9.5", "ce91c00cb3f4d627fb3827f46ce68e6a969ea265df1afb349c300a07be4bb16c", [:rebar3], [], "hexpm", "1288bba5eb6f08ea5df3dda9e051bdac8f4b1e50adcca5cf4d726e825ad81bed"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"sweet_xml": {:hex, :sweet_xml, "0.7.2", "4729f997286811fabdd8288f8474e0840a76573051062f066c4b597e76f14f9f", [:mix], [], "hexpm", "6894e68a120f454534d99045ea3325f7740ea71260bc315f82e29731d570a6e8"},