DB autogenerated, nodes autoconnect, mnesia is up, WOOOOOOOOOOO

This commit is contained in:
Mikko Ahlroth 2017-11-05 01:03:39 +02:00
parent 5668d4b3a0
commit 70bd2e7b4e
19 changed files with 328 additions and 12 deletions

2
.gitignore vendored
View file

@ -13,3 +13,5 @@ erl_crash.dump
# Secret configs for dev
config/*.secret.exs
ssh/known_hosts

View file

@ -17,7 +17,7 @@ use Mix.Config
# docs for separating out critical OTP applications such as those
# involved with firmware updates.
config :bootloader,
init: [:nerves_runtime, :nerves_init_gadget, :nerves_network],
init: [:nerves_runtime, :nerves_init_gadget, :nerves_network, :nerves_init_net_kernel],
app: :duck_tag
config :nerves_firmware_ssh,
@ -51,5 +51,7 @@ import_config "#{Mix.Project.config()[:target]}.exs"
# Include role specific config as last. There you can set custom configs based on the role of the device
if System.get_env("DUCKTAG_ROLE") do
config :duck_tag, role: "DUCKTAG_ROLE" |> System.get_env() |> String.to_atom()
import_config "#{System.get_env("DUCKTAG_ROLE")}.exs"
end

View file

@ -1,3 +1,7 @@
use Mix.Config
config :nerves_init_net_kernel,
iface: "wlan0",
name: "duck_tag_player"
import_config "player.secret.exs"

View file

@ -1,3 +1,7 @@
use Mix.Config
config :nerves_init_net_kernel,
iface: "eth0",
name: "duck_tag_respawn"
import_config "respawn.secret.exs"

110
lib/db/manager.ex Normal file
View file

@ -0,0 +1,110 @@
defmodule DuckTag.DB.Manager do
@moduledoc """
This module is responsible for defining and initialising the game state Mnesia database.
"""
@typedoc """
Player's status in the game:
- `:wait_start` - Waiting for the start of the game
- `:alive` - Alive
- `:dead` - Dead, can respawn at respawn point
- `:out` - Out of the game, cannot respawn
"""
@type player_status :: :wait_start | :alive | :dead | :out
use GenServer
use Amnesia
require Logger
defdatabase GameDB do
deftable Player, [{:id, autoincrement}, :name, :status, :score], type: :set, index: [:name] do
@type t :: %Player{
id: integer,
name: String.t(),
status: DuckTag.DB.Manager.player_status(),
score: integer
}
end
end
def start_link(opts) do
GenServer.start_link(__MODULE__, nil, opts)
end
def init(_opts) do
:ok = create_db()
{:ok, :ok}
end
@doc """
Create the database. This should only be run on node owning the DB.
"""
def create_db() do
Logger.debug("Starting Amnesia DB with mem copies on node #{inspect(node())}...")
# XXX This sometimes says schema already exists?! Still seems to work though...
Amnesia.Schema.create()
# XXX WTF?!
Logger.debug("Starting mnesia")
start_db()
Logger.debug("Stopping mnesia")
stop_db()
Logger.debug("Starting mnesia again, because mnesia likes to be used this way")
start_db()
# Now after this mystical dance we can actually create the database
GameDB.create!(memory: [node()])
:ok = GameDB.wait(15_000)
end
@doc """
Start mnesia.
"""
def start_db() do
Amnesia.start()
end
@doc """
Stop mnesia.
"""
def stop_db() do
Amnesia.stop()
end
# Add node, copying all tables to it
def add_node(newnode) do
Logger.debug("Received connection from remote node #{inspect(newnode)}!")
# Ensure remote mnesia is stopped first, why? I do not know
Logger.debug("Stopping mnesia on remote node")
:rpc.call(newnode, Amnesia, :stop, [])
copy_tables(newnode)
Logger.debug("Starting mnesia on remote node")
:rpc.call(newnode, Amnesia, :start, [])
add_db_node(newnode)
Logger.debug(
"#{inspect(newnode)} is now connected to Mnesia Lightspeed Distributed Hyper Database"
)
end
# Copy all tables to new node
defp copy_tables(newnode) do
Logger.debug("Adding Player copy to #{inspect(newnode)}")
GameDB.Player.add_copy(newnode, :memory)
end
# Tell mnesia to add node as new node for table
defp add_db_node(newnode) do
Logger.debug("Adding #{inspect(newnode)} as mnesia extra DB node")
:mnesia.change_config(:extra_db_nodes, [newnode])
end
end

View file

@ -1,2 +1,32 @@
defmodule DuckTag do
@moduledoc """
Util module for stuff that doesn't fit anywhere else.
"""
@type role :: :player | :respawn | :judge
@doc """
Get project config.
"""
@spec get_conf(atom) :: any
def get_conf(key) do
Application.get_env(:duck_tag, key)
end
@doc """
Get the currently active role, set at build time.
"""
@spec role() :: role
def role() do
get_conf(:role)
end
@doc """
Get the Judge's node name.
"""
@spec judge_node() :: atom
def judge_node() do
# Assume Judge has static IP
"duck_tag_judge@#{DuckTag.get_conf(:judge_ip)}" |> String.to_atom()
end
end

View file

@ -1,20 +1,52 @@
defmodule DuckTag.Application do
use Application
import Supervisor.Spec, warn: false
@doc """
Get the workers that should be started for the given role.
"""
@spec workers(DuckTag.role()) :: [any]
def workers(type)
def workers(:common) do
[]
end
def workers(:player) do
[
DuckTag.Player.JudgeAPI.child_spec(name: DuckTag.Player.JudgeAPI),
rfid_worker()
]
end
def workers(:respawn) do
[
rfid_worker()
]
end
def workers(:judge) do
[
# Judge needs to start epmd manually or starting the node won't work
DuckTag.NetUtils.EPMdStarter.child_spec(name: DuckTag.NetUtils.EPMdStarter),
DuckTag.NetUtils.JudgeNameSetter.child_spec(name: DuckTag.NetUtils.JudgeNameSetter),
DuckTag.DB.Manager.child_spec(name: DuckTag.DB.Manager)
]
end
# See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
def start(_type, _args) do
import Supervisor.Spec, warn: false
device_type = DuckTag.role()
# Define workers and child supervisors to be supervised
children = [
# worker(DuckTag.Worker, [arg1, arg2, arg3]),
worker(Nerves.IO.RC522, [{DuckTag.RFIDHandler, :tag_scanned}])
]
children = Enum.concat(workers(:common), workers(device_type))
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: DuckTag.Supervisor]
Supervisor.start_link(children, opts)
end
defp rfid_worker(), do: worker(Nerves.IO.RC522, [{DuckTag.RFIDHandler, :tag_scanned}])
end

View file

@ -1,4 +1,8 @@
defmodule DuckTag.RFIDHandler do
@moduledoc """
Handles incoming RFID reads, delegating them to the appropriate handler code.
"""
def tag_scanned(uid) do
IO.puts("TAG SCANNED")
IO.inspect(uid)

View file

@ -0,0 +1,20 @@
defmodule DuckTag.NetUtils.EPMdStarter do
@moduledoc """
Starts and manages EPMd on nodes that need it started manually (static IP).
"""
use GenServer
require Logger
def start_link(opts) do
GenServer.start_link(__MODULE__, nil, opts)
end
def init(_opts) do
Logger.debug("Starting EPMd manually...")
:os.cmd('epmd -daemon')
{:ok, nil}
end
end

View file

@ -0,0 +1,17 @@
defmodule DuckTag.NetUtils.JudgeNameSetter do
use GenServer
alias DuckTag.NetUtils.NodeStart
require Logger
def start_link(opts) do
GenServer.start_link(__MODULE__, nil, opts)
end
def init(_opts) do
Logger.debug("JudgeNameSetter starting node")
{:ok, pid} = NodeStart.start()
{:ok, pid}
end
end

View file

@ -0,0 +1,26 @@
defmodule DuckTag.NetUtils.NodeStart do
@moduledoc """
Utils related to setting up node for nodes with static IP.
"""
require Logger
@doc """
Start node with name appropriate for current role.
"""
def start() do
start(:judge)
end
@doc """
Start a role specific node.
"""
@spec start(DuckTag.role()) :: {:ok, pid} | {:error, term}
def start(role)
def start(:judge) do
Logger.debug("Setting node name to '#{inspect(DuckTag.judge_node())}'")
Node.start(DuckTag.judge_node())
end
end

50
lib/player/judge_api.ex Normal file
View file

@ -0,0 +1,50 @@
defmodule DuckTag.Player.JudgeAPI do
@moduledoc """
Functions for talking to the Judge and a GenServer that manages the connection.
"""
# How often to retry connecting to Judge, milliseconds
@connect_retry_delay 2000
use GenServer
require Logger
def start_link(opts) do
GenServer.start_link(__MODULE__, nil, opts)
end
def init(_opts) do
{:ok, try_connect()}
end
def handle_info(:retry_connect, {:connected, node}), do: {:ok, {:connected, node}}
def handle_info(:retry_connect, _state), do: {:ok, try_connect()}
defp try_connect() do
remote_node = DuckTag.judge_node()
case connect(remote_node) do
true ->
on_connect(remote_node)
{:connected, remote_node}
_ ->
Process.send_after(self(), :retry_connect, @connect_retry_delay)
:retrying
end
end
defp connect(node) do
Logger.debug("Attempting to connect to #{inspect(node)}...")
Node.connect(node)
end
# Stuff to run when connection is established
defp on_connect(node) do
Logger.debug("Connected to #{inspect(node)}!")
Logger.debug("Attempting to connect to Judge DB.")
:rpc.call(node, DuckTag.DB.Manager, :add_node, [node()])
end
end

View file

@ -63,7 +63,8 @@ defmodule DuckTag.Mixfile do
# Specify target specific dependencies
def deps("host"),
do: [
{:nerves_firmware_ssh, "~> 0.3"}
{:nerves_firmware_ssh, "~> 0.3"},
{:amnesia, "~> 0.2.7"}
]
def deps(target) do
@ -73,7 +74,9 @@ defmodule DuckTag.Mixfile do
{:nerves_init_gadget, "~> 0.2"},
{:nerves_io_rc522, "~> 0.1.0"},
{:observer_cli, "~> 1.1.0"},
{:nerves_network, "~> 0.3"}
{:nerves_network, "~> 0.3"},
{:amnesia, "~> 0.2.7"},
{:nerves_init_net_kernel, github: "mobileoverlord/nerves_init_net_kernel"}
] ++ system(target)
end

View file

@ -1,6 +1,8 @@
%{
"amnesia": {:hex, :amnesia, "0.2.7", "ffc2221bf72da4cfafbbb497adf9cf7e52138f1333cec5836187a53f94ae0665", [], [{:exquisite, "~> 0.1.7", [hex: :exquisite, repo: "hexpm", optional: false]}], "hexpm"},
"distillery": {:hex, :distillery, "1.5.2", "eec18b2d37b55b0bcb670cf2bcf64228ed38ce8b046bb30a9b636a6f5a4c0080", [], [], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [], [], "hexpm"},
"exquisite": {:hex, :exquisite, "0.1.8", "ee8f56aae477287ce5e7dfcbc163a420cccbb73e680a6d80a09203e9ef514fa4", [], [], "hexpm"},
"nerves": {:hex, :nerves, "0.7.5", "3aa6a336b2ad6c1c9589cc2b577511b3c4c375c1ba6c533ab9f88adb8c21f0c3", [], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_firmware_ssh": {:hex, :nerves_firmware_ssh, "0.3.1", "e8b1967fa0aff255230be539c68ec868d33884193a385caff957ebad7d6aa8af", [], [{:nerves_runtime, "~> 0.4", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_runtime": {:hex, :nerves_runtime, "0.5.0", "5f4135fe3c94ca5c9e25d677350fbb136f279d14aac4871236961b6f5ccbcfa5", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.5", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},

View file

@ -1,14 +1,17 @@
%{
"amnesia": {:hex, :amnesia, "0.2.7", "ffc2221bf72da4cfafbbb497adf9cf7e52138f1333cec5836187a53f94ae0665", [], [{:exquisite, "~> 0.1.7", [hex: :exquisite, repo: "hexpm", optional: false]}], "hexpm"},
"bootloader": {:hex, :bootloader, "0.1.2", "835ddcf50b796714658f342061d5d48ebc34cbd0d81cdbd5a5a8ae00705d72b1", [], [{:distillery, "~> 1.0", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"distillery": {:hex, :distillery, "1.5.2", "eec18b2d37b55b0bcb670cf2bcf64228ed38ce8b046bb30a9b636a6f5a4c0080", [], [], "hexpm"},
"dns": {:hex, :dns, "1.0.1", "1d88187fdf564d937cee202949141090707fd0c9d7fcae903a6878ef24ef5d1e", [], [{:socket, "~> 0.3.12", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [], [], "hexpm"},
"exquisite": {:hex, :exquisite, "0.1.8", "ee8f56aae477287ce5e7dfcbc163a420cccbb73e680a6d80a09203e9ef514fa4", [], [], "hexpm"},
"mdns": {:hex, :mdns, "0.1.6", "b51b902b15b50e0e1522483c6a5fb073413e3d3d6ef52a44b93a541460b47d29", [], [{:dns, "~> 1.0", [hex: :dns, repo: "hexpm", optional: false]}], "hexpm"},
"nerves": {:hex, :nerves, "0.7.5", "3aa6a336b2ad6c1c9589cc2b577511b3c4c375c1ba6c533ab9f88adb8c21f0c3", [], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_firmware_ssh": {:hex, :nerves_firmware_ssh, "0.3.1", "e8b1967fa0aff255230be539c68ec868d33884193a385caff957ebad7d6aa8af", [], [{:nerves_runtime, "~> 0.4", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_init_gadget": {:hex, :nerves_init_gadget, "0.2.1", "20f36dd062fb00e2be8817ddff1b9ced9762877cfe23f6ec1d5936a37e3fc2c8", [], [{:mdns, "~> 0.1", [hex: :mdns, repo: "hexpm", optional: false]}, {:nerves_firmware_ssh, "~> 0.2", [hex: :nerves_firmware_ssh, repo: "hexpm", optional: false]}, {:nerves_network, "~> 0.3", [hex: :nerves_network, repo: "hexpm", optional: false]}, {:nerves_runtime, "~> 0.3", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_init_net_kernel": {:git, "https://github.com/mobileoverlord/nerves_init_net_kernel.git", "7772c8558ed5bb32853bb47209621b40b1331ee3", []},
"nerves_io_rc522": {:hex, :nerves_io_rc522, "0.1.0", "5a84a23ff2ac6e4c9cc0ea2931e43cf06d175b991bfd8b0ef664192cee25b7a4", [], [{:elixir_make, "~> 0.3", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_network": {:hex, :nerves_network, "0.3.4", "c50a36b8263cda2bee18f408287d0f4474f8367702d170864325abbd5d424e4d", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nerves_network_interface, "~> 0.4.0", [hex: :nerves_network_interface, repo: "hexpm", optional: false]}, {:nerves_wpa_supplicant, "~> 0.3.0", [hex: :nerves_wpa_supplicant, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.4", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_network": {:hex, :nerves_network, "0.3.4", "c50a36b8263cda2bee18f408287d0f4474f8367702d170864325abbd5d424e4d", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nerves_network_interface, "~> 0.4.0", [hex: :nerves_network_interface, repo: "hexpm", optional: false]}, {:nerves_wpa_supplicant, "~> 0.3.0", [hex: :nerves_wpa_supplicant, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.4", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_network_interface": {:hex, :nerves_network_interface, "0.4.2", "7a3663a07803f2f9f1e37146714d24ccec1e9349268586e4ed8c41f38641d837", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_runtime": {:hex, :nerves_runtime, "0.5.0", "5f4135fe3c94ca5c9e25d677350fbb136f279d14aac4871236961b6f5ccbcfa5", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.5", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_system_br": {:hex, :nerves_system_br, "0.14.1", "b108f8e12b2fd5cfd75be72d8ade4a1cfa9b9fd9076380c431ad930a7ccd5526", [], [], "hexpm"},

View file

@ -1,12 +1,15 @@
%{
"amnesia": {:hex, :amnesia, "0.2.7", "ffc2221bf72da4cfafbbb497adf9cf7e52138f1333cec5836187a53f94ae0665", [], [{:exquisite, "~> 0.1.7", [hex: :exquisite, repo: "hexpm", optional: false]}], "hexpm"},
"bootloader": {:hex, :bootloader, "0.1.2", "835ddcf50b796714658f342061d5d48ebc34cbd0d81cdbd5a5a8ae00705d72b1", [:mix], [{:distillery, "~> 1.0", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"distillery": {:hex, :distillery, "1.5.2", "eec18b2d37b55b0bcb670cf2bcf64228ed38ce8b046bb30a9b636a6f5a4c0080", [:mix], [], "hexpm"},
"dns": {:hex, :dns, "1.0.1", "1d88187fdf564d937cee202949141090707fd0c9d7fcae903a6878ef24ef5d1e", [:mix], [{:socket, "~> 0.3.12", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [:mix], [], "hexpm"},
"exquisite": {:hex, :exquisite, "0.1.8", "ee8f56aae477287ce5e7dfcbc163a420cccbb73e680a6d80a09203e9ef514fa4", [], [], "hexpm"},
"mdns": {:hex, :mdns, "0.1.6", "b51b902b15b50e0e1522483c6a5fb073413e3d3d6ef52a44b93a541460b47d29", [:mix], [{:dns, "~> 1.0", [hex: :dns, repo: "hexpm", optional: false]}], "hexpm"},
"nerves": {:hex, :nerves, "0.7.5", "3aa6a336b2ad6c1c9589cc2b577511b3c4c375c1ba6c533ab9f88adb8c21f0c3", [:mix], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_firmware_ssh": {:hex, :nerves_firmware_ssh, "0.3.1", "e8b1967fa0aff255230be539c68ec868d33884193a385caff957ebad7d6aa8af", [:mix], [{:nerves_runtime, "~> 0.4", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_init_gadget": {:hex, :nerves_init_gadget, "0.2.1", "20f36dd062fb00e2be8817ddff1b9ced9762877cfe23f6ec1d5936a37e3fc2c8", [:mix], [{:mdns, "~> 0.1", [hex: :mdns, repo: "hexpm", optional: false]}, {:nerves_firmware_ssh, "~> 0.2", [hex: :nerves_firmware_ssh, repo: "hexpm", optional: false]}, {:nerves_network, "~> 0.3", [hex: :nerves_network, repo: "hexpm", optional: false]}, {:nerves_runtime, "~> 0.3", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_init_net_kernel": {:git, "https://github.com/mobileoverlord/nerves_init_net_kernel.git", "7772c8558ed5bb32853bb47209621b40b1331ee3", []},
"nerves_io_rc522": {:hex, :nerves_io_rc522, "0.1.0", "5a84a23ff2ac6e4c9cc0ea2931e43cf06d175b991bfd8b0ef664192cee25b7a4", [:make, :mix], [{:elixir_make, "~> 0.3", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_network": {:hex, :nerves_network, "0.3.4", "c50a36b8263cda2bee18f408287d0f4474f8367702d170864325abbd5d424e4d", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nerves_network_interface, "~> 0.4.0", [hex: :nerves_network_interface, repo: "hexpm", optional: false]}, {:nerves_wpa_supplicant, "~> 0.3.0", [hex: :nerves_wpa_supplicant, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.4", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_network_interface": {:hex, :nerves_network_interface, "0.4.2", "7a3663a07803f2f9f1e37146714d24ccec1e9349268586e4ed8c41f38641d837", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},

View file

@ -1,14 +1,17 @@
%{
"amnesia": {:hex, :amnesia, "0.2.7", "ffc2221bf72da4cfafbbb497adf9cf7e52138f1333cec5836187a53f94ae0665", [], [{:exquisite, "~> 0.1.7", [hex: :exquisite, repo: "hexpm", optional: false]}], "hexpm"},
"bootloader": {:hex, :bootloader, "0.1.2", "835ddcf50b796714658f342061d5d48ebc34cbd0d81cdbd5a5a8ae00705d72b1", [], [{:distillery, "~> 1.0", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"distillery": {:hex, :distillery, "1.5.2", "eec18b2d37b55b0bcb670cf2bcf64228ed38ce8b046bb30a9b636a6f5a4c0080", [], [], "hexpm"},
"dns": {:hex, :dns, "1.0.1", "1d88187fdf564d937cee202949141090707fd0c9d7fcae903a6878ef24ef5d1e", [], [{:socket, "~> 0.3.12", [hex: :socket, repo: "hexpm", optional: false]}], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [], [], "hexpm"},
"exquisite": {:hex, :exquisite, "0.1.8", "ee8f56aae477287ce5e7dfcbc163a420cccbb73e680a6d80a09203e9ef514fa4", [], [], "hexpm"},
"mdns": {:hex, :mdns, "0.1.6", "b51b902b15b50e0e1522483c6a5fb073413e3d3d6ef52a44b93a541460b47d29", [], [{:dns, "~> 1.0", [hex: :dns, repo: "hexpm", optional: false]}], "hexpm"},
"nerves": {:hex, :nerves, "0.7.5", "3aa6a336b2ad6c1c9589cc2b577511b3c4c375c1ba6c533ab9f88adb8c21f0c3", [], [{:distillery, "~> 1.4", [hex: :distillery, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_firmware_ssh": {:hex, :nerves_firmware_ssh, "0.3.1", "e8b1967fa0aff255230be539c68ec868d33884193a385caff957ebad7d6aa8af", [], [{:nerves_runtime, "~> 0.4", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_init_gadget": {:hex, :nerves_init_gadget, "0.2.1", "20f36dd062fb00e2be8817ddff1b9ced9762877cfe23f6ec1d5936a37e3fc2c8", [], [{:mdns, "~> 0.1", [hex: :mdns, repo: "hexpm", optional: false]}, {:nerves_firmware_ssh, "~> 0.2", [hex: :nerves_firmware_ssh, repo: "hexpm", optional: false]}, {:nerves_network, "~> 0.3", [hex: :nerves_network, repo: "hexpm", optional: false]}, {:nerves_runtime, "~> 0.3", [hex: :nerves_runtime, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_init_net_kernel": {:git, "https://github.com/mobileoverlord/nerves_init_net_kernel.git", "7772c8558ed5bb32853bb47209621b40b1331ee3", []},
"nerves_io_rc522": {:hex, :nerves_io_rc522, "0.1.0", "5a84a23ff2ac6e4c9cc0ea2931e43cf06d175b991bfd8b0ef664192cee25b7a4", [], [{:elixir_make, "~> 0.3", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_network": {:hex, :nerves_network, "0.3.4", "c50a36b8263cda2bee18f408287d0f4474f8367702d170864325abbd5d424e4d", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nerves_network_interface, "~> 0.4.0", [hex: :nerves_network_interface, repo: "hexpm", optional: false]}, {:nerves_wpa_supplicant, "~> 0.3.0", [hex: :nerves_wpa_supplicant, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.4", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_network": {:hex, :nerves_network, "0.3.4", "c50a36b8263cda2bee18f408287d0f4474f8367702d170864325abbd5d424e4d", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nerves_network_interface, "~> 0.4.0", [hex: :nerves_network_interface, repo: "hexpm", optional: false]}, {:nerves_wpa_supplicant, "~> 0.3.0", [hex: :nerves_wpa_supplicant, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.4", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_network_interface": {:hex, :nerves_network_interface, "0.4.2", "7a3663a07803f2f9f1e37146714d24ccec1e9349268586e4ed8c41f38641d837", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_runtime": {:hex, :nerves_runtime, "0.5.0", "5f4135fe3c94ca5c9e25d677350fbb136f279d14aac4871236961b6f5ccbcfa5", [], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:system_registry, "~> 0.5", [hex: :system_registry, repo: "hexpm", optional: false]}], "hexpm"},
"nerves_system_br": {:hex, :nerves_system_br, "0.14.1", "b108f8e12b2fd5cfd75be72d8ade4a1cfa9b9fd9076380c431ad930a7ccd5526", [], [], "hexpm"},

View file

@ -2,10 +2,10 @@
## Distributed Erlang Options
## The cookie needs to be configured prior to vm boot for
## for read only filesystem.
## read only filesystem.
# -name duck_tag@0.0.0.0
-setcookie QzZpjmW58COOicHqloZZKRdTN688yjYr6XL8Klbcr6cCT0br3dlKjVeABjGp5nOr
-setcookie ducktag_dev
## Use Ctrl-C to interrupt the current shell rather than invoking the emulator's
## break handler and possibly exiting the VM.

1
ssh/id_rsa Symbolic link
View file

@ -0,0 +1 @@
id_nerves