~bjornt/launchpad/architect-vision

« back to all changes in this revision

Viewing changes to lib/lp/services/sshserver/session.py

  • Committer: Bjorn Tillenius
  • Date: 2010-05-12 12:52:09 UTC
  • mfrom: (10599.1.251 launchpad)
  • Revision ID: bjorn@canonical.com-20100512125209-pip7jav1a7xq52d8
Merge RF.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2010 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
"""Patched SSH session for the Launchpad server."""
 
5
 
 
6
__metaclass__ = type
 
7
__all__ = [
 
8
    'PatchedSSHSession',
 
9
    ]
 
10
 
 
11
from twisted.conch.ssh import channel, session
 
12
 
 
13
 
 
14
class PatchedSSHSession(session.SSHSession, object):
 
15
    """Session adapter that corrects bugs in Conch.
 
16
 
 
17
    This object provides no custom logic for Launchpad, it just addresses some
 
18
    simple bugs in the base `session.SSHSession` class that are not yet fixed
 
19
    upstream.
 
20
    """
 
21
 
 
22
    def closeReceived(self):
 
23
        # Without this, the client hangs when it's finished transferring.
 
24
        # XXX: JonathanLange 2009-01-05: This does not appear to have a
 
25
        # corresponding bug in Twisted. We should test that the above comment
 
26
        # is indeed correct and then file a bug upstream.
 
27
        self.loseConnection()
 
28
 
 
29
    def loseConnection(self):
 
30
        # XXX: JonathanLange 2008-03-31: This deliberately replaces the
 
31
        # implementation of session.SSHSession.loseConnection. The default
 
32
        # implementation will try to call loseConnection on the client
 
33
        # transport even if it's None. I don't know *why* it is None, so this
 
34
        # doesn't necessarily address the root cause.
 
35
        # See http://twistedmatrix.com/trac/ticket/2754.
 
36
        transport = getattr(self.client, 'transport', None)
 
37
        if transport is not None:
 
38
            transport.loseConnection()
 
39
        # This is called by session.SSHSession.loseConnection. SSHChannel is
 
40
        # the base class of SSHSession.
 
41
        channel.SSHChannel.loseConnection(self)
 
42
 
 
43
    def stopWriting(self):
 
44
        """See `session.SSHSession.stopWriting`.
 
45
 
 
46
        When the client can't keep up with us, we ask the child process to
 
47
        stop giving us data.
 
48
        """
 
49
        # XXX: MichaelHudson 2008-06-27: Being cagey about whether
 
50
        # self.client.transport is entirely paranoia inspired by the comment
 
51
        # in `loseConnection` above. It would be good to know if and why it is
 
52
        # necessary. See http://twistedmatrix.com/trac/ticket/2754.
 
53
        transport = getattr(self.client, 'transport', None)
 
54
        if transport is not None:
 
55
            # For SFTP connections, 'transport' is actually a _DummyTransport
 
56
            # instance. Neither _DummyTransport nor the protocol it wraps
 
57
            # (filetransfer.FileTransferServer) support pausing.
 
58
            pauseProducing = getattr(transport, 'pauseProducing', None)
 
59
            if pauseProducing is not None:
 
60
                pauseProducing()
 
61
 
 
62
    def startWriting(self):
 
63
        """See `session.SSHSession.startWriting`.
 
64
 
 
65
        The client is ready for data again, so ask the child to start
 
66
        producing data again.
 
67
        """
 
68
        # XXX: MichaelHudson 2008-06-27: Being cagey about whether
 
69
        # self.client.transport is entirely paranoia inspired by the comment
 
70
        # in `loseConnection` above. It would be good to know if and why it is
 
71
        # necessary. See http://twistedmatrix.com/trac/ticket/2754.
 
72
        transport = getattr(self.client, 'transport', None)
 
73
        if transport is not None:
 
74
            # For SFTP connections, 'transport' is actually a _DummyTransport
 
75
            # instance. Neither _DummyTransport nor the protocol it wraps
 
76
            # (filetransfer.FileTransferServer) support pausing.
 
77
            resumeProducing = getattr(transport, 'resumeProducing', None)
 
78
            if resumeProducing is not None:
 
79
                resumeProducing()