... which converts decimal numbers into '/dev/sda', '/dev/sdb', etc.

Signed-off-by: Jose A. Lopes <[email protected]>
---
 lib/utils/storage.py                     | 33 +++++++++++++++++++++++
 test/py/ganeti.utils.storage_unittest.py | 45 ++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/lib/utils/storage.py b/lib/utils/storage.py
index e0328ff..64e2ec2 100644
--- a/lib/utils/storage.py
+++ b/lib/utils/storage.py
@@ -173,3 +173,36 @@ def LookupSpaceInfoByStorageType(storage_space_info, 
storage_type):
         logging.warning("Storage space information requested for"
                         " ambiguous storage type '%s'.", storage_type)
   return result
+
+
+def GetDiskLabels(prefix, num_disks, start=0):
+  """Generate disk labels for a number of disks
+
+  Note that disk labels are generated in the range [start..num_disks[
+  (e.g., as in range(start, num_disks))
+
+  @type prefix: string
+  @param prefix: disk label prefix (e.g., "/dev/sd")
+
+  @type num_disks: int
+  @param num_disks: number of disks (i.e., disk labels)
+
+  @type start: int
+  @param start: optional start index
+
+  @rtype: generator
+  @return: generator for the disk labels
+
+  """
+  def _GetDiskSuffix(i):
+    n = ord('z') - ord('a') + 1
+    if i < n:
+      return chr(ord('a') + i)
+    else:
+      mod = int(i % n)
+      pref = _GetDiskSuffix((i - mod) / (n + 1))
+      suf = _GetDiskSuffix(mod)
+      return pref + suf
+
+  for i in range(start, num_disks):
+    yield prefix + _GetDiskSuffix(i)
diff --git a/test/py/ganeti.utils.storage_unittest.py 
b/test/py/ganeti.utils.storage_unittest.py
index ac607ed..64e6277 100755
--- a/test/py/ganeti.utils.storage_unittest.py
+++ b/test/py/ganeti.utils.storage_unittest.py
@@ -110,5 +110,50 @@ class TestLookupSpaceInfoByStorageType(unittest.TestCase):
     self.assertEqual(None, result)
 
 
+class TestGetDiskLabels(unittest.TestCase):
+
+  def setUp(self):
+    pass
+
+  def testNormalPrefix(self):
+    labels = ["/dev/sda", "/dev/sdb", "/dev/sdc", "/dev/sdd",
+              "/dev/sde", "/dev/sdf", "/dev/sdg", "/dev/sdh",
+              "/dev/sdi", "/dev/sdj", "/dev/sdk", "/dev/sdl",
+              "/dev/sdm", "/dev/sdn", "/dev/sdo", "/dev/sdp",
+              "/dev/sdq", "/dev/sdr", "/dev/sds", "/dev/sdt",
+              "/dev/sdu", "/dev/sdv", "/dev/sdw", "/dev/sdx",
+              "/dev/sdy", "/dev/sdz", "/dev/sdaa", "/dev/sdab",
+              "/dev/sdac", "/dev/sdad", "/dev/sdae", "/dev/sdaf",
+              "/dev/sdag", "/dev/sdah", "/dev/sdai", "/dev/sdaj",
+              "/dev/sdak", "/dev/sdal", "/dev/sdam", "/dev/sdan",
+              "/dev/sdao", "/dev/sdap", "/dev/sdaq", "/dev/sdar",
+              "/dev/sdas", "/dev/sdat", "/dev/sdau", "/dev/sdav",
+              "/dev/sdaw", "/dev/sdax", "/dev/sday", "/dev/sdaz",
+              "/dev/sdba", "/dev/sdbb", "/dev/sdbc", "/dev/sdbd",
+              "/dev/sdbe", "/dev/sdbf", "/dev/sdbg", "/dev/sdbh"]
+    result = list(storage.GetDiskLabels("/dev/sd", 60))
+    self.assertEqual(labels, result)
+
+  def testEmptyPrefix(self):
+    labels = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
+              "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
+              "w", "x", "y", "z", "aa", "ab", "ac", "ad", "ae", "af",
+              "ag", "ah", "ai", "aj", "ak", "al", "am", "an", "ao",
+              "ap", "aq", "ar", "as", "at", "au", "av", "aw", "ax",
+              "ay", "az", "ba", "bb", "bc", "bd", "be", "bf", "bg",
+              "bh"]
+    result = list(storage.GetDiskLabels("", 60))
+    self.assertEqual(labels, result)
+
+  def testWrapAt2To3(self):
+    start1 = 27
+    start2 = 703
+    result1 = list(storage.GetDiskLabels("", start1))
+    result2 = \
+        map(lambda x: x[1:],
+            list(storage.GetDiskLabels("", start2, start=start2 - start1)))
+    self.assertEqual(result1, result2)
+
+
 if __name__ == "__main__":
   testutils.GanetiTestProgram()
-- 
1.9.1.423.g4596e3a

Reply via email to