Add PackageUpload task
The hardest bit of this was writing useful tests. I decided it would be
best to have something resembling real FTP and SFTP servers in unit
tests, so wrote basic ones using pyftpdlib and paramiko
respectively.
While the design called for a server test, I concluded that it would be
better to put it on a worker for resilience: if an upload hangs for some
reason, then it will only take out one external worker, not one of the
much more limited pool of Celery workers. The main point of that part
of the design was to avoid needing an environment to run dput, which
is still fulfilled here: we use ftplib or fabric to perform the
uploads.
There are some new dependencies here, but they're quite light: around 2 MiB of installed size.
Part of #364 (closed).