diff --git a/lib/utils.py b/lib/utils.py
index 07bdc0e45fb731245561810967944243751e0d6e..31762d3753ce320057a27368fded63838018ee7d 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -365,20 +365,29 @@ def RenameFile(old, new, mkdir=False, mkdir_mode=0750):
# as efficient.
if mkdir and err.errno == errno.ENOENT:
# Create directory and try again
- dirname = os.path.dirname(new)
- try:
- os.makedirs(dirname, mode=mkdir_mode)
- except OSError, err:
- # Ignore EEXIST. This is only handled in os.makedirs as included in
- # Python 2.5 and above.
- if err.errno != errno.EEXIST or not os.path.exists(dirname):
- raise
+ Makedirs(os.path.dirname(new))
return os.rename(old, new)
raise
+def Makedirs(path, mode=0750):
+ """Super-mkdir; create a leaf directory and all intermediate ones.
+
+ This is a wrapper around C{os.makedirs} adding error handling not implemented
+ before Python 2.5.
+
+ """
+ try:
+ os.makedirs(path, mode)
+ except OSError, err:
+ # Ignore EEXIST. This is only handled in os.makedirs as included in
+ # Python 2.5 and above.
+ if err.errno != errno.EEXIST or not os.path.exists(path):
+ raise
+
+
def ResetTempfileModule():
"""Resets the random name generator of the tempfile module.
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index 7c2a36bb6b7eb8ec83dc0a7e2baf17d4d6f08575..17d10fea653bf2f643442a4c051df026ef6b0b4a 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -1504,5 +1504,36 @@ class TestGetX509CertValidity(testutils.GanetiTestCase):
self.assertEqual(validity, (None, None))
+class TestMakedirs(unittest.TestCase):
+ def setUp(self):
+ self.tmpdir = tempfile.mkdtemp()
+
+ def tearDown(self):
+ shutil.rmtree(self.tmpdir)
+
+ def testNonExisting(self):
+ path = utils.PathJoin(self.tmpdir, "foo")
+ utils.Makedirs(path)
+ self.assert_(os.path.isdir(path))
+
+ def testExisting(self):
+ path = utils.PathJoin(self.tmpdir, "foo")
+ os.mkdir(path)
+ utils.Makedirs(path)
+ self.assert_(os.path.isdir(path))
+
+ def testRecursiveNonExisting(self):
+ path = utils.PathJoin(self.tmpdir, "foo/bar/baz")
+ utils.Makedirs(path)
+ self.assert_(os.path.isdir(path))
+
+ def testRecursiveExisting(self):
+ path = utils.PathJoin(self.tmpdir, "B/moo/xyz")
+ self.assert_(not os.path.exists(path))
+ os.mkdir(utils.PathJoin(self.tmpdir, "B"))
+ utils.Makedirs(path)
+ self.assert_(os.path.isdir(path))
+
+
if __name__ == '__main__':
testutils.GanetiTestProgram()