Пример #1
0
 def _check_socket(self):
   sock_stat = None
   try:
     sock_stat = os.stat(self.monitor_filename)
   except EnvironmentError, err:
     if err.errno == errno.ENOENT:
       raise errors.HypervisorError("No monitor socket found")
     else:
       raise errors.HypervisorError("Error checking monitor socket: %s",
                                    utils.ErrnoOrStr(err))
Пример #2
0
 def _check_socket(self):
     sock_stat = None
     try:
         sock_stat = os.stat(self.monitor_filename)
     except EnvironmentError as err:
         if err.errno == errno.ENOENT:
             raise errors.HypervisorError("No monitor socket found")
         else:
             raise errors.HypervisorError(
                 "Error checking monitor socket: %s", utils.ErrnoOrStr(err))
     if not stat.S_ISSOCK(sock_stat.st_mode):
         raise errors.HypervisorError("Monitor socket is not a socket")
Пример #3
0
def check_boot_parameters(hvparams):
    boot_order = hvparams[constants.HV_BOOT_ORDER]
    if (boot_order == constants.HT_BO_CDROM and
        not hvparams[constants.HV_CDROM_IMAGE_PATH]):
      raise errors.HypervisorError("Cannot boot from cdrom without an"
                                   " ISO path")
    kernel_path = hvparams[constants.HV_KERNEL_PATH]
    if kernel_path:
      if not hvparams[constants.HV_ROOT_PATH]:
        raise errors.HypervisorError("Need a root partition for the instance,"
                                     " if a kernel is defined")
    return True
Пример #4
0
def OpenTap(vnet_hdr=True, virtio_net_queues=1, name=""):
  """Open a new tap device and return its file descriptor.

  This is intended to be used by a qemu-type hypervisor together with the -net
  tap,fd=<fd> or -net tap,fds=x:y:...:z command line parameter.

  @type vnet_hdr: boolean
  @param vnet_hdr: Enable the VNET Header

  @type virtio_net_queues: int
  @param virtio_net_queues: Set number of tap queues but not more than 8,
                            queues only work with virtio-net device;
                            disabled by default (one queue).

  @type name: string
  @param name: name for the TAP interface being created; if an empty
               string is passed, the OS will generate a unique name

  @return: (ifname, [tapfds])
  @rtype: tuple

  """
  tapfds = []

  for _ in range(virtio_net_queues):
    try:
      tapfd = os.open("/dev/net/tun", os.O_RDWR)
    except EnvironmentError:
      raise errors.HypervisorError("Failed to open /dev/net/tun")

    flags = IFF_TAP | IFF_NO_PI

    if vnet_hdr and _ProbeTapVnetHdr(tapfd):
      flags |= IFF_VNET_HDR

    # Check if it's ok to enable IFF_MULTI_QUEUE
    if virtio_net_queues > 1 and _ProbeTapMqVirtioNet(tapfd):
      flags |= IFF_MULTI_QUEUE
    else:
      flags |= IFF_ONE_QUEUE

    # The struct ifreq ioctl request (see netdevice(7))
    ifr = struct.pack("16sh", name, flags)

    try:
      res = fcntl.ioctl(tapfd, TUNSETIFF, ifr)
    except EnvironmentError, err:
      raise errors.HypervisorError("Failed to allocate a new TAP device: %s" %
                                   err)

    tapfds.append(tapfd)
Пример #5
0
  def _CheckToolstack(self, xen_cmd):
    """Check whether the given toolstack is available on the node.

    @type xen_cmd: string
    @param xen_cmd: xen command (e.g. 'xm' or 'xl')

    """
    binary_found = self._CheckToolstackBinary(xen_cmd)
    if not binary_found:
      raise errors.HypervisorError("No '%s' binary found on node." % xen_cmd)
    elif xen_cmd == constants.XEN_CMD_XL:
      if not self._CheckToolstackXlConfigured():
        raise errors.HypervisorError("Toolstack '%s' is not enabled on this"
                                     "node." % xen_cmd)
Пример #6
0
def check_security_model(hvparams):
    security_model = hvparams[constants.HV_SECURITY_MODEL]
    if security_model == constants.HT_SM_USER:
        if not hvparams[constants.HV_SECURITY_DOMAIN]:
            raise errors.HypervisorError(
                "A security domain (user to run kvm as)"
                " must be specified")
    elif (security_model == constants.HT_SM_NONE or
          security_model == constants.HT_SM_POOL):
        if hvparams[constants.HV_SECURITY_DOMAIN]:
            raise errors.HypervisorError(
                "Cannot have a security domain when the"
                " security model is 'none' or 'pool'")
    return True
Пример #7
0
    def _Recv(self):
        """Receives a message from QMP and decodes the received JSON object.

    @rtype: QmpMessage
    @return: the received message
    @raise errors.HypervisorError: when there are communication errors
    @raise errors.ProgrammerError: when there are data serialization errors

    """
        self._check_connection()

        # Check if there is already a message in the buffer
        (message, self._buf) = self._ParseMessage(self._buf)
        if message:
            return message

        recv_buffer = StringIO.StringIO(self._buf)
        recv_buffer.seek(len(self._buf))
        try:
            while True:
                data = self.sock.recv(4096)
                if not data:
                    break
                recv_buffer.write(data)

                (message,
                 self._buf) = self._ParseMessage(recv_buffer.getvalue())
                if message:
                    return message

        except socket.timeout, err:
            raise errors.HypervisorError(
                "Timeout while receiving a QMP message: "
                "%s" % (err))
Пример #8
0
    def GetInstanceInfo(self, instance_name, hvparams=None):
        """Get instance properties.

    @type instance_name: string
    @param instance_name: the instance name
    @type hvparams: dict of strings
    @param hvparams: hvparams to be used with this instance
    @rtype: tuple of strings
    @return: (name, id, memory, vcpus, stat, times)

    """
        # TODO: read container info from the cgroup mountpoint

        result = utils.RunCmd(["lxc-info", "-s", "-n", instance_name])
        if result.failed:
            raise errors.HypervisorError("Running lxc-info failed: %s" %
                                         result.output)
        # lxc-info output examples:
        # 'state: STOPPED
        # 'state: RUNNING
        _, state = result.stdout.rsplit(None, 1)
        if state != "RUNNING":
            return None

        cpu_list = self._GetCgroupCpuList(instance_name)
        memory = self._GetCgroupMemoryLimit(instance_name) / (1024**2)
        return (instance_name, 0, memory, len(cpu_list),
                hv_base.HvInstanceState.RUNNING, 0)
Пример #9
0
    def _GetResponse(self, command):
        """Parse the QMP response

    If error key found in the response message raise HypervisorError.
    Ignore any async event and thus return the response message
    related to command.

    """
        # According the the QMP specification, there are only two reply types to a
        # command: either error (containing the "error" key) or success (containing
        # the "return" key). There is also a third possibility, that of an
        # (unrelated to the command) asynchronous event notification, identified by
        # the "event" key.
        while True:
            response = self._Recv()
            err = response[self._ERROR_KEY]
            if err:
                raise errors.HypervisorError(
                    "kvm: error executing the %s"
                    " command: %s (%s):" % (command, err[self._ERROR_DESC_KEY],
                                            err[self._ERROR_CLASS_KEY]))

            elif response[self._EVENT_KEY]:
                # Filter-out any asynchronous events
                continue

            return response[self._RETURN_KEY]
Пример #10
0
  def GetLinuxNodeInfo(meminfo="/proc/meminfo", cpuinfo="/proc/cpuinfo"):
    """For linux systems, return actual OS information.

    This is an abstraction for all non-hypervisor-based classes, where
    the node actually sees all the memory and CPUs via the /proc
    interface and standard commands. The other case if for example
    xen, where you only see the hardware resources via xen-specific
    tools.

    @param meminfo: name of the file containing meminfo
    @type meminfo: string
    @param cpuinfo: name of the file containing cpuinfo
    @type cpuinfo: string
    @return: a dict with the following keys (values in MiB):
          - memory_total: the total memory size on the node
          - memory_free: the available memory on the node for instances
          - memory_dom0: the memory used by the node itself, if available
          - cpu_total: total number of CPUs
          - cpu_dom0: number of CPUs used by the node OS
          - cpu_nodes: number of NUMA domains
          - cpu_sockets: number of physical CPU sockets

    """
    try:
      data = utils.ReadFile(meminfo).splitlines()
    except EnvironmentError, err:
      raise errors.HypervisorError("Failed to list node info: %s" % (err,))
Пример #11
0
class MonitorSocket(object):
    _SOCKET_TIMEOUT = 5

    def __init__(self, monitor_filename):
        """Instantiates the MonitorSocket object.

    @type monitor_filename: string
    @param monitor_filename: the filename of the UNIX raw socket on which the
                             monitor (QMP or simple one) is listening

    """
        self.monitor_filename = monitor_filename
        self._connected = False

    def _check_socket(self):
        sock_stat = None
        try:
            sock_stat = os.stat(self.monitor_filename)
        except EnvironmentError, err:
            if err.errno == errno.ENOENT:
                raise errors.HypervisorError("No monitor socket found")
            else:
                raise errors.HypervisorError(
                    "Error checking monitor socket: %s", utils.ErrnoOrStr(err))
        if not stat.S_ISSOCK(sock_stat.st_mode):
            raise errors.HypervisorError("Monitor socket is not a socket")
Пример #12
0
    def GetInstanceInfo(self, instance_name, hvparams=None):
        """Get instance properties.

    @type instance_name: string
    @param instance_name: the instance name
    @type hvparams: dict of strings
    @param hvparams: hvparams to be used with this instance

    @return: tuple of (name, id, memory, vcpus, stat, times)

    """
        file_name = self._InstanceFile(instance_name)
        if not os.path.exists(file_name):
            return None
        try:
            fh = open(file_name, "r")
            try:
                inst_id = fh.readline().strip()
                memory = utils.TryConvert(int, fh.readline().strip())
                vcpus = utils.TryConvert(int, fh.readline().strip())
                stat = hv_base.HvInstanceState.RUNNING
                times = 0
                return (instance_name, inst_id, memory, vcpus, stat, times)
            finally:
                fh.close()
        except IOError, err:
            raise errors.HypervisorError("Failed to list instance %s: %s" %
                                         (instance_name, err))
Пример #13
0
def check_vnc_parameters(hvparams):
    if (hvparams[constants.HV_VNC_X509_VERIFY] and
        not hvparams[constants.HV_VNC_X509]):
      raise errors.HypervisorError("%s must be defined, if %s is" %
                                   (constants.HV_VNC_X509,
                                    constants.HV_VNC_X509_VERIFY))
    return True
Пример #14
0
  def StartInstance(self, instance, block_devices, startup_paused):
    """Start an instance.

    """
    startup_memory = self._InstanceStartupMemory(instance)

    self._MakeConfigFile(instance, startup_memory, block_devices)

    cmd = ["create"]
    if startup_paused:
      cmd.append("-p")
    cmd.append(self._ConfigFileName(instance.name))

    result = self._RunXen(cmd, instance.hvparams)
    if result.failed:
      # Move the Xen configuration file to the log directory to avoid
      # leaving a stale config file behind.
      stashed_config = self._StashConfigFile(instance.name)
      raise errors.HypervisorError("Failed to start instance %s: %s (%s). Moved"
                                   " config file to %s" %
                                   (instance.name, result.fail_reason,
                                    result.output, stashed_config))

    for nic_seq, nic in enumerate(instance.nics):
      if nic.name and nic.name.startswith("gnt.com."):
        _ConfigureNIC(instance, nic_seq, nic, nic.name)
Пример #15
0
class MonitorSocket(object):
    _SOCKET_TIMEOUT = 5

    def __init__(self, monitor_filename):
        """Instantiates the MonitorSocket object.

    @type monitor_filename: string
    @param monitor_filename: the filename of the UNIX raw socket on which the
                             monitor (QMP or simple one) is listening

    """
        self.monitor_filename = monitor_filename
        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        # We want to fail if the server doesn't send a complete message
        # in a reasonable amount of time
        self.sock.settimeout(self._SOCKET_TIMEOUT)
        self._connected = False

    def _check_socket(self):
        sock_stat = None
        try:
            sock_stat = os.stat(self.monitor_filename)
        except EnvironmentError, err:
            if err.errno == errno.ENOENT:
                raise errors.HypervisorError("No monitor socket found")
            else:
                raise errors.HypervisorError(
                    "Error checking monitor socket: %s", utils.ErrnoOrStr(err))
        if not stat.S_ISSOCK(sock_stat.st_mode):
            raise errors.HypervisorError("Monitor socket is not a socket")
Пример #16
0
    def StartInstance(self, instance, block_devices, startup_paused):
        """Start an instance.

    For the fake hypervisor, it just creates a file in the base dir,
    creating an exception if it already exists. We don't actually
    handle race conditions properly, since these are *FAKE* instances.

    """
        if self._IsAlive(instance.name):
            raise errors.HypervisorError("Failed to start instance %s: %s" %
                                         (instance.name, "already running"))
        try:
            self._MarkUp(instance, self._InstanceStartupMemory(instance))
        except IOError, err:
            raise errors.HypervisorError("Failed to start instance %s: %s" %
                                         (instance.name, err))
Пример #17
0
  def _WriteNICInfoFile(cls, instance, idx, nic):
    """Write the Xen config file for the instance.

    This version of the function just writes the config file from static data.

    """
    instance_name = instance.name
    dirs = [(dname, constants.RUN_DIRS_MODE)
            for dname in cls._DIRS + [cls._InstanceNICDir(instance_name)]]
    utils.EnsureDirs(dirs)

    cfg_file = cls._InstanceNICFile(instance_name, idx)
    data = StringIO()

    data.write("TAGS=%s\n" % r"\ ".join(instance.GetTags()))
    if nic.netinfo:
      netinfo = objects.Network.FromDict(nic.netinfo)
      for k, v in netinfo.HooksDict().iteritems():
        data.write("%s=%s\n" % (k, v))

    data.write("MAC=%s\n" % nic.mac)
    if nic.ip:
      data.write("IP=%s\n" % nic.ip)
    data.write("INTERFACE_INDEX=%s\n" % str(idx))
    if nic.name:
      data.write("INTERFACE_NAME=%s\n" % nic.name)
    data.write("INTERFACE_UUID=%s\n" % nic.uuid)
    data.write("MODE=%s\n" % nic.nicparams[constants.NIC_MODE])
    data.write("LINK=%s\n" % nic.nicparams[constants.NIC_LINK])

    try:
      utils.WriteFile(cfg_file, data=data.getvalue())
    except EnvironmentError, err:
      raise errors.HypervisorError("Cannot write Xen instance configuration"
                                   " file %s: %s" % (cfg_file, err))
Пример #18
0
    def GetAllInstancesInfo(self, hvparams=None):
        """Get properties of all instances.

    @type hvparams: dict of strings
    @param hvparams: hypervisor parameter
    @return: list of tuples (name, id, memory, vcpus, stat, times)

    """
        data = []
        for file_name in os.listdir(self._ROOT_DIR):
            try:
                fh = open(utils.PathJoin(self._ROOT_DIR, file_name), "r")
                inst_id = "-1"
                memory = 0
                vcpus = 1
                stat = hv_base.HvInstanceState.SHUTDOWN
                times = -1
                try:
                    inst_id = fh.readline().strip()
                    memory = utils.TryConvert(int, fh.readline().strip())
                    vcpus = utils.TryConvert(int, fh.readline().strip())
                    stat = hv_base.HvInstanceState.RUNNING
                    times = 0
                finally:
                    fh.close()
                data.append((file_name, inst_id, memory, vcpus, stat, times))
            except IOError, err:
                raise errors.HypervisorError("Failed to list instances: %s" %
                                             err)
Пример #19
0
  def _DestroyInstanceIfAlive(self, name, hvparams):
    instance_info = self.GetInstanceInfo(name, hvparams=hvparams)

    if instance_info is None:
      raise errors.HypervisorError("Failed to destroy instance %s, already"
                                   " destroyed" % name)
    else:
      self._DestroyInstance(name, hvparams)
Пример #20
0
def validate_machine_version(hvparams, kvm_machine_output):
    machine_version = hvparams[constants.HV_KVM_MACHINE_VERSION]
    if machine_version:
      for test in _CHECK_MACHINE_VERSION_RE:
        if not test(machine_version).search(kvm_machine_output):
            raise errors.HypervisorError("Unsupported machine version: %s" %
                                         machine_version)
    return True
Пример #21
0
  def _CheckToolstackBinary(self, xen_cmd):
    """Checks whether the xen command's binary is found on the machine.

    """
    if xen_cmd not in constants.KNOWN_XEN_COMMANDS:
      raise errors.HypervisorError("Unknown xen command '%s'." % xen_cmd)
    result = self._run_cmd_fn(["which", xen_cmd])
    return not result.failed
Пример #22
0
def check_console_parameters(hvparams):
    if hvparams[constants.HV_SERIAL_CONSOLE]:
      serial_speed = hvparams[constants.HV_SERIAL_SPEED]
      valid_speeds = constants.VALID_SERIAL_SPEEDS
      if not serial_speed or serial_speed not in valid_speeds:
        raise errors.HypervisorError("Invalid serial console speed, must be"
                                     " one of: %s" %
                                     utils.CommaJoin(valid_speeds))
    return True
Пример #23
0
  def _Send(self, message):
    """Encodes and sends a message to KVM using QMP.

    @type message: QmpMessage
    @param message: message to send to KVM
    @raise errors.HypervisorError: when there are communication errors
    @raise errors.ProgrammerError: when there are data serialization errors

    """
    self._check_connection()
    try:
      self.sock.sendall(message.to_bytes())
    except socket.timeout as err:
      raise errors.HypervisorError("Timeout while sending a QMP message: "
                                   "%s" % err)
    except socket.error as err:
      raise errors.HypervisorError("Unable to send data from KVM using the"
                                   " QMP protocol: %s" % err)
Пример #24
0
 def testVerifyToolstackNotOk(self):
     hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
     mock_run_cmd = mock.Mock(return_value=self._result_ok)
     hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
                               _run_cmd_fn=mock_run_cmd)
     hv._CheckToolstack = mock.Mock()
     hv._CheckToolstack.side_effect = errors.HypervisorError("foo")
     result = hv.Verify(hvparams)
     self.assertTrue(result is not None)
Пример #25
0
def check_disk_cache_parameters(hvparams):
    disk_aio = hvparams[constants.HV_KVM_DISK_AIO]
    disk_cache = hvparams[constants.HV_DISK_CACHE]
    if disk_aio == constants.HT_KVM_AIO_NATIVE and \
            disk_cache != constants.HT_CACHE_NONE:
        raise errors.HypervisorError("When 'disk_aio' is set to 'native', the "
                                     "only supported value for 'disk_cache' is "
                                     "'none'.")
    return True
Пример #26
0
def _XenToHypervisorInstanceState(instance_info):
  if _IsInstanceRunning(instance_info):
    return hv_base.HvInstanceState.RUNNING
  elif _IsInstanceShutdown(instance_info):
    return hv_base.HvInstanceState.SHUTDOWN
  else:
    raise errors.HypervisorError("hv_xen._XenToHypervisorInstanceState:"
                                 " unhandled Xen instance state '%s'" %
                                   instance_info)
Пример #27
0
def validate_security_model(hvparams):
    security_model = hvparams[constants.HV_SECURITY_MODEL]
    if security_model == constants.HT_SM_USER:
        username = hvparams[constants.HV_SECURITY_DOMAIN]
        try:
            pwd.getpwnam(username)
        except KeyError:
            raise errors.HypervisorError("Unknown security domain user %s"
                                         % username)
    return True
Пример #28
0
    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

    """
        if not self._IsAlive(instance.name):
            raise errors.HypervisorError(
                "Failed to balloon memory for %s: %s" %
                (instance.name, "not running"))
        try:
            self._MarkUp(instance, mem)
        except EnvironmentError, err:
            raise errors.HypervisorError(
                "Failed to balloon memory for %s: %s" %
                (instance.name, utils.ErrnoOrStr(err)))
Пример #29
0
    def _GetCgroupCpuList(cls, instance_name):
        """Return the list of CPU ids for an instance.

    """
        try:
            cpumask = cls._GetCgroupInstanceValue(instance_name, "cpuset.cpus")
        except EnvironmentError, err:
            raise errors.HypervisorError("Getting CPU list for instance"
                                         " %s failed: %s" %
                                         (instance_name, err))
Пример #30
0
  def _ReadConfigFile(self, instance_name):
    """Returns the contents of the instance config file.

    """
    filename = self._ConfigFileName(instance_name)

    try:
      file_content = utils.ReadFile(filename)
    except EnvironmentError, err:
      raise errors.HypervisorError("Failed to load Xen config file: %s" % err)