# `NervesHubLink.UpdateManager.Updater`
[🔗](https://github.com/nerves-hub/nerves_hub_link/blob/v2.12.0/lib/nerves_hub_link/update_manager/updater.ex#L5)

A behaviour to help orchestrate the complete workflow of downloading and installing/applying
firmware updates.

This module provides a set of callbacks that must be implemented by any
updater module. The callbacks are used to start the update process, handle
messages from the `NervesHubLink.Downloader`, decide when to start the installation via
the `Fwup` library, and perform any necessary cleanup.

Creating a new updater module involves implementing the following callbacks:

- `c:start_update/3`: Called by `NervesHubLink.UpdateManager` to start the update process.
- `c:start/1`: Callback to setup, prepare, and trigger the download.
- `c:handle_downloader_message/2`: Process messages from the `NervesHubLink.Downloader`.
- `c:handle_fwup_message/2`: Process messages received from the `Fwup` library
- `c:cleanup/1`: Perform any necessary cleanup.

To simplify the implementation of these callbacks, you can use the provided
`NervesHubLink.UpdateManager.Updater` module as a base. This module provides
default implementations for the callbacks, which you can override as needed.

### Example Usage

Here's an example of how to create a new updater module using the provided
`NervesHubLink.UpdateManager.Updater` module as a base:

```elixir
defmodule MyApp.Updater do
  use NervesHubLink.UpdateManager.Updater

  def start_update(update_info, fwup_config, fwup_public_keys) do
    # Implement the start_update callback
  end

  def start(state) do
    # eg. Setup a temporary directory for storing downloaded files
  end

  def handle_downloader_message(message, state) do
    # eg. Forward packets to the Fwup module
  end

  # Use the default implementation provided by the base module
  #
  # def handle_fwup_message(message, state) do
  # end

  def cleanup(state) do
    # eg. Remove any temporary files or resources created during the update process
  end

  def log_prefix do
    "[MyApp.Updater]"
  end
end
```

# `standard_response`

```elixir
@type standard_response() ::
  {:noreply, new_state :: term()}
  | {:noreply, new_state :: term(),
     timeout() | :hibernate | {:continue, continue_arg :: term()}}
  | {:stop, reason :: term(), new_state :: term()}
```

# `t`

```elixir
@type t() :: NervesHubLink.UpdateManager.Updater
```

# `cleanup`

```elixir
@callback cleanup(state :: term()) :: :ok
```

Run any cleanup that might need to take place

# `handle_downloader_message`

```elixir
@callback handle_downloader_message(message :: term(), state :: term()) ::
  {:ok, new_state :: term()}
  | {:error, reason :: term(), new_state :: term()}
  | {:stop, reason :: term(), new_state :: term()}
```

Process messages from the `Downloader`

# `handle_fwup_message`

```elixir
@callback handle_fwup_message(message :: term(), state :: term()) ::
  {:ok, new_state :: term()} | {:stop, reason :: term(), new_state :: term()}
```

Process messages received from the `Fwup` library

# `log_prefix`

```elixir
@callback log_prefix() :: String.t()
```

A little hook to allow for customization of the logging prefix

# `start`

```elixir
@callback start(state :: term()) :: {:ok, new_state :: term()}
```

Setup and prepare for the firmware update.

# `start_update`

```elixir
@callback start_update(
  NervesHubLink.Message.UpdateInfo.t(),
  NervesHubLink.FwupConfig.t(),
  fwup_public_keys :: []
) :: GenServer.on_start()
```

Start an updater GenServer

---

*Consult [api-reference.md](api-reference.md) for complete listing*
