This package provides a mix task named mix upload.hotswap
to deploy local code changes to remote node(s) and to apply them without rebooting whole the application (the so-called hot code swapping
).
It could be convenient when you code for IoT devices backed by Nerves because it's much faster than mix firmware && mix upload
. Although you eventually need to update the firmware if you want to persist the changes onto devices, this task could be your help in development phase because it allows you to quickly confirm if your changes work fine on the devices without waiting long time.
Add mix_tasks_upload_hotswap
to your list of dependencies in mix.exs
:
def deps do
[
{:mix_tasks_upload_hotswap, "~> 0.1.0", only: :dev}
]
end
To use this package, you need to meet the requirements below:
- Add configurations for
mix upload.hotswap
- Start node(s) on your device(s) through which your code changes are deployed
The task mix upload.hotswap
depends on the settings below are available:
config :mix_tasks_upload_hotswap,
app_name: :example,
nodes: [:"example@nerves.local"],
cookie: :"secret token shared between nodes"
All the pairs above are required to be set.
See example/config/config.exs for working example.
Start a node which has the name and cookie set in the configuration above. The code should be like below:
# Start a node through which local code changes are deployed
# only when the device is running in the develop environment
if Application.get_env(:example, :env) == :dev do
System.cmd("epmd", ["-daemon"])
Node.start(:"example@nerves.local")
Node.set_cookie(Application.get_env(:mix_tasks_upload_hotswap, :cookie))
end
Notice that the node starts only when the :env
of the application is set to :dev
. Below is an example to configure the environment value in config.exs
:
config :example, env: Mix.env()
See example/lib/example/application.ex and example/config/config.exs for working example.
Make some changes into your code and just execute the mix task as below:
$ mix upload.hotswap
Imagine there is an Example application which has hello
method as below:
def hello do
:world
end
You can confirm the method invoked on your device:
$ ssh nerves.local
(snip)
iex(example@nerves.local)1> Example.hello
:world
Suppose you made some changes like below:
diff --git a/example/lib/example.ex b/example/lib/example.ex
index ca49896..81c696a 100644
--- a/example/lib/example.ex
+++ b/example/lib/example.ex
@@ -13,6 +13,6 @@ defmodule Example do
"""
def hello do
- :world
+ :"new world"
end
end
You can deploy the changes to the device as below:
$ mix upload.hotswap
==> nerves
==> example
Nerves environment
MIX_TARGET: rpi3
MIX_ENV: dev
Compiling 2 files (.ex)
Generated example app
Successfully connected to example@nerves.local
Successfully deployed Elixir.Example to example@nerves.local
Successfully deployed Elixir.Example.Application to example@nerves.local
Now you can see the changes applied into the code on the device:
$ ssh nerves.local
(snip)
iex(example@nerves.local)1> Example.hello
:"new world"
It's much faster than mix firmware && mix upload
.
You can specify the node(s) in the cluster as below:
$ mix upload.hotswap --node example@nerves.local
This --node
option can be used multiple times.
You can specify the module(s) as below:
$ mix upload.hotswap --module YourGoodApp
This --module
option
- can be used multiple times.
- searches for all modules that start with the specified module name.
Using Erlang Distribution to test hardware - Embedded Elixir inspired me how to implement this package.
MIT