Moblab: Servo Support via Host Attributes.

Moblab devices will look for servo_args inside a host's host
attributes.

Host attributes can be set via the CLI or the Web Frontend.

CLI to see attributes:
atest host stat <host>

CLI to set attribute:
atest host mod --attribute <attribute> --value <value> <host>

Updated the afe's management system so that it properly configures
the admin interface to allow editing of host attributes.

BUG=chromium:394544
TEST=local moblab setup. Tested both CLI and AFE host attribute
manipulation. Launched Servod, and ensure servo host is only
created when the attribute is applied to the host.

Change-Id: Ie3cccab31aa7518435ef0abc6ce206363406c272
Reviewed-on: https://chromium-review.googlesource.com/255550
Reviewed-by: Simran Basi <sbasi@chromium.org>
Commit-Queue: Simran Basi <sbasi@chromium.org>
Tested-by: Simran Basi <sbasi@chromium.org>
diff --git a/server/hosts/servo_host.py b/server/hosts/servo_host.py
index c0f2a9b..cbe6099 100644
--- a/server/hosts/servo_host.py
+++ b/server/hosts/servo_host.py
@@ -25,10 +25,17 @@
 from autotest_lib.client.common_lib.cros.network import ping_runner
 from autotest_lib.server import site_utils as server_site_utils
 from autotest_lib.server.cros.servo import servo
+from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
 from autotest_lib.server.hosts import ssh_host
 from autotest_lib.site_utils.rpm_control_system import rpm_client
 
 
+# Names of the host attributes in the database that represent the values for
+# the servo_host and servo_port for a servo connected to the DUT.
+SERVO_HOST_ATTR = 'servo_host'
+SERVO_PORT_ATTR = 'servo_port'
+
+
 class ServoHostException(error.AutoservError):
     """This is the base class for exceptions raised by ServoHost."""
     pass
@@ -325,6 +332,8 @@
         @raises ServoHostVerifyFailure if /var/lib/servod/config does not exist.
 
         """
+        if self._is_localhost:
+            return
         try:
             self.run('test -f /var/lib/servod/config')
         except (error.AutoservRunError, error.AutoservSSHTimeout) as e:
@@ -644,8 +653,19 @@
     @returns: A ServoHost object or None. See comments above.
 
     """
-    lab_servo_hostname = make_servo_hostname(dut)
-    is_in_lab = utils.host_is_in_lab_zone(lab_servo_hostname)
+    if not utils.is_moblab():
+        lab_servo_hostname = make_servo_hostname(dut)
+        is_in_lab = utils.host_is_in_lab_zone(lab_servo_hostname)
+    else:
+        # Servos on Moblab are not in the actual lab.
+        is_in_lab = False
+        afe = frontend_wrappers.RetryingAFE(timeout_min=5, delay_sec=10)
+        hosts = afe.get_hosts(hostname=dut)
+        if hosts and SERVO_HOST_ATTR in hosts[0].attributes:
+            servo_args = {}
+            servo_args[SERVO_HOST_ATTR] = hosts[0].attributes[SERVO_HOST_ATTR]
+            servo_args[SERVO_PORT_ATTR] = hosts[0].attributes.get(
+                    SERVO_PORT_ATTR, 9999)
 
     if not is_in_lab:
         if servo_args is None: