Index: telemetry/telemetry/internal/forwarders/cros_forwarder.py |
diff --git a/telemetry/telemetry/internal/forwarders/cros_forwarder.py b/telemetry/telemetry/internal/forwarders/cros_forwarder.py |
index 4316954559177e6428cc5584d4359be3ea1fd13a..e59167bbd628c46356d26cd0b8bf7ee669750613 100644 |
--- a/telemetry/telemetry/internal/forwarders/cros_forwarder.py |
+++ b/telemetry/telemetry/internal/forwarders/cros_forwarder.py |
@@ -3,7 +3,9 @@ |
# found in the LICENSE file. |
import logging |
+import re |
import subprocess |
+import tempfile |
from telemetry.internal import forwarders |
from telemetry.internal.forwarders import do_nothing_forwarder |
@@ -30,16 +32,36 @@ class CrOsSshForwarder(forwarders.Forwarder): |
super(CrOsSshForwarder, self).__init__(port_pair) |
self._cri = cri |
self._proc = None |
+ self._remote_port = None |
forwarding_args = self._ForwardingArgs( |
use_remote_port_forwarding, self.host_ip, port_pair) |
+ err_file = tempfile.NamedTemporaryFile() |
self._proc = subprocess.Popen( |
- self._cri.FormSSHCommandLine(['sleep', '999999999'], forwarding_args), |
+ self._cri.FormSSHCommandLine(['-NT'], forwarding_args, |
+ port_forward=use_remote_port_forwarding), |
stdout=subprocess.PIPE, |
- stderr=subprocess.PIPE, |
+ stderr=err_file, |
stdin=subprocess.PIPE, |
shell=False) |
+ def _get_remote_port(err_file): |
+ # When we specify the remote port '0' in ssh remote port forwarding, |
+ # the remote ssh server should return the port it binds to in stderr. |
+ # e.g. 'Allocated port 42360 for remote forward to localhost:12345', |
+ # the port 42360 is the port created remotely and the traffic to the |
+ # port will be relayed to localhost port 12345. |
+ line = err_file.readline() |
+ tokens = re.search(r'port (\d+) for remote forward to', line) |
+ if tokens: |
+ self._remote_port = int(tokens.group(1)) |
+ return tokens |
+ |
+ if use_remote_port_forwarding and port_pair.remote_port == 0: |
+ with open(err_file.name, 'r') as err_file_reader: |
+ py_utils.WaitFor(lambda: _get_remote_port(err_file_reader), 60) |
+ |
py_utils.WaitFor( |
lambda: self._cri.IsHTTPServerRunningOnPort(self.host_port), 60) |
+ err_file.close() |
logging.debug('Server started on %s:%d', self.host_ip, self.host_port) |
# pylint: disable=unused-argument |
@@ -55,6 +77,9 @@ class CrOsSshForwarder(forwarders.Forwarder): |
@property |
def host_port(self): |
+ # Return remote port if it is resolved remotely. |
+ if self._remote_port: |
+ return self._remote_port |
return self._port_pair.remote_port |
def Close(self): |