mirror of
https://github.com/teslamate-org/teslamate.git
synced 2026-01-24 21:06:08 +08:00
This will add support for nix flakes. Which really helps with my development on nixos. This has two basic parts: 1. DEVELOPMENT After this you can use the following commands on computer with nix and a patched version of direnv: direnv allow devenv up And it will automatically start and instance of postgresql and mosquitto for development. And the environment variables are already configured for teslamate. So then can start teslamate with: npm install --prefix ./assets && npm run deploy --prefix ./assets iex -S mix phx.server This part is all working as designed. And pretty simple and straight forward. 2. NIX PACKAGE OF TESLA This is 99% complete, but some pain points I haven't addressed yet. Because I don't yet know of good solutions. * There are two checksums in flake.nix that needs to be updated whenever mix.lock or package-lock.json changes.
174 lines
5.4 KiB
Elixir
174 lines
5.4 KiB
Elixir
import Config
|
|
|
|
defmodule Util do
|
|
def random_string(length) do
|
|
:crypto.strong_rand_bytes(length) |> Base.encode64() |> binary_part(0, length)
|
|
end
|
|
|
|
def to_integer(nil), do: nil
|
|
def to_integer(str), do: String.to_integer(str)
|
|
|
|
def validate_namespace!(nil), do: nil
|
|
def validate_namespace!(""), do: nil
|
|
|
|
def validate_namespace!(ns) when is_binary(ns) do
|
|
case String.contains?(ns, "/") do
|
|
true -> raise "MQTT_NAMESPACE must not contain '/'"
|
|
false -> ns
|
|
end
|
|
end
|
|
|
|
def parse_check_origin!("true"), do: true
|
|
def parse_check_origin!("false"), do: false
|
|
def parse_check_origin!(hosts) when is_binary(hosts), do: String.split(hosts, ",")
|
|
def parse_check_origin!(hosts), do: raise("Invalid check_origin option: #{inspect(hosts)}")
|
|
|
|
def validate_import_dir(nil), do: nil
|
|
|
|
def validate_import_dir(path) do
|
|
path = Path.absname(path)
|
|
|
|
case File.ls(path) do
|
|
{:ok, [_ | _] = files} ->
|
|
if Enum.any?(files, &TeslaMate.Import.valid_file_name?/1) do
|
|
IO.puts("[info] Found #{length(files)} file(s) at '#{path}'. Starting in import mode!")
|
|
path
|
|
else
|
|
nil
|
|
end
|
|
|
|
{:ok, []} ->
|
|
nil
|
|
|
|
{:error, :enoent} ->
|
|
nil
|
|
|
|
{:error, reason} ->
|
|
IO.puts("[warn] Cannot access directory '#{path}': #{inspect(reason)}")
|
|
nil
|
|
end
|
|
end
|
|
|
|
def choose_http_binding_address() do
|
|
port = Util.get_env("PORT", prod: "4000", dev: "4000", test: "4002")
|
|
defaults = [transport_options: [socket_opts: [:inet6]], port: port]
|
|
|
|
case System.get_env("HTTP_BINDING_ADDRESS", "") do
|
|
"" ->
|
|
defaults
|
|
|
|
address ->
|
|
case :inet.parse_address(to_charlist(address)) do
|
|
{:ok, ip} ->
|
|
[ip: ip, port: port]
|
|
|
|
{:error, reason} ->
|
|
case String.at(address, 0) do
|
|
"/" ->
|
|
[
|
|
ip: {:local, address},
|
|
port: 0,
|
|
transport_options: [
|
|
post_listen_callback: fn _ ->
|
|
File.chmod!(
|
|
address,
|
|
System.get_env("SOCKET_PERM", "755") |> String.to_integer(8)
|
|
)
|
|
end
|
|
]
|
|
]
|
|
|
|
_ ->
|
|
IO.puts("Cannot parse HTTP_BINDING_ADDRESS '#{address}': #{inspect(reason)}")
|
|
defaults
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def fetch_env!(varname, defaults \\ []) do
|
|
case config_env() do
|
|
:prod -> System.fetch_env!(varname)
|
|
env -> System.get_env(varname, defaults[env] || defaults[:all])
|
|
end
|
|
end
|
|
|
|
def get_env(varname, defaults \\ []) do
|
|
System.get_env(varname, defaults[config_env()])
|
|
end
|
|
end
|
|
|
|
config :teslamate,
|
|
default_geofence: System.get_env("DEFAULT_GEOFENCE")
|
|
|
|
config :teslamate, TeslaMate.Repo,
|
|
username: Util.fetch_env!("DATABASE_USER", all: "postgres"),
|
|
password: Util.fetch_env!("DATABASE_PASS", all: "postgres"),
|
|
database: Util.fetch_env!("DATABASE_NAME", dev: "teslamate_dev", test: "teslamate_test"),
|
|
hostname: Util.fetch_env!("DATABASE_HOST", all: "localhost"),
|
|
port: System.get_env("DATABASE_PORT", "5432"),
|
|
pool_size: System.get_env("DATABASE_POOL_SIZE", "10") |> String.to_integer(),
|
|
timeout: System.get_env("DATABASE_TIMEOUT", "60000") |> String.to_integer()
|
|
|
|
case System.get_env("DATABASE_SSL") do
|
|
"true" ->
|
|
ca_cert_file =
|
|
System.get_env("DATABASE_SSL_CA_CERT_FILE") || raise "DATABASE_SSL_CA_CERT_FILE must be set"
|
|
|
|
config :teslamate, TeslaMate.Repo,
|
|
ssl: true,
|
|
ssl_opts: [
|
|
verify: :verify_peer,
|
|
cacertfile: ca_cert_file
|
|
]
|
|
|
|
"noverify" ->
|
|
config :teslamate, TeslaMate.Repo,
|
|
ssl: true,
|
|
ssl_opts: [
|
|
server_name_indication:
|
|
to_charlist(
|
|
System.get_env("DATABASE_SSL_SNI") ||
|
|
Util.fetch_env!("DATABASE_HOST", all: "localhost")
|
|
),
|
|
verify: :verify_none
|
|
]
|
|
|
|
_false ->
|
|
config :teslamate, TeslaMate.Repo, ssl: false
|
|
end
|
|
|
|
if System.get_env("DATABASE_IPV6") == "true" do
|
|
config :teslamate, TeslaMate.Repo, socket_options: [:inet6]
|
|
end
|
|
|
|
config :teslamate, TeslaMateWeb.Endpoint,
|
|
http: Util.choose_http_binding_address(),
|
|
url: [host: System.get_env("VIRTUAL_HOST", "localhost"), port: 80],
|
|
secret_key_base: System.get_env("SECRET_KEY_BASE", Util.random_string(64)),
|
|
live_view: [signing_salt: System.get_env("SIGNING_SALT", Util.random_string(8))],
|
|
check_origin: System.get_env("CHECK_ORIGIN", "false") |> Util.parse_check_origin!()
|
|
|
|
if System.get_env("DISABLE_MQTT") != "true" or config_env() == :test do
|
|
config :teslamate, :mqtt,
|
|
host: Util.fetch_env!("MQTT_HOST", all: "localhost"),
|
|
port: System.get_env("MQTT_PORT") |> Util.to_integer(),
|
|
username: System.get_env("MQTT_USERNAME"),
|
|
password: System.get_env("MQTT_PASSWORD"),
|
|
tls: System.get_env("MQTT_TLS") == "true",
|
|
accept_invalid_certs: System.get_env("MQTT_TLS_ACCEPT_INVALID_CERTS") == "true",
|
|
namespace: System.get_env("MQTT_NAMESPACE") |> Util.validate_namespace!(),
|
|
ipv6: System.get_env("MQTT_IPV6") == "true"
|
|
end
|
|
|
|
if config_env() != :test do
|
|
config :teslamate,
|
|
import_directory: System.get_env("IMPORT_DIR", "import") |> Util.validate_import_dir()
|
|
end
|
|
|
|
config :teslamate, :srtm_cache, System.get_env("SRTM_CACHE", ".srtm_cache")
|
|
|
|
config :teslamate, TeslaMate.Vault, key: Util.get_env("ENCRYPTION_KEY", test: "secret")
|
|
|
|
config :tzdata, :data_dir, System.get_env("TZDATA_DIR", "/tmp")
|