Example #1
0
    def _report_coverage(self, req, body):
        self._stop_coverage(req)
        xml = False
        html = False
        path = None

        body = body['report']
        if 'file' in body.keys():
            path = body['file']
            if path != os.path.basename(path):
                msg = _("Invalid path")
                raise exc.HTTPBadRequest(explanation=msg)
            path = os.path.join(self.data_path, path)
        else:
            msg = _("No path given for report file")
            raise exc.HTTPBadRequest(explanation=msg)

        if 'xml' in body.keys():
            xml = body['xml']
        elif 'html' in body.keys():
            if not self.combine:
                msg = _("You can't use html reports without combining")
                raise exc.HTTPBadRequest(explanation=msg)
            html = body['html']

        if self.combine:
            data_out = os.path.join(self.data_path, '.nova-coverage')
            import coverage
            coverInst = coverage.coverage(data_file=data_out)
            coverInst.combine()
            if xml:
                coverInst.xml_report(outfile=path)
            elif html:
                if os.path.isdir(path):
                    msg = _("Directory conflict: %s already exists") % path
                    raise exc.HTTPBadRequest(explanation=msg)
                coverInst.html_report(directory=path)
            else:
                output = open(path, 'w')
                coverInst.report(file=output)
                output.close()
            for service in self.services:
                service['telnet'].close()
        else:
            if xml:
                apipath = path + '.api'
                self.coverInst.xml_report(outfile=apipath)
                for service in self.services:
                    self._report_coverage_telnet(service['telnet'],
                                              path + '.%s'
                                              % service['service'],
                                              xml=True)
            else:
                output = open(path + '.api', 'w')
                self.coverInst.report(file=output)
                for service in self.services:
                    self._report_coverage_telnet(service['telnet'],
                                            path + '.%s' % service['service'])
                output.close()
        return {'path': path}
Example #2
0
    def create(self, req, body):
        """Creates a new snapshot."""
        context = req.environ["nova.context"]
        authorize(context)

        if not self.is_valid_body(body, "snapshot"):
            raise exc.HTTPUnprocessableEntity()

        snapshot = body["snapshot"]
        volume_id = snapshot["volume_id"]

        LOG.audit(_("Create snapshot from volume %s"), volume_id, context=context)

        force = snapshot.get("force", False)
        try:
            force = strutils.bool_from_string(force, strict=True)
        except ValueError:
            msg = _("Invalid value '%s' for force.") % force
            raise exception.InvalidParameterValue(err=msg)

        if force:
            create_func = self.volume_api.create_snapshot_force
        else:
            create_func = self.volume_api.create_snapshot

        new_snapshot = create_func(
            context, volume_id, snapshot.get("display_name"), snapshot.get("display_description")
        )

        retval = _translate_snapshot_detail_view(context, new_snapshot)
        return {"snapshot": retval}
Example #3
0
    def _resize(self, req, instance_id, flavor_id, **kwargs):
        """Begin the resize process with given instance/flavor."""
        context = req.environ["nova.context"]
        instance = self._get_server(context, req, instance_id)

        try:
            self.compute_api.resize(context, instance, flavor_id, **kwargs)
        except exception.QuotaError as error:
            raise exc.HTTPRequestEntityTooLarge(
                explanation=error.format_message(),
                headers={'Retry-After': 0})
        except exception.FlavorNotFound:
            msg = _("Unable to locate requested flavor.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.CannotResizeToSameFlavor:
            msg = _("Resize requires a flavor change.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'resize')
        except exception.ImageNotAuthorized:
            msg = _("You are not authorized to access the image "
                    "the instance was started with.")
            raise exc.HTTPUnauthorized(explanation=msg)
        except exception.ImageNotFound:
            msg = _("Image that the instance was started "
                    "with could not be found.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.Invalid:
            msg = _("Invalid instance image.")
            raise exc.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)
    def is_cloneable(self, image_location, image_meta):
        url = image_location['url']
        try:
            fsid, pool, image, snapshot = self.parse_url(url)
        except exception.ImageUnacceptable as e:
            LOG.debug(_('not cloneable: %s'), e)
            return False

        if self._get_fsid() != fsid:
            reason = _('%s is in a different ceph cluster') % url
            LOG.debug(reason)
            return False

        if image_meta['disk_format'] != 'raw':
            reason = _("rbd image clone requires image format to be "
                       "'raw' but image {0} is '{1}'").format(
                           url, image_meta['disk_format'])
            LOG.debug(reason)
            return False

        # check that we can read the image
        try:
            return self.exists(image, pool=pool, snapshot=snapshot)
        except self.rbd.Error as e:
            LOG.debug(_('Unable to open image %(loc)s: %(err)s') %
                      dict(loc=url, err=e))
            return False
Example #5
0
    def _lookup_torrent_url_fn():
        """Load a "fetcher" func to get the right torrent URL via
        entrypoints.
        """
        matches = [ep for ep in
                   pkg_resources.iter_entry_points('nova.virt.xenapi.vm_utils')
                   if ep.name == 'torrent_url']

        if not matches:
            LOG.debug(_("No torrent URL fetcher extension found, using"
                        " default."))

            if not CONF.xenserver.torrent_base_url:
                raise RuntimeError(_('Cannot create default bittorrent URL'
                                     ' without torrent_base_url set'))

            def _default_torrent_url_fn(instance, image_id):
                return urlparse.urljoin(CONF.xenserver.torrent_base_url,
                                        "%s.torrent" % image_id)

            fn = _default_torrent_url_fn
        elif len(matches) > 1:
            raise RuntimeError(_("Multiple torrent URL fetcher extension"
                                 " found. Failing."))
        else:
            ep = matches[0]
            LOG.debug(_("Loading torrent URL fetcher from entry points"
                        " %(ep)s"), {'ep': ep})
            fn = ep.load()

        return fn
Example #6
0
    def update(self, req, id, body):
        """Update server then pass on to version-specific controller."""
        if not self.is_valid_body(body, 'server'):
            raise exc.HTTPBadRequest(_("The request body is invalid"))

        ctxt = req.environ['nova.context']
        update_dict = {}

        if 'name' in body['server']:
            name = body['server']['name']
            self._validate_server_name(name)
            update_dict['display_name'] = name.strip()

        if 'host_id' in body['server']:
            msg = _("host_id cannot be updated.")
            raise exc.HTTPBadRequest(explanation=msg)

        if list(self.update_extension_manager):
            self.update_extension_manager.map(self._update_extension_point,
                                              body['server'], update_dict)

        instance = common.get_instance(self.compute_api, ctxt, id,
                                       want_objects=True,
                                       expected_attrs=['pci_devices'])
        try:
            # NOTE(mikal): this try block needs to stay because save() still
            # might throw an exception.
            req.cache_db_instance(instance)
            policy.enforce(ctxt, 'compute:update', instance)
            instance.update(update_dict)
            instance.save()
            return self._view_builder.show(req, instance)
        except exception.NotFound:
            msg = _("Instance could not be found")
            raise exc.HTTPNotFound(explanation=msg)
Example #7
0
    def _action_reboot(self, req, id, body):
        if 'reboot' in body and 'type' in body['reboot']:
            if not isinstance(body['reboot']['type'], six.string_types):
                msg = _("Argument 'type' for reboot must be a string")
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)
            valid_reboot_types = ['HARD', 'SOFT']
            reboot_type = body['reboot']['type'].upper()
            if not valid_reboot_types.count(reboot_type):
                msg = _("Argument 'type' for reboot is not HARD or SOFT")
                LOG.error(msg)
                raise exc.HTTPBadRequest(explanation=msg)
        else:
            msg = _("Missing argument 'type' for reboot")
            LOG.error(msg)
            raise exc.HTTPBadRequest(explanation=msg)

        context = req.environ['nova.context']
        instance = self._get_server(context, req, id)

        try:
            self.compute_api.reboot(context, instance, reboot_type)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'reboot')
        return webob.Response(status_int=202)
Example #8
0
File: claims.py Project: ahil5/nova
    def _claim_test(self, resources, limits=None):
        """Test if this claim can be satisfied given available resources and
        optional oversubscription limits

        This should be called before the compute node actually consumes the
        resources required to execute the claim.

        :param resources: available local compute node resources
        :returns: Return true if resources are available to claim.
        """
        if not limits:
            limits = {}

        # If an individual limit is None, the resource will be considered
        # unlimited:
        memory_mb_limit = limits.get('memory_mb')
        disk_gb_limit = limits.get('disk_gb')
        vcpu_limit = limits.get('vcpu')

        msg = _("Attempting claim: memory %(memory_mb)d MB, disk %(disk_gb)d "
                "GB, VCPUs %(vcpus)d")
        params = {'memory_mb': self.memory_mb, 'disk_gb': self.disk_gb,
                  'vcpus': self.vcpus}
        LOG.audit(msg % params, instance=self.instance)

        reasons = [self._test_memory(resources, memory_mb_limit),
                   self._test_disk(resources, disk_gb_limit),
                   self._test_cpu(resources, vcpu_limit),
                   self._test_pci()]
        reasons = [r for r in reasons if r is not None]
        if len(reasons) > 0:
            raise exception.ComputeResourcesUnavailable(reason=
                    "; ".join(reasons))

        LOG.audit(_('Claim successful'), instance=self.instance)
Example #9
0
File: claims.py Project: ahil5/nova
    def _test(self, type_, unit, total, used, requested, limit):
        """Test if the given type of resource needed for a claim can be safely
        allocated.
        """
        LOG.audit(_('Total %(type)s: %(total)d %(unit)s, used: %(used).02f '
                    '%(unit)s'),
                  {'type': type_, 'total': total, 'unit': unit, 'used': used},
                  instance=self.instance)

        if limit is None:
            # treat resource as unlimited:
            LOG.audit(_('%(type)s limit not specified, defaulting to '
                        'unlimited'), {'type': type_}, instance=self.instance)
            return

        free = limit - used

        # Oversubscribed resource policy info:
        LOG.audit(_('%(type)s limit: %(limit).02f %(unit)s, free: %(free).02f '
                    '%(unit)s'),
                  {'type': type_, 'limit': limit, 'free': free, 'unit': unit},
                  instance=self.instance)

        if requested > free:
            return (_('Free %(type)s %(free).02f '
                      '%(unit)s < requested %(requested)d %(unit)s') %
                      {'type': type_, 'free': free, 'unit': unit,
                       'requested': requested})
Example #10
0
def limited(items, request, max_limit=CONF.osapi_max_limit):
    """Return a slice of items according to requested offset and limit.

    :param items: A sliceable entity
    :param request: ``wsgi.Request`` possibly containing 'offset' and 'limit'
                    GET variables. 'offset' is where to start in the list,
                    and 'limit' is the maximum number of items to return. If
                    'limit' is not specified, 0, or > max_limit, we default
                    to max_limit. Negative values for either offset or limit
                    will cause exc.HTTPBadRequest() exceptions to be raised.
    :kwarg max_limit: The maximum number of items to return from 'items'
    """
    try:
        offset = int(request.GET.get('offset', 0))
    except ValueError:
        msg = _('offset param must be an integer')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    try:
        limit = int(request.GET.get('limit', max_limit))
    except ValueError:
        msg = _('limit param must be an integer')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    if limit < 0:
        msg = _('limit param must be positive')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    if offset < 0:
        msg = _('offset param must be positive')
        raise webob.exc.HTTPBadRequest(explanation=msg)

    limit = min(max_limit, limit or max_limit)
    range_end = offset + limit
    return items[offset:range_end]
Example #11
0
 def inner(*args, **kwargs):
     if not CONF.allow_instance_snapshots:
         LOG.warn(_('Rejecting snapshot request, snapshots currently'
                    ' disabled'))
         msg = _("Instance snapshots are not permitted at this time.")
         raise webob.exc.HTTPBadRequest(explanation=msg)
     return f(*args, **kwargs)
Example #12
0
    def _get_flavors(self, req):
        """Helper function that returns a list of flavor dicts."""
        filters = {}

        context = req.environ['nova.context']
        if context.is_admin:
            # Only admin has query access to all flavor types
            filters['is_public'] = self._parse_is_public(
                    req.params.get('is_public', None))
        else:
            filters['is_public'] = True
            filters['disabled'] = False

        if 'min_ram' in req.params:
            try:
                filters['min_memory_mb'] = int(req.params['min_ram'])
            except ValueError:
                msg = _('Invalid min_ram filter [%s]') % req.params['min_ram']
                raise webob.exc.HTTPBadRequest(explanation=msg)

        if 'min_disk' in req.params:
            try:
                filters['min_root_gb'] = int(req.params['min_disk'])
            except ValueError:
                msg = (_('Invalid min_disk filter [%s]') %
                       req.params['min_disk'])
                raise webob.exc.HTTPBadRequest(explanation=msg)

        limited_flavors = flavors.get_all_flavors(context, filters=filters)
        flavors_list = limited_flavors.values()
        sorted_flavors = sorted(flavors_list,
                                key=lambda item: item['flavorid'])
        limited_flavors = common.limited_by_marker(sorted_flavors, req)
        return limited_flavors
Example #13
0
    def _get_mounted_disk_from_lun(self, target_iqn, target_lun,
                                   wait_for_device=False):
        # The WMI query in get_device_number_for_target can incorrectly
        # return no data when the system is under load.  This issue can
        # be avoided by adding a retry.
        for i in xrange(CONF.hyperv.mounted_disk_query_retry_count):
            device_number = self._volutils.get_device_number_for_target(
                            target_iqn, target_lun)
            if device_number is None:
                attempt = i + 1
                LOG.debug(_('Attempt %d to get device_number '
                          'from get_device_number_for_target failed. '
                          'Retrying...') % attempt)
                time.sleep(CONF.hyperv.mounted_disk_query_retry_interval)
            else:
                break

        if device_number is None:
            raise exception.NotFound(_('Unable to find a mounted disk for '
                                       'target_iqn: %s') % target_iqn)
        LOG.debug(_('Device number: %(device_number)s, '
                    'target lun: %(target_lun)s'),
                  {'device_number': device_number, 'target_lun': target_lun})
        #Finding Mounted disk drive
        for i in range(0, CONF.hyperv.volume_attach_retry_count):
            mounted_disk_path = self._vmutils.get_mounted_disk_by_drive_number(
                device_number)
            if mounted_disk_path or not wait_for_device:
                break
            time.sleep(CONF.hyperv.volume_attach_retry_interval)

        if not mounted_disk_path:
            raise exception.NotFound(_('Unable to find a mounted disk '
                                       'for target_iqn: %s') % target_iqn)
        return mounted_disk_path
Example #14
0
 def spawn(self, context, instance, image_meta, injected_files,
           admin_password, network_info=None, block_device_info=None):
     image_name = self._get_image_name(context, instance, image_meta)
     args = {
         'Hostname': instance['name'],
         'Image': image_name,
         'Memory': self._get_memory_limit_bytes(instance),
         'CpuShares': self._get_cpu_shares(instance)
     }
     default_cmd = self._get_default_cmd(image_name)
     if default_cmd:
         args['Cmd'] = default_cmd
     container_id = self._create_container(instance, args)
     if not container_id:
         msg = _('Image name "{0}" does not exist, fetching it...')
         LOG.info(msg.format(image_name))
         res = self.docker.pull_repository(image_name)
         if res is False:
             raise exception.InstanceDeployFailure(
                 _('Cannot pull missing image'),
                 instance_id=instance['name'])
         container_id = self._create_container(instance, args)
         if not container_id:
             raise exception.InstanceDeployFailure(
                 _('Cannot create container'),
                 instance_id=instance['name'])
     self.docker.start_container(container_id)
     try:
         self._setup_network(instance, network_info)
     except Exception as e:
         msg = _('Cannot setup network: {0}')
         raise exception.InstanceDeployFailure(msg.format(e),
                                               instance_id=instance['name'])
Example #15
0
def bm_node_associate_and_update(context, node_uuid, values):
    """Associate an instance to a node safely

    Associate an instance to a node only if that node is not yet assocated.
    Allow the caller to set any other fields they require in the same
    operation. For example, this is used to set the node's task_state to
    BUILDING at the beginning of driver.spawn().

    """
    if 'instance_uuid' not in values:
        raise exception.NovaException(_(
            "instance_uuid must be supplied to bm_node_associate_and_update"))

    session = db_session.get_session()
    with session.begin():
        query = model_query(context, models.BareMetalNode,
                                session=session, read_deleted="no").\
                        filter_by(uuid=node_uuid)

        count = query.filter_by(instance_uuid=None).\
                        update(values, synchronize_session=False)
        if count != 1:
            raise exception.NovaException(_(
                "Failed to associate instance %(i_uuid)s to baremetal node "
                "%(n_uuid)s.") % {'i_uuid': values['instance_uuid'],
                                  'n_uuid': node_uuid})
        ref = query.first()
    return ref
Example #16
0
    def teardown(self):
        LOG.debug(_("Tearing down appliance"))

        try:
            try:
                self.handle.aug_close()
            except RuntimeError as e:
                LOG.warn(_("Failed to close augeas %s"), e)

            try:
                self.handle.shutdown()
            except AttributeError:
                # Older libguestfs versions haven't an explicit shutdown
                pass
            except RuntimeError as e:
                LOG.warn(_("Failed to shutdown appliance %s"), e)

            try:
                self.handle.close()
            except AttributeError:
                # Older libguestfs versions haven't an explicit close
                pass
            except RuntimeError as e:
                LOG.warn(_("Failed to close guest handle %s"), e)
        finally:
            # dereference object and implicitly close()
            self.handle = None
Example #17
0
    def setup_os_root(self, root):
        LOG.debug(_("Inspecting guest OS root filesystem %s"), root)
        mounts = self.handle.inspect_get_mountpoints(root)

        if len(mounts) == 0:
            raise exception.NovaException(
                _("No mount points found in %(root)s of %(imgfile)s") % {"root": root, "imgfile": self.imgfile}
            )

        # the root directory must be mounted first
        mounts.sort(key=lambda mount: mount[0])

        root_mounted = False
        for mount in mounts:
            LOG.debug(_("Mounting %(dev)s at %(dir)s") % {"dev": mount[1], "dir": mount[0]})
            try:
                self.handle.mount_options("", mount[1], mount[0])
                root_mounted = True
            except RuntimeError as e:
                msg = _("Error mounting %(device)s to %(dir)s in image" " %(imgfile)s with libguestfs (%(e)s)") % {
                    "imgfile": self.imgfile,
                    "device": mount[1],
                    "dir": mount[0],
                    "e": e,
                }
                if root_mounted:
                    LOG.debug(msg)
                else:
                    raise exception.NovaException(msg)
Example #18
0
    def _cleanup(self, instance_name, destroy_disks=True):
        lpar_id = self._get_instance(instance_name)['lpar_id']
        try:
            vhost = self._operator.get_vhost_by_instance_id(lpar_id)
            disk_name = self._operator.get_disk_name_by_vhost(vhost)

            LOG.debug(_("Shutting down the instance '%s'") % instance_name)
            self._operator.stop_lpar(instance_name)

            #dperaza: LPAR should be deleted first so that vhost is
            #cleanly removed and detached from disk device.
            LOG.debug(_("Deleting the LPAR instance '%s'") % instance_name)
            self._operator.remove_lpar(instance_name)

            if disk_name and destroy_disks:
                # TODO(mrodden): we should also detach from the instance
                # before we start deleting things...
                volume_info = {'device_name': disk_name}
                #Volume info dictionary might need more info that is lost when
                #volume is detached from host so that it can be deleted
                self._disk_adapter.detach_volume_from_host(volume_info)
                self._disk_adapter.delete_volume(volume_info)
        except Exception:
            LOG.exception(_("PowerVM instance cleanup failed"))
            raise exception.PowerVMLPARInstanceCleanupFailed(
                                                  instance_name=instance_name)
Example #19
0
    def setup(self):
        LOG.debug(
            _("Setting up appliance for %(imgfile)s %(imgfmt)s") % {"imgfile": self.imgfile, "imgfmt": self.imgfmt}
        )
        try:
            self.handle = tpool.Proxy(guestfs.GuestFS(close_on_exit=False))
        except TypeError as e:
            if "close_on_exit" in str(e):
                # NOTE(russellb) In case we're not using a version of
                # libguestfs new enough to support the close_on_exit paramater,
                # which was added in libguestfs 1.20.
                self.handle = tpool.Proxy(guestfs.GuestFS())
            else:
                raise

        try:
            self.handle.add_drive_opts(self.imgfile, format=self.imgfmt)
            self.handle.launch()

            self.setup_os()

            self.handle.aug_init("/", 0)
        except RuntimeError as e:
            # dereference object and implicitly close()
            self.handle = None
            raise exception.NovaException(
                _("Error mounting %(imgfile)s with libguestfs (%(e)s)") % {"imgfile": self.imgfile, "e": e}
            )
        except Exception:
            self.handle = None
            raise
    def _get_cpu_allocation_ratio(self, host_state, filter_properties):
        context = filter_properties['context'].elevated()
        # TODO(uni): DB query in filter is a performance hit, especially for
        # system with lots of hosts. Will need a general solution here to fix
        # all filters with aggregate DB call things.
        metadata = db.aggregate_metadata_get_by_host(
                     context, host_state.host, key='cpu_allocation_ratio')
        aggregate_vals = metadata.get('cpu_allocation_ratio', set())
        num_values = len(aggregate_vals)

        if num_values == 0:
            return CONF.cpu_allocation_ratio

        if num_values > 1:
            LOG.warning(_("%(num_values)d ratio values found, "
                          "of which the minimum value will be used."),
                         {'num_values': num_values})

        try:
            ratio = min(map(float, aggregate_vals))
        except ValueError as e:
            LOG.warning(_("Could not decode cpu_allocation_ratio: '%s'"), e)
            ratio = CONF.cpu_allocation_ratio

        return ratio
Example #21
0
    def call_plugin_serialized_with_retry(self, plugin, fn, num_retries,
                                          callback, *args, **kwargs):
        """Allows a plugin to raise RetryableError so we can try again."""
        attempts = num_retries + 1
        sleep_time = 0.5
        for attempt in xrange(1, attempts + 1):
            LOG.info(_('%(plugin)s.%(fn)s attempt %(attempt)d/%(attempts)d'),
                     {'plugin': plugin, 'fn': fn, 'attempt': attempt,
                      'attempts': attempts})
            try:
                if attempt > 1:
                    time.sleep(sleep_time)
                    sleep_time = min(2 * sleep_time, 15)

                if callback:
                    callback(kwargs)

                return self.call_plugin_serialized(plugin, fn, *args, **kwargs)
            except self.XenAPI.Failure as exc:
                if self._is_retryable_exception(exc):
                    LOG.warn(_('%(plugin)s.%(fn)s failed. Retrying call.')
                             % {'plugin': plugin, 'fn': fn})
                else:
                    raise

        raise exception.PluginRetriesExceeded(num_retries=num_retries)
Example #22
0
 def __init__(self, virtapi, read_only=False, scheme="https"):
     super(VMwareVCDriver, self).__init__(virtapi)
     self._cluster_name = CONF.vmware.cluster_name
     if not self._cluster_name:
         self._cluster = None
     else:
         self._cluster = vm_util.get_cluster_ref_from_name(
                         self._session, self._cluster_name)
         if self._cluster is None:
             raise exception.NotFound(_("VMware Cluster %s is not found")
                                        % self._cluster_name)
     self._datastore_regex = None
     if CONF.vmware.datastore_regex:
         try:
             self._datastore_regex = re.compile(CONF.vmware.datastore_regex)
         except re.error:
             raise exception.InvalidInput(reason=
             _("Invalid Regular Expression %s")
             % CONF.vmware.datastore_regex)
     self._volumeops = volumeops.VMwareVolumeOps(self._session,
                                                 self._cluster)
     self._vmops = vmops.VMwareVMOps(self._session, self.virtapi,
                                     self._volumeops, self._cluster,
                                     self._datastore_regex)
     self._vc_state = None
Example #23
0
    def _detach_volume_iscsi(self, connection_info, instance, mountpoint):
        """Detach volume storage to VM instance."""
        instance_name = instance['name']
        vm_ref = vm_util.get_vm_ref(self._session, instance)
        # Detach Volume from VM
        LOG.debug(_("Detach_volume: %(instance_name)s, %(mountpoint)s"),
                  {'mountpoint': mountpoint, 'instance_name': instance_name})
        data = connection_info['data']

        # Discover iSCSI Target
        device_name, uuid = volume_util.find_st(self._session, data,
                                                self._cluster)
        if device_name is None:
            raise volume_util.StorageError(_("Unable to find iSCSI Target"))

        # Get the vmdk file name that the VM is pointing to
        hardware_devices = self._session._call_method(vim_util,
                        "get_dynamic_property", vm_ref,
                        "VirtualMachine", "config.hardware.device")
        device = vm_util.get_rdm_disk(hardware_devices, uuid)
        if device is None:
            raise volume_util.StorageError(_("Unable to find volume"))
        self.detach_disk_from_vm(vm_ref, instance, device, destroy_disk=True)
        LOG.info(_("Mountpoint %(mountpoint)s detached from "
                   "instance %(instance_name)s"),
                 {'mountpoint': mountpoint, 'instance_name': instance_name})
Example #24
0
 def discover_st(self, data):
     """Discover iSCSI targets."""
     target_portal = data['target_portal']
     target_iqn = data['target_iqn']
     LOG.debug(_("Discovering iSCSI target %(target_iqn)s from "
                 "%(target_portal)s."),
               {'target_iqn': target_iqn, 'target_portal': target_portal})
     device_name, uuid = volume_util.find_st(self._session, data,
                                             self._cluster)
     if device_name:
         LOG.debug(_("Storage target found. No need to discover"))
         return (device_name, uuid)
     # Rescan iSCSI HBA
     volume_util.rescan_iscsi_hba(self._session, self._cluster)
     # Find iSCSI Target again
     device_name, uuid = volume_util.find_st(self._session, data,
                                             self._cluster)
     if device_name:
         LOG.debug(_("Discovered iSCSI target %(target_iqn)s from "
                     "%(target_portal)s."),
                   {'target_iqn': target_iqn,
                    'target_portal': target_portal})
     else:
         LOG.debug(_("Unable to discovered iSCSI target %(target_iqn)s "
                     "from %(target_portal)s."),
                   {'target_iqn': target_iqn,
                    'target_portal': target_portal})
     return (device_name, uuid)
Example #25
0
    def _attach_volume_iscsi(self, connection_info, instance, mountpoint):
        """Attach iscsi volume storage to VM instance."""
        instance_name = instance['name']
        vm_ref = vm_util.get_vm_ref(self._session, instance)
        # Attach Volume to VM
        LOG.debug(_("Attach_volume: %(connection_info)s, %(instance_name)s, "
                    "%(mountpoint)s"),
                  {'connection_info': connection_info,
                   'instance_name': instance_name,
                   'mountpoint': mountpoint})

        data = connection_info['data']

        # Discover iSCSI Target
        device_name, uuid = self.discover_st(data)
        if device_name is None:
            raise volume_util.StorageError(_("Unable to find iSCSI Target"))

        # Get the vmdk file name that the VM is pointing to
        hardware_devices = self._session._call_method(vim_util,
                        "get_dynamic_property", vm_ref,
                        "VirtualMachine", "config.hardware.device")
        (vmdk_file_path, adapter_type,
         disk_type) = vm_util.get_vmdk_path_and_adapter_type(hardware_devices)

        self.attach_disk_to_vm(vm_ref, instance,
                               adapter_type, 'rdmp',
                               device_name=device_name)
        LOG.info(_("Mountpoint %(mountpoint)s attached to "
                   "instance %(instance_name)s"),
                 {'mountpoint': mountpoint, 'instance_name': instance_name})
Example #26
0
    def __init__(self, virtapi, read_only=False, scheme="https"):
        super(VMwareVCDriver, self).__init__(virtapi)

        # Get the list of clusters to be used
        self._cluster_names = CONF.vmware.cluster_name
        self.dict_mors = vm_util.get_all_cluster_refs_by_name(self._session,
                                          self._cluster_names)
        if not self.dict_mors:
            raise exception.NotFound(_("All clusters specified %s were not"
                                       " found in the vCenter")
                                     % self._cluster_names)

        # Check if there are any clusters that were specified in the nova.conf
        # but are not in the vCenter, for missing clusters log a warning.
        clusters_found = [v.get('name') for k, v in self.dict_mors.iteritems()]
        missing_clusters = set(self._cluster_names) - set(clusters_found)
        if missing_clusters:
            LOG.warn(_("The following clusters could not be found in the"
                " vCenter %s") % list(missing_clusters))

        # The _resources is used to maintain the vmops, volumeops and vcstate
        # objects per cluster
        self._resources = {}
        self._resource_keys = set()
        self._virtapi = virtapi
        self._update_resources()

        # The following initialization is necessary since the base class does
        # not use VC state.
        first_cluster = self._resources.keys()[0]
        self._vmops = self._resources.get(first_cluster).get('vmops')
        self._volumeops = self._resources.get(first_cluster).get('volumeops')
        self._vc_state = self._resources.get(first_cluster).get('vcstate')
Example #27
0
 def _poll_task(self, task_ref, done):
     """Poll the given task, and fires the given Deferred if we
     get a result.
     """
     try:
         task_info = self._call_method(vim_util, "get_dynamic_property",
                         task_ref, "Task", "info")
         task_name = task_info.name
         if task_info.state in ['queued', 'running']:
             return
         elif task_info.state == 'success':
             LOG.debug("Task [%(task_name)s] %(task_ref)s "
                       "status: success",
                       {'task_name': task_name, 'task_ref': task_ref})
             done.send(task_info)
         else:
             error_info = str(task_info.error.localizedMessage)
             LOG.warn(_("Task [%(task_name)s] %(task_ref)s "
                       "status: error %(error_info)s"),
                      {'task_name': task_name, 'task_ref': task_ref,
                       'error_info': error_info})
             # Check if we can raise a specific exception
             error = task_info.error
             name = error.fault.__class__.__name__
             task_ex = error_util.get_fault_class(name)(error_info)
             done.send_exception(task_ex)
     except Exception as excep:
         LOG.warn(_("In vmwareapi:_poll_task, Got this error %s") % excep)
         done.send_exception(excep)
    def destroy(self, context, instance, network_info, block_device_info=None):
        context = nova_context.get_admin_context()

        try:
            node = _get_baremetal_node_by_instance_uuid(instance['uuid'])
        except exception.InstanceNotFound:
            LOG.warning(_("Destroy called on non-existing instance %s")
                    % instance['uuid'])
            return

        try:
            self.driver.deactivate_node(context, node, instance)
            self.power_off(instance, node)
            self.driver.deactivate_bootloader(context, node, instance)
            self.driver.destroy_images(context, node, instance)

            self._detach_block_devices(instance, block_device_info)
            self._stop_firewall(instance, network_info)
            self._unplug_vifs(instance, network_info)

            _update_state(context, node, None, baremetal_states.DELETED)
        except Exception as e:
            with excutils.save_and_reraise_exception():
                try:
                    LOG.error(_("Error from baremetal driver "
                                "during destroy: %s") % e)
                    _update_state(context, node, instance,
                                  baremetal_states.ERROR)
                except Exception:
                    LOG.error(_("Error while recording destroy failure in "
                                "baremetal database: %s") % e)
Example #29
0
    def __init__(self, virtapi, read_only=False, scheme="https"):
        super(VMwareESXDriver, self).__init__(virtapi)

        self._do_deprecation_warning()

        self._host_ip = CONF.vmware.host_ip
        if not (self._host_ip or CONF.vmware.host_username is None or
                        CONF.vmware.host_password is None):
            raise Exception(_("Must specify host_ip, "
                              "host_username "
                              "and host_password to use "
                              "compute_driver=vmwareapi.VMwareESXDriver or "
                              "vmwareapi.VMwareVCDriver"))

        self._datastore_regex = None
        if CONF.vmware.datastore_regex:
            try:
                self._datastore_regex = re.compile(CONF.vmware.datastore_regex)
            except re.error:
                raise exception.InvalidInput(reason=
                    _("Invalid Regular Expression %s")
                    % CONF.vmware.datastore_regex)

        self._session = VMwareAPISession(scheme=scheme)
        self._volumeops = volumeops.VMwareVolumeOps(self._session)
        self._vmops = vmops.VMwareVMOps(self._session, self.virtapi,
                                        self._volumeops,
                                        datastore_regex=self._datastore_regex)
        self._host = host.Host(self._session)
        self._host_state = None

        #TODO(hartsocks): back-off into a configuration test module.
        if CONF.vmware.use_linked_clone is None:
            raise error_util.UseLinkedCloneConfigurationFault()
Example #30
0
 def _poll_task(self, instance_uuid, task_ref, done):
     """
     Poll the given task, and fires the given Deferred if we
     get a result.
     """
     try:
         task_info = self._call_method(vim_util, "get_dynamic_property",
                         task_ref, "Task", "info")
         task_name = task_info.name
         if task_info.state in ['queued', 'running']:
             return
         elif task_info.state == 'success':
             LOG.debug(_("Task [%(task_name)s] %(task_ref)s "
                         "status: success"),
                       {'task_name': task_name, 'task_ref': task_ref})
             done.send("success")
         else:
             error_info = str(task_info.error.localizedMessage)
             LOG.warn(_("Task [%(task_name)s] %(task_ref)s "
                       "status: error %(error_info)s"),
                      {'task_name': task_name, 'task_ref': task_ref,
                       'error_info': error_info})
             done.send_exception(exception.NovaException(error_info))
     except Exception as excep:
         LOG.warn(_("In vmwareapi:_poll_task, Got this error %s") % excep)
         done.send_exception(excep)
Example #31
0
class FixedIpAlreadyInUse(NovaException):
    msg_fmt = _("Fixed IP address %(address)s is already in use on instance "
                "%(instance_uuid)s.")
Example #32
0
class FloatingIpNotFound(NotFound):
    ec2_code = "UnsupportedOperation"
    msg_fmt = _("Floating ip not found for id %(id)s.")
Example #33
0
class FloatingIpExists(NovaException):
    msg_fmt = _("Floating ip %(address)s already exists.")
Example #34
0
class NoFixedIpsDefined(NotFound):
    msg_fmt = _("Zero fixed ips could be found.")
Example #35
0
class NoMoreFixedIps(NovaException):
    ec2_code = 'UnsupportedOperation'
    msg_fmt = _("Zero fixed ips available.")
Example #36
0
class FixedIpInvalid(Invalid):
    msg_fmt = _("Fixed IP address %(address)s is invalid.")
Example #37
0
class FixedIpAssociatedWithMultipleInstances(NovaException):
    msg_fmt = _("More than one instance is associated with fixed ip address "
                "'%(address)s'.")
Example #38
0
class FixedIpNotFoundForSpecificInstance(FixedIpNotFound):
    msg_fmt = _("Instance %(instance_uuid)s doesn't have fixed ip '%(ip)s'.")
Example #39
0
class FixedIpNotFoundForInstance(FixedIpNotFound):
    msg_fmt = _("Instance %(instance_uuid)s has zero fixed ips.")
Example #40
0
class FixedIpNotFoundForNetwork(FixedIpNotFound):
    msg_fmt = _("Fixed IP address (%(address)s) does not exist in "
                "network (%(network_uuid)s).")
Example #41
0
class FixedIpNotFound(NotFound):
    msg_fmt = _("No fixed IP associated with id %(id)s.")
Example #42
0
class FixedIpNotFoundForNetworkHost(FixedIpNotFound):
    msg_fmt = _("Network host %(host)s has zero fixed ips "
                "in network %(network_id)s.")
Example #43
0
class PortNotFree(Invalid):
    msg_fmt = _("No free port available for instance %(instance)s.")
Example #44
0
class FixedIpNotFoundForAddress(FixedIpNotFound):
    msg_fmt = _("Fixed ip not found for address %(address)s.")
Example #45
0
class PortRequiresFixedIP(Invalid):
    msg_fmt = _("Port %(port_id)s requires a FixedIP in order to be used.")
Example #46
0
class FixedIpExists(NovaException):
    msg_fmt = _("Fixed ip %(address)s already exists.")
Example #47
0
class DatastoreNotFound(NotFound):
    msg_fmt = _("Could not find the datastore reference(s) which the VM uses.")
Example #48
0
class PortNotUsable(Invalid):
    msg_fmt = _("Port %(port_id)s not usable for instance %(instance)s.")
Example #49
0
class NetworkRequiresSubnet(Invalid):
    msg_fmt = _("Network %(network_uuid)s requires a subnet in order to boot"
                " instances on.")
Example #50
0
class PortInUse(Invalid):
    msg_fmt = _("Port %(port_id)s is still in use.")
Example #51
0
class NetworkNotFoundForProject(NotFound):
    msg_fmt = _("Either network uuid %(network_uuid)s is not present or "
                "is not assigned to the project %(project_id)s.")
Example #52
0
class ExternalNetworkAttachForbidden(NotAuthorized):
    msg_fmt = _("It is not allowed to create an interface on "
                "external network %(network_uuid)s")
Example #53
0
class NoNetworksFound(NotFound):
    msg_fmt = _("No networks defined.")
Example #54
0
class NetworkAmbiguous(Invalid):
    msg_fmt = _("More than one possible network found. Specify "
                "network ID(s) to select which one(s) to connect to,")
Example #55
0
class NetworkNotFoundForCidr(NetworkNotFound):
    msg_fmt = _("Network could not be found with cidr %(cidr)s.")
Example #56
0
class NoMoreNetworks(NovaException):
    msg_fmt = _("No more available networks.")
Example #57
0
class NetworkNotFoundForBridge(NetworkNotFound):
    msg_fmt = _("Network could not be found for bridge %(bridge)s")
Example #58
0
class NetworkNotFoundForInstance(NetworkNotFound):
    msg_fmt = _("Network could not be found for instance %(instance_id)s.")
Example #59
0
class PortNotFound(NotFound):
    msg_fmt = _("Port id %(port_id)s could not be found.")
Example #60
0
class NetworkNotFoundForUUID(NetworkNotFound):
    msg_fmt = _("Network could not be found for uuid %(uuid)s")