1# Copyright 2011 Google Inc. All Rights Reserved. 2"""Compute image checksum.""" 3 4from __future__ import print_function 5 6import os 7import threading 8 9from cros_utils import logger 10from cros_utils.file_utils import FileUtils 11 12 13class 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