View Source NervesHubLink.Client behaviour (nerves_hub_link v2.6.0)

A behaviour module for customizing if and when firmware updates get applied.

By default NervesHubLink applies updates as soon as it knows about them from the NervesHubLink server and doesn't give warning before rebooting. This let's devices hook into the decision making process and monitor the update's progress.

Example

defmodule MyApp.NervesHubLinkClient do
  @behaviour NervesHubLink.Client

  # May return:
  #  * `:apply` - apply the action immediately
  #  * `:ignore` - don't apply the action, don't ask again.
  #  * `{:reschedule, timeout_in_milliseconds}` - call this function again later.

  @impl NervesHubLink.Client
  def update_available(data) do
    if SomeInternalAPI.is_now_a_good_time_to_update?(data) do
      :apply
    else
      {:reschedule, 60_000}
    end
  end
end

To have NervesHubLink invoke it, add the following to your config.exs:

config :nerves_hub_link, client: MyApp.NervesHubLinkClient

Summary

Types

Archive that comes over a socket.

Supported responses from archive_available/1

Firmware update progress, completion or error report

Update that comes over a socket.

Supported responses from update_available/1

Callbacks

Called when an archive is available for download

Called when an archive has been downloaded and is available for the application to do something

Called when downloading a firmware update fails.

Called on firmware update reports.

Callback to identify the device from NervesHub.

Optional callback to reboot the device when a firmware update completes

Optional callback when the socket disconnected, before starting to reconnect.

Called to find out what to do when a firmware update is available.

Functions

This function is called internally by NervesHubLink to notify clients of fwup errors.

This function is called internally by NervesHubLink to notify clients of fwup progress.

This function is called internally by NervesHubLink to identify a device.

This function is called internally by NervesHubLink to initiate a reboot.

This function is called internally by NervesHubLink to notify clients of disconnects.

This function is called internally by NervesHubLink to notify clients.

Types

archive_data()

@type archive_data() :: NervesHubLink.Message.ArchiveInfo.t()

Archive that comes over a socket.

archive_response()

@type archive_response() :: :download | :ignore | {:reschedule, pos_integer()}

Supported responses from archive_available/1

fwup_message()

@type fwup_message() ::
  {:ok, non_neg_integer(), String.t()}
  | {:warning, non_neg_integer(), String.t()}
  | {:error, non_neg_integer(), String.t()}
  | {:progress, 0..100}

Firmware update progress, completion or error report

update_data()

@type update_data() :: NervesHubLink.Message.UpdateInfo.t()

Update that comes over a socket.

update_response()

@type update_response() :: :apply | :ignore | {:reschedule, pos_integer()}

Supported responses from update_available/1

Callbacks

archive_available(archive_data)

@callback archive_available(archive_data()) :: archive_response()

Called when an archive is available for download

May return one of:

  • download - Download the archive right now
  • ignore - Don't download this archive.
  • {:reschedule, timeout} - Defer making a decision. Call this function again in timeout milliseconds.

archive_ready(archive_data, t)

@callback archive_ready(archive_data(), Path.t()) :: :ok

Called when an archive has been downloaded and is available for the application to do something

handle_error(any)

@callback handle_error(any()) :: :ok

Called when downloading a firmware update fails.

The return value of this function is not checked.

handle_fwup_message(fwup_message)

@callback handle_fwup_message(fwup_message()) :: :ok

Called on firmware update reports.

The return value of this function is not checked.

identify()

@callback identify() :: :ok

Callback to identify the device from NervesHub.

reboot()

(optional)
@callback reboot() :: no_return()

Optional callback to reboot the device when a firmware update completes

The default behavior is to call Nerves.Runtime.reboot/0 after a successful update. This is useful for testing and for doing additional work like notifying users in a UI that a reboot will happen soon. It is critical that a reboot does happen.

reconnect_backoff()

(optional)
@callback reconnect_backoff() :: [integer()] | nil

Optional callback when the socket disconnected, before starting to reconnect.

The return value is used to reset the next socket's retry timeout. nil uses the default. The default is a call to NervesHubLink.Backoff.delay_list/3.

You may wish to use this to dynamically change the reconnect backoffs. For instance, during a NervesHub deploy you may wish to change the reconnect based on your own logic to not create a thundering herd of reconnections. If you have a particularly flaky connection you can increase how fast the reconnect happens to avoid overloading your server.

update_available(update_data)

@callback update_available(update_data()) :: update_response()

Called to find out what to do when a firmware update is available.

May return one of:

  • apply - Download and apply the update right now.
  • ignore - Don't download and apply this update.
  • {:reschedule, timeout} - Defer making a decision. Call this function again in timeout milliseconds.

Functions

archive_available(data)

@spec archive_available(archive_data()) :: archive_response()

archive_ready(data, file_path)

@spec archive_ready(archive_data(), Path.t()) :: :ok

handle_error(data)

@spec handle_error(any()) :: :ok

This function is called internally by NervesHubLink to notify clients of fwup errors.

handle_fwup_message(data)

@spec handle_fwup_message(fwup_message()) :: :ok

This function is called internally by NervesHubLink to notify clients of fwup progress.

identify()

This function is called internally by NervesHubLink to identify a device.

initiate_reboot()

@spec initiate_reboot() :: :ok

This function is called internally by NervesHubLink to initiate a reboot.

After a successful firmware update, NervesHubLink calls this to start the reboot process. It calls reboot/0 if supplied or Nerves.Runtime.reboot/0.

reconnect_backoff()

@spec reconnect_backoff() :: [integer()]

This function is called internally by NervesHubLink to notify clients of disconnects.

update_available(data)

@spec update_available(update_data()) :: update_response()

This function is called internally by NervesHubLink to notify clients.