From: Alex Meade Date: Mon, 6 Jul 2015 14:18:18 +0000 (-0400) Subject: NetApp ONTAP: Add debug tracing X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=dbfb04f8ca0e23879fd5b24897188a4bfd4c2ac2;p=openstack-build%2Fcinder-build.git NetApp ONTAP: Add debug tracing Add debug tracing to the NetApp ONTAP drivers using the utils.trace_method and utils.trace_api decorators. This is enabled in the driver via the 'trace_flags' configuration option. Change-Id: I7a50b06af28d9dfee83ac44e0ba9dd8233151e2f --- diff --git a/cinder/volume/drivers/netapp/dataontap/block_7mode.py b/cinder/volume/drivers/netapp/dataontap/block_7mode.py index 719c8440e..ef7a22904 100644 --- a/cinder/volume/drivers/netapp/dataontap/block_7mode.py +++ b/cinder/volume/drivers/netapp/dataontap/block_7mode.py @@ -25,9 +25,11 @@ Volume driver library for NetApp 7-mode block storage systems. from oslo_log import log as logging from oslo_utils import timeutils from oslo_utils import units +import six from cinder import exception from cinder.i18n import _, _LW +from cinder import utils from cinder.volume import configuration from cinder.volume.drivers.netapp.dataontap import block_base from cinder.volume.drivers.netapp.dataontap.client import client_7mode @@ -38,8 +40,8 @@ from cinder.volume.drivers.netapp import utils as na_utils LOG = logging.getLogger(__name__) -class NetAppBlockStorage7modeLibrary(block_base. - NetAppBlockStorageLibrary): +@six.add_metaclass(utils.TraceWrapperMetaclass) +class NetAppBlockStorage7modeLibrary(block_base.NetAppBlockStorageLibrary): """NetApp block storage library for Data ONTAP (7-mode).""" def __init__(self, driver_name, driver_protocol, **kwargs): diff --git a/cinder/volume/drivers/netapp/dataontap/block_base.py b/cinder/volume/drivers/netapp/dataontap/block_base.py index 5a97b3424..5527f45de 100644 --- a/cinder/volume/drivers/netapp/dataontap/block_base.py +++ b/cinder/volume/drivers/netapp/dataontap/block_base.py @@ -33,6 +33,7 @@ import six from cinder import exception from cinder.i18n import _, _LE, _LI, _LW +from cinder import utils from cinder.volume.drivers.netapp.dataontap.client import api as na_api from cinder.volume.drivers.netapp import options as na_opts from cinder.volume.drivers.netapp import utils as na_utils @@ -65,6 +66,7 @@ class NetAppLun(object): self.handle, self.name, self.size, self.metadata) +@six.add_metaclass(utils.TraceWrapperMetaclass) class NetAppBlockStorageLibrary(object): """NetApp block storage library for Data ONTAP.""" diff --git a/cinder/volume/drivers/netapp/dataontap/block_cmode.py b/cinder/volume/drivers/netapp/dataontap/block_cmode.py index b019a0c65..0fd2263b6 100644 --- a/cinder/volume/drivers/netapp/dataontap/block_cmode.py +++ b/cinder/volume/drivers/netapp/dataontap/block_cmode.py @@ -43,8 +43,8 @@ LOG = logging.getLogger(__name__) QOS_CLEANUP_INTERVAL_SECONDS = 60 -class NetAppBlockStorageCmodeLibrary(block_base. - NetAppBlockStorageLibrary): +@six.add_metaclass(utils.TraceWrapperMetaclass) +class NetAppBlockStorageCmodeLibrary(block_base.NetAppBlockStorageLibrary): """NetApp block storage library for Data ONTAP (Cluster-mode).""" REQUIRED_CMODE_FLAGS = ['netapp_vserver'] diff --git a/cinder/volume/drivers/netapp/dataontap/client/api.py b/cinder/volume/drivers/netapp/dataontap/client/api.py index 7391f8a60..e900ad454 100644 --- a/cinder/volume/drivers/netapp/dataontap/client/api.py +++ b/cinder/volume/drivers/netapp/dataontap/client/api.py @@ -2,6 +2,7 @@ # Copyright (c) 2014 Navneet Singh. All rights reserved. # Copyright (c) 2014 Glenn Gobeli. All rights reserved. # Copyright (c) 2014 Clinton Knight. All rights reserved. +# Copyright (c) 2015 Alex Meade. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -29,6 +30,7 @@ from six.moves import urllib from cinder import exception from cinder.i18n import _ +from cinder import utils LOG = logging.getLogger(__name__) @@ -194,10 +196,18 @@ class NaServer(object): self._refresh_conn = True def invoke_elem(self, na_element, enable_tunneling=False): + """Invoke the API on the server.""" + return self.send_http_request(na_element, enable_tunneling) + + @utils.trace_api + def send_http_request(self, na_element, enable_tunneling=False): """Invoke the API on the server.""" if na_element and not isinstance(na_element, NaElement): ValueError('NaElement must be supplied to invoke API') - request = self._create_request(na_element, enable_tunneling) + + request, request_element = self._create_request(na_element, + enable_tunneling) + if not hasattr(self, '_opener') or not self._opener \ or self._refresh_conn: self._build_opener() @@ -210,8 +220,11 @@ class NaServer(object): raise NaApiError(e.code, e.msg) except Exception as e: raise NaApiError('Unexpected error', e) - xml = response.read() - return self._get_result(xml) + + response_xml = response.read() + response_element = self._get_result(response_xml) + + return response_element def invoke_successfully(self, na_element, enable_tunneling=False): """Invokes API and checks execution status as success. @@ -248,7 +261,7 @@ class NaServer(object): request = urllib.request.Request( self._get_url(), data=request_d, headers={'Content-Type': 'text/xml', 'charset': 'utf-8'}) - return request + return request, netapp_elem def _enable_tunnel_request(self, netapp_elem): """Enables vserver or vfiler tunneling.""" @@ -416,6 +429,12 @@ class NaElement(object): return etree.tostring(self._element, method=method, encoding=encoding, pretty_print=pretty) + def __str__(self): + return self.to_string(pretty=True) + + def __repr__(self): + return str(self) + def __getitem__(self, key): """Dict getter method for NaElement. diff --git a/cinder/volume/drivers/netapp/dataontap/client/client_7mode.py b/cinder/volume/drivers/netapp/dataontap/client/client_7mode.py index 87f713d1b..55d2471c7 100644 --- a/cinder/volume/drivers/netapp/dataontap/client/client_7mode.py +++ b/cinder/volume/drivers/netapp/dataontap/client/client_7mode.py @@ -23,6 +23,7 @@ import six from cinder import exception from cinder.i18n import _, _LW +from cinder import utils from cinder.volume.drivers.netapp.dataontap.client import api as netapp_api from cinder.volume.drivers.netapp.dataontap.client import client_base @@ -30,6 +31,7 @@ from cinder.volume.drivers.netapp.dataontap.client import client_base LOG = logging.getLogger(__name__) +@six.add_metaclass(utils.TraceWrapperMetaclass) class Client(client_base.Client): def __init__(self, volume_list=None, **kwargs): diff --git a/cinder/volume/drivers/netapp/dataontap/client/client_base.py b/cinder/volume/drivers/netapp/dataontap/client/client_base.py index 98c57133a..22cfece86 100644 --- a/cinder/volume/drivers/netapp/dataontap/client/client_base.py +++ b/cinder/volume/drivers/netapp/dataontap/client/client_base.py @@ -24,12 +24,14 @@ from oslo_utils import timeutils import six from cinder.i18n import _LE, _LW, _LI +from cinder import utils from cinder.volume.drivers.netapp.dataontap.client import api as netapp_api LOG = logging.getLogger(__name__) +@six.add_metaclass(utils.TraceWrapperMetaclass) class Client(object): def __init__(self, **kwargs): diff --git a/cinder/volume/drivers/netapp/dataontap/client/client_cmode.py b/cinder/volume/drivers/netapp/dataontap/client/client_cmode.py index 77d84d3eb..31b7f4a76 100644 --- a/cinder/volume/drivers/netapp/dataontap/client/client_cmode.py +++ b/cinder/volume/drivers/netapp/dataontap/client/client_cmode.py @@ -23,6 +23,7 @@ import six from cinder import exception from cinder.i18n import _, _LW +from cinder import utils from cinder.volume.drivers.netapp.dataontap.client import api as netapp_api from cinder.volume.drivers.netapp.dataontap.client import client_base from cinder.volume.drivers.netapp import utils as na_utils @@ -32,6 +33,7 @@ LOG = logging.getLogger(__name__) DELETED_PREFIX = 'deleted_cinder_' +@six.add_metaclass(utils.TraceWrapperMetaclass) class Client(client_base.Client): def __init__(self, **kwargs): diff --git a/cinder/volume/drivers/netapp/dataontap/nfs_7mode.py b/cinder/volume/drivers/netapp/dataontap/nfs_7mode.py index 09dc9ab88..e2984a06a 100644 --- a/cinder/volume/drivers/netapp/dataontap/nfs_7mode.py +++ b/cinder/volume/drivers/netapp/dataontap/nfs_7mode.py @@ -24,9 +24,11 @@ Volume driver for NetApp NFS storage. import os from oslo_log import log as logging +import six from cinder import exception from cinder.i18n import _ +from cinder import utils from cinder.volume.drivers.netapp.dataontap.client import client_7mode from cinder.volume.drivers.netapp.dataontap import nfs_base from cinder.volume.drivers.netapp import options as na_opts @@ -36,6 +38,7 @@ from cinder.volume.drivers.netapp import utils as na_utils LOG = logging.getLogger(__name__) +@six.add_metaclass(utils.TraceWrapperWithABCMetaclass) class NetApp7modeNfsDriver(nfs_base.NetAppNfsDriver): """NetApp NFS driver for Data ONTAP (7-mode).""" diff --git a/cinder/volume/drivers/netapp/dataontap/nfs_base.py b/cinder/volume/drivers/netapp/dataontap/nfs_base.py index 4ac9538ce..c2c559c64 100644 --- a/cinder/volume/drivers/netapp/dataontap/nfs_base.py +++ b/cinder/volume/drivers/netapp/dataontap/nfs_base.py @@ -49,6 +49,7 @@ LOG = logging.getLogger(__name__) CONF = cfg.CONF +@six.add_metaclass(utils.TraceWrapperWithABCMetaclass) class NetAppNfsDriver(nfs.NfsDriver): """Base class for NetApp NFS driver for Data ONTAP.""" diff --git a/cinder/volume/drivers/netapp/dataontap/nfs_cmode.py b/cinder/volume/drivers/netapp/dataontap/nfs_cmode.py index 29d4a3b66..aa0c7886e 100644 --- a/cinder/volume/drivers/netapp/dataontap/nfs_cmode.py +++ b/cinder/volume/drivers/netapp/dataontap/nfs_cmode.py @@ -45,6 +45,7 @@ LOG = logging.getLogger(__name__) QOS_CLEANUP_INTERVAL_SECONDS = 60 +@six.add_metaclass(utils.TraceWrapperWithABCMetaclass) class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver): """NetApp NFS driver for Data ONTAP (Cluster-mode).""" diff --git a/cinder/volume/drivers/netapp/dataontap/ssc_cmode.py b/cinder/volume/drivers/netapp/dataontap/ssc_cmode.py index a5deb012b..8c2c78133 100644 --- a/cinder/volume/drivers/netapp/dataontap/ssc_cmode.py +++ b/cinder/volume/drivers/netapp/dataontap/ssc_cmode.py @@ -3,6 +3,7 @@ # Copyright (c) 2014 Navneet Singh. All rights reserved. # Copyright (c) 2014 Clinton Knight. All rights reserved. # Copyright (c) 2015 Tom Barron. All rights reserved. +# Copyright (c) 2015 Alex Meade. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -98,6 +99,7 @@ class NetAppVolume(object): return vol_str +@utils.trace_method def get_cluster_vols_with_ssc(na_server, vserver, volume=None): """Gets ssc vols for cluster vserver.""" volumes = query_cluster_vols_for_ssc(na_server, vserver, volume) @@ -144,6 +146,7 @@ def get_cluster_vols_with_ssc(na_server, vserver, volume=None): return volumes +@utils.trace_method def query_cluster_vols_for_ssc(na_server, vserver, volume=None): """Queries cluster volumes for ssc.""" query = {'volume-attributes': None} @@ -173,6 +176,7 @@ def query_cluster_vols_for_ssc(na_server, vserver, volume=None): return vols +@utils.trace_method def create_vol_list(vol_attrs): """Creates vol list with features from attr list.""" vols = set() @@ -248,6 +252,7 @@ def create_vol_list(vol_attrs): return vols +@utils.trace_method def query_aggr_options(na_server, aggr_name): """Queries cluster aggr for attributes. @@ -277,6 +282,7 @@ def query_aggr_options(na_server, aggr_name): return attrs +@utils.trace_method def get_sis_vol_dict(na_server, vserver, volume=None): """Queries sis for volumes. @@ -318,6 +324,7 @@ def get_sis_vol_dict(na_server, vserver, volume=None): return sis_vols +@utils.trace_method def get_snapmirror_vol_dict(na_server, vserver, volume=None): """Queries snapmirror volumes.""" mirrored_vols = {} @@ -352,6 +359,7 @@ def get_snapmirror_vol_dict(na_server, vserver, volume=None): return mirrored_vols +@utils.trace_method def query_aggr_storage_disk(na_server, aggr): """Queries for storage disks associated to an aggregate.""" query = {'storage-disk-info': {'disk-raid-info': @@ -384,6 +392,7 @@ def query_aggr_storage_disk(na_server, aggr): return 'unknown' +@utils.trace_method def get_cluster_ssc(na_server, vserver): """Provides cluster volumes with ssc.""" netapp_volumes = get_cluster_vols_with_ssc(na_server, vserver) @@ -406,6 +415,7 @@ def get_cluster_ssc(na_server, vserver): return ssc_map +@utils.trace_method def refresh_cluster_stale_ssc(*args, **kwargs): """Refreshes stale ssc volumes with latest.""" backend = args[0] @@ -465,6 +475,7 @@ def refresh_cluster_stale_ssc(*args, **kwargs): na_utils.set_safe_attr(backend, 'refresh_stale_running', False) +@utils.trace_method def get_cluster_latest_ssc(*args, **kwargs): """Updates volumes including ssc.""" backend = args[0] @@ -498,6 +509,7 @@ def get_cluster_latest_ssc(*args, **kwargs): na_utils.set_safe_attr(backend, 'ssc_job_running', False) +@utils.trace_method def refresh_cluster_ssc(backend, na_server, vserver, synchronous=False): """Refresh cluster ssc for backend.""" if not isinstance(na_server, netapp_api.NaServer): @@ -528,6 +540,7 @@ def refresh_cluster_ssc(backend, na_server, vserver, synchronous=False): t.start() +@utils.trace_method def get_volumes_for_specs(ssc_vols, specs): """Shortlists volumes for extra specs provided.""" if specs is None or specs == {} or not isinstance(specs, dict): @@ -599,6 +612,7 @@ def get_volumes_for_specs(ssc_vols, specs): return result +@utils.trace_method def check_ssc_api_permissions(client_cmode): """Checks backend SSC API permissions for the user.""" api_map = {'storage-disk-get-iter': ['netapp:disk_type'],