Introduce the beginnings of an ssh app.
This introduces an ssh app, which factors out and structures the SSH
utility functions originally found in scmtools/sshutils.py.
The new ssh app contains an SSHClient object, which represents a session
tied either to a base .ssh directory, or a namespaced directory within.
Down the road, we may want to take further advantage of the namespacing,
such as for repository access. Right now, we deifne a namespace as a
Most of the original utility functions in sshutils now live within
SSHClient. Instead of each of those taking a local_site_name parameter,
this is now passed only when defining the SSHClient, as the namespace.
Multiple clients can exist at a time.
The various SSH-related errors have moved into ssh/errors.py, and have
been decoupled from SCMError. This is clean in all cases except
AuthenticationError. Both apps have a concept of an AuthenticationError,
with ssh's being a bit more specific.
What we're doing is keeping two versions. The SSH one is
SSHAuthenticationError, and contains all the original logic. The new one
is AuthenticationError, and basically has SSHAuthenticationError as a
mixin. The two call sites in scmtools that need to really deal with this
check for an SSHAuthenticationError and convert it into an
AuthenticationError. The purpose of this is to keep the ssh app
decoupled from SCMTools.