|
2 | 2 | import os |
3 | 3 | import typing |
4 | 4 | import shutil |
| 5 | +import subprocess |
5 | 6 | import re |
6 | 7 |
|
7 | 8 | from pleskdistup.common import action, files, leapp_configs, log, motd, packages, plesk, rpm, systemd, util |
@@ -511,3 +512,62 @@ def _revert_action(self) -> action.ActionResult: |
511 | 512 | for file in files.find_files_case_insensitive("/etc/yum.repos.d", self.KNOWN_INTERNETX_REPO_FILES): |
512 | 513 | files.restore_file_from_backup(file) |
513 | 514 | return action.ActionResult() |
| 515 | + |
| 516 | + |
| 517 | +class AssertCentosSignedKernelInstalled(action.CheckAction): |
| 518 | + def __init__(self): |
| 519 | + self.name = "checking if CentOS signed kernel is installed" |
| 520 | + self.description = """There is no kernel packages signed by CentOS installed. |
| 521 | +\tTo proceed with the conversion, please install the kernel from official CentoOS repository. |
| 522 | +""" |
| 523 | + |
| 524 | + def _get_pgp_key_id(self, file_path: str) -> typing.Optional[str]: |
| 525 | + try: |
| 526 | + output = subprocess.check_output(["/usr/bin/gpg", "--list-packets", file_path], universal_newlines=True) |
| 527 | + for line in output.splitlines(): |
| 528 | + line = line.strip() |
| 529 | + if line.startswith("keyid: "): |
| 530 | + return line.split(": ")[1].lower() |
| 531 | + except Exception as e: |
| 532 | + log.err(f"Failed to get PGP key ID from {file_path}: {e}") |
| 533 | + return None |
| 534 | + |
| 535 | + def _signed_by_one_of_keys(self, package_description: str, keys: typing.Set[str]) -> bool: |
| 536 | + for key_id in keys: |
| 537 | + if key_id in package_description: |
| 538 | + return True |
| 539 | + return False |
| 540 | + |
| 541 | + def _do_check(self) -> bool: |
| 542 | + # You could find the same list at centos/gpg-signatures.json in leapp-repository |
| 543 | + # Unfortunately leapp is not installed at this moment so we have to create set of id's manually |
| 544 | + known_pgp_keys_ids: typing.Set[str] = set([ |
| 545 | + "24c6a8a7f4a80eb5", |
| 546 | + "05b555b38483c65d", |
| 547 | + "4eb84e71f2ee9d55", |
| 548 | + "429785e181b961a5", |
| 549 | + "d07bf2a08d50eb66", |
| 550 | + "6c7cb6ef305d49d6" |
| 551 | + ]) |
| 552 | + |
| 553 | + default_key_path = "/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7" |
| 554 | + if os.path.exists(default_key_path): |
| 555 | + default_key_id = self._get_pgp_key_id(default_key_path) |
| 556 | + if default_key_id is not None: |
| 557 | + known_pgp_keys_ids.add(default_key_id) |
| 558 | + try: |
| 559 | + packages_with_pgpsig = subprocess.check_output(["/usr/bin/rpm", "-q", "--queryformat", "%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH} %{SIGPGP:pgpsig}\n", "kernel"], universal_newlines=True) |
| 560 | + except subprocess.CalledProcessError as e: |
| 561 | + log.err(f"Failed to get kernel package information: {e}") |
| 562 | + # The reason likely is not the same as described in the pre-checker description |
| 563 | + # So if we will show the message to user, they will be confused. So we just skip the pre-check |
| 564 | + return True |
| 565 | + |
| 566 | + if packages_with_pgpsig.startswith("package kernel is not installed"): |
| 567 | + # This means that kernel package is not installed. It is generally expected that a kernel package is present. |
| 568 | + # However, I'm not sure if it causes a problem on the Leapp side |
| 569 | + # So, we can bypass the pre-check and look for similar cases mentioned in feature requests on GitHub |
| 570 | + log.warn(f"Kernel package is not installed. Skipping the {self.__class__.__name__} precheck.") |
| 571 | + return True |
| 572 | + |
| 573 | + return any(self._signed_by_one_of_keys(pkg, known_pgp_keys_ids) for pkg in packages_with_pgpsig.splitlines() if pkg) |
0 commit comments