Example #1
0
    def consume_in_thread(self):
        """Runs the ZmqProxy service."""
        ipc_dir = CONF.rpc_zmq_ipc_dir
        consume_in = "tcp://%s:%s" % \
            (CONF.rpc_zmq_bind_address,
             CONF.rpc_zmq_port)
        consumption_proxy = InternalContext(None)

        try:
            os.makedirs(ipc_dir)
        except os.error:
            if not os.path.isdir(ipc_dir):
                with excutils.save_and_reraise_exception():
                    LOG.error(_LE("Required IPC directory does not exist at"
                                  " %s") % (ipc_dir, ))
        try:
            self.register(consumption_proxy,
                          consume_in,
                          zmq.PULL)
        except zmq.ZMQError:
            if os.access(ipc_dir, os.X_OK):
                with excutils.save_and_reraise_exception():
                    LOG.error(_LE("Permission denied to IPC directory at"
                                  " %s") % (ipc_dir, ))
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Could not create ZeroMQ receiver daemon. "
                              "Socket may already be in use."))

        super(ZmqProxy, self).consume_in_thread()
Example #2
0
    def consume_in_thread(self):
        """Runs the ZmqProxy service"""
        ipc_dir = CONF.rpc_zmq_ipc_dir
        consume_in = "tcp://%s:%s" % \
            (CONF.rpc_zmq_bind_address,
             CONF.rpc_zmq_port)
        consumption_proxy = InternalContext(None)

        if not os.path.isdir(ipc_dir):
            try:
                utils.execute('mkdir', '-p', ipc_dir, run_as_root=True)
                utils.execute('chown', "%s:%s" % (os.getuid(), os.getgid()),
                              ipc_dir, run_as_root=True)
                utils.execute('chmod', '750', ipc_dir, run_as_root=True)
            except utils.ProcessExecutionError:
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Could not create IPC directory %s") %
                              (ipc_dir, ))

        try:
            self.register(consumption_proxy,
                          consume_in,
                          zmq.PULL,
                          out_bind=True)
        except zmq.ZMQError:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Could not create ZeroMQ receiver daemon. "
                            "Socket may already be in use."))

        super(ZmqProxy, self).consume_in_thread()
Example #3
0
    def create_share(self, context, share_id, request_spec=None,
                     filter_properties=None, snapshot_id=None):
        """Creates a share."""
        context = context.elevated()
        if filter_properties is None:
            filter_properties = {}

        share_ref = self.db.share_get(context, share_id)
        if snapshot_id is not None:
            snapshot_ref = self.db.share_snapshot_get(context, snapshot_id)
        else:
            snapshot_ref = None

        share_network_id = share_ref.get('share_network_id', None)
        if share_network_id:
            try:
                share_server = self._share_server_get_or_create(
                    context, share_network_id)
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Failed to get share server"
                                " for share creation."))
                    self.db.share_update(context, share_id,
                                         {'status': 'error'})

            share_ref = self.db.share_update(
                context, share_id, {'share_server_id': share_server['id']})
            LOG.debug("Using share server %s" % share_server['id'])
        else:
            share_server = None

        try:
            if snapshot_ref:
                export_location = self.driver.create_share_from_snapshot(
                    context, share_ref, snapshot_ref)
            else:
                export_location = self.driver.create_share(
                    context, share_ref, share_server=share_server)
            self.db.share_update(context, share_id,
                                 {'export_location': export_location})
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Share %s failed on creation.") % share_id)
                self.db.share_update(context, share_id, {'status': 'error'})
        else:
            LOG.info(_("Share created successfully."))
            self.db.share_update(context, share_id,
                                 {'status': 'available',
                                  'launched_at': timeutils.utcnow()})
Example #4
0
    def _vserver_create_if_not_exists(self, network_info):
        """Creates vserver if not exists with given parameters."""
        vserver_name = self.configuration.netapp_vserver_name_template % \
                       network_info['server_id']
        vserver_client = driver.NetAppApiClient(
            self.api_version,
            vserver=vserver_name,
            configuration=self.configuration)
        if not self._vserver_exists(vserver_name):
            LOG.debug('Vserver %s does not exist, creating' % vserver_name)
            self._create_vserver(vserver_name)
        nodes = self._get_cluster_nodes()

        node_network_info = zip(nodes, network_info['network_allocations'])
        netmask = utils.cidr_to_netmask(network_info['cidr'])
        try:
            for node, net_info in node_network_info:
                port = self._get_node_data_port(node)
                ip = net_info['ip_address']
                self._create_lif_if_not_exists(vserver_name, net_info['id'],
                                               network_info['segmentation_id'],
                                               node, port, ip, netmask,
                                               vserver_client)
        except naapi.NaApiError:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Failed to create network interface"))
                self._delete_vserver(vserver_name, vserver_client)

        self._enable_nfs(vserver_client)

        security_services = network_info.get('security_services')
        if security_services:
            self._setup_security_services(security_services, vserver_client,
                                          vserver_name)
        return vserver_name
Example #5
0
        def _teardown_server():
            # NOTE(vponomaryov): Verify that there are no dependent shares.
            # Without this verification we can get here exception in next case:
            # share-server-delete API was called after share creation scheduled
            # and share_server reached ACTIVE status, but before update
            # of share_server_id field for share. If so, after lock realese
            # this method starts executing when amount of dependent shares
            # has been changed.
            shares = self.db.share_get_all_by_share_server(
                context, share_server['id'])
            if shares:
                raise exception.ShareServerInUse(
                    share_server_id=share_server['id'])

            self.db.share_server_update(context, share_server['id'],
                                        {'status': constants.STATUS_DELETING})
            sec_services = self.db.share_network_get(
                context,
                share_server['share_network_id'])['security_services']
            try:
                LOG.debug("Deleting share server")
                self.driver.teardown_server(share_server['backend_details'],
                                            security_services=sec_services)
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Share server %s failed on deletion.")
                              % share_server['id'])
                    self.db.share_server_update(
                        context, share_server['id'],
                        {'status': constants.STATUS_ERROR})
            else:
                self.db.share_server_delete(context, share_server['id'])
Example #6
0
        def _teardown_server():
            # NOTE(vponomaryov): Verify that there are no dependent shares.
            # Without this verification we can get here exception in next case:
            # share-server-delete API was called after share creation scheduled
            # and share_server reached ACTIVE status, but before update
            # of share_server_id field for share. If so, after lock realese
            # this method starts executing when amount of dependent shares
            # has been changed.
            shares = self.db.share_get_all_by_share_server(
                context, share_server['id'])
            if shares:
                raise exception.ShareServerInUse(
                    share_server_id=share_server['id'])

            self.db.share_server_update(context, share_server['id'],
                                        {'status': constants.STATUS_DELETING})
            sec_services = self.db.share_network_get(
                context, share_server['share_network_id'])['security_services']
            try:
                LOG.debug("Deleting share server")
                self.driver.teardown_server(share_server['backend_details'],
                                            security_services=sec_services)
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Share server %s failed on deletion."),
                              share_server['id'])
                    self.db.share_server_update(
                        context, share_server['id'],
                        {'status': constants.STATUS_ERROR})
            else:
                self.db.share_server_delete(context, share_server['id'])
Example #7
0
    def delete_snapshot(self, context, snapshot_id):
        """Delete share snapshot."""
        context = context.elevated()
        snapshot_ref = self.db.share_snapshot_get(context, snapshot_id)

        if context.project_id != snapshot_ref['project_id']:
            project_id = snapshot_ref['project_id']
        else:
            project_id = context.project_id

        try:
            self.driver.delete_snapshot(context, snapshot_ref)
        except exception.ShareSnapshotIsBusy:
            self.db.share_snapshot_update(context, snapshot_ref['id'],
                                          {'status': 'available'})
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_snapshot_update(context, snapshot_ref['id'],
                                              {'status': 'error_deleting'})
        else:
            self.db.share_snapshot_destroy(context, snapshot_id)
            try:
                reservations = QUOTAS.reserve(context,
                                              project_id=project_id,
                                              snapshots=-1,
                                              gigabytes=-snapshot_ref['size'])
            except Exception:
                reservations = None
                LOG.exception(_("Failed to update usages deleting snapshot"))

            if reservations:
                QUOTAS.commit(context, reservations, project_id=project_id)
Example #8
0
    def _setup_server(self, context, share_network, metadata=None):
        share_server_val = {
            'host': self.host,
            'share_network_id': share_network['id'],
            'status': constants.STATUS_CREATING
        }
        share_server = self.db.share_server_create(context,
                                                   share_server_val)

        try:
            allocation_number = self.driver.get_network_allocations_number()
            if allocation_number:
                self.network_api.allocate_network(
                    context, share_server, share_network,
                    count=allocation_number)

            share_network = self.db.share_network_get(context,
                                                      share_network['id'])
            network_info = self._form_network_info(context, share_server,
                                                   share_network)
            server_info = self.driver.setup_network(network_info,
                                                    metadata=metadata)
            if server_info and isinstance(server_info, dict):
                self.db.share_server_backend_details_set(context,
                                                         share_server['id'],
                                                         server_info)
            return self.db.share_server_update(
                context, share_server['id'],
                {'status': constants.STATUS_ACTIVE})
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_server_update(context, share_server['id'],
                    {'status': constants.STATUS_ERROR})
                self.network_api.deallocate_network(context, share_network)
Example #9
0
    def _setup_server(self, context, share_server, metadata=None):
        share_network = self.db.share_network_get(
            context, share_server['share_network_id'])
        try:
            allocation_number = self.driver.get_network_allocations_number()
            if allocation_number:
                self.network_api.allocate_network(context,
                                                  share_server,
                                                  share_network,
                                                  count=allocation_number)
                # If we reach here, then share_network was updated
                share_network = self.db.share_network_get(
                    context, share_server['share_network_id'])

            network_info = self._form_server_setup_info(
                context, share_server, share_network)
            server_info = self.driver.setup_server(network_info,
                                                   metadata=metadata)
            if server_info and isinstance(server_info, dict):
                self.db.share_server_backend_details_set(
                    context, share_server['id'], server_info)
            return self.db.share_server_update(
                context, share_server['id'],
                {'status': constants.STATUS_ACTIVE})
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_server_update(context, share_server['id'],
                                            {'status': constants.STATUS_ERROR})
                self.network_api.deallocate_network(context, share_network)
Example #10
0
    def delete_share(self, context, share_id):
        """Delete a share."""
        context = context.elevated()
        share_ref = self.db.share_get(context, share_id)

        if context.project_id != share_ref['project_id']:
            project_id = share_ref['project_id']
        else:
            project_id = context.project_id
        rules = self.db.share_access_get_all_for_share(context, share_id)
        try:
            for access_ref in rules:
                self._deny_access(context, access_ref, share_ref)
            self.driver.delete_share(context, share_ref)
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_update(context, share_id,
                                     {'status': 'error_deleting'})
        try:
            reservations = QUOTAS.reserve(context,
                                          project_id=project_id,
                                          shares=-1,
                                          gigabytes=-share_ref['size'])
        except Exception:
            reservations = None
            LOG.exception(_("Failed to update usages deleting share"))

        self.db.share_delete(context, share_id)
        LOG.info(_("share %s: deleted successfully"), share_ref['name'])

        if reservations:
            QUOTAS.commit(context, reservations, project_id=project_id)
Example #11
0
    def create_share(self, context, share_id, request_spec=None,
                     filter_properties=None, snapshot_id=None):
        """Creates a share."""
        context = context.elevated()
        if filter_properties is None:
            filter_properties = {}

        share_ref = self.db.share_get(context, share_id)
        if snapshot_id is not None:
            snapshot_ref = self.db.share_snapshot_get(context, snapshot_id)
        else:
            snapshot_ref = None

        try:
            if snapshot_ref:
                self.driver.allocate_container_from_snapshot(context,
                                                             share_ref,
                                                             snapshot_ref)
            else:
                self.driver.allocate_container(context, share_ref)
            export_location = self.driver.create_share(context, share_ref)
            self.db.share_update(context, share_id,
                                 {'export_location': export_location})
            self.driver.create_export(context, share_ref)
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_update(context, share_id, {'status': 'error'})
        else:
            self.db.share_update(context, share_id,
                                 {'status': 'available',
                                  'launched_at': timeutils.utcnow()})
Example #12
0
    def create_snapshot(self, context, share_id, snapshot_id):
        """Create snapshot for share."""
        snapshot_ref = self.db.share_snapshot_get(context, snapshot_id)
        share_server = self._get_share_server(context,
                                              snapshot_ref['share'])
        try:
            model_update = self.driver.create_snapshot(
                context, snapshot_ref, share_server=share_server)

            if model_update:
                model_dict = model_update.to_dict()
                self.db.share_snapshot_update(context, snapshot_ref['id'],
                                              model_dict)

        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_snapshot_update(context,
                                              snapshot_ref['id'],
                                              {'status': 'error'})

        self.db.share_snapshot_update(context,
                                      snapshot_ref['id'],
                                      {'status': 'available',
                                       'progress': '100%'})
        return snapshot_id
Example #13
0
    def _vserver_create_if_not_exists(self, network_info):
        """Creates vserver if not exists with given parameters."""
        vserver_name = (self.configuration.netapp_vserver_name_template %
                        network_info['server_id'])
        vserver_client = NetAppApiClient(
            self.api_version, vserver=vserver_name,
            configuration=self.configuration)
        if not self._vserver_exists(vserver_name):
            LOG.debug('Vserver %s does not exist, creating' % vserver_name)
            self._create_vserver(vserver_name)
        nodes = self._get_cluster_nodes()

        node_network_info = zip(nodes, network_info['network_allocations'])
        netmask = utils.cidr_to_netmask(network_info['cidr'])
        try:
            for node, net_info in node_network_info:
                port = self._get_node_data_port(node)
                ip = net_info['ip_address']
                self._create_lif_if_not_exists(
                    vserver_name, net_info['id'],
                    network_info['segmentation_id'], node, port,
                    ip, netmask, vserver_client)
        except naapi.NaApiError:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Failed to create network interface"))
                self._delete_vserver(vserver_name, vserver_client)

        self._enable_nfs(vserver_client)

        security_services = network_info.get('security_services')
        if security_services:
            self._setup_security_services(security_services, vserver_client,
                                          vserver_name)
        return vserver_name
Example #14
0
 def create_share(self, context, topic, share_id, snapshot_id=None, request_spec=None, filter_properties=None):
     try:
         self.driver.schedule_create_share(context, request_spec, filter_properties)
     except exception.NoValidHost as ex:
         self._set_share_error_state_and_notify("create_share", context, ex, request_spec)
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             self._set_share_error_state_and_notify("create_share", context, ex, request_spec)
Example #15
0
def remove_path_on_error(path):
    """Protect code that wants to operate on PATH atomically.
    Any exception will cause PATH to be removed.
    """
    try:
        yield
    except Exception:
        with excutils.save_and_reraise_exception():
            delete_if_exists(path)
Example #16
0
 def _deny_access(self, context, access_ref, share_ref):
     access_id = access_ref['id']
     try:
         self.driver.deny_access(context, share_ref, access_ref)
     except Exception:
         with excutils.save_and_reraise_exception():
             self.db.share_access_update(
                 context, access_id, {'state': access_ref.STATE_ERROR})
     self.db.share_access_delete(context, access_id)
Example #17
0
def logging_error(message):
    """Catches exception, write message to the log, re-raise.
    This is a common refinement of save_and_reraise that writes a specific
    message to the log.
    """
    try:
        yield
    except Exception as error:
        with excutils.save_and_reraise_exception():
            LOG.exception(message)
Example #18
0
    def rollback_and_reraise(self, msg=None, **kwargs):
        """Rollback a series of actions then re-raise the exception.

        .. note:: (sirp) This should only be called within an
                  exception handler.
        """
        with excutils.save_and_reraise_exception():
            if msg:
                LOG.exception(msg, **kwargs)

            self._rollback()
Example #19
0
def _serialize(data):
    """
    Serialization wrapper
    We prefer using JSON, but it cannot encode all types.
    Error if a developer passes us bad data.
    """
    try:
        return jsonutils.dumps(data, ensure_ascii=True)
    except TypeError:
        with excutils.save_and_reraise_exception():
            LOG.error(_("JSON serialization failed."))
Example #20
0
    def rollback_and_reraise(self, msg=None, **kwargs):
        """Rollback a series of actions then re-raise the exception.

        .. note:: (sirp) This should only be called within an
                  exception handler.
        """
        with excutils.save_and_reraise_exception():
            if msg:
                LOG.exception(msg, **kwargs)

            self._rollback()
Example #21
0
 def _deactivate_network(self, context, share_network):
     self.db.share_network_update(context, share_network['id'],
         {'status': constants.STATUS_DEACTIVATING})
     try:
         self.driver.teardown_network(share_network)
     except Exception as e:
         with excutils.save_and_reraise_exception():
             self.db.share_network_update(context, share_network['id'],
                 {'status': constants.STATUS_ERROR})
     else:
         self.db.share_network_update(context, share_network['id'],
             {'status': constants.STATUS_INACTIVE})
Example #22
0
 def _deny_access(self, context, access_ref, share_ref, share_server):
     access_id = access_ref['id']
     try:
         self.driver.deny_access(context,
                                 share_ref,
                                 access_ref,
                                 share_server=share_server)
     except Exception:
         with excutils.save_and_reraise_exception():
             self.db.share_access_update(context, access_id,
                                         {'state': access_ref.STATE_ERROR})
     self.db.share_access_delete(context, access_id)
Example #23
0
def remove_path_on_error(path, remove=delete_if_exists):
    """Protect code that wants to operate on PATH atomically.
    Any exception will cause PATH to be removed.

    :param path: File to work with
    :param remove: Optional function to remove passed path
    """

    try:
        yield
    except Exception:
        with excutils.save_and_reraise_exception():
            remove(path)
Example #24
0
 def create_share(self, context, topic, share_id, snapshot_id=None,
                  request_spec=None, filter_properties=None):
     try:
         self.driver.schedule_create_share(context, request_spec,
                                           filter_properties)
     except exception.NoValidHost as ex:
         self._set_share_error_state_and_notify('create_share',
                                                context, ex, request_spec)
     except Exception as ex:
         with excutils.save_and_reraise_exception():
             self._set_share_error_state_and_notify('create_share',
                                                    context, ex,
                                                    request_spec)
Example #25
0
 def allow_access(self, context, access_id):
     """Allow access to some share."""
     try:
         access_ref = self.db.share_access_get(context, access_id)
         share_ref = self.db.share_get(context, access_ref['share_id'])
         if access_ref['state'] == access_ref.STATE_NEW:
             self.driver.allow_access(context, share_ref, access_ref)
             self.db.share_access_update(
                 context, access_id, {'state': access_ref.STATE_ACTIVE})
     except Exception:
         with excutils.save_and_reraise_exception():
             self.db.share_access_update(
                 context, access_id, {'state': access_ref.STATE_ERROR})
Example #26
0
 def _activate_share_network(self, context, share_network, metadata=None):
     allocation_number = self.driver.get_network_allocations_number()
     if allocation_number:
         share_network = self.network_api.allocate_network(
                             context,
                             share_network,
                             count=allocation_number)
         try:
             self.driver.setup_network(share_network, metadata=metadata)
         except exception.ManilaException:
             with excutils.save_and_reraise_exception():
                 self.network_api.deallocate_network(context,
                                                     share_network)
         else:
             return share_network
Example #27
0
    def _vserver_create_if_not_exists(self, network_info):
        """Creates vserver if not exists with given parameters."""
        vserver_name = self._get_vserver_name(network_info['id'])
        vserver_client = driver.NetAppApiClient(
            self.api_version, vserver=vserver_name,
            configuration=self.configuration)
        args = {'query': {'vserver-info': {'vserver-name': vserver_name}}}

        LOG.debug(_('Checking if vserver is configured'))
        vserver_info = self._client.send_request('vserver-get-iter', args)
        if not int(vserver_info.get_child_content('num-records')):
            LOG.debug(_('Vserver %s does not exist, creating') % vserver_name)
            self._create_vserver(vserver_name)
        nodes = self._get_cluster_nodes()

        node_network_info = zip(nodes, network_info['network_allocations'])
        netmask = utils.cidr_to_netmask(network_info['cidr'])
        try:
            for node, net_info in node_network_info:
                port = self._get_node_data_port(node)
                ip = net_info['ip_address']
                self._create_lif_if_not_exists(
                    vserver_name, net_info['id'],
                    network_info['segmentation_id'], node, port,
                    ip, netmask, vserver_client)
        except naapi.NaApiError:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Failed to create network interface"))
                self._delete_vserver(vserver_name, vserver_client)

        self._enable_nfs(vserver_client)
        if network_info.get('security_services'):
            for security_service in network_info['security_services']:
                if security_service['type'].lower() == "ldap":
                    self._configure_ldap(security_service, vserver_client)
                elif security_service['type'].lower() == "active_directory":
                    self._configure_active_directory(security_service,
                                                     vserver_client)
                elif security_service['type'].lower() == "kerberos":
                    self._configure_kerberos(vserver_name, security_service,
                                             vserver_client)
                else:
                    raise exception.NetAppException(
                        _('Unsupported protocol %s for NetApp driver')
                        % security_service['type'])
        return vserver_name
Example #28
0
 def allow_access(self, context, access_id):
     """Allow access to some share."""
     try:
         access_ref = self.db.share_access_get(context, access_id)
         share_ref = self.db.share_get(context, access_ref['share_id'])
         share_server = self._get_share_server(context, share_ref)
         if access_ref['state'] == access_ref.STATE_NEW:
             self.driver.allow_access(context,
                                      share_ref,
                                      access_ref,
                                      share_server=share_server)
             self.db.share_access_update(context, access_id,
                                         {'state': access_ref.STATE_ACTIVE})
     except Exception:
         with excutils.save_and_reraise_exception():
             self.db.share_access_update(context, access_id,
                                         {'state': access_ref.STATE_ERROR})
Example #29
0
 def __iter__(self):
     """Return a result until we get a 'None' response from consumer"""
     if self._done:
         raise StopIteration
     while True:
         try:
             self._iterator.next()
         except Exception:
             with excutils.save_and_reraise_exception():
                 self.done()
         if self._got_ending:
             self.done()
             raise StopIteration
         result = self._result
         if isinstance(result, Exception):
             self.done()
             raise result
         yield result
Example #30
0
    def activate_network(self, context, share_network_id, metadata=None):
        share_network = self.db.share_network_get(context, share_network_id)
        if (hasattr(share_network, 'project_id') and
            context.project_id != share_network['project_id']):
            project_id = share_network['project_id']
        else:
            project_id = context.project_id

        reservations = None
        try:
            reservations = QUOTAS.reserve(context,
                                          project_id=project_id,
                                          share_networks=-1)
            self._activate_share_network(context, share_network, metadata)
        except Exception:
            with excutils.save_and_reraise_exception():
                if reservations:
                    QUOTAS.commit(context, reservations, project_id=project_id)
Example #31
0
 def create_export(self, server, share_name, recreate=False):
     """Create share at samba server."""
     share_path = os.path.join(self.configuration.share_mount_path,
                               share_name)
     create_cmd = [
         'sudo', 'net', 'conf', 'addshare', share_name, share_path,
         'writeable=y', 'guest_ok=y',
     ]
     try:
         self._ssh_exec(
             server, ['sudo', 'net', 'conf', 'showshare', share_name, ])
     except exception.ProcessExecutionError as parent_e:
         # Share does not exist, create it
         try:
             self._ssh_exec(server, create_cmd)
         except Exception:
             # If we get here, then it will be useful
             # to log parent exception too.
             with excutils.save_and_reraise_exception():
                 LOG.error(parent_e)
     else:
         # Share exists
         if recreate:
             self._ssh_exec(
                 server, ['sudo', 'net', 'conf', 'delshare', share_name, ])
             self._ssh_exec(server, create_cmd)
         else:
             msg = _('Share section %s already defined.') % share_name
             raise exception.ShareBackendException(msg=msg)
     parameters = {
         'browseable': 'yes',
         '\"create mask\"': '0755',
         '\"hosts deny\"': '0.0.0.0/0',  # deny all by default
         '\"hosts allow\"': '127.0.0.1',
         '\"read only\"': 'no',
     }
     set_of_commands = [':', ]  # : is just placeholder
     for param, value in parameters.items():
         # These are combined in one list to run in one process
         # instead of big chain of one action calls.
         set_of_commands.extend(['&&', 'sudo', 'net', 'conf', 'setparm',
                                 share_name, param, value])
     self._ssh_exec(server, set_of_commands)
     return '//%s/%s' % (server['public_address'], share_name)
Example #32
0
    def delete_share(self, context, share_id):
        """Delete a share."""
        context = context.elevated()
        share_ref = self.db.share_get(context, share_id)
        share_server = self._get_share_server(context, share_ref)

        if context.project_id != share_ref['project_id']:
            project_id = share_ref['project_id']
        else:
            project_id = context.project_id
        rules = self.db.share_access_get_all_for_share(context, share_id)
        try:
            for access_ref in rules:
                self._deny_access(context, access_ref, share_ref, share_server)
            self.driver.delete_share(context,
                                     share_ref,
                                     share_server=share_server)
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_update(context, share_id,
                                     {'status': 'error_deleting'})
        try:
            reservations = QUOTAS.reserve(context,
                                          project_id=project_id,
                                          shares=-1,
                                          gigabytes=-share_ref['size'])
        except Exception:
            reservations = None
            LOG.exception(_("Failed to update usages deleting share"))

        self.db.share_delete(context, share_id)
        LOG.info(_("Share %s: deleted successfully."), share_ref['name'])

        if reservations:
            QUOTAS.commit(context, reservations, project_id=project_id)

        if CONF.delete_share_server_with_last_share:
            share_server = self._get_share_server(context, share_ref)
            if share_server and not share_server.shares:
                LOG.debug("Scheduled deletion of share-server "
                          "with id '%s' automatically by "
                          "deletion of last share." % share_server['id'])
                self.delete_share_server(context, share_server)
Example #33
0
 def create_export(self, server, share_name, recreate=False):
     """Create share at samba server."""
     create_cmd = [
         'sudo', 'net', 'conf', 'addshare',
         share_name, self.configuration.share_mount_path,
         'writeable=y', 'guest_ok=y',
     ]
     try:
         self._ssh_exec(
             server, ['sudo', 'net', 'conf', 'showshare', share_name, ])
     except exception.ProcessExecutionError as parent_e:
         # Share does not exist, create it
         try:
             self._ssh_exec(server, create_cmd)
         except Exception:
             # If we get here, then it will be useful
             # to log parent exception too.
             with excutils.save_and_reraise_exception():
                 LOG.error(parent_e)
     else:
         # Share exists
         if recreate:
             self._ssh_exec(
                 server, ['sudo', 'net', 'conf', 'delshare', share_name, ])
             self._ssh_exec(server, create_cmd)
         else:
             msg = _('Share section %s already defined.') % share_name
             raise exception.ShareBackendException(msg=msg)
     parameters = {
         'browseable': 'yes',
         '\"create mask\"': '0755',
         '\"hosts deny\"': '0.0.0.0/0',  # deny all by default
         '\"hosts allow\"': '127.0.0.1',
         '\"read only\"': 'no',
     }
     set_of_commands = [':', ]  # : is just placeholder
     for param, value in parameters.items():
         # These are combined in one list to run in one process
         # instead of big chain of one action calls.
         set_of_commands.extend(['&&', 'sudo', 'net', 'conf', 'setparm',
                                 share_name, param, value])
     self._ssh_exec(server, set_of_commands)
     return '//%s/%s' % (server['public_address'], share_name)
Example #34
0
    def delete_share(self, context, share_id):
        """Delete a share."""
        context = context.elevated()
        share_ref = self.db.share_get(context, share_id)
        share_server = self._get_share_server(context, share_ref)

        if context.project_id != share_ref['project_id']:
            project_id = share_ref['project_id']
        else:
            project_id = context.project_id
        rules = self.db.share_access_get_all_for_share(context, share_id)
        try:
            for access_ref in rules:
                self._deny_access(context, access_ref, share_ref, share_server)
            self.driver.delete_share(context, share_ref,
                                     share_server=share_server)
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_update(context, share_id,
                                     {'status': 'error_deleting'})
        try:
            reservations = QUOTAS.reserve(context,
                                          project_id=project_id,
                                          shares=-1,
                                          gigabytes=-share_ref['size'])
        except Exception:
            reservations = None
            LOG.exception(_("Failed to update usages deleting share"))

        self.db.share_delete(context, share_id)
        LOG.info(_("Share %s: deleted successfully."), share_ref['name'])

        if reservations:
            QUOTAS.commit(context, reservations, project_id=project_id)

        if CONF.delete_share_server_with_last_share:
            share_server = self._get_share_server(context, share_ref)
            if share_server and not share_server.shares:
                LOG.debug("Scheduled deletion of share-server "
                          "with id '%s' automatically by "
                          "deletion of last share." % share_server['id'])
                self.delete_share_server(context, share_server)
Example #35
0
 def _activate_share_network(self, context, share_network, metadata=None):
     allocation_number = self.driver.get_network_allocations_number()
     if allocation_number:
         share_network = self.network_api.allocate_network(
                             context,
                             share_network,
                             count=allocation_number)
     try:
         self.db.share_network_update(context, share_network['id'],
             {'status': constants.STATUS_ACTIVATING})
         self.driver.setup_network(share_network, metadata=metadata)
         self.db.share_network_update(context, share_network['id'],
             {'status': constants.STATUS_ACTIVE})
     except exception.ManilaException:
         with excutils.save_and_reraise_exception():
             self.db.share_network_update(context, share_network['id'],
                 {'status': constants.STATUS_ERROR})
             self.network_api.deallocate_network(context, share_network)
     else:
         return share_network
Example #36
0
        def _teardown_server():
            share_network = self.db.share_network_get(
                context, share_server['share_network_id'])

            network_info = self._form_network_info(context, share_server,
                                                   share_network)

            self.db.share_server_update(context, share_server['id'],
                                        {'status': constants.STATUS_DELETING})
            try:
                LOG.debug("Deleting share server")
                self.driver.teardown_network(network_info)
            except Exception as e:
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Share server %s failed on deletion.")
                              % share_server['id'])
                    self.db.share_server_update(context, share_server['id'],
                        {'status': constants.STATUS_ERROR})
            else:
                self.db.share_server_delete(context, share_server['id'])
Example #37
0
    def create_share(self, context, share_id, request_spec=None,
                     filter_properties=None, snapshot_id=None):
        """Creates a share."""
        context = context.elevated()
        if filter_properties is None:
            filter_properties = {}

        share_ref = self.db.share_get(context, share_id)
        if snapshot_id is not None:
            snapshot_ref = self.db.share_snapshot_get(context, snapshot_id)
        else:
            snapshot_ref = None

        share_network_id = share_ref.get('share_network_id', None)
        if share_network_id:
            share_network = self.db.share_network_get(context,
                                                      share_network_id)
            if share_network['status'] == constants.STATUS_INACTIVE:
                share_network = self._activate_share_network(
                                    context,
                                    share_network)
        else:
            share_network = {}

        share_ref['network_info'] = share_network

        try:
            if snapshot_ref:
                export_location = self.driver.create_share_from_snapshot(
                    context, share_ref, snapshot_ref)
            else:
                export_location = self.driver.create_share(context, share_ref)
            self.db.share_update(context, share_id,
                                 {'export_location': export_location})
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_update(context, share_id, {'status': 'error'})
        else:
            self.db.share_update(context, share_id,
                                 {'status': 'available',
                                  'launched_at': timeutils.utcnow()})
Example #38
0
 def __iter__(self):
     """Return a result until we get a reply with an 'ending' flag."""
     if self._done:
         raise StopIteration
     while True:
         try:
             data = self._dataqueue.get(timeout=self._timeout)
             result = self._process_data(data)
         except queue.Empty:
             self.done()
             raise rpc_common.Timeout()
         except Exception:
             with excutils.save_and_reraise_exception():
                 self.done()
         if self._got_ending:
             self.done()
             raise StopIteration
         if isinstance(result, Exception):
             self.done()
             raise result
         yield result
Example #39
0
    def create_snapshot(self, context, share_id, snapshot_id):
        """Create snapshot for share."""
        snapshot_ref = self.db.share_snapshot_get(context, snapshot_id)

        try:
            snap_name = snapshot_ref['name']
            model_update = self.driver.create_snapshot(context, snapshot_ref)
            if model_update:
                self.db.share_snapshot_update(context, snapshot_ref['id'],
                                              model_update)

        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_snapshot_update(context,
                                              snapshot_ref['id'],
                                              {'status': 'error'})

        self.db.share_snapshot_update(context,
                                      snapshot_ref['id'],
                                      {'status': 'available',
                                       'progress': '100%'})
        return snapshot_id
Example #40
0
    def create_snapshot(self, context, share_id, snapshot_id):
        """Create snapshot for share."""
        snapshot_ref = self.db.share_snapshot_get(context, snapshot_id)
        share_server = self._get_share_server(context, snapshot_ref['share'])
        try:
            model_update = self.driver.create_snapshot(
                context, snapshot_ref, share_server=share_server)

            if model_update:
                model_dict = model_update.to_dict()
                self.db.share_snapshot_update(context, snapshot_ref['id'],
                                              model_dict)

        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_snapshot_update(context, snapshot_ref['id'],
                                              {'status': 'error'})

        self.db.share_snapshot_update(context, snapshot_ref['id'], {
            'status': 'available',
            'progress': '100%'
        })
        return snapshot_id
Example #41
0
    def delete_snapshot(self, context, snapshot_id):
        """Delete share snapshot."""
        context = context.elevated()
        snapshot_ref = self.db.share_snapshot_get(context, snapshot_id)

        share_server = self._get_share_server(context, snapshot_ref['share'])

        if context.project_id != snapshot_ref['project_id']:
            project_id = snapshot_ref['project_id']
        else:
            project_id = context.project_id

        try:
            self.driver.delete_snapshot(context,
                                        snapshot_ref,
                                        share_server=share_server)
        except exception.ShareSnapshotIsBusy:
            self.db.share_snapshot_update(context, snapshot_ref['id'],
                                          {'status': 'available'})
        except Exception:
            with excutils.save_and_reraise_exception():
                self.db.share_snapshot_update(context, snapshot_ref['id'],
                                              {'status': 'error_deleting'})
        else:
            self.db.share_snapshot_destroy(context, snapshot_id)
            try:
                reservations = QUOTAS.reserve(context,
                                              project_id=project_id,
                                              snapshots=-1,
                                              gigabytes=-snapshot_ref['size'])
            except Exception:
                reservations = None
                LOG.exception(_("Failed to update usages deleting snapshot"))

            if reservations:
                QUOTAS.commit(context, reservations, project_id=project_id)
Example #42
0
    def create(self,
               context,
               share_proto,
               size,
               name,
               description,
               snapshot=None,
               availability_zone=None,
               metadata=None,
               share_network_id=None,
               volume_type=None):
        """Create new share."""
        policy.check_policy(context, 'share', 'create')

        self._check_metadata_properties(context, metadata)

        if snapshot is not None:
            if snapshot['status'] != 'available':
                msg = _('status must be available')
                raise exception.InvalidShareSnapshot(reason=msg)
            if not size:
                size = snapshot['size']

            snapshot_id = snapshot['id']
        else:
            snapshot_id = None

        def as_int(s):
            try:
                return int(s)
            except (ValueError, TypeError):
                return s

        # tolerate size as stringified int
        size = as_int(size)

        if not isinstance(size, int) or size <= 0:
            msg = (_("Share size '%s' must be an integer and greater than 0") %
                   size)
            raise exception.InvalidInput(reason=msg)

        if snapshot and size < snapshot['size']:
            msg = (_("Share size '%s' must be equal or greater "
                     "than snapshot size") % size)
            raise exception.InvalidInput(reason=msg)

        if snapshot and volume_type:
            if volume_type['id'] != snapshot['volume_type_id']:
                msg = _("Invalid volume_type provided (requested type "
                        "must match source snapshot, or be omitted). "
                        "You should omit the argument.")
                raise exception.InvalidInput(reason=msg)

        # TODO(rushiagr): Find a suitable place to keep all the allowed
        #                 share types so that it becomes easier to add one
        if share_proto.lower() not in ['nfs', 'cifs']:
            msg = (_("Invalid share type provided: %s") % share_proto)
            raise exception.InvalidInput(reason=msg)

        try:
            reservations = QUOTAS.reserve(context, shares=1, gigabytes=size)
        except exception.OverQuota as e:
            overs = e.kwargs['overs']
            usages = e.kwargs['usages']
            quotas = e.kwargs['quotas']

            def _consumed(name):
                return (usages[name]['reserved'] + usages[name]['in_use'])

            if 'gigabytes' in overs:
                msg = _("Quota exceeded for %(s_pid)s, tried to create "
                        "%(s_size)sG share (%(d_consumed)dG of %(d_quota)dG "
                        "already consumed)")
                LOG.warn(
                    msg % {
                        's_pid': context.project_id,
                        's_size': size,
                        'd_consumed': _consumed('gigabytes'),
                        'd_quota': quotas['gigabytes']
                    })
                raise exception.ShareSizeExceedsAvailableQuota()
            elif 'shares' in overs:
                msg = _("Quota exceeded for %(s_pid)s, tried to create "
                        "share (%(d_consumed)d shares "
                        "already consumed)")
                LOG.warn(msg % {
                    's_pid': context.project_id,
                    'd_consumed': _consumed('shares')
                })
                raise exception.ShareLimitExceeded(allowed=quotas['shares'])

        if availability_zone is None:
            availability_zone = CONF.storage_availability_zone

        options = {
            'size': size,
            'user_id': context.user_id,
            'project_id': context.project_id,
            'snapshot_id': snapshot_id,
            'share_network_id': share_network_id,
            'availability_zone': availability_zone,
            'metadata': metadata,
            'status': "creating",
            'scheduled_at': timeutils.utcnow(),
            'display_name': name,
            'display_description': description,
            'share_proto': share_proto,
            'volume_type_id': volume_type['id'] if volume_type else None
        }

        try:
            share = self.db.share_create(context, options)
            QUOTAS.commit(context, reservations)
        except Exception:
            with excutils.save_and_reraise_exception():
                try:
                    self.db.share_delete(context, share['id'])
                finally:
                    QUOTAS.rollback(context, reservations)

        request_spec = {
            'share_properties': options,
            'share_proto': share_proto,
            'share_id': share['id'],
            'snapshot_id': share['snapshot_id'],
            'volume_type': volume_type
        }

        filter_properties = {}

        self.scheduler_rpcapi.create_share(context,
                                           CONF.share_topic,
                                           share['id'],
                                           snapshot_id,
                                           request_spec=request_spec,
                                           filter_properties=filter_properties)

        return share
Example #43
0
    def create_snapshot(self, context, share, name, description, force=False):
        policy.check_policy(context, 'share', 'create_snapshot', share)

        if ((not force) and (share['status'] != "available")):
            msg = _("must be available")
            raise exception.InvalidShare(reason=msg)

        size = share['size']

        try:
            reservations = QUOTAS.reserve(context, snapshots=1, gigabytes=size)
        except exception.OverQuota as e:
            overs = e.kwargs['overs']
            usages = e.kwargs['usages']
            quotas = e.kwargs['quotas']

            def _consumed(name):
                return (usages[name]['reserved'] + usages[name]['in_use'])

            if 'gigabytes' in overs:
                msg = _("Quota exceeded for %(s_pid)s, tried to create "
                        "%(s_size)sG snapshot (%(d_consumed)dG of "
                        "%(d_quota)dG already consumed)")
                LOG.warn(
                    msg % {
                        's_pid': context.project_id,
                        's_size': size,
                        'd_consumed': _consumed('gigabytes'),
                        'd_quota': quotas['gigabytes']
                    })
                raise exception.ShareSizeExceedsAvailableQuota()
            elif 'snapshots' in overs:
                msg = _("Quota exceeded for %(s_pid)s, tried to create "
                        "snapshot (%(d_consumed)d snapshots "
                        "already consumed)")
                LOG.warn(
                    msg % {
                        's_pid': context.project_id,
                        'd_consumed': _consumed('snapshots')
                    })
                raise exception.SnapshotLimitExceeded(
                    allowed=quotas['snapshots'])
        options = {
            'share_id': share['id'],
            'size': share['size'],
            'user_id': context.user_id,
            'project_id': context.project_id,
            'status': "creating",
            'progress': '0%',
            'share_size': share['size'],
            'display_name': name,
            'display_description': description,
            'share_proto': share['share_proto'],
            'export_location': share['export_location']
        }

        try:
            snapshot = self.db.share_snapshot_create(context, options)
            QUOTAS.commit(context, reservations)
        except Exception:
            with excutils.save_and_reraise_exception():
                try:
                    self.db.snapshot_delete(context, share['id'])
                finally:
                    QUOTAS.rollback(context, reservations)

        self.share_rpcapi.create_snapshot(context, share, snapshot)
        return snapshot
Example #44
0
    def setup_server(self, emc_share_driver, network_info, metadata=None):
        """Set up and configures share server with given network parameters."""
        # Only support single security service with type 'active_directory'
        interface_info = []
        vdm_name = 'vdm-' + network_info['server_id']
        vlan_id = network_info['segmentation_id']
        active_directory = None
        sec_services = []

        if network_info.get('security_services'):
            sec_services = network_info['security_services']
            is_valid, data = self._get_valid_security_service(sec_services)
            if is_valid:
                active_directory = data
            else:
                LOG.error(data)
                raise exception.EMCVnxXMLAPIError(err=data)

        try:
            # Refresh DataMover/VDM by the configuration
            moverRef = self.get_mover_ref_by_name(self._mover_name)
            if not self._vdm_exist(vdm_name):
                LOG.debug('Share Server %s not found. Creating', vdm_name)
                self._create_vdm(vdm_name, moverRef)

            status, vdmRef = self._XMLAPI_helper.get_vdm_by_name(vdm_name)
            if constants.STATUS_OK != status:
                message = (_('Could not get Share Server by name %(name)s. '
                             'Reason: %(err)s.') % {
                                 'name': vdm_name,
                                 'err': vdmRef
                             })
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

            netmask = utils.cidr_to_netmask(network_info['cidr'])

            allocated_interfaces = []
            device_port = self._get_device_port(moverRef)

            for net_info in network_info['network_allocations']:
                ip = net_info['ip_address']
                if_name = 'if-' + net_info['id'][-12:]
                if_info = {'ip': ip, 'if_name': if_name}
                interface_info.append(if_info)
                status, interface = self._XMLAPI_helper.create_mover_interface(
                    if_name, device_port['name'], ip, moverRef['id'], netmask,
                    vlan_id)

                if constants.STATUS_OK != status:
                    message = (_('Interface creation failed. Reason: %s.') %
                               interface)
                    LOG.error(message)
                    raise exception.EMCVnxXMLAPIError(err=message)
                allocated_interfaces.append(interface)

            if active_directory:
                self._configure_active_directory(active_directory, vdmRef,
                                                 allocated_interfaces[0])

            self._enable_nfs_service(vdmRef, allocated_interfaces[1])

            return {
                'share_server_name': vdm_name,
                'share_server_id': vdmRef['id'],
                'cifs_if': allocated_interfaces[0]['ip'],
                'nfs_if': allocated_interfaces[1]['ip'],
            }

        except Exception as ex:
            with excutils.save_and_reraise_exception():
                message = _('Could not setup server. Reason: %s.') % ex
                LOG.error(message)
                server_details = self._contruct_backend_details(
                    vdm_name, vdmRef, interface_info)
                self.teardown_server(None, server_details, sec_services)
Example #45
0
    def create_share(self,
                     context,
                     share_id,
                     request_spec=None,
                     filter_properties=None,
                     snapshot_id=None):
        """Creates a share."""
        context = context.elevated()
        if filter_properties is None:
            filter_properties = {}

        share_ref = self.db.share_get(context, share_id)
        if snapshot_id is not None:
            snapshot_ref = self.db.share_snapshot_get(context, snapshot_id)
            parent_share_server_id = snapshot_ref['share']['share_server_id']
        else:
            snapshot_ref = None
            parent_share_server_id = None

        share_network_id = share_ref.get('share_network_id', None)

        if parent_share_server_id:
            try:
                share_server = self.db.share_server_get(
                    context, parent_share_server_id)
                LOG.debug("Using share_server "
                          "%s for share %s" % (share_server['id'], share_id))
                share_ref = self.db.share_update(
                    context, share_id, {'share_server_id': share_server['id']})
            except exception.ShareServerNotFound:
                with excutils.save_and_reraise_exception():
                    LOG.error(_("Share server %s does not exist."),
                              parent_share_server_id)
                    self.db.share_update(context, share_id,
                                         {'status': 'error'})
        elif share_network_id:
            try:
                share_server, share_ref = self._provide_share_server_for_share(
                    context, share_network_id, share_id)
            except Exception:
                with excutils.save_and_reraise_exception():
                    LOG.error(
                        _("Failed to get share server"
                          " for share creation."))
                    self.db.share_update(context, share_id,
                                         {'status': 'error'})
        else:
            share_server = None

        try:
            if snapshot_ref:
                export_location = self.driver.create_share_from_snapshot(
                    context,
                    share_ref,
                    snapshot_ref,
                    share_server=share_server)
            else:
                export_location = self.driver.create_share(
                    context, share_ref, share_server=share_server)
            self.db.share_update(context, share_id,
                                 {'export_location': export_location})
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.error(_("Share %s failed on creation."), share_id)
                self.db.share_update(context, share_id, {'status': 'error'})
        else:
            LOG.info(_("Share created successfully."))
            self.db.share_update(context, share_id, {
                'status': 'available',
                'launched_at': timeutils.utcnow()
            })