Raise an error if inventory-repo-dir is not clean.

Raise an exception when "atest server/host" is given an
inventory-repo-dir with local uncommitted changes.

BUG=chromium:832309
TEST="atest server/host list"

Change-Id: I085a29d4daf23ba2da68a65db854e33dd510b6c7
Reviewed-on: https://chromium-review.googlesource.com/1086378
Commit-Ready: Ningning Xia <nxia@chromium.org>
Tested-by: Ningning Xia <nxia@chromium.org>
Reviewed-by: Xixuan Wu <xixuan@chromium.org>
diff --git a/cli/server.py b/cli/server.py
index f389413..3316dfb 100644
--- a/cli/server.py
+++ b/cli/server.py
@@ -193,6 +193,25 @@
         return (options, leftover)
 
 
+    def execute_skylab(self):
+        """Execute 'atest server list --skylab'
+
+        @return: A list of servers matched the given hostname and role.
+        """
+        inventory_repo = skylab_utils.InventoryRepo(
+                        self.inventory_repo_dir)
+        inventory_repo.initialize()
+        infrastructure = text_manager.load_infrastructure(
+                inventory_repo.get_data_dir())
+
+        return skylab_server.get_servers(
+                infrastructure,
+                self.environment,
+                hostname=self.hostname,
+                role=self.role,
+                status=self.status)
+
+
     def execute(self):
         """Execute the command.
 
@@ -200,20 +219,10 @@
         """
         if self.skylab:
             try:
-                inventory_repo = skylab_utils.InventoryRepo(
-                        self.inventory_repo_dir)
-                inventory_repo.initialize()
-                infrastructure = text_manager.load_infrastructure(
-                        inventory_repo.get_data_dir())
-
-                return skylab_server.get_servers(
-                        infrastructure,
-                        self.environment,
-                        hostname=self.hostname,
-                        role=self.role,
-                        status=self.status)
+                return self.execute_skylab()
             except (skylab_server.SkylabServerActionError,
-                    revision_control.GitError) as e:
+                    revision_control.GitError,
+                    skylab_utils.InventoryRepoDirNotClean) as e:
                 self.failure(e, what_failed='Failed to list servers from skylab'
                              ' inventory.', item=self.hostname, fatal=True)
         else:
@@ -322,7 +331,8 @@
                 return self.execute_skylab()
             except (skylab_server.SkylabServerActionError,
                     revision_control.GitError,
-                    gob_util.GOBError) as e:
+                    gob_util.GOBError,
+                    skylab_utils.InventoryRepoDirNotClean) as e:
                 self.failure(e, what_failed='Failed to create server in skylab '
                              'inventory.', item=self.hostname, fatal=True)
         else:
@@ -389,7 +399,8 @@
                 return True
             except (skylab_server.SkylabServerActionError,
                     revision_control.GitError,
-                    gob_util.GOBError) as e:
+                    gob_util.GOBError,
+                    skylab_utils.InventoryRepoDirNotClean) as e:
                 self.failure(e, what_failed='Failed to delete server from '
                              'skylab inventory.', item=self.hostname,
                              fatal=True)
@@ -551,7 +562,8 @@
                 return self.execute_skylab()
             except (skylab_server.SkylabServerActionError,
                     revision_control.GitError,
-                    gob_util.GOBError) as e:
+                    gob_util.GOBError,
+                    skylab_utils.InventoryRepoDirNotClean) as e:
                 self.failure(e, what_failed='Failed to modify server in skylab'
                              ' inventory.', item=self.hostname, fatal=True)
         else:
diff --git a/cli/skylab_utils.py b/cli/skylab_utils.py
index d021e77..60a3dfd 100644
--- a/cli/skylab_utils.py
+++ b/cli/skylab_utils.py
@@ -38,6 +38,10 @@
     """Error raised when no inventory repo change number is found."""
 
 
+class InventoryRepoDirNotClean(Exception):
+    """Error raised when the given inventory_repo_dir contains local changes."""
+
+
 def get_cl_url(change_number):
     return INTERNAL_GERRIT_HOST_URL + '/' + str(change_number)
 
@@ -111,6 +115,12 @@
                 abs_work_tree=self.inventory_repo_dir)
 
         if self.git_repo.is_repo_initialized():
+            if self.git_repo.status():
+                raise InventoryRepoDirNotClean(
+                       'The inventory_repo_dir "%s" contains uncommitted '
+                       'changes. Please clean up the local repo directory or '
+                       'use another clean directory.' % self.inventory_repo_dir)
+
             logging.info('Inventory repo was already initialized, start '
                          'pulling.')
             self.git_repo.checkout('master')