1# -*- coding: utf-8 -*- 2# Copyright 2011 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Compute image checksum.""" 7 8 9import os 10import threading 11 12from cros_utils import logger 13from cros_utils.file_utils import FileUtils 14 15 16class ImageChecksummer(object): 17 """Compute image checksum.""" 18 19 class PerImageChecksummer(object): 20 """Compute checksum for an image.""" 21 22 def __init__(self, label, log_level): 23 self._lock = threading.Lock() 24 self.label = label 25 self._checksum = None 26 self.log_level = log_level 27 28 def Checksum(self): 29 with self._lock: 30 if not self._checksum: 31 logger.GetLogger().LogOutput( 32 "Acquiring checksum for '%s'." % self.label.name 33 ) 34 self._checksum = None 35 if self.label.image_type != "local": 36 raise RuntimeError( 37 "Called Checksum on non-local image!" 38 ) 39 if self.label.chromeos_image: 40 if os.path.exists(self.label.chromeos_image): 41 self._checksum = FileUtils().Md5File( 42 self.label.chromeos_image, 43 log_level=self.log_level, 44 ) 45 logger.GetLogger().LogOutput( 46 "Computed checksum is " ": %s" % self._checksum 47 ) 48 if not self._checksum: 49 raise RuntimeError("Checksum computing error.") 50 logger.GetLogger().LogOutput( 51 "Checksum is: %s" % self._checksum 52 ) 53 return self._checksum 54 55 _instance = None 56 _lock = threading.Lock() 57 _per_image_checksummers = {} 58 59 def __new__(cls, *args, **kwargs): 60 with cls._lock: 61 if not cls._instance: 62 cls._instance = super(ImageChecksummer, cls).__new__( 63 cls, *args, **kwargs 64 ) 65 return cls._instance 66 67 def Checksum(self, label, log_level): 68 if label.image_type != "local": 69 raise RuntimeError("Attempt to call Checksum on non-local image.") 70 with self._lock: 71 if label.name not in self._per_image_checksummers: 72 self._per_image_checksummers[ 73 label.name 74 ] = ImageChecksummer.PerImageChecksummer(label, log_level) 75 checksummer = self._per_image_checksummers[label.name] 76 77 try: 78 return checksummer.Checksum() 79 except: 80 logger.GetLogger().LogError( 81 "Could not compute checksum of image in label" 82 " '%s'." % label.name 83 ) 84 raise 85