1#!/usr/bin/env python3

2# This file is part of Checkbox.

3#

4# Copyright 2024 Canonical Ltd.

5# Written by:

6# Stanley Huang <stanley.huang@canonical.com>

7#

8# Checkbox is free software: you can redistribute it and/or modify

9# it under the terms of the GNU General Public License version 3,

10# as published by the Free Software Foundation.

11#

12# Checkbox is distributed in the hope that it will be useful,

13# but WITHOUT ANY WARRANTY; without even the implied warranty of

14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

15# GNU General Public License for more details.

16#

17# You should have received a copy of the GNU General Public License

18# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.

19

20 import os

21 import sys

22 import json

23 import shlex

24 import logging

25 import subprocess

26 from checkbox_support.snap_utils.snapd import Snapd

27

28

29 def get_fwupdmgr_services_versions():

30 """Show fwupd client and daemon versions

31

32 Returns:

33 list: fwupd client and daemon versions

34 """

35 fwupd_vers = subprocess.run(

36 shlex.split("fwupdmgr --version --json"), capture_output=True

37 )

38 fwupd_vers = json.loads(fwupd_vers.stdout).get("Versions", [])

39

40 return fwupd_vers

41

42

43 def get_fwupd_runtime_version():

44 """Get fwupd runtime version

45

46 Returns:

47 tuple: fwupd runtime version

48 """

49 runtime_ver = ()

50

51 for ver in get_fwupdmgr_services_versions():

52 if (

53 ver.get("Type") == "runtime"

54 and ver.get("AppstreamId") == "org.freedesktop.fwupd"

55 ):

56 runtime_ver = tuple(map(int, ver.get("Version").split(".")))

57

58 return runtime_ver

59

60

61 def get_firmware_info_fwupd():

62 """

63 Dump firmware information for all devices detected by fwupd

64 """

65 if Snapd().list("fwupd"):

66 # Dump firmware info by fwupd snap

67 subprocess.run(shlex.split("fwupd.fwupdmgr get-devices --json"))

68 else:

69 # Dump firmware info by fwupd debian package

70 runtime_ver = get_fwupd_runtime_version()

71 # Apply workaround to unset the SNAP for the fwupd issue

72 # See details from following PR

73 # https://github.com/canonical/checkbox/pull/1089

74

75 # SNAP environ is avaialble, so it's running on checkbox snap

76 # Unset the environ variable if debian fwupd lower than 1.9.14

77 if os.environ.get("SNAP") and runtime_ver < (1, 9, 14):

78 del os.environ["SNAP"]

79

80 subprocess.run(shlex.split("fwupdmgr get-devices --json"))

81

82

83 if __name__ == "__main__":

84

85 root_logger = logging.getLogger()

86 root_logger.setLevel(logging.INFO)

87 logger_format = "%(asctime)s %(levelname)-8s %(message)s"

88 date_format = "%Y-%m-%d %H:%M:%S"

89

90 # Log DEBUG and INFO to stdout, others to stderr

91 stdout_handler = logging.StreamHandler(sys.stdout)

92 stdout_handler.setFormatter(logging.Formatter(logger_format, date_format))

93

94 stderr_handler = logging.StreamHandler(sys.stderr)

95 stderr_handler.setFormatter(logging.Formatter(logger_format, date_format))

96

97 stdout_handler.setLevel(logging.DEBUG)

98 stderr_handler.setLevel(logging.WARNING)

99

100 # Add a filter to the stdout handler to limit log records to

101 # INFO level and below

102 stdout_handler.addFilter(lambda record: record.levelno <= logging.INFO)

103

104 root_logger.addHandler(stderr_handler)

105 root_logger.addHandler(stdout_handler)

106

107 try:

108 get_firmware_info_fwupd()

109 except Exception as err:

110 logging.error(err)