Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NEXMANAGE-1297] Update OS detection method #654

Merged
merged 4 commits into from
Mar 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions inbm-lib/inbm_lib/detect_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ class LinuxDistType(Enum):
Deby = 3
Debian = 4
CentOS = 5
Mariner = 6 # TODO: Remove this when confirmed that Tiber is in use
tiber = 7
microvisor = 6


def verify_os_supported() -> str:
Expand Down Expand Up @@ -103,6 +102,9 @@ def detect_os() -> str:
if lsb_release_name is not None and lsb_release_name in LinuxDistType.__members__:
logger.debug("Detected OS with lsb_release: " + lsb_release_name)
os_name = lsb_release_name
elif lsb_release_name is not None and LinuxDistType.microvisor.name in lsb_release_name.lower():
logger.debug("Detected EMT OS with lsb_release: " + lsb_release_name)
os_name = lsb_release_name
elif path.exists(SYSTEM_IS_YOCTO_PATH):
if not path.exists(MENDER_FILE_PATH):
raise ValueError("Yocto detected but unable to find Mender")
Expand Down
17 changes: 12 additions & 5 deletions inbm/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,30 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- (NEXMANAGE-956) Improve failure reason from TC that is logged in Mjunct DB for FOTA
- (NEXMANAGE-1194) provision-tc/mqtt services will now handle UDM
- (NEXMANAGE-1253) Implement INBS (UDM) decommission command, which removes device credentials
- Rename Tiber references from old name to Tiber in code
- (NEXMANAGE-1297) Update OS detection method

### Security
- (NEXMANAGE-1236) Upgrade golang.org/x/net from 0.23.0 to 0.33.0, fixing CVE-2024-45338
- (N/A) Fix two 3rd party CVEs: CVE-2024-45338, CVE-2024-12797

### Fixed
- (NEXMANAGE-1281) Result message empty when shutdown binary is missing
- (NEXMANAGE-1280) Software Update Release Date and URL should not be required in common.proto
- (NEXMANAGE-1284) Timed out waiting for INBM Dispatcher response after trigger first run for power heuristic operation
- Fixed that when `shutdown` binary was not available, status was not reported back to INBS correctly for in-band power cycle

### Added
- (NEXMANAGE-1222) Add support for Ubuntu 24.04
- (NEXMANAGE-610, NEXMANAGE-692) Add support to handle OOB AMT RPC activation command

### Fixed
- (NEXMANAGE-1281) Result message empty when shutdown binary is missing
## 4.2.8.4 - 2025-02-14
### Changed
- Rename Tiber references from old name to Tiber in code

### Security
- (NEXMANAGE-1236) Upgrade golang.org/x/net from 0.23.0 to 0.33.0, fixing CVE-2024-45338

### Added
- (NEXMANAGE-1222) Add support for Ubuntu 24.04


## 4.2.8.2 - 2024-12-18
### Changed
Expand Down
2 changes: 1 addition & 1 deletion inbm/dispatcher-agent/dispatcher/sota/downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def download(self,
"""

if uri is None:
raise SotaError("URI is None while performing Tiber download")
raise SotaError("URI is None while performing emt download")

password = read_release_server_token()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ def save_granular_log(self, update_logger: UpdateLogger, check_package: bool = T
"""
log = {}
current_os = detect_os()
# TODO: Remove Mariner when confirmed that Tiber is in use
with self._granular_lock:
if current_os == LinuxDistType.tiber.name or current_os == LinuxDistType.Mariner.name:
if LinuxDistType.microvisor.name in current_os.lower():
# Delete the previous log if exist.
if os.path.exists(GRANULAR_LOG_FILE):
with open(GRANULAR_LOG_FILE, "r+") as file:
Expand All @@ -49,14 +48,14 @@ def save_granular_log(self, update_logger: UpdateLogger, check_package: bool = T
"StatusDetail.Status": update_logger.detail_status,
"Version": get_image_build_date()
}
# In Tiber, no package level information needed.
# In EMT, no package level information needed.
update_logger.save_granular_log_file(log=log, check_package=False)
else:
update_logger.save_granular_log_file(check_package=check_package)

def map_failure_reason(self, error_log: str) -> str:
""" This method parses the error log to map the enum of failure reasons as required by MM.
It is only used for Tiber.
It is only used for Edge Microvisor Toolkit.

@param error_log: Error message to be checked
@return: Corresponding mapping of the failure reason
Expand Down
8 changes: 2 additions & 6 deletions inbm/dispatcher-agent/dispatcher/sota/os_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,8 @@ def get_os(self, os_type) -> "ISotaOs":
elif os_type == OsType.Windows.name:
logger.debug("Windows returned")
return Windows(self._dispatcher_broker)
#TODO: Remove this when confirmed that Tiber is in use
elif os_type == LinuxDistType.Mariner.name:
logger.debug("Mariner returned")
return TiberBasedSotaOs(self._dispatcher_broker, self._signature, self._uri)
elif os_type == LinuxDistType.tiber.name:
logger.debug("Tiber returned")
elif LinuxDistType.microvisor.name in os_type.lower():
logger.debug("EMT returned")
return TiberBasedSotaOs(self._dispatcher_broker, self._signature, self._uri)
raise ValueError('Unsupported OS type: ' + os_type)

Expand Down
4 changes: 2 additions & 2 deletions inbm/dispatcher-agent/tests/unit/sota/test_downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def test_tiber_download_successful(self, mock_download, mock_read_token) -> None

assert isinstance(TestDownloader.sota_instance, SOTA)
TestDownloader.sota_instance.factory = SotaOsFactory(
MockDispatcherBroker.build_mock_dispatcher_broker(), None, []).get_os('tiber')
MockDispatcherBroker.build_mock_dispatcher_broker(), None, []).get_os('Edge Microvisor Toolkit')
factory = TestDownloader.sota_instance.factory
assert isinstance(factory, TiberBasedSotaOs)
installer = factory.create_downloader()
Expand All @@ -155,7 +155,7 @@ def test_tiber_download_with_empty_uri(self) -> None:
password = "mock_password"
assert isinstance(TestDownloader.sota_instance, SOTA)
TestDownloader.sota_instance.factory = SotaOsFactory(
MockDispatcherBroker.build_mock_dispatcher_broker(), None, []).get_os('tiber')
MockDispatcherBroker.build_mock_dispatcher_broker(), None, []).get_os('Edge Microvisor Toolkit')
factory = TestDownloader.sota_instance.factory
assert isinstance(factory, TiberBasedSotaOs)
installer = factory.create_downloader()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ class TestGranularLogHandler(testtools.TestCase):
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('dispatcher.sota.granular_log_handler.get_image_build_date', return_value='20241026100955')
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_success_log(self, mock_run, mock_get_image_build_date, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_success_log(self, mock_run, mock_get_image_build_date, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = OTA_SUCCESS

Expand All @@ -41,8 +41,8 @@ def test_save_granular_in_tiber_with_success_log(self, mock_run, mock_get_image_
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('dispatcher.sota.granular_log_handler.get_image_build_date', return_value='20241026100955')
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_pending_log(self, mock_run, mock_get_image_build_date, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_pending_log(self, mock_run, mock_get_image_build_date, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = OTA_PENDING

Expand All @@ -64,8 +64,8 @@ def test_save_granular_in_tiber_with_pending_log(self, mock_run, mock_get_image_
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
update_logger.error = 'Error getting artifact size from https://registry-rs.internal.ledgepark.intel.com/v2/one-intel-edge/tiber/manifests/latest using token'
Expand All @@ -89,8 +89,8 @@ def test_save_granular_in_tiber_with_fail_log(self, mock_run, mock_load, mock_du
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_rollback_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_rollback_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = ROLLBACK
update_logger.error = 'FAILED INSTALL: System has not been properly updated; reverting..'
Expand All @@ -113,8 +113,8 @@ def test_save_granular_in_tiber_with_rollback_log(self, mock_run, mock_load, moc
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('dispatcher.sota.granular_log_handler.get_image_build_date', return_value='20241026100955')
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_truncate_file_being_called(self, mock_run, mock_get_image_build_date, mock_load, mock_dump, mock_exists) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_truncate_file_being_called(self, mock_run, mock_get_image_build_date, mock_load, mock_dump, mock_exists) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = OTA_SUCCESS

Expand All @@ -139,8 +139,8 @@ def test_save_granular_in_tiber_with_truncate_file_being_called(self, mock_run,
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_insufficient_storage_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_insufficient_storage_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
update_logger.error = 'Insufficient free space'
Expand All @@ -163,8 +163,8 @@ def test_save_granular_in_tiber_with_insufficient_storage_fail_log(self, mock_ru
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_ut_write_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_ut_write_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
update_logger.error = 'Command: /usr/bin/os-update-tool.sh -w -u /var/cache/manageability/repository-tool/sota/tiber-readonly-1.0.20241120.0715.raw.gz status: Failed errors: '
Expand All @@ -187,8 +187,8 @@ def test_save_granular_in_tiber_with_ut_write_fail_log(self, mock_run, mock_load
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_ut_apply_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_ut_apply_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
update_logger.error = 'Command: /usr/bin/os-update-tool.sh -a status: Failed errors: '
Expand All @@ -211,8 +211,8 @@ def test_save_granular_in_tiber_with_ut_apply_fail_log(self, mock_run, mock_load
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_ut_commit_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_ut_commit_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
update_logger.error = 'FAILED INSTALL: System has not been properly updated; reverting.. Error: Failed to run UT commit command /usr/bin/os-update-tool.sh -c . Error:'
Expand All @@ -235,8 +235,8 @@ def test_save_granular_in_tiber_with_ut_commit_fail_log(self, mock_run, mock_loa
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_rsauthentication_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_rsauthentication_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
update_logger.error = 'Failed to access URI:Status code for https://files-rs.internal.ledgepark.intel.com/repository/Tiber/Tiber-nonRT/tiber-readonly-1.0.20241120.0715.raw.gz is 0. Invalid URI or Token might be expired.'
Expand All @@ -259,8 +259,8 @@ def test_save_granular_in_tiber_with_rsauthentication_fail_log(self, mock_run, m
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_signature_check_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_signature_check_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
update_logger.error = 'Signature checks failed'
Expand All @@ -283,8 +283,8 @@ def test_save_granular_in_tiber_with_signature_check_fail_log(self, mock_run, mo
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog":[]})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_critical_service_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_critical_service_fail_log(self, mock_run, mock_load, mock_dump, mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
update_logger.error = 'Critical service failure'
Expand All @@ -307,8 +307,8 @@ def test_save_granular_in_tiber_with_critical_service_fail_log(self, mock_run, m
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog": []})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_trusted_repository_fail_log(self, mock_run, mock_load, mock_dump,
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_trusted_repository_fail_log(self, mock_run, mock_load, mock_dump,
mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
Expand All @@ -332,8 +332,8 @@ def test_save_granular_in_tiber_with_trusted_repository_fail_log(self, mock_run,
@patch('os.path.exists', return_value=False)
@patch('json.dump')
@patch('json.load', return_value={"UpdateLog": []})
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("tiber", "", 0))
def test_save_granular_in_tiber_with_unspecified_fail_log(self, mock_run, mock_load, mock_dump,
@patch('inbm_common_lib.shell_runner.PseudoShellRunner.run', return_value=("Edge Microvisor Toolkit", "", 0))
def test_save_granular_in_emt_with_unspecified_fail_log(self, mock_run, mock_load, mock_dump,
mock_exists, mock_truncate) -> None:
update_logger = UpdateLogger("SOTA", "metadata")
update_logger.detail_status = FAIL
Expand All @@ -352,5 +352,3 @@ def test_save_granular_in_tiber_with_unspecified_fail_log(self, mock_run, mock_l
}

mock_dump.assert_called_with(expected_content, m_open(), indent=4)


2 changes: 1 addition & 1 deletion inbm/dispatcher-agent/tests/unit/sota/test_os_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_get_factory_windows(self) -> None:
assert type(SotaOsFactory(self.mock_disp_broker).get_os('Windows')) is Windows

def test_get_factory_tiber(self) -> None:
assert type(SotaOsFactory(self.mock_disp_broker).get_os('tiber')) is TiberBasedSotaOs
assert type(SotaOsFactory(self.mock_disp_broker).get_os('Edge Microvisor Toolkit')) is TiberBasedSotaOs

def test_raise_error_unsupported_OsFactory(self) -> None:
factory = SotaOsFactory(self.mock_disp_broker)
Expand Down
Loading