Fix breakage introduced by commit 8044bf655
[ganeti-local] / lib / hypervisor / hv_chroot.py
index 954c922..f33fed2 100644 (file)
@@ -67,11 +67,7 @@ class ChrootManager(hv_base.BaseHypervisor):
 
   def __init__(self):
     hv_base.BaseHypervisor.__init__(self)
-    if not os.path.exists(self._ROOT_DIR):
-      os.mkdir(self._ROOT_DIR)
-    if not os.path.isdir(self._ROOT_DIR):
-      raise HypervisorError("Needed path %s is not a directory" %
-                            self._ROOT_DIR)
+    utils.EnsureDirs([(self._ROOT_DIR, constants.RUN_DIRS_MODE)])
 
   @staticmethod
   def _IsDirLive(path):
@@ -87,30 +83,29 @@ class ChrootManager(hv_base.BaseHypervisor):
   def _GetMountSubdirs(path):
     """Return the list of mountpoints under a given path.
 
-    This function is Linux-specific.
+    """
+    result = []
+    for _, mountpoint, _, _ in utils.GetMounts():
+      if (mountpoint.startswith(path) and
+          mountpoint != path):
+        result.append(mountpoint)
+
+    result.sort(key=lambda x: x.count("/"), reverse=True)
+    return result
+
+  @classmethod
+  def _InstanceDir(cls, instance_name):
+    """Return the root directory for an instance.
 
     """
-    #TODO(iustin): investigate and document non-linux options
-    #(e.g. via mount output)
-    data = []
-    fh = open("/proc/mounts", "r")
-    try:
-      for line in fh:
-        _, mountpoint, _ = line.split(" ", 2)
-        if (mountpoint.startswith(path) and
-            mountpoint != path):
-          data.append(mountpoint)
-    finally:
-      fh.close()
-    data.sort(key=lambda x: x.count("/"), reverse=True)
-    return data
+    return utils.PathJoin(cls._ROOT_DIR, instance_name)
 
   def ListInstances(self):
     """Get the list of running instances.
 
     """
     return [name for name in os.listdir(self._ROOT_DIR)
-            if self._IsDirLive(os.path.join(self._ROOT_DIR, name))]
+            if self._IsDirLive(utils.PathJoin(self._ROOT_DIR, name))]
 
   def GetInstanceInfo(self, instance_name):
     """Get instance properties.
@@ -121,7 +116,7 @@ class ChrootManager(hv_base.BaseHypervisor):
     @return: (name, id, memory, vcpus, stat, times)
 
     """
-    dir_name = "%s/%s" % (self._ROOT_DIR, instance_name)
+    dir_name = self._InstanceDir(instance_name)
     if not self._IsDirLive(dir_name):
       raise HypervisorError("Instance %s is not running" % instance_name)
     return (instance_name, 0, 0, 0, 0, 0)
@@ -134,7 +129,7 @@ class ChrootManager(hv_base.BaseHypervisor):
     """
     data = []
     for file_name in os.listdir(self._ROOT_DIR):
-      path = os.path.join(self._ROOT_DIR, file_name)
+      path = utils.PathJoin(self._ROOT_DIR, file_name)
       if self._IsDirLive(path):
         data.append((file_name, 0, 0, 0, 0, 0))
     return data
@@ -146,7 +141,7 @@ class ChrootManager(hv_base.BaseHypervisor):
     execute '/ganeti-chroot start'.
 
     """
-    root_dir = "%s/%s" % (self._ROOT_DIR, instance.name)
+    root_dir = self._InstanceDir(instance.name)
     if not os.path.exists(root_dir):
       try:
         os.mkdir(root_dir)
@@ -170,7 +165,7 @@ class ChrootManager(hv_base.BaseHypervisor):
       raise HypervisorError("Can't run the chroot start script: %s" %
                             result.output)
 
-  def StopInstance(self, instance, force=False, retry=False):
+  def StopInstance(self, instance, force=False, retry=False, name=None):
     """Stop an instance.
 
     This method has complicated cleanup tests, as we must:
@@ -179,7 +174,10 @@ class ChrootManager(hv_base.BaseHypervisor):
       - finally unmount the instance dir
 
     """
-    root_dir = "%s/%s" % (self._ROOT_DIR, instance.name)
+    if name is None:
+      name = instance.name
+
+    root_dir = self._InstanceDir(name)
     if not os.path.exists(root_dir) or not self._IsDirLive(root_dir):
       return
 
@@ -202,11 +200,23 @@ class ChrootManager(hv_base.BaseHypervisor):
         raise HypervisorError("Can't stop the processes using the chroot")
       return
 
+  def CleanupInstance(self, instance_name):
+    """Cleanup after a stopped instance
+
+    """
+    root_dir = self._InstanceDir(instance_name)
+
+    if not os.path.exists(root_dir):
+      return
+
+    if self._IsDirLive(root_dir):
+      raise HypervisorError("Processes are still using the chroot")
+
     for mpath in self._GetMountSubdirs(root_dir):
       utils.RunCmd(["umount", mpath])
 
     result = utils.RunCmd(["umount", root_dir])
-    if result.failed and force:
+    if result.failed:
       msg = ("Processes still alive in the chroot: %s" %
              utils.RunCmd("fuser -vm %s" % root_dir).output)
       logging.error(msg)
@@ -240,7 +250,7 @@ class ChrootManager(hv_base.BaseHypervisor):
     """Return a command for connecting to the console of an instance.
 
     """
-    root_dir = "%s/%s" % (cls._ROOT_DIR, instance.name)
+    root_dir = cls._InstanceDir(instance.name)
     if not os.path.ismount(root_dir):
       raise HypervisorError("Instance %s is not running" % instance.name)
 
@@ -265,7 +275,7 @@ class ChrootManager(hv_base.BaseHypervisor):
   def MigrateInstance(self, instance, target, live):
     """Migrate an instance.
 
-    @type instance: L{object.Instance}
+    @type instance: L{objects.Instance}
     @param instance: the instance to be migrated
     @type target: string
     @param target: hostname (usually ip) of the target node