--- /dev/null
+# 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)
SheepDog Volume Driver.
"""
+import re
from cinder import exception
from cinder import 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:
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