GenServer that owns an OTP :ssh.daemon/2 listening for TUI clients.
This is the transport-level supervisor for ExRatatui.App under
transport: :ssh. It starts an :ssh daemon on the requested port,
registers the app module as an SSH subsystem + default shell, and
tears the daemon down on shutdown. Each connected SSH client gets its
own ExRatatui.SSH channel process, which in turn supervises its own
internal server running the app — so a single Daemon can serve
many concurrent clients without any shared state between them.
Usage
Typically you don't start this directly; use ExRatatui.App routes
start_link(transport: :ssh, ...) through here. But for full control
you can add it to a supervision tree by hand:
children = [
{ExRatatui.SSH.Daemon,
mod: MyApp.TUI,
port: 2222,
system_dir: ~c"/etc/ssh",
user_dir: ~c"/var/ssh/users"}
]Options
:mod(required) — theExRatatui.Appmodule to serve.:port(default2222) — TCP port to listen on.0picks a random free port — callport/1on the daemon pid to discover the chosen port.:system_dir— path to the daemon's host key directory, forwarded as-is to:ssh.daemon/2. May be a binary or charlist; binaries are converted automatically.:auto_host_key(defaultfalse) — whentrue, the daemon resolves the OTP application that owns:mod, ensures<priv_dir>/ssh/exists, and generates a 2048-bit RSA host key there on first boot (ssh_host_rsa_key). Subsequent boots reuse the same key. Set:system_direxplicitly to override the directory; passing both raises. Intended for "drop into a supervision tree and it just works" setups (Phoenix admin TUIs, internal tools); production deployments should keep an explicit:system_dirunder their own configuration management.:user_dir— path to client-authentication key material.:authorized_keys— forwarded through to:ssh.daemon/2.:name— process name (default__MODULE__, passnilto skip).:app_opts— extra opts that will be merged into every client'smount/1callbacks (e.g. shared PubSub topic names).- Any other keyword pair is forwarded verbatim to
:ssh.daemon/2, so e.g.:pwdfun,:idle_time,:profileall work unchanged.
Testability
:daemon_starter and :daemon_stopper keyword options let tests
substitute fakes for &:ssh.daemon/2 and &:ssh.stop_daemon/1 so the
GenServer can be exercised without starting a real SSH listener. The
real functions are the defaults; production callers never pass either.
Summary
Functions
Returns a specification to start this module under a supervisor.
Returns the {:ok, daemon_ref} handle of the underlying OTP :ssh
daemon, or {:error, :not_started} if it isn't up.
Returns the port the daemon is listening on.
Starts a supervised SSH daemon serving the given ExRatatui.App
module. Returns the daemon's process pid on success.
Types
@type t() :: %ExRatatui.SSH.Daemon{ daemon_ref: term() | nil, daemon_stopper: (term() -> :ok), mod: module(), port: non_neg_integer() }
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec daemon_ref(GenServer.server()) :: {:ok, term()} | {:error, :not_started}
Returns the {:ok, daemon_ref} handle of the underlying OTP :ssh
daemon, or {:error, :not_started} if it isn't up.
@spec port(GenServer.server()) :: non_neg_integer()
Returns the port the daemon is listening on.
@spec start_link(keyword()) :: GenServer.on_start()
Starts a supervised SSH daemon serving the given ExRatatui.App
module. Returns the daemon's process pid on success.
See the module docs for the full list of accepted options.