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
_DIR_MODE = 0755
PARAMETERS = {
+ constants.HV_CPU_MASK: hv_base.OPT_CPU_MASK_CHECK,
}
def __init__(self):
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.
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)
# 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")
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)
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.
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.
"""
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")