Merge remote branch 'cros/upstream' into autotest-rebase

Merged to upstream trunk@5066, from trunk@4749.

There is no way I could enlist each individual CL from the upstream here since it will blow up the changelist description field.

BUG=
TEST=
Had patched this CL into a fresh cut client to avoid any side effect.
run_remote_test bvt from both emerged location and third_party/autotest/file.

Both test passed!

We should also keep any eye on this to see how it gets propagated into cautotest server.
TBR=dalecurtis

Change-Id: I72f2bc7a9de530178484aea1bfb5ace68bcad029
diff --git a/server/hosts/abstract_ssh.py b/server/hosts/abstract_ssh.py
index 3d8d9e9..3723c46 100644
--- a/server/hosts/abstract_ssh.py
+++ b/server/hosts/abstract_ssh.py
@@ -115,6 +115,17 @@
                           " ".join(sources), dest)
 
 
+    def _make_ssh_cmd(self, cmd):
+        """
+        Create a base ssh command string for the host which can be used
+        to run commands directly on the machine
+        """
+        base_cmd = make_ssh_command(user=self.user, port=self.port,
+                                    opts=self.master_ssh_option,
+                                    hosts_file=self.known_hosts_fd)
+
+        return '%s %s "%s"' % (base_cmd, self.hostname, utils.sh_escape(cmd))
+
     def _make_scp_cmd(self, sources, dest):
         """
         Given a list of source paths and a destination path, produces the
diff --git a/server/hosts/factory.py b/server/hosts/factory.py
index f1a054f..7a2a724 100644
--- a/server/hosts/factory.py
+++ b/server/hosts/factory.py
@@ -68,9 +68,8 @@
     site_factory.postprocess_classes(classes, hostname,
                                      auto_monitor=auto_monitor, **args)
 
-    args['user'] = ssh_user
-    args['port'] = ssh_port
-    args['password'] = ssh_pass
+    hostname, args['user'], args['password'], args['port'] = \
+            server_utils.parse_machine(hostname, ssh_user, ssh_pass, ssh_port)
 
     # create a custom host class for this machine and return an instance of it
     host_class = type("%s_host" % hostname, tuple(classes), {})
diff --git a/server/hosts/logfile_monitor.py b/server/hosts/logfile_monitor.py
index 1608a6b..9595cc8 100644
--- a/server/hosts/logfile_monitor.py
+++ b/server/hosts/logfile_monitor.py
@@ -26,15 +26,6 @@
     """Error occurred launching followfiles remotely."""
 
 
-def run_cmd_on_host(hostname, cmd, stdin, stdout, stderr):
-    base_cmd = abstract_ssh.make_ssh_command()
-    full_cmd = "%s %s \"%s\"" % (base_cmd, hostname,
-                                 server_utils.sh_escape(cmd))
-
-    return subprocess.Popen(full_cmd, stdin=stdin, stdout=stdout,
-                            stderr=stderr, shell=True)
-
-
 def list_remote_pythons(host):
     """List out installed pythons on host."""
     result = host.run('ls /usr/bin/python[0-9]*')
@@ -72,25 +63,24 @@
             raise FollowFilesLaunchError('No supported Python on host.')
 
     remote_monitordir = copy_monitordir(host)
-    remote_script_path = os.path.join(
-        remote_monitordir, 'followfiles.py')
+    remote_script_path = os.path.join(remote_monitordir, 'followfiles.py')
 
     followfiles_cmd = '%s %s --lastlines_dirpath=%s %s' % (
         supported_python, remote_script_path,
         lastlines_dirpath, ' '.join(follow_paths))
 
-    devnull_r = open(os.devnull, 'r')
-    devnull_w = open(os.devnull, 'w')
-    remote_followfiles_proc = run_cmd_on_host(
-        host.hostname, followfiles_cmd, stdout=subprocess.PIPE,
-        stdin=devnull_r, stderr=devnull_w)
+    remote_ff_proc = subprocess.Popen(host._make_ssh_cmd(followfiles_cmd),
+                                      stdin=open(os.devnull, 'r'),
+                                      stdout=subprocess.PIPE, shell=True)
+
+
     # Give it enough time to crash if it's going to (it shouldn't).
     time.sleep(5)
-    doa = remote_followfiles_proc.poll()
+    doa = remote_ff_proc.poll()
     if doa:
         raise FollowFilesLaunchError('ssh command crashed.')
 
-    return remote_followfiles_proc
+    return remote_ff_proc
 
 
 def resolve_patterns_path(patterns_path):
diff --git a/server/hosts/remote.py b/server/hosts/remote.py
index e46bc1b..d1b4b46 100644
--- a/server/hosts/remote.py
+++ b/server/hosts/remote.py
@@ -27,7 +27,7 @@
     LAST_BOOT_TAG = object()
     DEFAULT_HALT_TIMEOUT = 2 * 60
 
-    VAR_LOG_MESSAGES_COPY_PATH = "/var/log/messages.autotest_start"
+    VAR_LOG_MESSAGES_COPY_PATH = "/var/tmp/messages.autotest_start"
 
     def _initialize(self, hostname, autodir=None, *args, **dargs):
         super(RemoteHost, self)._initialize(*args, **dargs)
@@ -230,8 +230,8 @@
             keyvals = utils.read_keyval(keyval_path)
             all_labels = keyvals.get('labels', '')
             if all_labels:
-              all_labels = all_labels.split(',')
-              return [urllib.unquote(label) for label in all_labels]
+                all_labels = all_labels.split(',')
+                return [urllib.unquote(label) for label in all_labels]
         return []
 
 
diff --git a/server/hosts/serial.py b/server/hosts/serial.py
index d514dba..d363cb7 100644
--- a/server/hosts/serial.py
+++ b/server/hosts/serial.py
@@ -165,6 +165,7 @@
                     # Run on num_attempts=1 or last retry
                     try:
                         self.wait_for_restart(timeout,
+                                              old_boot_id=old_boot_id,
                                               **wait_for_restart_kwargs)
                     except error.AutoservShutdownError:
                         logging.warning(warning_msg, num_attempts, num_attempts)