Home | History | Annotate | Download | only in crosperf
      1 # Copyright 2011 Google Inc. All Rights Reserved.
      2 """Compute image checksum."""
      3 
      4 from __future__ import print_function
      5 
      6 import os
      7 import threading
      8 
      9 from cros_utils import logger
     10 from cros_utils.file_utils import FileUtils
     11 
     12 
     13 class ImageChecksummer(object):
     14   """Compute image checksum."""
     15 
     16   class PerImageChecksummer(object):
     17     """Compute checksum for an image."""
     18 
     19     def __init__(self, label, log_level):
     20       self._lock = threading.Lock()
     21       self.label = label
     22       self._checksum = None
     23       self.log_level = log_level
     24 
     25     def Checksum(self):
     26       with self._lock:
     27         if not self._checksum:
     28           logger.GetLogger().LogOutput("Acquiring checksum for '%s'." %
     29                                        self.label.name)
     30           self._checksum = None
     31           if self.label.image_type != 'local':
     32             raise RuntimeError('Called Checksum on non-local image!')
     33           if self.label.chromeos_image:
     34             if os.path.exists(self.label.chromeos_image):
     35               self._checksum = FileUtils().Md5File(
     36                   self.label.chromeos_image, log_level=self.log_level)
     37               logger.GetLogger().LogOutput('Computed checksum is '
     38                                            ': %s' % self._checksum)
     39           if not self._checksum:
     40             raise RuntimeError('Checksum computing error.')
     41           logger.GetLogger().LogOutput('Checksum is: %s' % self._checksum)
     42         return self._checksum
     43 
     44   _instance = None
     45   _lock = threading.Lock()
     46   _per_image_checksummers = {}
     47 
     48   def __new__(cls, *args, **kwargs):
     49     with cls._lock:
     50       if not cls._instance:
     51         cls._instance = super(ImageChecksummer, cls).__new__(cls, *args,
     52                                                              **kwargs)
     53       return cls._instance
     54 
     55   def Checksum(self, label, log_level):
     56     if label.image_type != 'local':
     57       raise RuntimeError('Attempt to call Checksum on non-local image.')
     58     with self._lock:
     59       if label.name not in self._per_image_checksummers:
     60         self._per_image_checksummers[label.name] = (
     61             ImageChecksummer.PerImageChecksummer(label, log_level))
     62       checksummer = self._per_image_checksummers[label.name]
     63 
     64     try:
     65       return checksummer.Checksum()
     66     except:
     67       logger.GetLogger().LogError('Could not compute checksum of image in label'
     68                                   " '%s'." % label.name)
     69       raise
     70