opcodes: Annotate the OP_RESULT of query operations
[ganeti-local] / lib / hypervisor / hv_lxc.py
index 23a7974..70e7384 100644 (file)
@@ -29,8 +29,9 @@ import time
 import logging
 
 from ganeti import constants
-from ganeti import errors # pylint: disable-msg=W0611
+from ganeti import errors # pylint: disable=W0611
 from ganeti import utils
+from ganeti import objects
 from ganeti.hypervisor import hv_base
 from ganeti.errors import HypervisorError
 
@@ -88,6 +89,7 @@ class LXCHypervisor(hv_base.BaseHypervisor):
   _DIR_MODE = 0755
 
   PARAMETERS = {
+    constants.HV_CPU_MASK: hv_base.OPT_CPU_MASK_CHECK,
     }
 
   def __init__(self):
@@ -149,17 +151,8 @@ class LXCHypervisor(hv_base.BaseHypervisor):
     except EnvironmentError, err:
       raise errors.HypervisorError("Getting CPU list for instance"
                                    " %s failed: %s" % (instance_name, err))
-    # cpuset.cpus format: comma-separated list of CPU ids
-    # or dash-separated id ranges
-    # Example: "0-1,3"
-    cpu_list = []
-    for range_def in cpus.split(","):
-      boundaries = range_def.split("-")
-      n_elements = len(boundaries)
-      lower = int(boundaries[0])
-      higher = int(boundaries[n_elements - 1])
-      cpu_list.extend(range(lower, higher + 1))
-    return cpu_list
+
+    return utils.ParseCpuMask(cpus)
 
   def ListInstances(self):
     """Get the list of running instances.
@@ -207,7 +200,9 @@ class LXCHypervisor(hv_base.BaseHypervisor):
     return data
 
   def _CreateConfigFile(self, instance, root_dir):
-    """Create an lxc.conf file for an instance"""
+    """Create an lxc.conf file for an instance.
+
+    """
     out = []
     # hostname
     out.append("lxc.utsname = %s" % instance.name)
@@ -231,6 +226,19 @@ class LXCHypervisor(hv_base.BaseHypervisor):
 
     # TODO: additional mounts, if we disable CAP_SYS_ADMIN
 
+    # CPUs
+    if instance.hvparams[constants.HV_CPU_MASK]:
+      cpu_list = utils.ParseCpuMask(instance.hvparams[constants.HV_CPU_MASK])
+      cpus_in_mask = len(cpu_list)
+      if cpus_in_mask != instance.beparams["vcpus"]:
+        raise errors.HypervisorError("Number of VCPUs (%d) doesn't match"
+                                     " the number of CPUs in the"
+                                     " cpu_mask (%d)" %
+                                     (instance.beparams["vcpus"],
+                                      cpus_in_mask))
+      out.append("lxc.cgroup.cpuset.cpus = %s" %
+                 instance.hvparams[constants.HV_CPU_MASK])
+
     # Device control
     # deny direct device access
     out.append("lxc.cgroup.devices.deny = a")
@@ -258,11 +266,11 @@ class LXCHypervisor(hv_base.BaseHypervisor):
 
     return "\n".join(out) + "\n"
 
-  def StartInstance(self, instance, block_devices):
+  def StartInstance(self, instance, block_devices, startup_paused):
     """Start an instance.
 
-    For LCX, we try to mount the block device and execute 'lxc-start
-    start' (we use volatile containers).
+    For LCX, we try to mount the block device and execute 'lxc-start'.
+    We use volatile containers.
 
     """
     root_dir = self._InstanceDir(instance.name)
@@ -353,6 +361,18 @@ class LXCHypervisor(hv_base.BaseHypervisor):
     raise HypervisorError("The LXC hypervisor doesn't implement the"
                           " reboot functionality")
 
+  def BalloonInstanceMemory(self, instance, mem):
+    """Balloon an instance memory to a certain value.
+
+    @type instance: L{objects.Instance}
+    @param instance: instance to be accepted
+    @type mem: int
+    @param mem: actual memory size to use for instance runtime
+
+    """
+    # Currently lxc instances don't have memory limits
+    pass
+
   def GetNodeInfo(self):
     """Return information about the node.
 
@@ -367,11 +387,15 @@ class LXCHypervisor(hv_base.BaseHypervisor):
     return self.GetLinuxNodeInfo()
 
   @classmethod
-  def GetShellCommandForConsole(cls, instance, hvparams, beparams):
+  def GetInstanceConsole(cls, instance, hvparams, beparams):
     """Return a command for connecting to the console of an instance.
 
     """
-    return "lxc-console -n %s" % instance.name
+    return objects.InstanceConsole(instance=instance.name,
+                                   kind=constants.CONS_SSH,
+                                   host=instance.primary_node,
+                                   user=constants.GANETI_RUNAS,
+                                   command=["lxc-console", "-n", instance.name])
 
   def Verify(self):
     """Verify the hypervisor.
@@ -401,3 +425,16 @@ class LXCHypervisor(hv_base.BaseHypervisor):
 
     """
     raise HypervisorError("Migration is not supported by the LXC hypervisor")
+
+  def GetMigrationStatus(self, instance):
+    """Get the migration status
+
+    @type instance: L{objects.Instance}
+    @param instance: the instance that is being migrated
+    @rtype: L{objects.MigrationStatus}
+    @return: the status of the current migration (one of
+             L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
+             progress info that can be retrieved from the hypervisor
+
+    """
+    raise HypervisorError("Migration is not supported by the LXC hypervisor")