~ubuntu-branches/ubuntu/raring/cinder/raring-updates

« back to all changes in this revision

Viewing changes to cinder/volume/drivers/netapp.py

Tags: upstream-2013.1~g2
ImportĀ upstreamĀ versionĀ 2013.1~g2

Show diffs side-by-side

added added

removed removed

Lines of Context:
57
57
    cfg.StrOpt('netapp_storage_service',
58
58
               default=None,
59
59
               help=('Storage service to use for provisioning '
60
 
                    '(when volume_type=None)')),
 
60
                     '(when volume_type=None)')),
61
61
    cfg.StrOpt('netapp_storage_service_prefix',
62
62
               default=None,
63
63
               help=('Prefix of storage service name to use for '
64
 
                    'provisioning (volume_type name will be appended)')),
 
64
                     'provisioning (volume_type name will be appended)')),
65
65
    cfg.StrOpt('netapp_vfiler',
66
66
               default=None,
67
 
               help='Vfiler to use for provisioning'),
68
 
    ]
 
67
               help='Vfiler to use for provisioning'), ]
69
68
 
70
69
FLAGS = flags.FLAGS
71
70
FLAGS.register_opts(netapp_opts)
148
147
    def _check_flags(self):
149
148
        """Ensure that the flags we care about are set."""
150
149
        required_flags = ['netapp_wsdl_url', 'netapp_login', 'netapp_password',
151
 
                'netapp_server_hostname', 'netapp_server_port']
 
150
                          'netapp_server_hostname', 'netapp_server_port']
152
151
        for flag in required_flags:
153
152
            if not getattr(FLAGS, flag, None):
154
153
                raise exception.InvalidInput(reason=_('%s is not set') % flag)
155
154
        if not (FLAGS.netapp_storage_service or
156
155
                FLAGS.netapp_storage_service_prefix):
157
 
            raise exception.InvalidInput(reason=_('Either '
158
 
                'netapp_storage_service or netapp_storage_service_prefix must '
159
 
                'be set'))
 
156
            raise exception.InvalidInput(
 
157
                reason=_('Either '
 
158
                         'netapp_storage_service or '
 
159
                         'netapp_storage_service_prefix must '
 
160
                         'be set'))
160
161
 
161
162
    def do_setup(self, context):
162
163
        """Setup the NetApp Volume driver.
166
167
        client.
167
168
        """
168
169
        self._check_flags()
169
 
        self._create_client(wsdl_url=FLAGS.netapp_wsdl_url,
 
170
        self._create_client(
 
171
            wsdl_url=FLAGS.netapp_wsdl_url,
170
172
            login=FLAGS.netapp_login, password=FLAGS.netapp_password,
171
173
            hostname=FLAGS.netapp_server_hostname,
172
174
            port=FLAGS.netapp_server_port, cache=True)
204
206
        """Discover all of the LUNs in a dataset."""
205
207
        server = self.client.service
206
208
        res = server.DatasetMemberListInfoIterStart(
207
 
                DatasetNameOrId=dataset.id,
208
 
                IncludeExportsInfo=True,
209
 
                IncludeIndirect=True,
210
 
                MemberType='lun_path')
 
209
            DatasetNameOrId=dataset.id,
 
210
            IncludeExportsInfo=True,
 
211
            IncludeIndirect=True,
 
212
            MemberType='lun_path')
211
213
        tag = res.Tag
212
214
        suffix = None
213
215
        if volume:
217
219
                res = server.DatasetMemberListInfoIterNext(Tag=tag,
218
220
                                                           Maximum=100)
219
221
                if (not hasattr(res, 'DatasetMembers') or
220
 
                            not res.DatasetMembers):
 
222
                        not res.DatasetMembers):
221
223
                    break
222
224
                for member in res.DatasetMembers.DatasetMemberInfo:
223
225
                    if suffix and not member.MemberName.endswith(suffix):
324
326
        """
325
327
        if ss_type and not self.storage_service_prefix:
326
328
            msg = _('Attempt to use volume_type without specifying '
327
 
                'netapp_storage_service_prefix flag.')
 
329
                    'netapp_storage_service_prefix flag.')
328
330
            raise exception.VolumeBackendAPIException(data=msg)
329
331
        if not (ss_type or self.storage_service):
330
332
            msg = _('You must set the netapp_storage_service flag in order to '
331
 
                'create volumes with no volume_type.')
 
333
                    'create volumes with no volume_type.')
332
334
            raise exception.VolumeBackendAPIException(data=msg)
333
335
        storage_service = self.storage_service
334
336
        if ss_type:
358
360
        metadata.DfmMetadataField = [field1, field2]
359
361
 
360
362
        res = self.client.service.StorageServiceDatasetProvision(
361
 
                StorageServiceNameOrId=storage_service,
362
 
                DatasetName=dataset_name,
363
 
                AssumeConfirmation=True,
364
 
                StorageSetDetails=details,
365
 
                DatasetMetadata=metadata)
 
363
            StorageServiceNameOrId=storage_service,
 
364
            DatasetName=dataset_name,
 
365
            AssumeConfirmation=True,
 
366
            StorageSetDetails=details,
 
367
            DatasetMetadata=metadata)
366
368
 
367
369
        ds = DfmDataset(res.DatasetId, dataset_name, project, ss_type)
368
370
        self.discovered_datasets.append(ds)
627
629
        igroup_infos = igroups[0]['initiator-group-info']
628
630
        for igroup_info in igroup_infos:
629
631
            if ('iscsi' != igroup_info['initiator-group-type'][0] or
630
 
                'linux' != igroup_info['initiator-group-os-type'][0]):
 
632
                    'linux' != igroup_info['initiator-group-os-type'][0]):
631
633
                continue
632
634
            igroup_name = igroup_info['initiator-group-name'][0]
633
635
            if not igroup_name.startswith(self.IGROUP_PREFIX):
678
680
        request.Name = 'lun-map-list-info'
679
681
        request.Args = text.Raw('<path>%s</path>' % (lunpath))
680
682
        response = self.client.service.ApiProxy(Target=host_id,
681
 
                                                 Request=request)
 
683
                                                Request=request)
682
684
        self._check_fail(request, response)
683
685
        igroups = response.Results['initiator-groups']
684
686
        if self._api_elem_is_empty(igroups):
830
832
            '<volume-uuid>%s</volume-uuid>'
831
833
            '</clone-id-info></clone-id>')
832
834
        request.Args = text.Raw(clone_list_status_xml % (clone_op_id,
833
 
                                                          volume_uuid))
 
835
                                                         volume_uuid))
834
836
        response = self.client.service.ApiProxy(Target=host_id,
835
837
                                                Request=request)
836
838
        self._check_fail(request, response)
 
839
        if isinstance(response.Results, text.Text):
 
840
            return False
837
841
        status = response.Results['status']
838
842
        if self._api_elem_is_empty(status):
839
843
            return False
856
860
        else:
857
861
            no_snap = 'true'
858
862
        request.Args = text.Raw(clone_start_xml % (src_path, no_snap,
859
 
                                                    dest_path))
 
863
                                                   dest_path))
860
864
        response = self.client.service.ApiProxy(Target=host_id,
861
865
                                                Request=request)
862
866
        self._check_fail(request, response)
966
970
        snap_size = snapshot['volume_size']
967
971
        if vol_size != snap_size:
968
972
            msg = _('Cannot create volume of size %(vol_size)s from '
969
 
                'snapshot of size %(snap_size)s')
 
973
                    'snapshot of size %(snap_size)s')
970
974
            raise exception.VolumeBackendAPIException(data=msg % locals())
971
975
        vol_name = snapshot['volume_name']
972
976
        snapshot_name = snapshot['name']
978
982
        new_type = self._get_ss_type(volume)
979
983
        if new_type != old_type:
980
984
            msg = _('Cannot create volume of type %(new_type)s from '
981
 
                'snapshot of type %(old_type)s')
 
985
                    'snapshot of type %(old_type)s')
982
986
            raise exception.VolumeBackendAPIException(data=msg % locals())
983
987
        lun = self._get_lun_details(lun_id)
984
988
        extra_gb = vol_size
993
997
        self._refresh_dfm_luns(lun.HostId)
994
998
        self._discover_dataset_luns(dataset, clone_name)
995
999
 
 
1000
    def create_cloned_volume(self, volume, src_vref):
 
1001
        """Creates a clone of the specified volume."""
 
1002
        raise NotImplementedError()
 
1003
 
996
1004
 
997
1005
class NetAppLun(object):
998
1006
    """Represents a LUN on NetApp storage."""
1039
1047
    def _check_flags(self):
1040
1048
        """Ensure that the flags we care about are set."""
1041
1049
        required_flags = ['netapp_wsdl_url', 'netapp_login', 'netapp_password',
1042
 
                'netapp_server_hostname', 'netapp_server_port']
 
1050
                          'netapp_server_hostname', 'netapp_server_port']
1043
1051
        for flag in required_flags:
1044
1052
            if not getattr(FLAGS, flag, None):
1045
1053
                msg = _('%s is not set') % flag
1053
1061
        client.
1054
1062
        """
1055
1063
        self._check_flags()
1056
 
        self._create_client(wsdl_url=FLAGS.netapp_wsdl_url,
 
1064
        self._create_client(
 
1065
            wsdl_url=FLAGS.netapp_wsdl_url,
1057
1066
            login=FLAGS.netapp_login, password=FLAGS.netapp_password,
1058
1067
            hostname=FLAGS.netapp_server_hostname,
1059
1068
            port=FLAGS.netapp_server_port, cache=True)
1069
1078
            meta_dict = {}
1070
1079
            if hasattr(lun, 'Metadata'):
1071
1080
                meta_dict = self._create_dict_from_meta(lun.Metadata)
1072
 
            discovered_lun = NetAppLun(lun.Handle, lun.Name, lun.Size,
1073
 
                meta_dict)
 
1081
            discovered_lun = NetAppLun(lun.Handle,
 
1082
                                       lun.Name,
 
1083
                                       lun.Size,
 
1084
                                       meta_dict)
1074
1085
            self._add_lun_to_table(discovered_lun)
1075
1086
        LOG.debug(_("Success getting LUN list from server"))
1076
1087
 
1095
1106
        lun = server.ProvisionLun(Name=name, Size=size,
1096
1107
                                  Metadata=metadata)
1097
1108
        LOG.debug(_("Created LUN with name %s") % name)
1098
 
        self._add_lun_to_table(NetAppLun(lun.Handle, lun.Name,
1099
 
             lun.Size, self._create_dict_from_meta(lun.Metadata)))
 
1109
        self._add_lun_to_table(
 
1110
            NetAppLun(lun.Handle,
 
1111
                      lun.Name,
 
1112
                      lun.Size,
 
1113
                      self._create_dict_from_meta(lun.Metadata)))
1100
1114
 
1101
1115
    def delete_volume(self, volume):
1102
1116
        """Driver entry point for destroying existing volumes."""
1143
1157
        msg = _("Mapped LUN %(handle)s to the initiator %(initiator_name)s")
1144
1158
        LOG.debug(msg % locals())
1145
1159
 
1146
 
        target_details_list = server.GetLunTargetDetails(Handle=handle,
1147
 
                InitiatorType="iscsi", InitiatorName=initiator_name)
 
1160
        target_details_list = server.GetLunTargetDetails(
 
1161
            Handle=handle,
 
1162
            InitiatorType="iscsi",
 
1163
            InitiatorName=initiator_name)
1148
1164
        msg = _("Succesfully fetched target details for LUN %(handle)s and "
1149
1165
                "initiator %(initiator_name)s")
1150
1166
        LOG.debug(msg % locals())
1255
1271
        lun = server.CloneLun(Handle=handle, NewName=new_name,
1256
1272
                              Metadata=metadata)
1257
1273
        LOG.debug(_("Cloned LUN with new name %s") % new_name)
1258
 
        self._add_lun_to_table(NetAppLun(lun.Handle, lun.Name,
1259
 
             lun.Size, self._create_dict_from_meta(lun.Metadata)))
 
1274
        self._add_lun_to_table(
 
1275
            NetAppLun(lun.Handle,
 
1276
                      lun.Name,
 
1277
                      lun.Size,
 
1278
                      self._create_dict_from_meta(lun.Metadata)))
1260
1279
 
1261
1280
    def _create_metadata_list(self, extra_args):
1262
1281
        """Creates metadata from kwargs."""
1283
1302
        for meta in metadata:
1284
1303
            meta_dict[meta.Key] = meta.Value
1285
1304
        return meta_dict
 
1305
 
 
1306
    def copy_image_to_volume(self, context, volume, image_service, image_id):
 
1307
        """Fetch the image from image_service and write it to the volume."""
 
1308
        raise NotImplementedError()
 
1309
 
 
1310
    def copy_volume_to_image(self, context, volume, image_service, image_id):
 
1311
        """Copy the volume to the specified image."""
 
1312
        raise NotImplementedError()
 
1313
 
 
1314
    def create_cloned_volume(self, volume, src_vref):
 
1315
        """Creates a clone of the specified volume."""
 
1316
        raise NotImplementedError()