nerves-hub / nerves_hub_link Goto Github PK
View Code? Open in Web Editor NEWConnect devices to NervesHub via a Phoenix channel
Home Page: https://hex.pm/packages/nerves_hub_link
License: Apache License 2.0
Connect devices to NervesHub via a Phoenix channel
Home Page: https://hex.pm/packages/nerves_hub_link
License: Apache License 2.0
extty
supports changing the window size of the remote console via ExTTY.window_change/3
The ConsoleChannel docs show that window_size
is an optional message from the Server, but it doesn't actually have a matching handle_info
clause to handle that message, so it needs to be added.
Also, this would be the counterpart to nerves-hub/nerves_hub_web#654
I am trying to setup a custom instance of NervesHub on AWS. Via the terraform repo, I am able to setup but getting issues on running the api.
nerves-hub-ca - running
nerves-hub-device - running
nerves-hub-www - running
nerves-hub-api - crashing
The nerves-hub-api task is throwing these errors:
Crash dump is being written to: erl_crash.dump...done942d30302e5849de81cd99c590efc743
Crash dump is being written to: erl_crash.dump...done
init terminating in do_boot ({,[{Elixir.File,read!,1,[{},{}]},{Elixir.Enum,-map/2-lists^map/1-0-,2,[{},{}]},{erl_eval,do_apply,6,[{},{}]},{erl_eval,expr_list,6,[{},{}]},{erl_eval,expr,5,[{},{942d30302e5849de81cd99c590efc743
init terminating in do_boot ({,[{Elixir.File,read!,1,[{},{}]},{Elixir.Enum,-map/2-lists^map/1-0-,2,[{},{}]},{erl_eval,do_apply,6,[{},{}]},{erl_eval,expr_list,6,[{},{}]},{erl_eval,expr,5,[{},{
942d30302e5849de81cd99c590efc743
{"init terminating in do_boot",{#{'exception'=>true,'struct'=>'Elixir.File.Error',action=><<"read file">>,path=><<"/etc/ssl/user-root-ca.pem">>,reason=>enoent},[{'Elixir.File','read!',1,[{file,"lib/file.ex"},{line,353}]},{'Elixir.Enum','-map/2-lists^map/1-0-',2,[{file,"lib/enum.ex"},{line,1396}]},{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,680}]},{erl_eval,expr_list,6,[{file,"erl_eval.erl"},{line,888}]},{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,411}]},{erl_eval,expr_list,6,[{file,"erl_eval.erl"},{line,888}]},{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,411}]},{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,449}]}]}}942d30302e5849de81cd99c590efc743
{"init terminating in do_boot",{#{'exception'=>true,'struct'=>'Elixir.File.Error',action=><<"read file">>,path=><<"/etc/ssl/user-root-ca.pem">>,reason=>enoent},[{'Elixir.File','read!',1,[{file,"lib/file.ex"},{line,353}]},{'Elixir.Enum','-map/2-lists^map/1-0-',2,[{file,"lib/enum.ex"},{line,1396}]},{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,680}]},{erl_eval,expr_list,6,[{file,"erl_eval.erl"},{line,888}]},{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,411}]},{erl_eval,expr_list,6,[{file,"erl_eval.erl"},{line,888}]},{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,411}]},{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,449}]}]}}
** (File.Error) could not read file "/etc/ssl/user-root-ca.pem": no such file or directory942d30302e5849de81cd99c590efc743
** (File.Error) could not read file "/etc/ssl/user-root-ca.pem": no such file or directory
(elixir 1.10.4) lib/file.ex:353: File.read!/1942d30302e5849de81cd99c590efc743
(elixir 1.10.4) lib/file.ex:353: File.read!/1
(elixir 1.10.4) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2942d30302e5849de81cd99c590efc743
(elixir 1.10.4) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
(stdlib 3.13.1) erl_eval.erl:680: :erl_eval.do_apply/6942d30302e5849de81cd99c590efc743
(stdlib 3.13.1) erl_eval.erl:680: :erl_eval.do_apply/6
(stdlib 3.13.1) erl_eval.erl:888: :erl_eval.expr_list/6942d30302e5849de81cd99c590efc743
(stdlib 3.13.1) erl_eval.erl:888: :erl_eval.expr_list/6
(stdlib 3.13.1) erl_eval.erl:411: :erl_eval.expr/5942d30302e5849de81cd99c590efc743
(stdlib 3.13.1) erl_eval.erl:411: :erl_eval.expr/5
(stdlib 3.13.1) erl_eval.erl:888: :erl_eval.expr_list/6942d30302e5849de81cd99c590efc743
(stdlib 3.13.1) erl_eval.erl:888: :erl_eval.expr_list/6
(stdlib 3.13.1) erl_eval.erl:411: :erl_eval.expr/5942d30302e5849de81cd99c590efc743
(stdlib 3.13.1) erl_eval.erl:411: :erl_eval.expr/5
(stdlib 3.13.1) erl_eval.erl:449: :erl_eval.expr/5942d30302e5849de81cd99c590efc743
(stdlib 3.13.1) erl_eval.erl:449: :erl_eval.expr/5
ERROR! Config provider Config.Reader failed with:942d30302e5849de81cd99c590efc743
ERROR! Config provider Config.Reader failed with:
2020-12-28 11:39:[email protected] [email protected] [email protected]
[email protected] [email protected] [email protected]
% Total % Received % Xferd Average Speed Time Time Time Current942d30302e5849de81cd99c590efc743
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed942d30302e5849de81cd99c590efc743
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 956 100 956 0 0 933k 0 --:--:-- --:--:-- --:--:-- 933k942d30302e5849de81cd99c590efc743
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 956 100 956 0 0 933k 0 --:--:-- --:--:-- --:--:-- 933k
download: s3://se-nh-staging-staging-ca/ssl/.empty to ../etc/ssl/.empty942d30302e5849de81cd99c590efc743
download: s3://se-nh-staging-staging-ca/ssl/.empty to ../etc/ssl/.empty
I am using api_image = "nerveshub/nerves_hub_api:latest" in terraform.tfvars file. I don't know if this latest docker image is having issue or there is some configuration change I might be missing.
Moving this from nerves-hub/nerves_hub_web#595
TL;DR - If you get a firmware url and delay applying it before the TTL expires (~10 minutes), then issues happening.
We should adapt the download request here to ask for a new, generated URL if the link is expired, but limit to only X number of retries (3 maybe?)
This will prob require new channel message in nerves_hub_web
to support getting another download URL because currently it only happens on channel join or when deployment/device changes in nerves_hub_web
In the switch from NervesHub to NervesHubLink the NervesHubLink.Supervisor
is automatically started on boot instead of "whenever I want to start it". This change has introduced a race condition in my code because my NervesHubLink.Client
relies on a process that may not have been started yet. Obviously I can catch the exception and reschedule the update but I'm wondering why the change?
This change also takes away the ability to conditionally include the supervisor which is something I do in development all the time when I'm testing without pushing releases.
I've been wondering how I corrupted an SD card before, and now I found at least one way: with an active deployment running and fwup in progress, but also local performing a fwup via ssh, it looks like the two update processes simultaneously wrote to the "unused" partition, resulting in complete garbage.
As an aside, is the on-disk cecksum not verified on firmware updates?
If downloading an update over a slow or metered connection fails, it would be much better if the download could be resumed. Currently, the download fails and restarts from the beginning.
Documentation still refers to phoenix_client, which has long been replaced with slipstream afaik.
In certain scenarios it makes sense for NervesHub to know what version of FWUP a device is running this means FWUP needs to report this data in it's communications with the NervesHub back end.
Reproduce:
12:26:28.140 [error] GenServer NervesHubLink.Socket terminating
** (Jason.EncodeError) invalid byte 0xAA in <<170>>
(jason 1.2.1) lib/jason.ex:150: Jason.encode!/2
(phoenix_client 0.11.0) lib/phoenix_client/socket.ex:254: PhoenixClient.Socket.transport_send/2
(phoenix_client 0.11.0) lib/phoenix_client/socket.ex:182: PhoenixClient.Socket.handle_info/2
(stdlib 3.11.2) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib 3.11.2) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib 3.11.2) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: :flush
12:26:33.141 [error] GenServer #PID<0.1495.0> terminating
** (stop) exited in: GenServer.call(#PID<0.1549.0>, {:push, "put_chars", %{data: <<170>>, encoding: :unicode}}, 5000)
** (EXIT) time out
(elixir 1.10.2) lib/gen_server.ex:1023: GenServer.call/3
(nerves_hub_link 0.8.2) lib/nerves_hub_link/console_channel.ex:200: NervesHubLink.ConsoleChannel.io_request/4
(nerves_hub_link 0.8.2) lib/nerves_hub_link/console_channel.ex:107: NervesHubLink.ConsoleChannel.handle_info/2
(stdlib 3.11.2) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib 3.11.2) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib 3.11.2) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {:io_request, #PID<0.1581.0>, #Reference<0.3180141690.537395201.92461>, {:put_chars, :unicode, <<170>>}}
12:26:34.971 [error] GenServer #PID<0.1595.0> terminating
** (MatchError) no match of right hand side value: nil
(nerves_hub_link 0.8.2) lib/nerves_hub_link/console_channel.ex:91: NervesHubLink.ConsoleChannel.handle_info/2
(stdlib 3.11.2) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib 3.11.2) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib 3.11.2) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: %PhoenixClient.Message{channel_pid: #PID<0.1595.0>, event: "io_reply", join_ref: nil, payload: %{"data" => "cmd(\"ls\")", "kind" => "get_line"}, ref: nil, topic: "console"}
12:26:35.283 [warn] Firmware stream error: "Unhandled Console handle_info - %PhoenixClient.Message{channel_pid: #PID<0.1597.0>, event: \"phx_reply\", join_ref: \"1\", payload: %{\"response\" => %{}, \"status\" => \"ok\"}, ref: \"2\", topic: \"console\"}"
12:26:35.284 [warn] Firmware stream error: "unknown"
Then new consoles become unresponsive and if you keep on trying to open consoles then eventually the nerves hub link application crashes and the device is marked offline.
Example of nerves_hub_link eventually crashing on a device:
2020-06-09T13:00:45.180+01:00
device_id=PROD-006 [error] GenServer #PID<0.1568.0> terminating ** (stop) exited in: GenServer.call(#PID<0.1677.0>, {:push, "put_chars", %{data: <<9, 68, 97, 116, 97, 32, 115, 101, 114, 118, 105, 99, 101, 32, 99, 97, 112, 97, 98, 105, 108, 105, 116, 105, 101, 115, 58, 32, 39, 49, 39, 10, 9, 9, 91, 48, 93, 58, 32, 39, 108, 116, 101, 39, 10, 9, ...>>, encoding: :unicode}}, 5000) ** (EXIT) time out (elixir 1.10.3) lib/gen_server.ex:1023: GenServer.call/3 (nerves_hub_link 0.8.2) lib/nerves_hub_link/console_channel.ex:200: NervesHubLink.ConsoleChannel.io_request/4 (nerves_hub_link 0.8.2) lib/nerves_hub_link/console_channel.ex:107: NervesHubLink.ConsoleChannel.handle_info/2 (stdlib 3.11.2) gen_server.erl:637: :gen_server.try_dispatch/4 (stdlib 3.11.2) gen_server.erl:711: :gen_server.handle_msg/6 (stdlib 3.11.2) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 Last message: {:io_request, #PID<0.1710.0>, #Reference<0.2557500624.537657345.219803>, {:put_chars, :unicode, <<9, 68, 97, 116, 97, 32, 115, 101, 114, 118, 105, 99, 101, 32, 99, 97, 112, 97, 98, 105, 108, 105, 116, 105, 101, 115, 58, 32, 39, 49, 39, 10, 9, 9, 91, 48, 93, 58, 32, 39, 108, 116, 101, ...>>}}
2020-06-09T13:01:19.170+01:00
device_id=PROD-006 [error] GenServer #PID<0.1861.0> terminating ** (MatchError) no match of right hand side value: nil (nerves_hub_link 0.8.2) lib/nerves_hub_link/console_channel.ex:91: NervesHubLink.ConsoleChannel.handle_info/2 (stdlib 3.11.2) gen_server.erl:637: :gen_server.try_dispatch/4 (stdlib 3.11.2) gen_server.erl:711: :gen_server.handle_msg/6 (stdlib 3.11.2) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 Last message: %PhoenixClient.Message{channel_pid: #PID<0.1861.0>, event: "io_reply", join_ref: nil, payload: %{"data" => "ping \"google.com\", ifname: :wwan0", "kind" => "get_line"}, ref: nil, topic: "console"}
2020-06-09T13:01:19.245+01:00
device_id=PROD-006 [warn] Firmware stream error: "unknown"
2020-06-09T13:01:19.245+01:00
device_id=PROD-006 [warn] Firmware stream error: "Unhandled Console handle_info - %PhoenixClient.Message{channel_pid: #PID<0.1878.0>, event: \"phx_reply\", join_ref: \"1\", payload: %{\"response\" => %{}, \"status\" => \"ok\"}, ref: \"2\", topic: \"console\"}"
2020-06-09T13:01:23.246+01:00
device_id=PROD-006 [error] GenServer #PID<0.1878.0> terminating ** (MatchError) no match of right hand side value: nil (nerves_hub_link 0.8.2) lib/nerves_hub_link/console_channel.ex:91: NervesHubLink.ConsoleChannel.handle_info/2 (stdlib 3.11.2) gen_server.erl:637: :gen_server.try_dispatch/4 (stdlib 3.11.2) gen_server.erl:711: :gen_server.handle_msg/6 (stdlib 3.11.2) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 Last message: %PhoenixClient.Message{channel_pid: #PID<0.1878.0>, event: "io_reply", join_ref: nil, payload: %{"data" => "", "kind" => "get_line"}, ref: nil, topic: "console"}
2020-06-09T13:01:23.329+01:00
device_id=PROD-006 [warn] Firmware stream error: "Unhandled Console handle_info - %PhoenixClient.Message{channel_pid: #PID<0.1883.0>, event: \"phx_reply\", join_ref: \"3\", payload: %{\"response\" => %{}, \"status\" => \"ok\"}, ref: \"4\", topic: \"console\"}"
2020-06-09T13:01:23.330+01:00
device_id=PROD-006 [warn] Firmware stream error: "unknown"
2020-06-09T13:01:23.457+01:00
device_id=PROD-006 [error] GenServer #PID<0.1883.0> terminating ** (MatchError) no match of right hand side value: nil (nerves_hub_link 0.8.2) lib/nerves_hub_link/console_channel.ex:91: NervesHubLink.ConsoleChannel.handle_info/2 (stdlib 3.11.2) gen_server.erl:637: :gen_server.try_dispatch/4 (stdlib 3.11.2) gen_server.erl:711: :gen_server.handle_msg/6 (stdlib 3.11.2) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 Last message: %PhoenixClient.Message{channel_pid: #PID<0.1883.0>, event: "io_reply", join_ref: nil, payload: %{"data" => "", "kind" => "get_line"}, ref: nil, topic: "console"}
2020-06-09T13:01:23.529+01:00
device_id=PROD-006 [warn] Firmware stream error: "Unhandled Console handle_info - %PhoenixClient.Message{channel_pid: #PID<0.1886.0>, event: \"phx_reply\", join_ref: \"5\", payload: %{\"response\" => %{}, \"status\" => \"ok\"}, ref: \"6\", topic: \"console\"}"
2020-06-09T13:01:23.530+01:00
device_id=PROD-006 [warn] Firmware stream error: "unknown"
2020-06-09T13:01:23.641+01:00
device_id=PROD-006 [error] GenServer #PID<0.1886.0> terminating
** (MatchError) no match of right hand side value: nil
(nerves_hub_link 0.8.2) lib/nerves_hub_link/console_channel.ex:91: NervesHubLink.ConsoleChannel.handle_info/2
(stdlib 3.11.2) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib 3.11.2) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib 3.11.2) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: %PhoenixClient.Message{channel_pid: #PID<0.1886.0>, event: "io_reply", join_ref: nil, payload: %{"data" => "", "kind" => "get_line"}, ref: nil, topic: "console"}
2020-06-09T13:01:23.650+01:00
device_id=PROD-006 [info] Application nerves_hub_link exited: shutdown
Describe the bug
If we use nerves_hub_link 0.10.1 with fwup_public_keys which is reffered to by atom name, the nerves cannot update its firmware.
The log is below,
22:42:59.835 [error] FWUP ERROR: Error decoding public key
22:42:59.843 [error] GenServer Fwup.Stream terminating
** (stop) {:exit, 1}
Last message: {#Port<0.226>, {:exit_status, 1}}
State: %{cm: #PID<0.1478.0>, port: nil}
To Reproduce
$ git clone https://github.com/pojiro/nerves_hub_link_test
$ git checkout v0.1.0-nerves_hub_link_0.10.1
$ cd nerves_hub_link_test
# change ssh key config and fwup_public_keys(use atom name) in config/target.exs
$ export MIX_TARGET=[you have]
$ mix deps.get && mix deps.compile
$ mix nerves_hub.device create
$ mix nerves_hub.device cert create [device id]
$ mkdir rootfs_overlay/certs && cp nerves_hub/*.pem rootfs_overlay/certs
# change nerves_hub_link ssl config in config/target.exs, ssl: [certfile: /certs/[***].pem, keyfile: /certs/[***].pem]
$ mix firmware
$ mix nerves_hub.device burn [device id]
$ git checkout v0.1.1
$ mix firmware
$ mix nerves_hub.firmware publish --key [yourkey]
# then create deployment and activate it on nerves-hub or use api
Expected behavior
It should also works with atom name.
Environment
mix nerves.env --info
)$ mix nerves.env --info
==> nerves
==> hello_nerves_hub
|nerves_bootstrap| Environment Package List
Pkg: nerves_toolchain_armv7_nerves_linux_gnueabihf
Vsn: 1.4.1
Type: toolchain
BuildRunner: {Nerves.Artifact.BuildRunners.Local, []}
Pkg: nerves_system_br
Vsn: 1.14.4
Type: system_platform
BuildRunner: {nil, []}
Pkg: nerves_system_bbb
Vsn: 2.9.0
Type: system
BuildRunner: {Nerves.Artifact.BuildRunners.Local, []}
Pkg: nerves_toolchain_ctng
Vsn: 1.8.2
Type: toolchain_platform
BuildRunner: {nil, []}
|nerves_bootstrap| Loadpaths Start
Nerves environment
MIX_TARGET: bbb
MIX_ENV: dev
|nerves_bootstrap| Environment Variable List
target: bbb
toolchain: /home/pojiro/.nerves/artifacts/nerves_toolchain_armv7_nerves_linux_gnueabihf-linux_x86_64-1.4.1
system: /home/pojiro/.nerves/artifacts/nerves_system_bbb-portable-2.9.0
app: /home/pojiro/Sandbox/hello_nerves_hub
|nerves_bootstrap| Loadpaths End
I confirm this issue on rpi3 and bbb.
Additional context
Hello folks,
I'm having throble to connect my nerves_hub_web with my nerves project (firmware),
using the nerves_hub_link and nerves_hub_cli, and trying to connect to my local nerves_hub_web,
i am not using the default certificates, inside the test folder
i will walkthrow about my setup:
so, i cloned https://github.com/nerves-hub/nerves_hub_web
cd nerves_hub_web
echo "127.0.0.1 nerves-hub.org" | sudo tee -a /etc/hosts
docker run -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres -e POSTGRES_DB=nerves_hub_dev -d postgres:13
mix deps.get
mix compile
mix ecto.reset
mix assets.install
iex -S mix phx.server
and the nerves_hub_web works perfect
after that i create a new nerves project with command line:
mix nerves.new firmeware
cd firmeware
export MIX_TARGET=rpi4
mix deps.get
mix compile
mix firmeware
mix burn
and put the sdcard into my rpi4 and connected into my network
so the command mix update
works fine and nerves booted without any problems
then i understand that i need to connect the link, so i did:
in the nerves_hub_web clone folder i created a "env" file: /home/me/nerves_hub_web/.env.dev.local
with the follow content
export DATABASE_URL=postgres://postgres:postgres@localhost:5432/nerves_hub_dev
export LOCAL_IPV4=127.0.0.1
export NERVES_HUB_CA_DIR=/home/me/.nerves-hub
export ERL_COOKIE=cookie
export LIVE_VIEW_SIGNING_SALT=yz/zh1ND2xUzaQxYOn/tBrLW46prOG76CmUMLouxPOr/nXdbq/AV+DCAVyqWYNg4
export SECRET_KEY_BASE=CgVs//sLSh+Yp1iBt/LN7OgMUZdVp3kvgtLFpzmXFu94vvrsLwQ10BobN4HgAnu+
export HOST=nerveshub.nerves-hub.org
export PORT=4000
export DEVICE_HOST=nerveshub.nerves-hub.org
export DEVICE_PORT=4001
export API_HOST=nerveshub.nerves-hub.org
export API_PORT=4002
i found this reference in a elixirforum post: https://elixirforum.com/t/what-is-the-proper-certificates-configuration-for-nerveshub-2-0-and-nerveshublink/55809
pls note this variable NERVES_HUB_CA_DIR
, i just assign the dir folder where i put the certificates,
i found this env var in config/dev.exs in nerves_hub_web,
and on the firmware project i change the config/dev.exs with the follow code:
config :nerves, :firmware,
rootfs_overlay: "rootfs_overlay",
provisioning: :nerves_hub_link
ca_certs = "/home/me/.nerves-hub"
config :nerves_hub_link,
device_api_host: "192.168.0.88",
device_api_port: 4001,
ca_certs: ca_certs
config :nerves_hub_cli,
org: "myorg",
host: "nerveshub.nerves-hub.org",
port: 4001,
server_name_indication: 'nerveshub.nerves-hub.org',
ca_certs: ca_certs
and the mix.exs:
...
{:nerves_runtime, "~> 0.13.0"},
{:nerves_hub_link, git: "https://github.com/nerves-hub/nerves_hub_link.git", branch: "main"},
{:nerves_hub_cli, git: "https://github.com/nerves-hub/nerves_hub_cli.git", branch: "main"},
{:nerves_time, "~> 0.4.6"},
...
and a .env file /home/me/firmeware/.env.nerves_hub_cli with:
export NERVES_HUB_TOKEN=nhu_000W98StoQxUhLAjoAYcfq4vXAOjVb3AMLfX
# export NERVES_HUB_HOST=nerveshub.nerves-hub.org
export NERVES_HUB_PORT=4001
export NERVES_HUB_CERT=/home/me/.nerves-hub/SERIAL-cert.pem
export NERVES_HUB_KEY=/home/me/.nerves-hub/SERIAL-key.pem
export NERVES_HUB_ORG=myorg
the NERVES_HUB_TOKEN
i created using the defaut user on nerves_hub_web on http://localhost:4000/account/nerveshub/tokens
and then i follow this gist to create the certificates:
https://gist.github.com/guillego/86b31452e639d7558c0e63b6937606bc
and i finish creating the certificates like
Generate the ca.key with
openssl genrsa -out ca.key 2048
Generate the ca.pem with
openssl req -x509 -new -nodes -key ca.key -sha256 -days 1825 -out ca.pem -subj '/OU=NervesHub/'
Generate nerveshub.nerves-hub.org-key.pem with
openssl genrsa -out nerveshub.nerves-hub.org-key.pem
Generate nerveshub.nerves-hub.org.csr with
openssl req -new -key nerveshub.nerves-hub.org-key.pem -out nerveshub.nerves-hub.org.csr -subj '/CN=nerveshub.nerves-hub.org/'
Create nerveshub.nerves-hub.org.ext with:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
[alt_names]
DNS.1 = nerveshub.nerves-hub.org
Generate nerveshub.nerves-hub.org.pem:
openssl x509 -req -in nerveshub.nerves-hub.org.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out nerveshub.nerves-hub.org.pem -days 825 -sha256 -extfile nerveshub.nerves-hub.org.ext
Move nerveshub.nerves-hub.org.pem and nerveshub.nerves-hub.org-key.pem to /home/me/.nerves-hub
when i run
mix nerves_hub.device create --identifier myid --tag test --description "i am a device"
i had this:
Nerves environment
MIX_TARGET: rpi4
MIX_ENV: dev
Generated firmeware app
NervesHub server: nerveshub.nerves-hub.org:4001
NervesHub organization: myorg
14:49:34.567 [warning] [NervesHubLink] No CA store or :cacerts have been specified. Request will fail
** (ArgumentError) errors were found at the given arguments:
* 1st argument: not a binary
:erlang.binary_to_atom(nil, :utf8)
(tesla 1.8.0) lib/tesla/adapter/mint.ex:161: Tesla.Adapter.Mint.open_conn/2
(tesla 1.8.0) lib/tesla/adapter/mint.ex:121: Tesla.Adapter.Mint.do_request/5
(tesla 1.8.0) lib/tesla/adapter/mint.ex:61: Tesla.Adapter.Mint.call/2
(tesla 1.8.0) lib/tesla/middleware/json.ex:57: Tesla.Middleware.JSON.call/3
(tesla 1.8.0) lib/tesla/middleware/follow_redirects.ex:46: Tesla.Middleware.FollowRedirects.redirect/3
(nerves_hub_cli 2.0.0) lib/nerves_hub_cli/api.ex:42: NervesHubCLI.API.request/4
(nerves_hub_cli 2.0.0) lib/mix/tasks/nerves_hub.device.ex:278: Mix.Tasks.NervesHub.Device.create/3
and my firmware is not connected to nerves_hub and the nerves_hub_web not shows new devices
It appears that as soon as NervesKey is successfully configured, the identifier for the device becomes the manufacturer_sn
provisioned into the board, even though /etc/boardid.config
specifies otherwise:
iex(10)> cat "/etc/boardid.config"
# boardid.config
# Please consider using an ATECCx08 or NervesKey rather than storing serial
# numbers in U-Boot environment blocks. Override this file in your project's
# rootfs_overlay directory and uncomment the following line if you go this
# route:
# -b nerves_key -f /dev/i2c-1
# Read the serial number from the U-boot environment block. The variable
# "nerves_serial_number" is the desired variable to use. "serial_number" is
# checked as a backup.
-b uboot_env -u nerves_serial_number
-b uboot_env -u serial_number
# Last resort: use 4 digits of the RPi's unique ID as the serial number
-b rpi -n 4
There seems to be no way to override this behavior. When I remove the nerves_key
dependency, the device reports to have a different identifier.
So either we need to update the documentation and specify that manufacturer_sn
will be the identifier or we need code that uses boardid.config
Hi,
I have a nerves hub instance up and running on our web server. I was reading through the documentation and didn't found any useful link which indicates how to change the URL to point somewhere else.
The Documentation only says
The following sections will walk you through updating your Nerves project to work with the nerves-hub.org NervesHub server. Using your own NervesHub server will require setting URLs to point elsewhere and is not covered below to simplify first usage.
I have recently switched over from nerves_hub
- after returning :apply
from my client I see the following exception in my logs:
00:47:39.221 [error] [NervesHubLink] Client: Elixir.MyApp.NervesHubLinkClient.update_available/1 bad return value: {:error, :function_clause} Applying update.
00:47:39.237 [error] GenServer NervesHubLink.Channel terminating
** (MatchError) no match of right hand side value: {:error, {{:badmatch, {:error, {:already_started, #PID<0.1875.0>}}}, [{NervesHubLink.HTTPFwupStream, :init, 1, [file: 'lib/nerves_hub_link/http_fwup_stream.ex', line: 72]}, {:gen_server, :init_it, 2, [file: 'gen_server.erl', line: 374]}, {:gen_server, :init_it, 6, [file: 'gen_server.erl', line: 342]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}}
(nerves_hub_link) lib/nerves_hub_link/channel.ex:148: NervesHubLink.Channel.maybe_update_firmware/2
(nerves_hub_link) lib/nerves_hub_link/channel.ex:58: NervesHubLink.Channel.handle_info/2
(stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: %PhoenixClient.Message{channel_pid: #PID<0.1646.0>, event: "update", join_ref: nil, payload: %{"deployment_id" => 491, "firmware_url" => "https://s3.amazonaws.com/nerves-hub/firmware/316/xxx.fw?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxx&X-Amz-Date=20200216T004739Z&X-Amz-Expires=600&X-Amz-Security-Token=xxx&X-Amz-SignedHeaders=xxx&X-Amz-Signature=xxx"}, ref: nil, topic: "device"}
State: %NervesHubLink.Channel.State{channel: #PID<0.1711.0>, connected?: true, params: %{"nerves_fw_application_part0_devpath" => "/dev/mmcblk0p3", "nerves_fw_application_part0_fstype" => "ext4", "nerves_fw_application_part0_target" => "/root", "nerves_fw_architecture" => "arm", "nerves_fw_author" => "The Nerves Team", "nerves_fw_description" => "", "nerves_fw_misc" => "", "nerves_fw_platform" => "rpi3", "nerves_fw_product" => "claw", "nerves_fw_uuid" => "6097bae1-0553-596a-501a-82417e2432a7", "nerves_fw_vcs_identifier" => "", "nerves_fw_version" => "0.1.6"}, socket: NervesHubLink.Socket, status: {:updating, 38}, topic: "device"}
Here are the interesting deps:
$ mix deps
* fwup 0.4.0 (Hex package) (mix)
locked at 0.4.0 (fwup) 88cdf2c2
ok
* nerves 1.5.4 (Hex package) (mix)
locked at 1.5.4 (nerves) 283ce855
ok
* phoenix_client 0.10.0 (Hex package) (mix)
locked at 0.10.0 (phoenix_client) 9374a29a
ok
* nerves_runtime 0.11.0 (Hex package) (mix)
locked at 0.11.0 (nerves_runtime) 7adc7f71
ok
* nerves_hub_user_api 0.6.0 (Hex package) (mix)
locked at 0.6.0 (nerves_hub_user_api) de682a5f
ok
* nerves_hub_cli 0.9.1 (Hex package) (mix)
locked at 0.9.1 (nerves_hub_cli) b956b75b
ok
* nerves_hub_link 0.7.6 (Hex package) (mix)
locked at 0.7.6 (nerves_hub_link) 550807ec
ok
Thanks!
It would be great to use arrow keys to cycle thought the command history for the remote shell (even if just per session).
I was trying to get a certificate set up on the ATECC608A today, and I ran into the following error:
15:33:26.670 [info] Application nerves_hub_link exited: exited in: NervesHubLink.Application.start(:normal, [])
** (EXIT) exited in: GenServer.call(ATECC508A.Transport.I2CSupervisor, {:start_child, {{ATECC508A.Transport.I2CServer, :start_link, [["i2c-1", 96, :"Elixir.ATECC508A.Transport.I2C.i2c-1.96"]]}, :permanent, 5000, :worker, [ATECC508A.Transport.I2CServer]}}, :infinity)
** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
I also get this when I run this from ssh console on the device:
iex(2)> Application.ensure_all_started(:thirsty)
{:error,
{:nerves_hub_link,
{:bad_return,
{{NervesHubLink.Application, :start, [:normal, []]},
{:EXIT,
{:noproc,
{GenServer, :call,
[
ATECC508A.Transport.I2CSupervisor,
{:start_child,
{{ATECC508A.Transport.I2CServer, :start_link,
[["i2c-1", 96, :"Elixir.ATECC508A.Transport.I2C.i2c-1.96"]]},
:permanent, 5000, :worker, [ATECC508A.Transport.I2CServer]}},
:infinity
]}}}}}}}
Trying to establish connection to ATEC608A results in similar error:
iex(3)> {:ok, i2c} = ATECC508A.Transport.I2C.init(bus_name: "i2c-1")
** (exit) exited in: GenServer.call(ATECC508A.Transport.I2CSupervisor, {:start_child, {{ATECC508A.Transport.I2CServer, :start_link, [["i2c-1", 96, :"Elixir.ATECC508A.Transport.I2C.i2c-1.96"]]}, :permanent, 5000, :worker, [ATECC508A.Transport.I2CServer]}}, :infinity)
** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
(elixir 1.11.2) lib/gen_server.ex:1017: GenServer.call/3
lib/atecc508a/transport/i2c.ex:43: ATECC508A.Transport.I2C.init/1
I am pretty stumped as to what is wrong. This runs on a Raspberry Pi Zero W rev 1.2, I really appreciate some guidance on this.
These are my current dependencies:
defp deps do
[
# Dependencies for all targets
{:nerves, "~> 1.7.0", runtime: false},
{:nerves_hub_cli, "~> 0.10.4", runtime: false},
{:nerves_hub_link, "~> 0.9.2"},
{:nerves_time, "~> 0.2"},
{:nerves_key, "~> 0.5"},
{:toolshed, "~> 0.2.13"},
{:shoehorn, "~> 0.7"},
{:ring_logger, "~> 0.8.1"},
{:circuits_i2c, "~> 0.3.7"},
{:circuits_gpio, "~> 0.4.6"},
{:ads1115, "~> 0.1"},
{:gen_rmq, "~> 3.0"},
{:jason, "~> 1.2"},
{:wafer, git: "https://gitlab.com/jimsy/wafer"},
# Dependencies for all targets except :host
{:nerves_runtime, "~> 0.11.3"},
{:nerves_pack, "~> 0.4.0", targets: @all_targets},
{:busybox, "~> 0.1", targets: @all_targets},
# Dependencies for specific targets
{:nerves_system_rpi, "~> 1.13", runtime: false, targets: :rpi},
{:nerves_system_rpi0, "~> 1.13", runtime: false, targets: :rpi0},
{:nerves_system_rpi2, "~> 1.13", runtime: false, targets: :rpi2},
{:nerves_system_rpi3, "~> 1.13", runtime: false, targets: :rpi3},
{:nerves_system_rpi3a, "~> 1.13", runtime: false, targets: :rpi3a},
{:nerves_system_rpi4, "~> 1.13", runtime: false, targets: :rpi4},
{:nerves_system_bbb, "~> 2.6", runtime: false, targets: :bbb},
{:nerves_system_x86_64, "~> 1.13", runtime: false, targets: :x86_64},
]
end
06:48:16.099 [warn] [NervesHubLink] error: {:error, {:upgrade_failure, %{reason: %Mint.WebSocket.UpgradeFailureError{status_code: 403, headers: [{"date", "Fri, 17 May 2024 06:48:15 GMT"}, {"content-length", "0"}, {"vary", "accept-encoding"}, {"cache-control", "max-age=0, private, must-revalidate"}]}, status_code: 403, resp_headers: [{"date", "Fri, 17 May 2024 06:48:15 GMT"}, {"content-length", "0"}, {"vary", "accept-encoding"}, {"cache-control", "max-age=0, private, must-revalidate"}]}}}
06:48:16.099 [info] :alarm_handler: {:set,
{NervesHubLink.Disconnected,
[
reason: {:error,
{:upgrade_failure,
%{
reason: %Mint.WebSocket.UpgradeFailureError{
status_code: 403,
headers: [
{"date", "Fri, 17 May 2024 06:48:15 GMT"},
{"content-length", "0"},
{"vary", "accept-encoding"},
{"cache-control", "max-age=0, private, must-revalidate"}
]
},
status_code: 403,
resp_headers: [
{"date", "Fri, 17 May 2024 06:48:15 GMT"},
{"content-length", "0"},
{"vary", "accept-encoding"},
{"cache-control", "max-age=0, private, must-revalidate"}
]
}}}
]}}
06:48:16.108 [warn] [NervesHubLink.Socket] Unhandled handle_info: {:EXIT, #Port<0.100>, :normal}
06:48:32.561 [info] disconnect --------
06:48:32.562 [warn] [NervesHubLink] error: {:error, {:upgrade_failure, %{reason: %Mint.WebSocket.UpgradeFailureError{status_code: 403, headers: [{"date", "Fri, 17 May 2024 06:48:31 GMT"}, {"content-length", "0"}, {"vary", "accept-encoding"}, {"cache-control", "max-age=0, private, must-revalidate"}]}, status_code: 403, resp_headers: [{"date", "Fri, 17 May 2024 06:48:31 GMT"}, {"content-length", "0"}, {"vary", "accept-encoding"}, {"cache-control", "max-age=0, private, must-revalidate"}]}}}
06:48:32.563 [info] :alarm_handler: {:set,
{NervesHubLink.Disconnected,
[
reason: {:error,
{:upgrade_failure,
%{
reason: %Mint.WebSocket.UpgradeFailureError{
status_code: 403,
headers: [
{"date", "Fri, 17 May 2024 06:48:31 GMT"},
{"content-length", "0"},
{"vary", "accept-encoding"},
{"cache-control", "max-age=0, private, must-revalidate"}
]
},
status_code: 403,
resp_headers: [
{"date", "Fri, 17 May 2024 06:48:31 GMT"},
{"content-length", "0"},
{"vary", "accept-encoding"},
{"cache-control", "max-age=0, private, must-revalidate"}
]
}}}
]}}
06:48:32.572 [warn] [NervesHubLink.Socket] Unhandled handle_info: {:EXIT, #Port<0.105>, :normal}
This might be the setup of NervesCloud @joshk, or it could be normal thing.
Is there a token or something written to the data partition or something. It seems to happen after I've done a firmware update, it starts up, gets networking but fails to auth?
IO servers can have their own tab expansion handlers:
fun = fn(str) ->
{:yes, 'aa', ['aa1', 'aab', 'aac']}
end
:io.setopts(:expand_fun, fun)
We can use this to tunnel tab completion for the remote console
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.