# Generated by the mesh. Do not edit: module supabase writes this file and replaces it at every push. # # logflare 1.4.0 copies two of its settings into its own database once and never reads them again: # LOGFLARE_API_KEY becomes the default user's api_key when that user is created, and # POSTGRES_BACKEND_URL becomes each source's backend when that source is created. A changed value # reaches neither: a rotated key is refused, and a moved database is never written to (every # source here pointed at db:5432, a name that resolves nowhere, so nothing was stored). # # Run by the start script before logflare starts, through logflare's own code (its Repo, its Users # and Backends contexts and their changesets): it makes both copies say what the environment says. # It changes nothing when they already do, says what it changed, never prints the key or a URL's # password, and stops the start when it cannot finish. fail = fn why -> IO.puts(:stderr, "analytics: #{why}; not starting") System.halt(1) end say = fn what -> IO.puts(:stderr, "analytics: #{what}") end key = System.get_env("LOGFLARE_API_KEY") url = System.get_env("POSTGRES_BACKEND_URL") schema = System.get_env("POSTGRES_BACKEND_SCHEMA") if key in [nil, ""], do: fail.("LOGFLARE_API_KEY is not set, so the key logflare must accept is unknown") if url in [nil, ""], do: fail.("POSTGRES_BACKEND_URL is not set, so where logflare must store logs is unknown") where = fn u -> case URI.parse(to_string(u)) do %URI{host: host, port: port, path: path} when is_binary(host) -> "#{host}:#{port}#{path}" _ -> "an unreadable URL" end end Application.ensure_all_started(:ssl) outcome = Ecto.Migrator.with_repo(Logflare.Repo, fn _repo -> # Backends.update_source_backend_config restarts the source's pipeline after saving, and looks # it up in this registry to do so; logflare is not running yet, so the registry is empty and # there is nothing to restart. {:ok, _} = Registry.start_link(keys: :unique, name: Logflare.Backends.SourceRegistry) case Logflare.SingleTenant.get_default_user() do nil -> say.("no default user yet; logflare creates it from LOGFLARE_API_KEY and POSTGRES_BACKEND_URL as it starts") :ok user -> if user.api_key == key and is_nil(user.old_api_key) do say.("the default user's API key is LOGFLARE_API_KEY already") else # old_api_key is cleared too: logflare's UI can swap it back in, and the key replaced # here may be one that leaked. case Logflare.Users.update_user_all_fields(user, %{api_key: key, old_api_key: nil}) do {:ok, _} -> say.("the default user's API key was replaced with LOGFLARE_API_KEY") {:error, changeset} -> fail.("the default user's API key could not be replaced: #{inspect(changeset.errors)}") end end results = for source <- Logflare.Sources.list_sources_by_user(user), backend <- Logflare.Backends.list_source_backends(source), backend.type == :postgres do if backend.config.url == url and backend.config.schema == schema do :same else case Logflare.Backends.update_source_backend_config(backend, %{url: url, schema: schema}) do {:ok, _} -> say.("source #{source.name} stored logs at #{where.(backend.config.url)} schema #{inspect(backend.config.schema)}; now at #{where.(url)} schema #{inspect(schema)}") {:error, changeset} -> fail.("source #{source.name}'s backend could not be pointed at #{where.(url)}: #{inspect(changeset.errors)}") end end end say.("#{Enum.count(results, &(&1 == :same))} source backend(s) already at #{where.(url)}") :ok end end) case outcome do {:ok, :ok, _} -> :ok other -> fail.("logflare's database could not be reconciled: #{inspect(other)}") end