farmbot_os/platform/target/bootstrap/network/ntp.ex

88 lines
2.3 KiB
Elixir

defmodule Farmbot.Target.Network.Ntp do
@moduledoc """
Sets time.
"""
use Farmbot.Logger
import Farmbot.Target.Network, only: [test_dns: 1]
@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('0.pool.ntp.org') 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})"
:os.cmd('ntpd -q -p 0.pool.ntp.org -p 1.pool.ntp.org')
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
end