コード例 #1
0
ファイル: san.py プロジェクト: stuartbyma/nova
    def _cliq_run_xml(self, verb, cliq_args, check_cliq_result=True):
        """Runs a CLIQ command over SSH, parsing and checking the output"""
        cliq_args['output'] = 'XML'
        (out, _err) = self._cliq_run(verb, cliq_args)

        LOG.debug(_("CLIQ command returned %s"), out)

        result_xml = etree.fromstring(out)
        if check_cliq_result:
            response_node = result_xml.find("response")
            if response_node is None:
                msg = (_("Malformed response to CLIQ command "
                         "%(verb)s %(cliq_args)s. Result=%(out)s") %
                       locals())
                raise exception.VolumeBackendAPIException(data=msg)

            result_code = response_node.attrib.get("result")

            if result_code != "0":
                msg = (_("Error running CLIQ command %(verb)s %(cliq_args)s. "
                         " Result=%(out)s") %
                       locals())
                raise exception.VolumeBackendAPIException(data=msg)

        return result_xml
コード例 #2
0
    def initialize_connection(self, volume, connector):
        try:
            xensm_properties = dict(
                self.db.sm_volume_get(self.ctxt, volume['id']))
        except Exception as ex:
            LOG.exception(ex)
            msg = _("Failed to find volume in db")
            raise exception.VolumeBackendAPIException(data=msg)

        # Keep the volume id key consistent with what ISCSI driver calls it
        xensm_properties['volume_id'] = xensm_properties['id']
        del xensm_properties['id']

        try:
            backend_conf = self.db.sm_backend_conf_get(
                self.ctxt, xensm_properties['backend_id'])
        except Exception as ex:
            LOG.exception(ex)
            msg = _("Failed to find backend in db")
            raise exception.VolumeBackendAPIException(data=msg)

        params = self._convert_config_params(backend_conf['config_params'])

        xensm_properties['flavor_id'] = backend_conf['flavor_id']
        xensm_properties['sr_uuid'] = backend_conf['sr_uuid']
        xensm_properties['sr_type'] = backend_conf['sr_type']
        xensm_properties.update(params)
        _introduce_sr_keys = self._get_introduce_sr_keys(params)
        xensm_properties['introduce_sr_keys'] = _introduce_sr_keys
        return {'driver_volume_type': 'xensm', 'data': xensm_properties}
コード例 #3
0
 def check_for_setup_error(self):
     """Returns an error if prerequisites aren't met"""
     (stdout, stderr) = self._execute('rados', 'lspools')
     pools = stdout.split("\n")
     if not FLAGS.rbd_pool in pools:
         exception_message = (_("rbd has no pool %s") % FLAGS.rbd_pool)
         raise exception.VolumeBackendAPIException(data=exception_message)
コード例 #4
0
ファイル: san.py プロジェクト: stuartbyma/nova
    def _get_luid(self, volume):
        zfs_poolname = self._build_zfs_poolname(volume)
        zvol_name = '/dev/zvol/rdsk/%s' % zfs_poolname

        (out, _err) = self._execute('/usr/sbin/sbdadm', 'list-lu')

        lines = _collect_lines(out)

        # Strip headers
        if len(lines) >= 1:
            if lines[0] == '':
                lines = lines[1:]

        if len(lines) >= 4:
            assert 'Found' in lines[0]
            assert '' == lines[1]
            assert 'GUID' in lines[2]
            assert '------------------' in lines[3]

            lines = lines[4:]

        for line in lines:
            items = line.split()
            assert len(items) == 3
            if items[2] == zvol_name:
                luid = items[0].strip()
                return luid

        msg = _('LUID not found for %(zfs_poolname)s. '
                'Output=%(out)s') % locals()
        raise exception.VolumeBackendAPIException(data=msg)
コード例 #5
0
    def _create_storage_repo(self, context, backend_ref):
        """Either creates or introduces SR on host
        depending on whether it exists in xapi db."""
        params = self._convert_config_params(backend_ref['config_params'])
        if 'name_label' in params:
            label = params['name_label']
            del params['name_label']
        else:
            label = 'SR-' + str(backend_ref['id'])

        params['sr_type'] = backend_ref['sr_type']

        if backend_ref['sr_uuid'] is None:
            # run the sr create command
            try:
                LOG.debug(_('SR name = %s') % label)
                LOG.debug(_('Params: %s') % str(params))
                sr_uuid = self._volumeops.create_sr(label, params)
            # update sr_uuid and created in db
            except Exception as ex:
                LOG.debug(
                    _("Failed to create sr %s...continuing") %
                    str(backend_ref['id']))
                msg = _('Create failed')
                raise exception.VolumeBackendAPIException(data=msg)

            LOG.debug(_('SR UUID of new SR is: %s') % sr_uuid)
            try:
                self.db.sm_backend_conf_update(context, backend_ref['id'],
                                               dict(sr_uuid=sr_uuid))
            except Exception as ex:
                LOG.exception(ex)
                msg = _("Failed to update db")
                raise exception.VolumeBackendAPIException(data=msg)

        else:
            # sr introduce, if not already done
            try:
                self._volumeops.introduce_sr(backend_ref['sr_uuid'], label,
                                             params)
            except Exception as ex:
                LOG.exception(ex)
                LOG.debug(
                    _("Failed to introduce sr %s...continuing") %
                    str(backend_ref['id']))
コード例 #6
0
 def _create_storage_repos(self, context):
     """Create/Introduce storage repositories at start."""
     backends = self.db.sm_backend_conf_get_all(context)
     for backend in backends:
         try:
             self._create_storage_repo(context, backend)
         except Exception as ex:
             LOG.exception(ex)
             msg = _('Failed to reach backend %d') % backend['id']
             raise exception.VolumeBackendAPIException(data=msg)
コード例 #7
0
 def check_for_setup_error(self):
     """Returns an error if prerequisites aren't met"""
     out, err = self._execute('vgs',
                              '--noheadings',
                              '-o',
                              'name',
                              run_as_root=True)
     volume_groups = out.split()
     if not FLAGS.volume_group in volume_groups:
         exception_message = (_("volume group %s doesn't exist") %
                              FLAGS.volume_group)
         raise exception.VolumeBackendAPIException(data=exception_message)
コード例 #8
0
ファイル: san.py プロジェクト: stuartbyma/nova
    def _view_exists(self, luid):
        (out, _err) = self._execute('/usr/sbin/stmfadm',
                                    'list-view', '-l', luid,
                                    check_exit_code=False)
        if "no views found" in out:
            return False

        if "View Entry:" in out:
            return True

        msg = _("Cannot parse list-view output: %s") % out
        raise exception.VolumeBackendAPIException(data=msg)
コード例 #9
0
    def delete_volume(self, volume):

        vol_rec = self.db.sm_volume_get(self.ctxt, volume['id'])
        if not vol_rec:
            raise exception.NotFound(_("Volume %s does not exist"),
                                     volume['id'])
        try:
            # If compute runs on this node, detach could have disconnected SR
            backend_ref = self.db.sm_backend_conf_get(self.ctxt,
                                                      vol_rec['backend_id'])
            self._create_storage_repo(self.ctxt, backend_ref)
            self._volumeops.delete_volume_for_sm(vol_rec['vdi_uuid'])
        except Exception as ex:
            LOG.exception(ex)
            msg = _("Failed to delete vdi")
            raise exception.VolumeBackendAPIException(data=msg)

        try:
            self.db.sm_volume_delete(self.ctxt, volume['id'])
        except Exception as ex:
            LOG.exception(ex)
            msg = _("Failed to delete volume in db")
            raise exception.VolumeBackendAPIException(data=msg)
コード例 #10
0
    def create_volume(self, volume):
        """Creates a logical volume. Can optionally return a Dictionary of
        changes to the volume object to be persisted."""

        # For now the scheduling logic will be to try to fit the volume in
        # the first available backend.
        # TODO(renukaapte) better scheduling once APIs are in place
        sm_vol_rec = None
        backends = self.db.sm_backend_conf_get_all(self.ctxt)
        for backend in backends:
            # Ensure that storage repo exists, if not create.
            # This needs to be done because if nova compute and
            # volume are both running on this host, then, as a
            # part of detach_volume, compute could potentially forget SR
            self._create_storage_repo(self.ctxt, backend)
            sm_vol_rec = self._volumeops.create_volume_for_sm(
                volume, backend['sr_uuid'])
            if sm_vol_rec:
                LOG.debug(
                    _('Volume will be created in backend - %d') %
                    backend['id'])
                break

        if sm_vol_rec:
            # Update db
            sm_vol_rec['id'] = volume['id']
            sm_vol_rec['backend_id'] = backend['id']
            try:
                self.db.sm_volume_create(self.ctxt, sm_vol_rec)
            except Exception as ex:
                LOG.exception(ex)
                msg = _("Failed to update volume in db")
                raise exception.VolumeBackendAPIException(data=msg)

        else:
            msg = _('Unable to create volume')
            raise exception.VolumeBackendAPIException(data=msg)
コード例 #11
0
    def __init__(self, *args, **kwargs):
        """Connect to the hypervisor."""

        # This driver leverages Xen storage manager, and hence requires
        # hypervisor to be Xen
        if FLAGS.connection_type != 'xenapi':
            msg = _('XenSMDriver requires xenapi connection')
            raise exception.VolumeBackendAPIException(data=msg)

        url = FLAGS.xenapi_connection_url
        username = FLAGS.xenapi_connection_username
        password = FLAGS.xenapi_connection_password
        try:
            session = xenapi_conn.XenAPISession(url, username, password)
            self._volumeops = volumeops.VolumeOps(session)
        except Exception as ex:
            LOG.exception(ex)
            msg = _("Failed to initiate session")
            raise exception.VolumeBackendAPIException(data=msg)

        super(XenSMDriver, self).__init__(execute=utils.execute,
                                          sync_exec=utils.execute,
                                          *args,
                                          **kwargs)
コード例 #12
0
    def check_for_setup_error(self):
        """Returns an error if prerequisites aren't met"""
        try:
            #NOTE(francois-charlier) Since 0.24 'collie cluster info -r'
            #  gives short output, but for compatibility reason we won't
            #  use it and just check if 'running' is in the output.
            (out, err) = self._execute('collie', 'cluster', 'info')
            if not 'running' in out.split():
                exception_message = _("Sheepdog is not working: %s") % out
                raise exception.VolumeBackendAPIException(
                    data=exception_message)

        except exception.ProcessExecutionError:
            exception_message = _("Sheepdog is not working")
            raise exception.NovaException(data=exception_message)
コード例 #13
0
ファイル: san.py プロジェクト: stuartbyma/nova
    def _cliq_get_cluster_vip(self, cluster_name):
        """Gets the IP on which a cluster shares iSCSI volumes"""
        cluster_xml = self._cliq_get_cluster_info(cluster_name)

        vips = []
        for vip in cluster_xml.findall("response/cluster/vip"):
            vips.append(vip.attrib.get('ipAddress'))

        if len(vips) == 1:
            return vips[0]

        _xml = etree.tostring(cluster_xml)
        msg = (_("Unexpected number of virtual ips for cluster "
                 " %(cluster_name)s. Result=%(_xml)s") %
               locals())
        raise exception.VolumeBackendAPIException(data=msg)
コード例 #14
0
ファイル: san.py プロジェクト: stuartbyma/nova
 def local_path(self, volume):
     # TODO(justinsb): Is this needed here?
     msg = _("local_path not supported")
     raise exception.VolumeBackendAPIException(data=msg)