From 716a32cbd9161f79dc63383d34a606d7c04450e7 Mon Sep 17 00:00:00 2001
From: Guido Trotter <ultrotter@google.com>
Date: Fri, 28 May 2010 19:48:17 +0100
Subject: [PATCH] Move hash functions to the compat module

Since the hash functions' changed their module name between python 2.4
and 2.6, and we have to do an try/import/except trick, we'll do it just
once, for both hash functions, and in compat.py. This also fixes a use
of md5 in the utils unittests which didn't use the trick before, and
generated a deprecation warning under 2.6.

In compat we keep both a ganeti-wide non-version-specific version to be
used by other ganeti modules, and a python-version specific that can be
passed to python modules which expect a hash function for their input
but call it differently under different versions of python (hmac, for
example).

Signed-off-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 lib/compat.py                 | 19 +++++++++++++++++++
 lib/http/auth.py              |  9 ++-------
 lib/utils.py                  | 13 +++----------
 test/ganeti.utils_unittest.py |  6 +++---
 4 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/lib/compat.py b/lib/compat.py
index 692ab246f..db3ae2874 100644
--- a/lib/compat.py
+++ b/lib/compat.py
@@ -31,6 +31,25 @@ except ImportError:
   functools = None
 
 
+# compat.md5_hash and compat.sha1_hash can be called to generate and md5 and a
+# sha1 hashing modules, under python 2.4, 2.5 and 2.6, even though some changes
+# went on. compat.sha1 is python-version specific and is used for python
+# modules (hmac, for example) which have changed their behavior as well from
+# one version to the other.
+try:
+  # Yes, we're not using the imports in this module.
+  # pylint: disable-msg=W0611
+  from hashlib import md5 as md5_hash
+  from hashlib import sha1 as sha1_hash
+  # this additional version is needed for compatibility with the hmac module
+  sha1 = sha1_hash
+except ImportError:
+  from md5 import new as md5_hash
+  import sha
+  sha1 = sha
+  sha1_hash = sha.new
+
+
 def all(seq, pred=bool): # pylint: disable-msg=W0622
   """Returns True if pred(x) is True for every element in the iterable.
 
diff --git a/lib/http/auth.py b/lib/http/auth.py
index f71ede097..f66f54bf9 100644
--- a/lib/http/auth.py
+++ b/lib/http/auth.py
@@ -28,16 +28,11 @@ import base64
 import binascii
 
 from ganeti import utils
+from ganeti import compat
 from ganeti import http
 
 from cStringIO import StringIO
 
-try:
-  from hashlib import md5
-except ImportError:
-  from md5 import new as md5
-
-
 # Digest types from RFC2617
 HTTP_BASIC_AUTH = "Basic"
 HTTP_DIGEST_AUTH = "Digest"
@@ -271,7 +266,7 @@ class HttpServerRequestAuthentication(object):
         # There can not be a valid password for this case
         raise AssertionError("No authentication realm")
 
-      expha1 = md5()
+      expha1 = compat.md5_hash()
       expha1.update("%s:%s:%s" % (username, realm, password))
 
       return (expected_password.lower() == expha1.hexdigest().lower())
diff --git a/lib/utils.py b/lib/utils.py
index 7b93870d8..f2f00b56b 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -54,11 +54,6 @@ import IN
 
 from cStringIO import StringIO
 
-try:
-  from hashlib import sha1
-except ImportError:
-  import sha as sha1
-
 try:
   import ctypes
 except ImportError:
@@ -66,6 +61,7 @@ except ImportError:
 
 from ganeti import errors
 from ganeti import constants
+from ganeti import compat
 
 
 _locksheld = []
@@ -748,10 +744,7 @@ def _FingerprintFile(filename):
 
   f = open(filename)
 
-  if callable(sha1):
-    fp = sha1()
-  else:
-    fp = sha1.new()
+  fp = compat.sha1_hash()
   while True:
     data = f.read(4096)
     if not data:
@@ -2799,7 +2792,7 @@ def Sha1Hmac(key, text, salt=None):
   else:
     salted_text = text
 
-  return hmac.new(key, salted_text, sha1).hexdigest()
+  return hmac.new(key, salted_text, compat.sha1).hexdigest()
 
 
 def VerifySha1Hmac(key, text, digest, salt=None):
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index 511e48a54..d72232ba4 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -39,12 +39,12 @@ import OpenSSL
 import warnings
 import distutils.version
 import glob
-import md5
 import errno
 
 import ganeti
 import testutils
 from ganeti import constants
+from ganeti import compat
 from ganeti import utils
 from ganeti import errors
 from ganeti import serializer
@@ -670,7 +670,7 @@ class TestReadFile(testutils.GanetiTestCase):
     data = utils.ReadFile(self._TestDataFilename("cert1.pem"))
     self.assertEqual(len(data), 814)
 
-    h = md5.new()
+    h = compat.md5_hash()
     h.update(data)
     self.assertEqual(h.hexdigest(), "a491efb3efe56a0535f924d5f8680fd4")
 
@@ -679,7 +679,7 @@ class TestReadFile(testutils.GanetiTestCase):
                           size=100)
     self.assertEqual(len(data), 100)
 
-    h = md5.new()
+    h = compat.md5_hash()
     h.update(data)
     self.assertEqual(h.hexdigest(), "893772354e4e690b9efd073eed433ce7")
 
-- 
GitLab