--- /dev/null
+# Copyright 2014 Tom Barron. 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
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import platform
+
+import mock
+
+from cinder.openstack.common import processutils as putils
+from cinder import test
+from cinder import version
+from cinder.volume.drivers.netapp import utils as na_utils
+
+
+class OpenstackInfoTestCase(test.TestCase):
+
+ UNKNOWN_VERSION = 'unknown version'
+ UNKNOWN_RELEASE = 'unknown release'
+ UNKNOWN_VENDOR = 'unknown vendor'
+ UNKNOWN_PLATFORM = 'unknown platform'
+ VERSION_STRING_RET_VAL = 'fake_version_1'
+ RELEASE_STRING_RET_VAL = 'fake_release_1'
+ PLATFORM_RET_VAL = 'fake_platform_1'
+ VERSION_INFO_VERSION = 'fake_version_2'
+ VERSION_INFO_RELEASE = 'fake_release_2'
+ RPM_INFO_VERSION = 'fake_version_3'
+ RPM_INFO_RELEASE = 'fake_release_3'
+ RPM_INFO_VENDOR = 'fake vendor 3'
+ PUTILS_RPM_RET_VAL = ('fake_version_3 fake_release_3 fake vendor 3', '')
+ NO_PKG_FOUND = ('', 'whatever')
+ PUTILS_DPKG_RET_VAL = ('epoch:upstream_version-debian_revision', '')
+ DEB_RLS = 'upstream_version-debian_revision'
+ DEB_VENDOR = 'debian_revision'
+
+ def setUp(self):
+ super(OpenstackInfoTestCase, self).setUp()
+
+ def test_openstack_info_init(self):
+ info = na_utils.OpenStackInfo()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+
+ @mock.patch.object(version.version_info, 'version_string',
+ mock.Mock(return_value=VERSION_STRING_RET_VAL))
+ def test_update_version_from_version_string(self):
+ info = na_utils.OpenStackInfo()
+ info._update_version_from_version_string()
+
+ self.assertEqual(self.VERSION_STRING_RET_VAL, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+
+ @mock.patch.object(version.version_info, 'version_string',
+ mock.Mock(side_effect=Exception))
+ def test_xcption_in_update_version_from_version_string(self):
+ info = na_utils.OpenStackInfo()
+ info._update_version_from_version_string()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+
+ @mock.patch.object(version.version_info, 'release_string',
+ mock.Mock(return_value=RELEASE_STRING_RET_VAL))
+ def test_update_release_from_release_string(self):
+ info = na_utils.OpenStackInfo()
+ info._update_release_from_release_string()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.RELEASE_STRING_RET_VAL, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+
+ @mock.patch.object(version.version_info, 'release_string',
+ mock.Mock(side_effect=Exception))
+ def test_xcption_in_update_release_from_release_string(self):
+ info = na_utils.OpenStackInfo()
+ info._update_release_from_release_string()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+
+ @mock.patch.object(platform, 'platform',
+ mock.Mock(return_value=PLATFORM_RET_VAL))
+ def test_update_platform(self):
+ info = na_utils.OpenStackInfo()
+ info._update_platform()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.PLATFORM_RET_VAL, info._platform)
+
+ @mock.patch.object(platform, 'platform',
+ mock.Mock(side_effect=Exception))
+ def test_xcption_in_update_platform(self):
+ info = na_utils.OpenStackInfo()
+ info._update_platform()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+
+ @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_version',
+ mock.Mock(return_value=VERSION_INFO_VERSION))
+ @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_release',
+ mock.Mock(return_value=VERSION_INFO_RELEASE))
+ def test_update_info_from_version_info(self):
+ info = na_utils.OpenStackInfo()
+ info._update_info_from_version_info()
+
+ self.assertEqual(self.VERSION_INFO_VERSION, info._version)
+ self.assertEqual(self.VERSION_INFO_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+
+ @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_version',
+ mock.Mock(return_value=''))
+ @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_release',
+ mock.Mock(return_value=None))
+ def test_no_info_from_version_info(self):
+ info = na_utils.OpenStackInfo()
+ info._update_info_from_version_info()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+
+ @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_version',
+ mock.Mock(return_value=VERSION_INFO_VERSION))
+ @mock.patch.object(na_utils.OpenStackInfo, '_get_version_info_release',
+ mock.Mock(side_effect=Exception))
+ def test_xcption_in_info_from_version_info(self):
+ info = na_utils.OpenStackInfo()
+ info._update_info_from_version_info()
+
+ self.assertEqual(self.VERSION_INFO_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+
+ @mock.patch.object(putils, 'execute',
+ mock.Mock(return_value=PUTILS_RPM_RET_VAL))
+ def test_update_info_from_rpm(self):
+ info = na_utils.OpenStackInfo()
+ found_package = info._update_info_from_rpm()
+
+ self.assertEqual(self.RPM_INFO_VERSION, info._version)
+ self.assertEqual(self.RPM_INFO_RELEASE, info._release)
+ self.assertEqual(self.RPM_INFO_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+ self.assertTrue(found_package)
+
+ @mock.patch.object(putils, 'execute',
+ mock.Mock(return_value=NO_PKG_FOUND))
+ def test_update_info_from_rpm_no_pkg_found(self):
+ info = na_utils.OpenStackInfo()
+ found_package = info._update_info_from_rpm()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+ self.assertFalse(found_package)
+
+ @mock.patch.object(putils, 'execute',
+ mock.Mock(side_effect=Exception))
+ def test_xcption_in_update_info_from_rpm(self):
+ info = na_utils.OpenStackInfo()
+ found_package = info._update_info_from_rpm()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+ self.assertFalse(found_package)
+
+ @mock.patch.object(putils, 'execute',
+ mock.Mock(return_value=PUTILS_DPKG_RET_VAL))
+ def test_update_info_from_dpkg(self):
+ info = na_utils.OpenStackInfo()
+ found_package = info._update_info_from_dpkg()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.DEB_RLS, info._release)
+ self.assertEqual(self.DEB_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+ self.assertTrue(found_package)
+
+ @mock.patch.object(putils, 'execute',
+ mock.Mock(return_value=NO_PKG_FOUND))
+ def test_update_info_from_dpkg_no_pkg_found(self):
+ info = na_utils.OpenStackInfo()
+ found_package = info._update_info_from_dpkg()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+ self.assertFalse(found_package)
+
+ @mock.patch.object(putils, 'execute',
+ mock.Mock(side_effect=Exception))
+ def test_xcption_in_update_info_from_dpkg(self):
+ info = na_utils.OpenStackInfo()
+ found_package = info._update_info_from_dpkg()
+
+ self.assertEqual(self.UNKNOWN_VERSION, info._version)
+ self.assertEqual(self.UNKNOWN_RELEASE, info._release)
+ self.assertEqual(self.UNKNOWN_VENDOR, info._vendor)
+ self.assertEqual(self.UNKNOWN_PLATFORM, info._platform)
+ self.assertFalse(found_package)
+
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_version_from_version_string', mock.Mock())
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_release_from_release_string', mock.Mock())
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_platform', mock.Mock())
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_info_from_version_info', mock.Mock())
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_info_from_rpm', mock.Mock(return_value=True))
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_info_from_dpkg')
+ def test_update_openstack_info_rpm_pkg_found(self, mock_updt_from_dpkg):
+ info = na_utils.OpenStackInfo()
+ info._update_openstack_info()
+
+ self.assertFalse(mock_updt_from_dpkg.called)
+
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_version_from_version_string', mock.Mock())
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_release_from_release_string', mock.Mock())
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_platform', mock.Mock())
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_info_from_version_info', mock.Mock())
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_info_from_rpm', mock.Mock(return_value=False))
+ @mock.patch.object(na_utils.OpenStackInfo,
+ '_update_info_from_dpkg')
+ def test_update_openstack_info_rpm_pkg_not_found(self,
+ mock_updt_from_dpkg):
+ info = na_utils.OpenStackInfo()
+ info._update_openstack_info()
+
+ self.assertTrue(mock_updt_from_dpkg.called)
import binascii
import copy
import decimal
+import platform
import socket
import uuid
from cinder import exception
from cinder.i18n import _
from cinder.openstack.common import log as logging
+from cinder.openstack.common import processutils as putils
from cinder.openstack.common import timeutils
from cinder import utils
+from cinder import version
from cinder.volume.drivers.netapp.api import NaApiError
from cinder.volume.drivers.netapp.api import NaElement
from cinder.volume.drivers.netapp.api import NaErrors
'netapp_thick_provisioned': 'netapp_thin_provisioned'}
-def provide_ems(requester, server, stats, netapp_backend,
+def provide_ems(requester, server, netapp_backend, app_version,
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):
+
+ def _create_ems(netapp_backend, app_version, 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"
+ if server_type == "cluster":
+ dest = "cluster node"
+ else:
+ dest = "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('app-version', app_version)
ems_log.add_new_child('category', 'provisioning')
ems_log.add_new_child('event-description',
- 'OpenStack volume created on %s' % dest)
+ 'OpenStack Cinder connected to %s' % dest)
ems_log.add_new_child('log-level', '6')
- ems_log.add_new_child('auto-support', 'true')
+ ems_log.add_new_child('auto-support', 'false')
return ems_log
def _create_vs_get():
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)):
+ sec_limit = 3559
+ if not (timeutils.is_older_than(requester.last_ems, sec_limit)):
do_ems = False
if do_ems:
na_server = copy.copy(server)
na_server.set_timeout(25)
- ems = _create_ems(stats, netapp_backend, server_type)
+ ems = _create_ems(netapp_backend, app_version, server_type)
try:
if server_type == "cluster":
api_version = na_server.get_api_version()
msg = _('Extra spec %(old)s is deprecated. Use %(new)s instead.')
args = {'old': spec, 'new': DEPRECATED_SSC_SPECS[spec]}
LOG.warn(msg % args)
+
+
+class OpenStackInfo(object):
+ """OS/distribution, release, and version.
+
+ NetApp uses these fields as content for EMS log entry.
+ """
+
+ PACKAGE_NAME = 'python-cinder'
+
+ def __init__(self):
+ self._version = 'unknown version'
+ self._release = 'unknown release'
+ self._vendor = 'unknown vendor'
+ self._platform = 'unknown platform'
+
+ def _update_version_from_version_string(self):
+ try:
+ self._version = version.version_info.version_string()
+ except Exception:
+ pass
+
+ def _update_release_from_release_string(self):
+ try:
+ self._release = version.version_info.release_string()
+ except Exception:
+ pass
+
+ def _update_platform(self):
+ try:
+ self._platform = platform.platform()
+ except Exception:
+ pass
+
+ @staticmethod
+ def _get_version_info_version():
+ return version.version_info.version
+
+ @staticmethod
+ def _get_version_info_release():
+ return version.version_info.release
+
+ def _update_info_from_version_info(self):
+ try:
+ ver = self._get_version_info_version()
+ if ver:
+ self._version = ver
+ except Exception:
+ pass
+ try:
+ rel = self._get_version_info_release()
+ if rel:
+ self._release = rel
+ except Exception:
+ pass
+
+ # RDO, RHEL-OSP, Mirantis on Redhat, SUSE
+ def _update_info_from_rpm(self):
+ LOG.debug('Trying rpm command.')
+ try:
+ out, err = putils.execute("rpm", "-qa", "--queryformat",
+ "'%{version}\t%{release}\t%{vendor}'",
+ self.PACKAGE_NAME)
+ if not out:
+ LOG.info(_('No rpm info found for %(pkg)s package.') % {
+ 'pkg': self.PACKAGE_NAME})
+ return False
+ parts = out.split()
+ self._version = parts[0]
+ self._release = parts[1]
+ self._vendor = ' '.join(parts[2::])
+ return True
+ except Exception as e:
+ LOG.info(_('Could not run rpm command: %(msg)s.') % {
+ 'msg': e})
+ return False
+
+ # ubuntu, mirantis on ubuntu
+ def _update_info_from_dpkg(self):
+ LOG.debug('Trying dpkg-query command.')
+ try:
+ _vendor = None
+ out, err = putils.execute("dpkg-query", "-W", "-f='${Version}'",
+ self.PACKAGE_NAME)
+ if not out:
+ LOG.info(_('No dpkg-query info found for %(pkg)s package.') % {
+ 'pkg': self.PACKAGE_NAME})
+ return False
+ # debian format: [epoch:]upstream_version[-debian_revision]
+ deb_version = out
+ # in case epoch or revision is missing, copy entire string
+ _release = deb_version
+ if ':' in deb_version:
+ deb_epoch, upstream_version = deb_version.split(':')
+ _release = upstream_version
+ if '-' in deb_version:
+ deb_revision = deb_version.split('-')[1]
+ _vendor = deb_revision
+ self._release = _release
+ if _vendor:
+ self._vendor = _vendor
+ return True
+ except Exception as e:
+ LOG.info(_('Could not run dpkg-query command: %(msg)s.') % {
+ 'msg': e})
+ return False
+
+ def _update_openstack_info(self):
+ self._update_version_from_version_string()
+ self._update_release_from_release_string()
+ self._update_platform()
+ # some distributions override with more meaningful information
+ self._update_info_from_version_info()
+ # see if we have still more targeted info from rpm or apt
+ found_package = self._update_info_from_rpm()
+ if not found_package:
+ self._update_info_from_dpkg()
+
+ def info(self):
+ self._update_openstack_info()
+ return '%(version)s|%(release)s|%(vendor)s|%(platform)s' % {
+ 'version': self._version, 'release': self._release,
+ 'vendor': self._vendor, 'platform': self._platform}