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