Current section
Files
Jump to
Current section
Files
lib/nerves_tier.ex
defmodule NervesTier do
use GenServer
require Logger
@zt_home Application.get_env(:nerves_tier, :zt_home, "/root/.zt/")
@zt_port Application.get_env(:nerves_tier, :zt_conf_port, 9993)
defp token!() do
File.read!(Path.join(@zt_home, "/authtoken.secret"))
end
def info() do
HTTPoison.get!("127.0.0.1:#{@zt_port}/status?auth=#{token!()}").body |> Poison.decode!()
end
def networks() do
HTTPoison.get!("127.0.0.1:#{@zt_port}/networks?auth=#{token!()}").body |> Poison.decode!()
end
def network(id) do
HTTPoison.get!("127.0.0.1:#{@zt_port}/network/#{id}?auth=#{token!()}").body |> Poison.decode!()
end
def network_join(id, params \\ %{}) do
HTTPoison.post!("127.0.0.1:#{@zt_port}/network/#{id}?auth=#{token!()}", params |> Poison.encode!()).body |> Poison.decode!()
end
def network_leave(id) do
HTTPoison.delete!("127.0.0.1:#{@zt_port}/network/#{id}?auth=#{token!()}").body |> Poison.decode!()
end
def peers() do
HTTPoison.get!("127.0.0.1:#{@zt_port}/networks?auth=#{token!()}").body |> Poison.decode!()
end
end
defmodule NervesTier.PortServer do
use GenServer
require Logger
# Callbacks
@zt_home Application.get_env(:nerves_tier, :zt_home, "/root/.zt/")
@zt_port Application.get_env(:nerves_tier, :zt_conf_port, 9993)
def start_link(args \\ [], opts \\ []) do
GenServer.start_link(__MODULE__, args, opts ++ [name: __MODULE__])
end
@impl true
def init(args \\ []) do
GenServer.cast(self(), :start)
Process.flag(:trap_exit, true)
{:ok, %{port: nil}}
end
@impl true
def handle_info(:check, state) do
unless state.port |> Port.info() do
Logger.error "zerotier port died"
# raise "zerotier port died"
end
{:noreply, state }
end
@impl true
def handle_info(msg, state) do
Logger.error "zerotier info: #{inspect msg}"
{:noreply, state }
end
@impl true
def handle_cast(:start, state) do
Logger.info("Starting ZerotierOne")
{_, 0} = System.cmd("modprobe", ["tun"])
# run_zt = "#{:code.priv_dir(:nerves_tier)}/run-zt.sh"
zt_bin = "#{:code.priv_dir(:nerves_tier)}/usr/sbin/zerotier-one"
port = Port.open({:spawn_executable, zt_bin}, [:binary, args: [@zt_home]])
# port = Port.open({:spawn_executable, run_zt}, [:binary, args: [zt_bin, @zt_home]])
Process.send_after(self(), :check, 1_000, [])
{:noreply, %{ state | port: port} }
end
def handle_call(:status, state) do
{:reply, Port.info(state.port), state}
end
def handle_call(:port, _from, state) do
{:reply, state.port, state}
end
def terminate(reason, state) do
Logger.error "#{__MODULE__}.terminate/2 called with reason: #{inspect reason}"
port_info = Port.info(state.port)
Logger.error("#{__MODULE__}.termindate port: #{inspect port_info}")
case port_info[:os_pid] do
ospid when is_number(ospid) ->
Logger.info "#{__MODULE__} terminate port, os process: #{inspect ospid}"
System.cmd("kill", ["-KILL", "#{ospid}"], [])
nil ->
nil
end
end
end
defmodule NervesTier.Application do
use Application
@moduledoc """
Documentation for NervesTier.
"""
def start(_type, _args) do
children = [
NervesTier.PortServer,
]
Supervisor.start_link(children, strategy: :one_for_one)
end
end