1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import subprocess 7 8from telemetry.core import util 9from telemetry.internal import forwarders 10from telemetry.internal.forwarders import do_nothing_forwarder 11 12 13class CrOsForwarderFactory(forwarders.ForwarderFactory): 14 15 def __init__(self, cri): 16 super(CrOsForwarderFactory, self).__init__() 17 self._cri = cri 18 19 # pylint: disable=arguments-differ 20 def Create(self, port_pairs, use_remote_port_forwarding=True): 21 if self._cri.local: 22 return do_nothing_forwarder.DoNothingForwarder(port_pairs) 23 return CrOsSshForwarder(self._cri, use_remote_port_forwarding, port_pairs) 24 25 26class CrOsSshForwarder(forwarders.Forwarder): 27 28 def __init__(self, cri, use_remote_port_forwarding, port_pairs): 29 super(CrOsSshForwarder, self).__init__(port_pairs) 30 self._cri = cri 31 self._proc = None 32 forwarding_args = self._ForwardingArgs( 33 use_remote_port_forwarding, self.host_ip, port_pairs) 34 self._proc = subprocess.Popen( 35 self._cri.FormSSHCommandLine(['sleep', '999999999'], forwarding_args), 36 stdout=subprocess.PIPE, 37 stderr=subprocess.PIPE, 38 stdin=subprocess.PIPE, 39 shell=False) 40 util.WaitFor( 41 lambda: self._cri.IsHTTPServerRunningOnPort(self.host_port), 60) 42 logging.debug('Server started on %s:%d', self.host_ip, self.host_port) 43 44 # pylint: disable=unused-argument 45 @staticmethod 46 def _ForwardingArgs(use_remote_port_forwarding, host_ip, port_pairs): 47 if use_remote_port_forwarding: 48 arg_format = '-R{pp.remote_port}:{host_ip}:{pp.local_port}' 49 else: 50 arg_format = '-L{pp.local_port}:{host_ip}:{pp.remote_port}' 51 return [arg_format.format(**locals()) for pp in port_pairs if pp] 52 53 @property 54 def host_port(self): 55 return self._port_pairs.http.remote_port 56 57 def Close(self): 58 if self._proc: 59 self._proc.kill() 60 self._proc = None 61 super(CrOsSshForwarder, self).Close() 62