mirror of
https://github.com/netfun2000/hipudding-teslamate.git
synced 2026-02-27 09:44:28 +08:00
feat(db-check): allow beta / rc PostgreSQL versions for testing (#4795)
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
- feat: use Grafana 12.0.2 (#4805 - @swiffer)
|
||||
- feat(mqtt): always publish healthy status and disable retain to prevent stale healthy status via mqtt (#4817 - @allivshits)
|
||||
- feat: use the k8s-style API introduced in Grafana v12 if using manual dashboard setup (#4764- @IngmarStein)
|
||||
- feat(db-check): allow beta / rc PostgreSQL versions for testing (#4795 - @swiffer)
|
||||
|
||||
#### Build, CI, internal
|
||||
|
||||
|
||||
@@ -2,70 +2,71 @@ defmodule TeslaMate.DatabaseCheck do
|
||||
alias Ecto.Adapters.SQL
|
||||
alias TeslaMate.Repo
|
||||
|
||||
# Minimum versions for supported major releases
|
||||
@min_version_16 "16.7"
|
||||
@min_version_17 "17.3"
|
||||
defmodule Version do
|
||||
defstruct [:version_string, :version_num, :major]
|
||||
end
|
||||
|
||||
@version_requirements %{
|
||||
1600 => %{min_version: "16.7", min_version_num: 160_007},
|
||||
1700 => %{min_version: "17.3", min_version_num: 170_003}
|
||||
}
|
||||
|
||||
def check_postgres_version do
|
||||
# Start the Repo manually without running migrations
|
||||
{:ok, _pid} = Repo.start_link()
|
||||
|
||||
# Query the PostgreSQL version
|
||||
{:ok, result} =
|
||||
SQL.query(
|
||||
Repo,
|
||||
"SELECT regexp_replace(version(), 'PostgreSQL ([^ ]+) .*', '\\1') AS version",
|
||||
[]
|
||||
)
|
||||
version = get_postgres_version()
|
||||
check_compatibility(version)
|
||||
|
||||
raw_version = result.rows |> List.first() |> List.first()
|
||||
|
||||
# Normalize to SemVer by appending .0 if needed
|
||||
version = normalize_version(raw_version)
|
||||
|
||||
# Split into major and minor parts
|
||||
[major, _minor] = String.split(version, ".", parts: 2)
|
||||
major_int = String.to_integer(major)
|
||||
|
||||
# Check based on major version
|
||||
case major_int do
|
||||
16 ->
|
||||
case Version.compare(version, normalize_version(@min_version_16)) do
|
||||
:lt ->
|
||||
raise "PostgreSQL version #{raw_version} is not supported. Minimum required for 16.x is #{@min_version_16}."
|
||||
|
||||
_ ->
|
||||
IO.puts("PostgreSQL version #{raw_version} is compatible (16.x series).")
|
||||
end
|
||||
|
||||
17 ->
|
||||
case Version.compare(version, normalize_version(@min_version_17)) do
|
||||
:lt ->
|
||||
raise "PostgreSQL version #{raw_version} is not supported. Minimum required for 17.x is #{@min_version_17}."
|
||||
|
||||
_ ->
|
||||
IO.puts("PostgreSQL version #{raw_version} is compatible (17.x series).")
|
||||
end
|
||||
|
||||
major_int when major_int > 17 ->
|
||||
IO.puts(
|
||||
"PostgreSQL version #{raw_version} is not officially tested or supported yet. Use at your own risk."
|
||||
)
|
||||
|
||||
_ ->
|
||||
raise "PostgreSQL version #{raw_version} is not supported. Only 16.x (min #{@min_version_16}) and 17.x (min #{@min_version_17}) are supported."
|
||||
end
|
||||
|
||||
# Stop the Repo after the check
|
||||
Repo.stop()
|
||||
end
|
||||
|
||||
# Helper function to normalize PostgreSQL version to SemVer
|
||||
defp normalize_version(version) do
|
||||
case String.split(version, ".") do
|
||||
[major, minor] -> "#{major}.#{minor}.0"
|
||||
[major, minor, patch | _] -> "#{major}.#{minor}.#{patch}"
|
||||
_ -> raise "Invalid PostgreSQL version format: #{version}"
|
||||
defp get_postgres_version do
|
||||
{:ok, result} =
|
||||
SQL.query(
|
||||
Repo,
|
||||
"""
|
||||
SELECT regexp_replace(version(), 'PostgreSQL ([^ ]+) .*', '\\1') AS version,
|
||||
current_setting('server_version_num')::integer AS version_num
|
||||
""",
|
||||
[]
|
||||
)
|
||||
|
||||
[version_string, version_num] = List.first(result.rows)
|
||||
|
||||
# https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSERVERVERSION
|
||||
major = div(version_num, 100)
|
||||
|
||||
%Version{
|
||||
version_string: version_string,
|
||||
version_num: version_num,
|
||||
major: major
|
||||
}
|
||||
end
|
||||
|
||||
defp check_compatibility(%Version{
|
||||
major: major,
|
||||
version_string: version,
|
||||
version_num: version_num
|
||||
}) do
|
||||
cond do
|
||||
major > 1700 ->
|
||||
IO.puts(
|
||||
"PostgreSQL version #{version} is not officially tested or supported yet. Use at your own risk."
|
||||
)
|
||||
|
||||
not Map.has_key?(@version_requirements, major) ->
|
||||
supported_versions =
|
||||
@version_requirements
|
||||
|> Map.values()
|
||||
|> Enum.map_join(" and ", & &1.min_version)
|
||||
|
||||
raise "PostgreSQL version #{version} is not supported. Only #{supported_versions} are supported."
|
||||
|
||||
version_num < @version_requirements[major].min_version_num ->
|
||||
raise "PostgreSQL version #{version} is not supported. Minimum required for #{div(major, 100)}.x is #{@version_requirements[major].min_version}."
|
||||
|
||||
true ->
|
||||
IO.puts("PostgreSQL version #{version} is compatible (#{div(major, 100)}.x series).")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user