Esempio n. 1
0
    def serial_connection(self, value):
        """Override parent property setter to add ESXi validation.

        For the parameters, see :meth:`~COTDeploy.serial_connection`
        """
        if len(value) > 4:
            raise ValueUnsupportedError(
                'serial port connection list', value,
                'no more than 4 connections (ESXi limitation)')
        super(COTDeployESXi, self.__class__).serial_connection.fset(self,
                                                                    value)
Esempio n. 2
0
    def detect_type_from_name(cls, filename):
        """Check the given filename to see if it looks like a type we support.

        Does not check file contents, as the given filename may not yet exist.

        Args:
          filename (str): File name or path
        Returns:
          str: A string representing a recognized and supported type of file
        Raises:
          ValueUnsupportedError: if COT can't recognize the file type or
              doesn't know how to handle this file type.
        """
        raise ValueUnsupportedError("filename", filename, ("none implemented"))
Esempio n. 3
0
    def validate_cpu_count(self, cpus):
        """C9800CL supports 4,6 or 10 CPUs.

        Args:
          cpus (int): Number of CPUs.

        Raises:
          ValueTooLowError: if ``cpus`` is less than 4
          ValueTooHighError: if ``cpus`` is more than 10
          ValueUnsupportedError: if ``cpus`` is a value other than 4, 6, 10
        """
        super(C9800CL, self).validate_cpu_count(cpus)
        if cpus not in [4, 6, 10]:
            raise ValueUnsupportedError("CPUs", cpus, [4, 6, 10])
Esempio n. 4
0
    def validate_nic_type(self, type_string):
        """Throw an error if the NIC type string is not supported.

        .. seealso::
           - :func:`COT.data_validation.canonicalize_nic_subtype`
           - :data:`COT.data_validation.NIC_TYPES`

        Args:
          type_string (str): See :data:`COT.data_validation.NIC_TYPES`

        Raises:
          ValueUnsupportedError: if ``type_string`` is not in
              :const:`SUPPORTED_NIC_TYPES`
        """
        if type_string not in self.SUPPORTED_NIC_TYPES:
            raise ValueUnsupportedError("NIC type for {0}".format(self),
                                        type_string, self.SUPPORTED_NIC_TYPES)
Esempio n. 5
0
    def item_tag_for_namespace(self, namespace):
        """Get the Item tag for the given XML namespace.

        Args:
          namespace (str): XML namespace
        Returns:
          str: 'Item', 'StorageItem', or 'EthernetPortItem' as appropriate.
        Raises:
          ValueUnsupportedError: if the namespace is unrecognized
        """
        if namespace == self.RASD:
            return self.ITEM
        elif namespace == self.SASD:
            return self.STORAGE_ITEM
        elif namespace == self.EPASD:
            return self.ETHERNET_PORT_ITEM
        else:
            raise ValueUnsupportedError("namespace",
                                        namespace,
                                        [self.RASD, self.SASD, self.EPASD])
Esempio n. 6
0
def guess_controller_type(platform, ctrl_item, drive_type):
    """If a controller type wasn't specified, try to guess from context.

    Args:
      platform (Platform): Platform instance to guess controller for
      ctrl_item (object): Any known controller object, or None
      drive_type (str): "cdrom" or "harddisk"
    Returns:
      str: 'ide', 'sata', or 'scsi'
    Raises:
      ValueUnsupportedError: if ``ctrl_item`` is not None but is also not
          an IDE, SATA, or SCSI controller device.
    Examples:
      ::

        >>> from COT.platforms import Platform
        >>> guess_controller_type(Platform(), None, 'harddisk')
        'ide'
    """
    if ctrl_item is None:
        # If the user didn't tell us which controller type they wanted,
        # and we didn't find a controller item based on existing file/disk,
        # then we need to guess which type of controller we need,
        # based on the platform and the disk drive type.
        ctrl_type = platform.controller_type_for_device(drive_type)
        logger.warning(
            "Controller type not specified - guessing it should be"
            " %s based on disk drive type %s and platform %s", ctrl_type,
            drive_type, platform)
    else:
        ctrl_type = ctrl_item.hardware_type
        if ctrl_type not in ['ide', 'sata', 'scsi']:
            raise ValueUnsupportedError("controller ResourceType", ctrl_type,
                                        "'ide', 'sata', or 'scsi'")
        logger.notice(
            "Controller type not specified - using"
            " '%s' based on existing Item", ctrl_type)
    return ctrl_type
Esempio n. 7
0
    def validate_kind(cls, kind):
        """Validate the connection type string and munge it as needed.

        Args:
          kind (str): Connection type string, possibly in need of munging.
        Returns:
          str: A valid type string
        Raises:
          ValueUnsupportedError: if ``kind`` is not recognized as valid
        """
        kind = kind.lower()
        if kind == '':
            kind = 'device'
        valid_kinds = [
            'device',  # physical serial port like /dev/ttyS0
            'file',  # output to file, no input
            'pipe',  # named pipe
            'tcp',  # raw tcp socket
            'telnet',  # telnet socket
        ]
        if kind in valid_kinds:
            return kind
        else:
            raise ValueUnsupportedError('connection type', kind, valid_kinds)
Esempio n. 8
0
File: item.py Progetto: sentrium/cot
    def add_item(self, item):
        """Add the given ``Item`` element to this OVFItem.

        Args:
          item (xml.etree.ElementTree.Element): XML ``Item`` element

        Raises:
          ValueUnsupportedError: if the ``item`` is not a recognized
              Item variant.
          OVFItemDataError: if the new Item conflicts with existing data
              already in the OVFItem.
        """
        logger.spam("Adding new %s", item.tag)
        self.namespace = self.namespace_for_item_tag(item.tag)
        if not self.namespace:
            raise ValueUnsupportedError("item", item.tag,
                                        "Item, StorageItem, EthernetPortItem")

        profiles = set(item.get(self.ITEM_CONFIG, "").split())
        # Store any attributes of the Item itself:
        for (attrib, value) in item.attrib.items():
            if attrib == self.ITEM_CONFIG:
                continue
            attrib_string = attrib + self.ATTRIB_KEY_SUFFIX
            self.set_property(attrib_string, value, profiles, overwrite=False)

        # Store any child elements of the Item.
        # We save the ElementName and Description elements for last because
        # they may include references to the VirtualQuantity, ResourceSubType,
        # and/or Connection entries, which we won't know until we process them.
        children = list(item)
        name_child = next((child for child in children
                           if XML.strip_ns(child.tag) == self.ELEMENT_NAME),
                          None)
        desc_child = next(
            (child for child in children
             if XML.strip_ns(child.tag) == self.ITEM_DESCRIPTION), None)
        if name_child is not None:
            children.remove(name_child)
            children.append(name_child)
        # Description is *after* name because it may reference name
        if desc_child is not None:
            children.remove(desc_child)
            children.append(desc_child)

        for child in children:
            tag = XML.strip_ns(child.tag)
            if tag not in self.ITEM_CHILDREN:
                # Non-standard elements may not follow the standard rules -
                # for example, VMware OVF extensions may have multiple
                # vmw:Config elements, each distinguished by its vmw:key attr.
                # Rather than try to guess how these items do or do not match,
                # we simply store the whole item
                self.set_property((ET.tostring(child).decode().strip() +
                                   self.ELEMENT_KEY_SUFFIX),
                                  ET.tostring(child).decode(),
                                  profiles,
                                  overwrite=False)
                continue
            # Store the value of this element:
            self.set_property(tag, child.text, profiles, overwrite=False)
            # Store any attributes of this element
            for (attrib, value) in child.attrib.items():
                attrib_string = tag + "_attrib_" + attrib
                self.set_property(attrib_string,
                                  value,
                                  profiles,
                                  overwrite=False)

        self.modified = True
        logger.spam("Added %s - new status:\n%s", item.tag, str(self))
        self.validate()
Esempio n. 9
0
    def run(self):
        """Do the actual work of this command.

        Raises:
          InvalidInputError: if :func:`ready_to_run` reports ``False``
          ValueUnsupportedError: if the
              :const:`~COT.platforms.Platform.BOOTSTRAP_DISK_TYPE` of
              the associated VM's
              :attr:`~COT.vm_description.VMDescription.platform` is not
              'cdrom' or 'harddisk'
          LookupError: if unable to find a disk drive device to inject
              the configuration into.
        """
        super(COTInjectConfig, self).run()

        vm = self.vm

        platform = vm.platform

        # Find the disk drive where the config should be injected
        # First, look for any previously-injected config disk to overwrite:
        if platform.BOOTSTRAP_DISK_TYPE == 'cdrom':
            (fileelem, _, _, drive_device) = vm.search_from_filename(
                'config.iso')
        elif platform.BOOTSTRAP_DISK_TYPE == 'harddisk':
            (fileelem, _, _, drive_device) = vm.search_from_filename(
                'config.vmdk')
        else:
            raise ValueUnsupportedError("bootstrap disk drive type",
                                        platform.BOOTSTRAP_DISK_TYPE,
                                        "'cdrom' or 'harddisk'")
        if fileelem is not None:
            file_id = vm.get_id_from_file(fileelem)
            self.ui.confirm_or_die(
                "Existing configuration disk '{0}' found.\n"
                "Continue and overwrite it?".format(file_id))
            logger.notice("Overwriting existing config disk '%s'", file_id)
        else:
            file_id = None
            # Find the empty slot where we should inject the config
            drive_device = vm.find_empty_drive(platform.BOOTSTRAP_DISK_TYPE)

        if drive_device is None:
            raise LookupError("Could not find an empty {0} drive to "
                              "inject the config into"
                              .format(platform.BOOTSTRAP_DISK_TYPE))
        (cont_type, drive_address) = vm.find_device_location(drive_device)

        # Copy config file(s) to per-platform name in working directory
        config_files = []
        if self.config_file:
            dest = os.path.join(vm.working_dir, platform.CONFIG_TEXT_FILE)
            shutil.copy(self.config_file, dest)
            config_files.append(dest)
        if self.secondary_config_file:
            dest = os.path.join(vm.working_dir,
                                platform.SECONDARY_CONFIG_TEXT_FILE)
            shutil.copy(self.secondary_config_file, dest)
            config_files.append(dest)

        # Extra files are packaged as-is
        config_files += self.extra_files

        # Package the config files into a disk image
        # pylint:disable=redefined-variable-type
        if platform.BOOTSTRAP_DISK_TYPE == 'cdrom':
            bootstrap_file = os.path.join(vm.working_dir, 'config.iso')
            disk_format = 'iso'
        elif platform.BOOTSTRAP_DISK_TYPE == 'harddisk':
            bootstrap_file = os.path.join(vm.working_dir, 'config.img')
            disk_format = 'raw'
        else:
            raise ValueUnsupportedError("bootstrap disk drive type",
                                        platform.BOOTSTRAP_DISK_TYPE,
                                        "'cdrom' or 'harddisk'")

        disk_image = DiskRepresentation.for_new_file(bootstrap_file,
                                                     disk_format,
                                                     files=config_files)

        # Inject the disk image into the OVA, using "add-disk" functionality
        add_disk_worker(
            ui=self.ui,
            vm=vm,
            disk_image=disk_image,
            drive_type=platform.BOOTSTRAP_DISK_TYPE,
            file_id=file_id,
            controller=cont_type,
            address=drive_address,
            subtype=None,
            description='Configuration disk',
            diskname=None,
        )