• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# -*- coding: utf-8 -*-
2# Copyright 2011 The Chromium OS Authors. All rights reserved.
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
8from __future__ import print_function
9
10import os
11import threading
12
13from cros_utils import logger
14from cros_utils.file_utils import FileUtils
15
16
17class ImageChecksummer(object):
18  """Compute image checksum."""
19
20  class PerImageChecksummer(object):
21    """Compute checksum for an image."""
22
23    def __init__(self, label, log_level):
24      self._lock = threading.Lock()
25      self.label = label
26      self._checksum = None
27      self.log_level = log_level
28
29    def Checksum(self):
30      with self._lock:
31        if not self._checksum:
32          logger.GetLogger().LogOutput(
33              "Acquiring checksum for '%s'." % self.label.name)
34          self._checksum = None
35          if self.label.image_type != 'local':
36            raise RuntimeError('Called Checksum on non-local image!')
37          if self.label.chromeos_image:
38            if os.path.exists(self.label.chromeos_image):
39              self._checksum = FileUtils().Md5File(
40                  self.label.chromeos_image, log_level=self.log_level)
41              logger.GetLogger().LogOutput('Computed checksum is '
42                                           ': %s' % self._checksum)
43          if not self._checksum:
44            raise RuntimeError('Checksum computing error.')
45          logger.GetLogger().LogOutput('Checksum is: %s' % self._checksum)
46        return self._checksum
47
48  _instance = None
49  _lock = threading.Lock()
50  _per_image_checksummers = {}
51
52  def __new__(cls, *args, **kwargs):
53    with cls._lock:
54      if not cls._instance:
55        cls._instance = super(ImageChecksummer, cls).__new__(
56            cls, *args, **kwargs)
57      return cls._instance
58
59  def Checksum(self, label, log_level):
60    if label.image_type != 'local':
61      raise RuntimeError('Attempt to call Checksum on non-local image.')
62    with self._lock:
63      if label.name not in self._per_image_checksummers:
64        self._per_image_checksummers[label.name] = (
65            ImageChecksummer.PerImageChecksummer(label, log_level))
66      checksummer = self._per_image_checksummers[label.name]
67
68    try:
69      return checksummer.Checksum()
70    except:
71      logger.GetLogger().LogError('Could not compute checksum of image in label'
72                                  " '%s'." % label.name)
73      raise
74