Move job_repo_url related calls to afe_utils

This is to allow adb_host to adopt similar appraoch to store devserver
url to host attributes.

BUG=chromium:586327
TEST=local run test, unittest suite

Change-Id: Iab2d05c4b7a8278ca8499025038995ea1d5aaae1
Reviewed-on: https://chromium-review.googlesource.com/327257
Commit-Ready: Dan Shi <dshi@google.com>
Tested-by: Dan Shi <dshi@google.com>
Reviewed-by: Kevin Cheng <kevcheng@chromium.org>
diff --git a/server/afe_utils.py b/server/afe_utils.py
index 1f13c0e..99fd8ef 100644
--- a/server/afe_utils.py
+++ b/server/afe_utils.py
@@ -10,8 +10,13 @@
 """
 
 import common
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.common_lib.cros import dev_server
 from autotest_lib.server import utils
+from autotest_lib.server.cros.dynamic_suite import constants as ds_constants
 from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
+from autotest_lib.server.cros.dynamic_suite import tools
+
 
 AFE = frontend_wrappers.RetryingAFE(timeout_min=5, delay_sec=10)
 
@@ -115,3 +120,65 @@
     @returns Stable version of the given board.
     """
     return AFE.run('get_stable_version', board=board, android=android)
+
+
+def lookup_job_repo_url(host):
+    """Looks up the job_repo_url for the host.
+
+    @param host: A Host object to lookup for job_repo_url.
+
+    @returns job_repo_url from AFE or None if not found.
+
+    @raises KeyError if the host does not have a job_repo_url
+    """
+    hosts = AFE.get_hosts(hostname=host.hostname)
+    if hosts and ds_constants.JOB_REPO_URL in hosts[0].attributes:
+        return hosts[0].attributes[ds_constants.JOB_REPO_URL]
+    else:
+        return None
+
+
+def clear_job_repo_url(host):
+    """Clear host attribute job_repo_url.
+
+    @param host: A Host object to clear job_repo_url.
+    """
+    if not host_in_lab(host):
+        return
+    update_job_repo_url(host, None, None)
+
+
+def update_job_repo_url(host, devserver_url, image_name):
+    """
+    Updates the job_repo_url host attribute and asserts it's value.
+
+    @param host: A Host object to update job_repo_url.
+    @param devserver_url: The devserver to use in the job_repo_url.
+    @param image_name: The name of the image to use in the job_repo_url.
+
+    @raises AutoservError: If we failed to update the job_repo_url.
+    """
+    repo_url = None
+    if devserver_url and image_name:
+        repo_url = tools.get_package_url(devserver_url, image_name)
+    AFE.set_host_attribute(ds_constants.JOB_REPO_URL, repo_url,
+                           hostname=host.hostname)
+    if lookup_job_repo_url(host) != repo_url:
+        raise error.AutoservError('Failed to update job_repo_url with %s, '
+                                  'host %s' % (repo_url, host.hostname))
+
+
+def add_job_repo_url(host, image_name):
+    """Add cros_version labels and host attribute job_repo_url.
+
+    @param host: A Host object to add job_repo_url.
+    @param image_name: The name of the image e.g.
+            lumpy-release/R27-3837.0.0
+
+    """
+    if not host_in_lab(host):
+        return
+
+    devserver_url = dev_server.ImageServer.resolve(image_name,
+                                                   host.hostname).url()
+    update_job_repo_url(host, devserver_url, image_name)
diff --git a/server/cros/autoupdate_utils.py b/server/cros/autoupdate_utils.py
index 9e8e39b..9ee0a27 100644
--- a/server/cros/autoupdate_utils.py
+++ b/server/cros/autoupdate_utils.py
@@ -9,6 +9,7 @@
 import common
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.common_lib.cros import autoupdater, dev_server
+from autotest_lib.server import afe_utils
 from autotest_lib.server.cros.dynamic_suite import tools
 
 
@@ -34,7 +35,7 @@
     # specified in the host attributes for the host.
     if not job_repo_url:
         try:
-            job_repo_url = host.lookup_job_repo_url()
+            job_repo_url = afe_utils.lookup_job_repo_url(host)
         except KeyError:
             logging.fatal('Could not lookup job_repo_url from afe.')
 
diff --git a/server/hosts/cros_host.py b/server/hosts/cros_host.py
index 0ea3421..658cd34 100644
--- a/server/hosts/cros_host.py
+++ b/server/hosts/cros_host.py
@@ -384,56 +384,18 @@
     def lookup_job_repo_url(self):
         """Looks up the job_repo_url for the host.
 
+        This is kept for backwards compatibility as AU test code in older
+        branch does not use server-side packaging and calls this method through
+        the host object.
+
+        TODO(dshi): Once R50 falls off the stable branch, we should remove this
+        method.
+
         @returns job_repo_url from AFE or None if not found.
 
         @raises KeyError if the host does not have a job_repo_url
         """
-        hosts = self._AFE.get_hosts(hostname=self.hostname)
-        if hosts and ds_constants.JOB_REPO_URL in hosts[0].attributes:
-            return hosts[0].attributes[ds_constants.JOB_REPO_URL]
-        else:
-            return None
-
-
-    def clear_job_repo_url(self):
-        """Clear host attribute job_repo_url."""
-        if not afe_utils.host_in_lab(self):
-            return
-        self.update_job_repo_url(None, None)
-
-
-    def update_job_repo_url(self, devserver_url, image_name):
-        """
-        Updates the job_repo_url host attribute and asserts it's value.
-
-        @param devserver_url: The devserver to use in the job_repo_url.
-        @param image_name: The name of the image to use in the job_repo_url.
-
-        @raises AutoservError: If we failed to update the job_repo_url.
-        """
-        repo_url = None
-        if devserver_url and image_name:
-            repo_url = tools.get_package_url(devserver_url, image_name)
-        self._AFE.set_host_attribute(ds_constants.JOB_REPO_URL, repo_url,
-                                     hostname=self.hostname)
-        if self.lookup_job_repo_url() != repo_url:
-            raise error.AutoservError('Failed to update job_repo_url with %s, '
-                                      'host %s' % (repo_url, self.hostname))
-
-
-    def add_job_repo_url(self, image_name):
-        """Add cros_version labels and host attribute job_repo_url.
-
-        @param image_name: The name of the image e.g.
-                lumpy-release/R27-3837.0.0
-
-        """
-        if not afe_utils.host_in_lab(self):
-            return
-
-        devserver_url = dev_server.ImageServer.resolve(image_name,
-                                                       self.hostname).url()
-        self.update_job_repo_url(devserver_url, image_name)
+        return afe_utils.lookup_job_repo_url(self)
 
 
     def verify_job_repo_url(self, tag=''):
@@ -459,7 +421,7 @@
         @raises urllib2.URLError: If the devserver embedded in job_repo_url
                                   doesn't respond within the timeout.
         """
-        job_repo_url = self.lookup_job_repo_url()
+        job_repo_url = afe_utils.lookup_job_repo_url(self)
         if not job_repo_url:
             logging.warning('No job repo url set on host %s', self.hostname)
             return
@@ -513,7 +475,7 @@
                         'Failed to parse build name from %s' % image)
             ds = dev_server.ImageServer.resolve(image_name)
         else:
-            job_repo_url = self.lookup_job_repo_url()
+            job_repo_url = afe_utils.lookup_job_repo_url(self)
             if job_repo_url:
                 devserver_url, image_name = (
                     tools.get_devserver_build_from_package_url(job_repo_url))
@@ -755,7 +717,7 @@
         logging.debug('Update URL is %s', update_url)
 
         # Remove cros-version and job_repo_url host attribute from host.
-        self.clear_job_repo_url()
+        afe_utils.clear_job_repo_url(self)
 
         # Create a file to indicate if provision fails. The file will be removed
         # by stateful update or full install.
@@ -831,7 +793,7 @@
 
         self._post_update_processing(updater, inactive_kernel)
         image_name = autoupdater.url_to_image_name(update_url)
-        self.add_job_repo_url(image_name)
+        afe_utils.add_job_repo_url(self, image_name)
         return image_name
 
 
diff --git a/server/site_tests/autoupdate_EndToEndTest/autoupdate_EndToEndTest.py b/server/site_tests/autoupdate_EndToEndTest/autoupdate_EndToEndTest.py
index 481f9b1..70968fc 100755
--- a/server/site_tests/autoupdate_EndToEndTest/autoupdate_EndToEndTest.py
+++ b/server/site_tests/autoupdate_EndToEndTest/autoupdate_EndToEndTest.py
@@ -15,7 +15,7 @@
 from autotest_lib.client.common_lib import error, global_config
 from autotest_lib.client.common_lib.cros import autoupdater, dev_server
 from autotest_lib.client.common_lib.cros.graphite import autotest_stats
-from autotest_lib.server import autotest, hosts, test
+from autotest_lib.server import afe_utils, autotest, hosts, test
 from autotest_lib.server.cros.dynamic_suite import tools
 
 
@@ -1029,7 +1029,7 @@
             # Attempt to get the job_repo_url to find the stateful payload for
             # the target image.
             try:
-                job_repo_url = self._host.lookup_job_repo_url()
+                job_repo_url = afe_utils.lookup_job_repo_url(self._host)
             except KeyError:
                 # If this failed, assume the stateful update is next to the
                 # update payload.