Autotest: Add label detection to site_host and add it to the CLI

Currently we manually maintain the list of labels for a given DUT,
in order to make this process easier we added methods to site_hosts
to automatically determine certain attributes/labels for a given
host.

The autotest CLI was also updated such that it can now utilize the
auto label detection methods. If no platform is provided for a given
list of hostnames, it will look up the correct platform for each.
And if it can retrieve the host's labels it will assign a Set of the
detectable labels merged with the command line inputted labels.

BUG=chromium-os:18976
TEST=Ran cli/atest create host locally.

Change-Id: I50480fcddbce60b8d5693f1268ca36d1aea12e23
Reviewed-on: https://gerrit.chromium.org/gerrit/35889
Commit-Ready: Simran Basi <sbasi@chromium.org>
Reviewed-by: Simran Basi <sbasi@chromium.org>
Tested-by: Simran Basi <sbasi@chromium.org>
diff --git a/client/bin/site_utils.py b/client/bin/site_utils.py
index 7bff3d6..2a9cced 100644
--- a/client/bin/site_utils.py
+++ b/client/bin/site_utils.py
@@ -246,3 +246,33 @@
 
 def random_username():
     return str(uuid.uuid4()) + '@example.com'
+
+
+def parse_cmd_output(command, run_method=utils.run):
+    """Runs a command on a host object to retrieve host attributes.
+
+    The command should output to stdout in the format of:
+    <key> = <value> # <optional_comment>
+
+
+    @param command: Command to execute on the host.
+    @param run_method: Function to use to execute the command. Defaults to
+                       utils.run so that the command will be executed locally.
+                       Can be replace with a host.run call so that it will
+                       execute on a DUT or external machine. Method must accept
+                       a command argument, stdout_tee and stderr_tee args and
+                       return a result object with a string attribute stdout
+                       which will be parsed.
+
+    @returns a dictionary mapping host attributes to their values.
+    """
+    result = {}
+    # Suppresses stdout so that the files are not printed to the logs.
+    cmd_result = run_method(command, stdout_tee=None, stderr_tee=None)
+    for line in cmd_result.stdout.splitlines():
+        # Lines are of the format "<key>     = <value>      # <comment>"
+        key_value = re.match('^\s*(?P<key>[^ ]+)\s*=\s*(?P<value>[^ ]+)'
+                             '(?:\s*#.*)?$', line)
+        if key_value:
+            result[key_value.group('key')] = key_value.group('value')
+    return result
\ No newline at end of file