[moblab] Check if dut has test image by testing ssh connection

Attempt to SSH into connected duts. If SSH failed, it's likely the
DUT doesn't have a test image. Show a message on the UI to let users
know.

BUG=chromium:616373
TEST=local moblab with one test image DUT and one non-test image DUT

Change-Id: I3f9e82b04d7c47a19522f8fc627bcb06f28c7d02
Reviewed-on: https://chromium-review.googlesource.com/902166
Commit-Ready: Keith Haddow <[email protected]>
Tested-by: Matt Mallett <[email protected]>
Reviewed-by: Keith Haddow <[email protected]>
diff --git a/frontend/afe/moblab_rpc_interface.py b/frontend/afe/moblab_rpc_interface.py
index cb5a703..ff71ad6 100644
--- a/frontend/afe/moblab_rpc_interface.py
+++ b/frontend/afe/moblab_rpc_interface.py
@@ -543,6 +543,14 @@
     # Make a list of the connected DUT's
     leases = _get_dhcp_dut_leases()
 
+    connected_duts = {}
+    for ip in leases:
+        ssh_connection_ok = _test_dut_ssh_connection(ip)
+        connected_duts[ip] = {
+            'mac_address': leases[ip],
+            'ssh_connection_ok': ssh_connection_ok
+        }
+
     # Get a list of the AFE configured DUT's
     hosts = list(rpc_utils.get_host_query((), False, True, {}))
     models.Host.objects.populate_relationships(hosts, models.Label,
@@ -558,7 +566,7 @@
 
     return rpc_utils.prepare_for_serialization(
             {'configured_duts': configured_duts,
-             'connected_duts': leases})
+             'connected_duts': connected_duts})
 
 
 def _get_dhcp_dut_leases():
@@ -580,6 +588,20 @@
                  leases[ipaddress] = mac_address_search.group(1)
      return leases
 
+def _test_dut_ssh_connection(ip):
+    """ Test if a connected dut is accessible via ssh.
+    The primary use case is to verify that the dut has a test image.
+
+    @return: True if the ssh connection is good False else
+    """
+    cmd = ('ssh -o ConnectTimeout=2 -o StrictHostKeyChecking=no '
+            "root@%s 'timeout 2 cat /etc/lsb-release'") % ip
+    try:
+        release = subprocess.check_output(cmd, shell=True)
+        return 'CHROMEOS_RELEASE_APPID' in release
+    except:
+        return False
+
 
 @rpc_utils.moblab_only
 def add_moblab_dut(ipaddress):