| 18 | |
| 19 | |
| 20 | class SSHSocket(socket.socket): |
| 21 | def __init__(self, host): |
| 22 | super().__init__( |
| 23 | socket.AF_INET, socket.SOCK_STREAM) |
| 24 | self.host = host |
| 25 | self.port = None |
| 26 | self.user = None |
| 27 | if ':' in self.host: |
| 28 | self.host, self.port = self.host.split(':') |
| 29 | if '@' in self.host: |
| 30 | self.user, self.host = self.host.split('@') |
| 31 | |
| 32 | self.proc = None |
| 33 | |
| 34 | def connect(self, **kwargs): |
| 35 | args = ['ssh'] |
| 36 | if self.user: |
| 37 | args = args + ['-l', self.user] |
| 38 | |
| 39 | if self.port: |
| 40 | args = args + ['-p', self.port] |
| 41 | |
| 42 | args = args + ['--', self.host, 'docker system dial-stdio'] |
| 43 | |
| 44 | preexec_func = None |
| 45 | if not constants.IS_WINDOWS_PLATFORM: |
| 46 | def f(): |
| 47 | signal.signal(signal.SIGINT, signal.SIG_IGN) |
| 48 | preexec_func = f |
| 49 | |
| 50 | env = dict(os.environ) |
| 51 | |
| 52 | # drop LD_LIBRARY_PATH and SSL_CERT_FILE |
| 53 | env.pop('LD_LIBRARY_PATH', None) |
| 54 | env.pop('SSL_CERT_FILE', None) |
| 55 | |
| 56 | self.proc = subprocess.Popen( |
| 57 | args, |
| 58 | env=env, |
| 59 | stdout=subprocess.PIPE, |
| 60 | stdin=subprocess.PIPE, |
| 61 | preexec_fn=preexec_func) |
| 62 | |
| 63 | def _write(self, data): |
| 64 | if not self.proc or self.proc.stdin.closed: |
| 65 | raise Exception('SSH subprocess not initiated.' |
| 66 | 'connect() must be called first.') |
| 67 | written = self.proc.stdin.write(data) |
| 68 | self.proc.stdin.flush() |
| 69 | return written |
| 70 | |
| 71 | def sendall(self, data): |
| 72 | self._write(data) |
| 73 | |
| 74 | def send(self, data): |
| 75 | return self._write(data) |
| 76 | |
| 77 | def recv(self, n): |
no outgoing calls