Exemple #1
0
def parse_floating_cpu(spec):
    """Parse a CPU set specification.

    Each element in the list is either a single CPU number, a range of
    CPU numbers.

    :param spec: cpu set string eg "1-4,6"
    :returns: a set of CPU indexes

    """

    cpuset_ids = set()
    for rule in spec.split(','):
        range_part = rule.strip().split("-", 1)
        if len(range_part) > 1:
            try:
                start, end = [int(p.strip()) for p in range_part]
            except ValueError:
                raise exception.Invalid()
            if start < end:
                cpuset_ids |= set(range(start, end + 1))
            else:
                raise exception.Invalid()
        else:
            try:
                cpuset_ids.add(int(rule))
            except ValueError:
                raise exception.Invalid()

    return cpuset_ids
Exemple #2
0
 def delete_volume(self, volume):
     volume_id = volume.volume_id
     cinder_api = cinder.CinderAPI(self.context)
     try:
         cinder_api.delete_volume(volume_id)
     except cinder_exception as e:
         raise exception.Invalid(_("Delete Volume failed: %s") % str(e))
Exemple #3
0
 def delete_volume(self, volume):
     volume_id = volume.volume_id
     try:
         self.cinder_api.delete_volume(volume_id)
     except cinder_exception as e:
         raise exception.Invalid(
             _("Delete Volume failed: %s") % six.text_type(e))
Exemple #4
0
 def put_archive(self, context, container, path, data):
     with docker_utils.docker_client() as docker:
         try:
             docker.put_archive(container.container_id, path, data)
         except errors.APIError as api_error:
             if is_not_found(api_error):
                 raise exception.Invalid(_("%s") % str(api_error))
             raise
Exemple #5
0
 def get_archive(self, context, container, path):
     with docker_utils.docker_client() as docker:
         try:
             stream, stat = docker.get_archive(container.container_id, path)
             filedata = stream.read()
             return filedata, stat
         except errors.APIError as api_error:
             if is_not_found(api_error):
                 raise exception.Invalid(_("%s") % str(api_error))
             raise
Exemple #6
0
 def execute_resize(self, exec_id, height, width):
     height = int(height)
     width = int(width)
     with docker_utils.docker_client() as docker:
         try:
             docker.exec_resize(exec_id, height=height, width=width)
         except errors.APIError as api_error:
             if is_not_found(api_error):
                 raise exception.Invalid(_(
                     "no such exec instance: %s") % str(api_error))
             raise
Exemple #7
0
 def exec_resize(self, exec_id, height=None, width=None):
     # NOTE(hongbin): This is a temporary work-around for a docker issue
     # See: https://github.com/moby/moby/issues/35561
     try:
         super(DockerHTTPClient, self).exec_resize(
             exec_id, height=height, width=width)
     except errors.APIError as e:
         if "process not found for container" in str(e):
             raise exception.Invalid(_(
                 "no such exec instance: %s") % str(e))
         raise
Exemple #8
0
def get_floating_cpu_set():
    """Parse floating_cpu_set config.

    :returns: a set of pcpu ids can be used by containers
    """

    if not CONF.floating_cpu_set:
        return None

    cpuset_ids = parse_floating_cpu(CONF.floating_cpu_set)
    if not cpuset_ids:
        raise exception.Invalid(
            _("No CPUs available after parsing %r") % CONF.floating_cpu_set)
    return cpuset_ids
Exemple #9
0
 def get_archive(self, context, container, path):
     with docker_utils.docker_client() as docker:
         try:
             stream, stat = docker.get_archive(
                 container.container_id, path)
             if isinstance(stream, types.GeneratorType):
                 filedata = six.b("").join(stream)
             else:
                 filedata = stream.read()
             return filedata, stat
         except errors.APIError as api_error:
             if is_not_found(api_error):
                 raise exception.Invalid(_("%s") % str(api_error))
             raise
Exemple #10
0
    def detach_volume(self, volume):
        volume_id = volume.volume_id
        try:
            self.cinder_api.begin_detaching(volume_id)
        except cinder_exception.BadRequest as e:
            raise exception.Invalid(_("Invalid volume: %s") % six.text_type(e))

        conn_info = jsonutils.loads(volume.connection_info)
        try:
            self._disconnect_volume(conn_info)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.exception('Failed to disconnect volume %(volume_id)s',
                              {'volume_id': volume_id})
                self.cinder_api.roll_detaching(volume_id)

        self.cinder_api.terminate_connection(volume_id,
                                             get_volume_connector_properties())
        self.cinder_api.detach(volume_id)
Exemple #11
0
 def delete_volume(self, volmap):
     volume_id = volmap.cinder_volume_id
     try:
         self.cinder_api.delete_volume(volume_id)
     except cinder_exception as e:
         raise exception.Invalid(_("Delete Volume failed: %s") % str(e))
Exemple #12
0
    def _build_requested_volumes(self, context, volume_spec, volume_mounts,
                                 capsule):
        # NOTE(hongbin): We assume cinder is the only volume provider here.
        # The logic needs to be re-visited if a second volume provider
        # (i.e. Manila) is introduced.
        # NOTE(kevinz): We assume the volume_mounts has been pretreated,
        # there won't occur that volume multiple attach and no untapped
        # volume.
        cinder_api = cinder.CinderAPI(context)
        volume_driver = "cinder"
        requested_volumes = []
        volume_created = []
        try:
            for mount in volume_spec:
                mount_driver = mount[volume_driver]
                auto_remove = False
                if mount_driver.get("volumeID"):
                    uuid = mount_driver.get("volumeID")
                    volume = cinder_api.search_volume(uuid)
                    cinder_api.ensure_volume_usable(volume)
                else:
                    size = mount_driver.get("size")
                    volume = cinder_api.create_volume(size)
                    volume_created.append(volume)
                    if "autoRemove" in mount_driver.keys() \
                            and mount_driver.get("autoRemove", False):
                        auto_remove = True

                mount_destination = None
                container_name = None

                volume_object = objects.Volume(context,
                                               cinder_volume_id=volume.id,
                                               volume_provider=volume_driver,
                                               user_id=context.user_id,
                                               project_id=context.project_id,
                                               auto_remove=auto_remove)
                volume_object.create(context)

                for item in volume_mounts:
                    if item['name'] == mount['name']:
                        mount_destination = item['mountPath']
                        container_name = item['container_name']
                        volmapp = objects.VolumeMapping(
                            context,
                            container_path=mount_destination,
                            user_id=context.user_id,
                            project_id=context.project_id,
                            volume_id=volume_object.id)
                        requested_volumes.append({container_name: volmapp})

                if not mount_destination or not container_name:
                    msg = _("volume mount parameters is invalid.")
                    raise exception.Invalid(msg)
        except Exception as e:
            # if volume search or created failed, will remove all
            # the created volume. The existed volume will remain.
            for volume in volume_created:
                try:
                    cinder_api.delete_volume(volume.id)
                except Exception as exc:
                    LOG.error('Error on deleting volume "%s": %s.', volume.id,
                              six.text_type(exc))

            # Since the container and capsule database model has been created,
            # we need to delete them here due to the volume create failed.
            for container in capsule.containers:
                try:
                    container.destroy(context)
                except Exception as exc:
                    LOG.warning('fail to delete the container %s: %s',
                                container.uuid, exc)

            capsule.destroy(context)

            raise e

        return requested_volumes
Exemple #13
0
 def decorated_function(*args, **kwargs):
     container = args[2]
     if getattr(container, 'container_id', None) is None:
         msg = _("Cannot operate an uncreated container.")
         raise exception.Invalid(message=msg)
     return function(*args, **kwargs)