diff --git a/providers/base/bin/get_firmware_info_fwupd.py b/providers/base/bin/get_firmware_info_fwupd.py new file mode 100755 index 0000000000..97a1635f28 --- /dev/null +++ b/providers/base/bin/get_firmware_info_fwupd.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# This file is part of Checkbox. +# +# Copyright 2024 Canonical Ltd. +# Written by: +# Stanley Huang +# +# Checkbox is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3, +# as published by the Free Software Foundation. +# +# Checkbox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Checkbox. If not, see . + +import os +import json +import shlex +import subprocess +from checkbox_support.snap_utils.snapd import Snapd + + +def get_firmware_info_fwupd(): + + fwupd_snap = Snapd().list("fwupd") + if fwupd_snap: + # Dump firmware info by fwupd snap + subprocess.run(shlex.split("fwupd.fwupdmgr get-devices --json")) + else: + # Dump firmware info by fwupd debian package + fwupd_vers = subprocess.run( + shlex.split("fwupdmgr --version --json"), + capture_output=True) + fwupd_vers = json.loads(fwupd_vers.stdout) + + runtime_ver = () + for ver in fwupd_vers.get("Versions", []): + if (ver.get("Type") == "runtime" and + ver.get("AppstreamId") == "org.freedesktop.fwupd"): + runtime_ver = tuple(map(int, ver.get("Version").split("."))) + # Apply workaround to unset the SNAP for the fwupd issue + # See details from following PR + # https://github.com/canonical/checkbox/pull/1089 + + # SNAP environ is avaialble, so it's running on checkbox snap + # Unset the environ variable if debian fwupd lower than 1.9.14 + if os.environ["SNAP"] and runtime_ver < (1, 9, 14): + del os.environ["SNAP"] + + subprocess.run(shlex.split("fwupdmgr get-devices --json")) + + +if __name__ == "__main__": + try: + get_firmware_info_fwupd() + except Exception as err: + print(err) diff --git a/providers/base/tests/test_get_firmware_info_fwupd.py b/providers/base/tests/test_get_firmware_info_fwupd.py new file mode 100644 index 0000000000..564260c0ea --- /dev/null +++ b/providers/base/tests/test_get_firmware_info_fwupd.py @@ -0,0 +1,65 @@ +import os +import unittest +from unittest.mock import patch +from get_firmware_info_fwupd import get_firmware_info_fwupd + + +class TestGetFirmwareInfo(unittest.TestCase): + + @patch("subprocess.run") + @patch("checkbox_support.snap_utils.snapd.Snapd.list") + def test_get_firmware_data_by_fwupd_snap( + self, mock_snapd, mock_subporcess): + + mock_snapd.return_value = True + get_firmware_info_fwupd() + mock_snapd.assert_called_with("fwupd") + mock_subporcess.assert_called_with( + ['fwupd.fwupdmgr', 'get-devices', '--json']) + + @patch.dict(os.environ, {"SNAP": "checkbox-snap"}) + @patch("json.loads") + @patch("subprocess.run") + @patch("checkbox_support.snap_utils.snapd.Snapd.list") + def test_get_firmware_data_by_fwupd1914_deb_on_checkbox_snap( + self, mock_snapd, mock_subporcess, mock_json): + + mock_snapd.return_value = False + mock_json.return_value = { + "Versions": [ + { + "Type": "runtime", + "AppstreamId": "org.freedesktop.fwupd", + "Version": "1.9.14" + } + ] + } + get_firmware_info_fwupd() + mock_snapd.assert_called_with("fwupd") + mock_subporcess.assert_called_with( + ['fwupdmgr', 'get-devices', '--json']) + self.assertEqual( + os.environ.get("SNAP"), "checkbox-snap") + + @patch.dict(os.environ, {"SNAP": "checkbox-snap"}) + @patch("json.loads") + @patch("subprocess.run") + @patch("checkbox_support.snap_utils.snapd.Snapd.list") + def test_get_firmware_data_by_fwupd_deb_on_checkbox_snap( + self, mock_snapd, mock_subporcess, mock_json): + + mock_snapd.return_value = False + mock_json.return_value = { + "Versions": [ + { + "Type": "runtime", + "AppstreamId": "org.freedesktop.fwupd", + "Version": "1.7.9" + } + ] + } + get_firmware_info_fwupd() + mock_snapd.assert_called_with("fwupd") + mock_subporcess.assert_called_with( + ['fwupdmgr', 'get-devices', '--json']) + self.assertIsNone(os.environ.get("SNAP")) diff --git a/providers/base/units/firmware/jobs.pxu b/providers/base/units/firmware/jobs.pxu index 1739c86d06..de4edf0f0f 100644 --- a/providers/base/units/firmware/jobs.pxu +++ b/providers/base/units/firmware/jobs.pxu @@ -112,7 +112,6 @@ category_id: com.canonical.plainbox::firmware _summary: Collect the device firmware update information _purpose: Attach information about the devices, as reported by the fwupdmgr requires: - executable.name == "fwupdmgr" + executable.name in ("fwupdmgr", "fwupd.fwupdmgr") command: - unset SNAP - fwupdmgr get-devices --json + get_firmware_info_fwupd.py