# `SSHSubsystemFwup`
[🔗](https://github.com/nerves-project/ssh_subsystem_fwup/blob/v0.6.7/lib/ssh_subsystem_fwup.ex#L6)

SSH subsystem for upgrading Nerves devices

This module provides an SSH subsystem for Erlang's `ssh` application. This
makes it possible to send firmware updates to Nerves devices using plain old
`ssh` like this:

```shell
cat $firmware | ssh -s $ip_address fwup
```

Where `$ip_address` is the IP address of your Nerves device. Depending on how
you have Erlang's `ssh` application set up, you may need to pass more
parameters (like username, port, identities, etc.).

See [`nerves_ssh`](https://github.com/nerves-project/nerves_ssh/) for an easy
way to set this up. If you don't want to use `nerves_ssh`, then in your call
to `:ssh.daemon` add the return value from
`SSHSubsystemFwup.subsystem_spec/1`:

```elixir
devpath = Nerves.Runtime.KV.get("nerves_fw_devpath")

:ssh.daemon([
      {:subsystems, [SSHSubsystemFwup.subsystem_spec(devpath: devpath)]}
    ])
```

See `SSHSubsystemFwup.subsystem_spec/1` for options. You will almost always
need to pass the path to the device that should be updated since that is
device-specific.

# `options`

```elixir
@type options() :: [
  devpath: Path.t(),
  fwup_path: Path.t(),
  fwup_env: [{String.t(), String.t()}],
  fwup_extra_options: [String.t()],
  precheck_callback: mfargs() | nil,
  task: String.t(),
  success_callback: mfargs()
]
```

Options:

* `:devpath` - path for fwup to upgrade (Required)
* `:fwup_path` - path to the fwup firmware update utility
* `:fwup_env` - a list of name,value tuples to be passed to the OS environment for fwup
* `:fwup_extra_options` - additional options to pass to fwup like for setting
  public keys
* `:precheck_callback` - an MFArgs to call when there's a connection. If
  specified, the callback will be passed the username and the current set of
  options. If allowed, it should return `{:ok, new_options}`. Any other
  return value closes the connection.
* `:success_callback` - an MFArgs to call when a firmware update completes
  successfully. Defaults to `{Nerves.Runtime, :reboot, []}`.
* `:task` - the task to run in the firmware update. Defaults to `"upgrade"`

# `subsystem_spec`

```elixir
@spec subsystem_spec(options()) :: :ssh.subsystem_spec()
```

Helper for creating the SSH subsystem spec

---

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