Add initial PGSQL plumbing
This commit is contained in:
parent
a51b59aa4c
commit
5a5de72e2a
10 changed files with 107 additions and 6 deletions
|
@ -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: []
|
||||
|
|
|
@ -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/")
|
||||
|
||||
|
|
|
@ -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
10
lib/ha_handler/pgsql.ex
Normal 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
|
17
lib/ha_handler/pgsql/supervisor.ex
Normal file
17
lib/ha_handler/pgsql/supervisor.ex
Normal 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
|
42
lib/ha_handler/pgsql/watcher.ex
Normal file
42
lib/ha_handler/pgsql/watcher.ex
Normal 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
|
|
@ -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(),
|
||||
|
|
|
@ -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>
|
||||
|
|
3
mix.exs
3
mix.exs
|
@ -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
|
||||
|
||||
|
|
4
mix.lock
4
mix.lock
|
@ -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"},
|
||||
|
|
Loading…
Reference in a new issue