def _wait_for_clone_finish(self, clone_op_id, vol_uuid): """Waits till a clone operation is complete or errored out.""" clone_ls_st = NaElement('clone-list-status') clone_id = NaElement('clone-id') clone_ls_st.add_child_elem(clone_id) clone_id.add_node_with_children('clone-id-info', **{'clone-op-id': clone_op_id, 'volume-uuid': vol_uuid}) task_running = True while task_running: result = self._invoke_successfully(clone_ls_st, None) status = result.get_child_by_name('status') ops_info = status.get_children() if ops_info: state = ops_info[0].get_child_content('clone-state') if state == 'completed': task_running = False elif state == 'failed': code = ops_info[0].get_child_content('error') reason = ops_info[0].get_child_content('reason') raise NaApiError(code, reason) else: time.sleep(1) else: raise NaApiError( 'UnknownCloneId', 'No clone operation for clone id %s found on the filer' % (clone_id))
def _clone_lun(self, name, new_name, space_reserved): """Clone LUN with the given handle to the new name.""" metadata = self._get_lun_attr(name, 'metadata') path = metadata['Path'] (parent, splitter, name) = path.rpartition('/') clone_path = '%s/%s' % (parent, new_name) clone_start = NaElement.create_node_with_children( 'clone-start', **{'source-path': path, 'destination-path': clone_path, 'no-snap': 'true'}) result = self.client.invoke_successfully(clone_start, True) clone_id_el = result.get_child_by_name('clone-id') cl_id_info = clone_id_el.get_child_by_name('clone-id-info') vol_uuid = cl_id_info.get_child_content('volume-uuid') clone_id = cl_id_info.get_child_content('clone-op-id') if vol_uuid: self._check_clone_status(clone_id, vol_uuid, name, new_name) cloned_lun = self._get_lun_by_args(path=clone_path) if cloned_lun: self._set_space_reserve(clone_path, space_reserved) clone_meta = self._create_lun_meta(cloned_lun) handle = self._create_lun_handle(clone_meta) self._add_lun_to_table( NetAppLun(handle, new_name, cloned_lun.get_child_content('size'), clone_meta)) else: raise NaApiError('ENOLUNENTRY', 'No Lun entry found on the filer')
def _get_cluster_node(na_server): """Get the cluster node for ems.""" na_server.set_vserver(None) vs_get = _create_vs_get() res = na_server.invoke_successfully(vs_get) if (res.get_child_content('num-records') and int(res.get_child_content('num-records')) > 0): attr_list = res.get_child_by_name('attributes-list') vs_info = attr_list.get_child_by_name('vserver-info') vs_name = vs_info.get_child_content('vserver-name') return vs_name raise NaApiError(code='Not found', message='No records found')
def _check_clone_status(self, clone_id, vol_uuid, name, new_name): """Checks for the job till completed.""" clone_status = NaElement('clone-list-status') cl_id = NaElement('clone-id') clone_status.add_child_elem(cl_id) cl_id.add_node_with_children( 'clone-id-info', **{ 'clone-op-id': clone_id, 'volume-uuid': vol_uuid }) running = True clone_ops_info = None while running: result = self.client.invoke_successfully(clone_status, True) status = result.get_child_by_name('status') ops_info = status.get_children() if ops_info: for info in ops_info: if info.get_child_content('clone-state') == 'running': time.sleep(1) break else: running = False clone_ops_info = info break else: if clone_ops_info: fmt = {'name': name, 'new_name': new_name} if clone_ops_info.get_child_content('clone-state')\ == 'completed': LOG.debug( _("Clone operation with src %(name)s" " and dest %(new_name)s completed") % fmt) else: LOG.debug( _("Clone operation with src %(name)s" " and dest %(new_name)s failed") % fmt) raise NaApiError( clone_ops_info.get_child_content('error'), clone_ops_info.get_child_content('reason'))
def provide_ems(requester, server, stats, netapp_backend, server_type="cluster"): """Provide ems with volume stats for the requester. :param server_type: cluster or 7mode. """ def _create_ems(stats, netapp_backend, server_type): """Create ems api request.""" ems_log = NaElement('ems-autosupport-log') host = socket.getfqdn() or 'Cinder_node' dest = "cluster node" if server_type == "cluster"\ else "7 mode controller" ems_log.add_new_child('computer-name', host) ems_log.add_new_child('event-id', '0') ems_log.add_new_child('event-source', 'Cinder driver %s' % netapp_backend) ems_log.add_new_child('app-version', stats.get('driver_version', 'Undefined')) ems_log.add_new_child('category', 'provisioning') ems_log.add_new_child('event-description', 'OpenStack volume created on %s' % dest) ems_log.add_new_child('log-level', '6') ems_log.add_new_child('auto-support', 'true') return ems_log def _create_vs_get(): """Create vs_get api request.""" vs_get = NaElement('vserver-get-iter') vs_get.add_new_child('max-records', '1') query = NaElement('query') query.add_node_with_children('vserver-info', **{'vserver-type': 'node'}) vs_get.add_child_elem(query) desired = NaElement('desired-attributes') desired.add_node_with_children( 'vserver-info', **{ 'vserver-name': '', 'vserver-type': '' }) vs_get.add_child_elem(desired) return vs_get def _get_cluster_node(na_server): """Get the cluster node for ems.""" na_server.set_vserver(None) vs_get = _create_vs_get() res = na_server.invoke_successfully(vs_get) if (res.get_child_content('num-records') and int(res.get_child_content('num-records')) > 0): attr_list = res.get_child_by_name('attributes-list') vs_info = attr_list.get_child_by_name('vserver-info') vs_name = vs_info.get_child_content('vserver-name') return vs_name return None do_ems = True if hasattr(requester, 'last_ems'): sec_limit = 604800 if not (timeutils.is_older_than(requester.last_ems, sec_limit) or timeutils.is_older_than(requester.last_ems, sec_limit - 59)): do_ems = False if do_ems: na_server = copy.copy(server) na_server.set_timeout(25) ems = _create_ems(stats, netapp_backend, server_type) try: if server_type == "cluster": api_version = na_server.get_api_version() if api_version: major, minor = api_version else: raise NaApiError(code='Not found', message='No api version found') if major == 1 and minor > 15: node = getattr(requester, 'vserver', None) else: node = _get_cluster_node(na_server) if node is None: raise NaApiError(code='Not found', message='No vserver found') na_server.set_vserver(node) else: na_server.set_vfiler(None) na_server.invoke_successfully(ems, True) LOG.debug("ems executed successfully.") except NaApiError as e: LOG.warn(_("Failed to invoke ems. Message : %s") % e) finally: requester.last_ems = timeutils.utcnow()