From 81dcc2c2f1cd2fa6874c63fe13a46b51a64c6657 Mon Sep 17 00:00:00 2001
From: Bjorn Tillenius <bjorn@tillenius.me>
Date: Fri, 24 Oct 2014 14:29:07 +0000
Subject: [PATCH] Apply the patch from
 lp:~tribaal/charms/trusty/swift-storage/trunk-fix-1350049.

---
 hooks/swift_storage_utils.py           | 14 ++++++++++---
 unit_tests/test_swift_storage_utils.py | 29 ++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/hooks/swift_storage_utils.py b/hooks/swift_storage_utils.py
index d0aaabd..8f11a67 100644
--- a/hooks/swift_storage_utils.py
+++ b/hooks/swift_storage_utils.py
@@ -37,6 +37,7 @@ from charmhelpers.core.hookenv import (
 
 from charmhelpers.contrib.storage.linux.utils import (
     is_block_device,
+    is_device_mounted,
 )
 
 from charmhelpers.contrib.openstack.utils import (
@@ -141,10 +142,17 @@ def do_openstack_upgrade(configs):
      (ACCOUNT_SVCS + CONTAINER_SVCS + OBJECT_SVCS)]
 
 
+def _is_storage_ready(partition):
+    """
+    A small helper to determine if a given device is suitabe to be used as
+    a storage device.
+    """
+    return is_block_device(partition) and not is_device_mounted(partition)
+
+
 def find_block_devices():
     found = []
     incl = ['sd[a-z]', 'vd[a-z]', 'cciss\/c[0-9]d[0-9]']
-    blacklist = ['sda', 'vda', 'cciss/c0d0']
 
     with open('/proc/partitions') as proc:
         print proc
@@ -152,9 +160,9 @@ def find_block_devices():
     for partition in [p[3] for p in partitions if p]:
         for inc in incl:
             _re = re.compile(r'^(%s)$' % inc)
-            if _re.match(partition) and partition not in blacklist:
+            if _re.match(partition):
                 found.append(os.path.join('/dev', partition))
-    return [f for f in found if is_block_device(f)]
+    return [f for f in found if _is_storage_ready(f)]
 
 
 def determine_block_devices():
diff --git a/unit_tests/test_swift_storage_utils.py b/unit_tests/test_swift_storage_utils.py
index ec7b0e9..016a550 100644
--- a/unit_tests/test_swift_storage_utils.py
+++ b/unit_tests/test_swift_storage_utils.py
@@ -17,6 +17,7 @@ TO_PATCH = [
     'ensure_block_device',
     'clean_storage',
     'is_block_device',
+    'is_device_mounted',
     'get_os_codename_package',
     'get_os_codename_install_source',
     'unit_private_ip',
@@ -62,6 +63,15 @@ SCRIPT_RC_ENV = {
 }
 
 
+REAL_WORLD_PARTITIONS = """
+major minor  #blocks  name
+
+   8        0  117220824 sda
+   8        1  117219800 sda1
+   8       16  119454720 sdb
+"""
+
+
 class SwiftStorageUtilsTests(CharmTestCase):
 
     def setUp(self):
@@ -172,8 +182,15 @@ class SwiftStorageUtilsTests(CharmTestCase):
                                       group='swift')
         self.mount.assert_called('/dev/vdb', '/srv/node/vdb', persist=True)
 
+    def _fake_is_device_mounted(self, device):
+        if device in ["/dev/sda", "/dev/vda", "/dev/cciss/c0d0"]:
+            return True
+        else:
+            return False
+
     def test_find_block_devices(self):
         self.is_block_device.return_value = True
+        self.is_device_mounted.side_effect = self._fake_is_device_mounted
         with patch_open() as (_open, _file):
             _file.read.return_value = PROC_PARTITIONS
             _file.readlines = MagicMock()
@@ -182,6 +199,18 @@ class SwiftStorageUtilsTests(CharmTestCase):
         ex = ['/dev/sdb', '/dev/vdb', '/dev/cciss/c1d0']
         self.assertEquals(ex, result)
 
+    def test_find_block_devices_real_world(self):
+        self.is_block_device.return_value = True
+        side_effect = lambda x: x in ["/dev/sda", "/dev/sda1"]
+        self.is_device_mounted.side_effect = side_effect
+        with patch_open() as (_open, _file):
+            _file.read.return_value = REAL_WORLD_PARTITIONS
+            _file.readlines = MagicMock()
+            _file.readlines.return_value = REAL_WORLD_PARTITIONS.split('\n')
+            result = swift_utils.find_block_devices()
+        expected = ["/dev/sdb"]
+        self.assertEquals(expected, result)
+
     def test_save_script_rc(self):
         self.unit_private_ip.return_value = '10.0.0.1'
         swift_utils.save_script_rc()