image_checksummer.py revision 139092449a545d4d87c06af3a6d8f3d71e42e927
1#!/usr/bin/python
2
3# Copyright 2011 Google Inc. All Rights Reserved.
4
5import os
6import threading
7
8from utils import logger
9from utils.file_utils import FileUtils
10
11
12class ImageChecksummer(object):
13  class PerImageChecksummer(object):
14    def __init__(self, label, log_level):
15      self._lock = threading.Lock()
16      self.label = label
17      self._checksum = None
18      self.log_level = log_level
19
20    def Checksum(self):
21      with self._lock:
22        if not self._checksum:
23          logger.GetLogger().LogOutput("Acquiring checksum for '%s'." %
24                                       self.label.name)
25          self._checksum = None
26          if self.label.image_type != "local":
27            raise Exception("Called Checksum on non-local image!")
28          if self.label.chromeos_image:
29            if os.path.exists(self.label.chromeos_image):
30              self._checksum = FileUtils().Md5File(self.label.chromeos_image,
31                                                   log_level=self.log_level)
32              logger.GetLogger().LogOutput("Computed checksum is "
33                                           ": %s" % self._checksum)
34          if not self._checksum:
35            if self.label.image_md5sum:
36              self._checksum = self.label.image_md5sum
37              logger.GetLogger().LogOutput("Checksum in experiment file is "
38                                           ": %s" % self._checksum)
39            else:
40              raise Exception("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,
52                                                             *args, **kwargs)
53      return cls._instance
54
55  def Checksum(self, label, log_level):
56    if label.image_type != "local":
57      raise Exception("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] = (ImageChecksummer.
61                                                    PerImageChecksummer(label,
62                                                                        log_level))
63      checksummer = self._per_image_checksummers[label.name]
64
65    try:
66      return checksummer.Checksum()
67    except Exception, e:
68      logger.GetLogger().LogError("Could not compute checksum of image in label"
69                                  " '%s'."% label.name)
70      raise e
71