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