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