From 1867b89a53e3e46394e9db80e0dc82471661068c Mon Sep 17 00:00:00 2001 From: Wenhao Xu Date: Sun, 3 Mar 2013 01:19:08 +0800 Subject: [PATCH] Add get_volume_stats in the sheepdog driver. 1. Allow sheepdog driver to report capabilities to the scheduler. 2. add the initial test_sheepdog.py Fixes Bug #1140162 Change-Id: I6fb1fb6714ab4ae9878b593e6eee0a94d95ef29f --- cinder/tests/test_sheepdog.py | 64 +++++++++++++++++++++++++++++++ cinder/volume/drivers/sheepdog.py | 32 ++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 cinder/tests/test_sheepdog.py diff --git a/cinder/tests/test_sheepdog.py b/cinder/tests/test_sheepdog.py new file mode 100644 index 000000000..70fab1afd --- /dev/null +++ b/cinder/tests/test_sheepdog.py @@ -0,0 +1,64 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 Wenhao Xu +# 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. + +from cinder import exception +from cinder import test +from cinder.volume.drivers.sheepdog import SheepdogDriver + +COLLIE_NODE_INFO = """ +0 107287605248 3623897354 3% +Total 107287605248 3623897354 3% 54760833024 +""" + + +class SheepdogTestCase(test.TestCase): + + def setUp(self): + super(SheepdogTestCase, self).setUp() + self.driver = SheepdogDriver() + + def test_update_volume_stats(self): + def fake_stats(*args): + return COLLIE_NODE_INFO, '' + self.stubs.Set(self.driver, '_execute', fake_stats) + expected = dict( + volume_backend_name='sheepdog', + vendor_name='Open Source', + dirver_version='1.0', + storage_protocol='sheepdog', + total_capacity_gb=float(107287605248) / (1024 ** 3), + free_capacity_gb=float(107287605248 - 3623897354) / (1024 ** 3), + reserved_percentage=0, + QoS_support=False) + actual = self.driver.get_volume_stats(True) + self.assertDictMatch(expected, actual) + + def test_update_volume_stats_error(self): + def fake_stats(*args): + raise exception.ProcessExecutionError() + self.stubs.Set(self.driver, '_execute', fake_stats) + expected = dict( + volume_backend_name='sheepdog', + vendor_name='Open Source', + dirver_version='1.0', + storage_protocol='sheepdog', + total_capacity_gb='unknown', + free_capacity_gb='unknown', + reserved_percentage=0, + QoS_support=False) + actual = self.driver.get_volume_stats(True) + self.assertDictMatch(expected, actual) diff --git a/cinder/volume/drivers/sheepdog.py b/cinder/volume/drivers/sheepdog.py index 9fb390482..d1916c7ad 100644 --- a/cinder/volume/drivers/sheepdog.py +++ b/cinder/volume/drivers/sheepdog.py @@ -16,6 +16,7 @@ SheepDog Volume Driver. """ +import re from cinder import exception from cinder import flags @@ -30,6 +31,19 @@ FLAGS = flags.FLAGS class SheepdogDriver(driver.VolumeDriver): """Executes commands relating to Sheepdog Volumes""" + def __init__(self, *args, **kwargs): + super(SheepdogDriver, self).__init__(*args, **kwargs) + self._stats = dict( + volume_backend_name='sheepdog', + vendor_name='Open Source', + dirver_version='1.0', + storage_protocol='sheepdog', + total_capacity_gb='unknown', + free_capacity_gb='unknown', + reserved_percentage=0, + QoS_support=False) + self.stats_pattern = re.compile(r'[\w\s%]*Total\s(\d+)\s(\d+)*') + def check_for_setup_error(self): """Returns an error if prerequisites aren't met""" try: @@ -101,3 +115,21 @@ class SheepdogDriver(driver.VolumeDriver): def terminate_connection(self, volume, connector, **kwargs): pass + + def _update_volume_stats(self): + stats = {} + try: + stdout, _err = self._execute('collie', 'node', 'info', '-r') + m = self.stats_pattern.match(stdout) + total = float(m.group(1)) + used = float(m.group(2)) + stats['total_capacity_gb'] = total / (1024 ** 3) + stats['free_capacity_gb'] = (total - used) / (1024 ** 3) + except exception.ProcessExecutionError: + LOG.exception(_('error refreshing volume stats')) + self._stats.update(stats) + + def get_volume_stats(self, refresh=False): + if refresh: + self._update_volume_stats() + return self._stats -- 2.45.2