fix dns request failures at boot

pull/627/head
Connor Rigby 2018-08-16 16:16:38 -07:00
parent 470cfe2245
commit 293f9cf6c6
No known key found for this signature in database
GPG Key ID: 9B7C52AA37F36C18
7 changed files with 69 additions and 109 deletions

View File

@ -41,12 +41,15 @@ config :farmbot, :init, [
# Wait for time time come up.
Farmbot.Target.Network.WaitForTime,
# Wait for DNS resolution
Farmbot.Target.Network.DnsTask,
# Stops the disk from getting full.
Farmbot.Target.Network.TzdataTask,
# Reports SOC temperature to BotState.
Farmbot.Target.SocTempWorker,
# Reports Wifi info to BotState.
Farmbot.Target.Network.InfoSupervisor,

View File

@ -41,6 +41,9 @@ config :farmbot, :init, [
# Wait for time time come up.
Farmbot.Target.Network.WaitForTime,
# Wait for DNS resolution
Farmbot.Target.Network.DnsTask,
# Stops the disk from getting full.
Farmbot.Target.Network.TzdataTask,

View File

@ -0,0 +1,60 @@
defmodule Farmbot.Target.Network.DnsTask do
use Farmbot.Logger
use GenServer
import Farmbot.Target.Network, only: [test_dns: 0]
import Farmbot.System.ConfigStorage, only: [get_config_value: 3]
def start_link(args, opts) do
GenServer.start_link(__MODULE__, args, opts)
end
def init([]) do
# Block and reset if after 10 tries
# resolution doesn't work.
block_check(true)
{:ok, %{timer: start_timer()}}
end
def handle_info(:checkup, state) do
# Block and don't reset if after 10 tries
# resolution doesn't work.
block_check()
{:noreply, %{state | timer: start_timer()}}
end
defp block_check(reset \\ false, tries \\ 10)
defp block_check(false, 0) do
server = get_config_value(:string, "authorization", "server")
Logger.error 1, "Could not resolve #{server} after 10 tries."
end
defp block_check(true, 0) do
server = get_config_value(:string, "authorization", "server")
Logger.error 1, "Tried 10 times to resolve DNS requests."
msg = """
FarmBot is unable to make DNS requests to #{server} after
10 tries. It is possible your network has a firewall blocking this
url, or your FarmBot is configured incorrectly.
"""
Farmbot.System.factory_reset(msg)
end
defp block_check(reset, tries) do
server = get_config_value(:string, "authorization", "server")
case test_dns() do
{:ok, _} -> :ok
{:error, :nxdomain} ->
Process.sleep(10_000)
Logger.error 1, "Trying to resolve #{server} #{tries - 1} more times."
block_check(reset, tries - 1)
err ->
Logger.error 1, "Failed to resolve #{server}: #{inspect err}"
block_check(reset, tries)
end
end
defp start_timer do
Process.send_after(self(), :checkup, 45_000)
end
end

View File

@ -150,20 +150,11 @@ defmodule Farmbot.Target.Network.Manager do
reconnect_timer: reconnect_timer
}
{:noreply, new_state}
# if state.connected do
# NotFoundTimer.start()
# Nerves.Network.IFSupervisor.teardown(state.interface)
# Process.sleep(5000)
# {:stop, :reconnect_timer, state}
# else
# # This event can come in for a brief moment while connecting.
# {:noreply, state}
# end
end
def handle_info({Nerves.WpaSupplicant, info, infoa}, state) do
# :"CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid=\"Rory's Phone\" auth_failures=2 duration=20 reason=CONN_FAILED"
case to_string(info) do
case is_atom(info) && to_string(info) do
<<"CTRL-EVENT-SSID-TEMP-DISABLED" <> _>> = msg ->
if String.contains?(msg, "duration=20") do
reconnect_timer = if state.connected, do: restart_connection_timer(state)
@ -189,8 +180,6 @@ defmodule Farmbot.Target.Network.Manager do
def handle_info(:reconnect_timer, %{ap_connected: false} = state) do
Logger.warn 1, "Wireless network not found still. Trying again."
# new_state = %{state | reconnect_timer: restart_connection_timer(state)}
# {:noreply, new_state}
{:stop, :reconnect_timer, state}
end

View File

@ -120,6 +120,7 @@ defmodule Farmbot.Target.Network do
end
def test_dns(hostname) do
:ok = :inet_db.clear_cache()
# IO.puts "testing dns: #{hostname}"
case :inet.parse_ipv4_address(hostname) do
{:ok, addr} -> {:ok, {:hostent, hostname, [], :inet, 4, [addr]}}

View File

@ -1,96 +0,0 @@
defmodule Farmbot.Target.Network.Ntp do
@moduledoc """
Sets time.
"""
use Farmbot.Logger
import Farmbot.Target.Network, only: [test_dns: 1]
import Farmbot.System.ConfigStorage, only: [get_config_value: 3]
@doc """
Tries to set the time from ntp.
This will try 3 times to set the time. if it fails the thrid time,
it will return an error
"""
def set_time(tries \\ 0)
def set_time(tries) when tries < 4 do
Process.sleep(1000 * tries)
case test_dns(to_charlist(ntp_server_1())) do
{:ok, {:hostent, _url, _, _, _, _}} ->
do_try_set_time(tries)
{:error, err} ->
Logger.error 1, "Failed to set time (#{tries}): DNS Lookup: #{inspect err}"
set_time(tries + 1)
end
end
def set_time(_), do: {:error, :timeout}
defp do_try_set_time(tries) when tries < 4 do
# we try to set ntp time 3 times before giving up.
# Logger.busy 3, "Trying to set time (try #{tries})"
IO.puts "Trying to set time (try #{tries})"
:os.cmd('ntpd -q -p #{ntp_server_1()} -p #{ntp_server_2()}')
wait_for_time(tries)
end
defp wait_for_time(tries, loops \\ 0)
defp wait_for_time(tries, loops) when loops > 5 do
:os.cmd('killall ntpd')
set_time(tries)
end
defp wait_for_time(tries, loops) do
case :os.system_time(:seconds) do
t when t > 1_474_929 ->
# Logger.success 2, "Time is set."
# Logger.busy 2, "Updating tzdata."
update_tzdata()
_ ->
Process.sleep(1_000 * loops)
wait_for_time(tries, loops + 1)
end
end
defp update_tzdata(retries \\ 0)
defp update_tzdata(retries) when retries > 5 do
Logger.error 1, "Failed too update tzdata!"
{:error, :failed_to_update_tzdata}
end
defp update_tzdata(retries) do
maybe_hack_tzdata()
case Tzdata.DataLoader.download_new() do
{:ok, _, _, _, _} ->
# Logger.success 3, "Successfully updated tzdata."
:ok
_ -> update_tzdata(retries + 1)
end
end
@fb_data_dir Application.get_env(:farmbot, :data_path)
@tzdata_dir Application.app_dir(:tzdata, "priv")
def maybe_hack_tzdata do
case Tzdata.Util.data_dir() do
@fb_data_dir -> :ok
_ ->
Logger.warn 3, "Hacking tzdata."
objs_to_cp = Path.wildcard(Path.join(@tzdata_dir, "*"))
for obj <- objs_to_cp do
File.cp_r obj, @fb_data_dir
end
Application.put_env(:tzdata, :data_dir, @fb_data_dir)
:ok
end
end
defp ntp_server_1 do
get_config_value(:string, "settings", "default_ntp_server_1")
end
defp ntp_server_2 do
get_config_value(:string, "settings", "default_ntp_server_2")
end
end

View File

@ -8,7 +8,7 @@ defmodule Farmbot.Target.Network.WaitForTime do
defp wait_for_time do
case :os.system_time(:seconds) do
t when t > 1_474_929 ->
t when t > 1534459652 ->
:ok
_ ->