Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 1 | # |
| 2 | # SPDX-License-Identifier: GPL-2.0-only |
| 3 | # |
| 4 | |
| 5 | from oe.rootfs import Rootfs |
| 6 | from oe.manifest import Manifest |
| 7 | from oe.utils import execute_pre_post_process |
Brad Bishop | f6355e4 | 2020-12-08 14:30:50 -0500 | [diff] [blame^] | 8 | from oe.package_manager.rpm.manifest import RpmManifest |
Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 9 | from oe.package_manager.rpm import RpmPM |
| 10 | |
Brad Bishop | f6355e4 | 2020-12-08 14:30:50 -0500 | [diff] [blame^] | 11 | class RpmRootfs(Rootfs): |
Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 12 | def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None): |
Brad Bishop | f6355e4 | 2020-12-08 14:30:50 -0500 | [diff] [blame^] | 13 | super(RpmRootfs, self).__init__(d, progress_reporter, logcatcher) |
Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 14 | self.log_check_regex = r'(unpacking of archive failed|Cannot find package'\ |
| 15 | r'|exit 1|ERROR: |Error: |Error |ERROR '\ |
| 16 | r'|Failed |Failed: |Failed$|Failed\(\d+\):)' |
| 17 | |
Brad Bishop | f6355e4 | 2020-12-08 14:30:50 -0500 | [diff] [blame^] | 18 | self.manifest = RpmManifest(d, manifest_dir) |
Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 19 | |
| 20 | self.pm = RpmPM(d, |
| 21 | d.getVar('IMAGE_ROOTFS'), |
| 22 | self.d.getVar('TARGET_VENDOR') |
| 23 | ) |
| 24 | |
| 25 | self.inc_rpm_image_gen = self.d.getVar('INC_RPM_IMAGE_GEN') |
| 26 | if self.inc_rpm_image_gen != "1": |
| 27 | bb.utils.remove(self.image_rootfs, True) |
| 28 | else: |
| 29 | self.pm.recovery_packaging_data() |
| 30 | bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True) |
| 31 | |
| 32 | self.pm.create_configs() |
| 33 | |
| 34 | ''' |
| 35 | While rpm incremental image generation is enabled, it will remove the |
| 36 | unneeded pkgs by comparing the new install solution manifest and the |
| 37 | old installed manifest. |
| 38 | ''' |
| 39 | def _create_incremental(self, pkgs_initial_install): |
| 40 | if self.inc_rpm_image_gen == "1": |
| 41 | |
| 42 | pkgs_to_install = list() |
| 43 | for pkg_type in pkgs_initial_install: |
| 44 | pkgs_to_install += pkgs_initial_install[pkg_type] |
| 45 | |
| 46 | installed_manifest = self.pm.load_old_install_solution() |
| 47 | solution_manifest = self.pm.dump_install_solution(pkgs_to_install) |
| 48 | |
| 49 | pkg_to_remove = list() |
| 50 | for pkg in installed_manifest: |
| 51 | if pkg not in solution_manifest: |
| 52 | pkg_to_remove.append(pkg) |
| 53 | |
| 54 | self.pm.update() |
| 55 | |
| 56 | bb.note('incremental update -- upgrade packages in place ') |
| 57 | self.pm.upgrade() |
| 58 | if pkg_to_remove != []: |
| 59 | bb.note('incremental removed: %s' % ' '.join(pkg_to_remove)) |
| 60 | self.pm.remove(pkg_to_remove) |
| 61 | |
| 62 | self.pm.autoremove() |
| 63 | |
| 64 | def _create(self): |
| 65 | pkgs_to_install = self.manifest.parse_initial_manifest() |
| 66 | rpm_pre_process_cmds = self.d.getVar('RPM_PREPROCESS_COMMANDS') |
| 67 | rpm_post_process_cmds = self.d.getVar('RPM_POSTPROCESS_COMMANDS') |
| 68 | |
| 69 | # update PM index files |
| 70 | self.pm.write_index() |
| 71 | |
| 72 | execute_pre_post_process(self.d, rpm_pre_process_cmds) |
| 73 | |
| 74 | if self.progress_reporter: |
| 75 | self.progress_reporter.next_stage() |
| 76 | |
| 77 | if self.inc_rpm_image_gen == "1": |
| 78 | self._create_incremental(pkgs_to_install) |
| 79 | |
| 80 | if self.progress_reporter: |
| 81 | self.progress_reporter.next_stage() |
| 82 | |
| 83 | self.pm.update() |
| 84 | |
| 85 | pkgs = [] |
| 86 | pkgs_attempt = [] |
| 87 | for pkg_type in pkgs_to_install: |
| 88 | if pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY: |
| 89 | pkgs_attempt += pkgs_to_install[pkg_type] |
| 90 | else: |
| 91 | pkgs += pkgs_to_install[pkg_type] |
| 92 | |
| 93 | if self.progress_reporter: |
| 94 | self.progress_reporter.next_stage() |
| 95 | |
| 96 | self.pm.install(pkgs) |
| 97 | |
| 98 | if self.progress_reporter: |
| 99 | self.progress_reporter.next_stage() |
| 100 | |
| 101 | self.pm.install(pkgs_attempt, True) |
| 102 | |
| 103 | if self.progress_reporter: |
| 104 | self.progress_reporter.next_stage() |
| 105 | |
| 106 | self.pm.install_complementary() |
| 107 | |
| 108 | if self.progress_reporter: |
| 109 | self.progress_reporter.next_stage() |
| 110 | |
| 111 | self._setup_dbg_rootfs(['/etc', '/var/lib/rpm', '/var/cache/dnf', '/var/lib/dnf']) |
| 112 | |
| 113 | execute_pre_post_process(self.d, rpm_post_process_cmds) |
| 114 | |
| 115 | if self.inc_rpm_image_gen == "1": |
| 116 | self.pm.backup_packaging_data() |
| 117 | |
| 118 | if self.progress_reporter: |
| 119 | self.progress_reporter.next_stage() |
| 120 | |
| 121 | |
| 122 | @staticmethod |
| 123 | def _depends_list(): |
| 124 | return ['DEPLOY_DIR_RPM', 'INC_RPM_IMAGE_GEN', 'RPM_PREPROCESS_COMMANDS', |
| 125 | 'RPM_POSTPROCESS_COMMANDS', 'RPM_PREFER_ELF_ARCH'] |
| 126 | |
| 127 | def _get_delayed_postinsts(self): |
| 128 | postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/rpm-postinsts") |
| 129 | if os.path.isdir(postinst_dir): |
| 130 | files = os.listdir(postinst_dir) |
| 131 | for f in files: |
| 132 | bb.note('Delayed package scriptlet: %s' % f) |
| 133 | return files |
| 134 | |
| 135 | return None |
| 136 | |
| 137 | def _save_postinsts(self): |
| 138 | # this is just a stub. For RPM, the failed postinstalls are |
| 139 | # already saved in /etc/rpm-postinsts |
| 140 | pass |
| 141 | |
| 142 | def _log_check(self): |
| 143 | self._log_check_warn() |
| 144 | self._log_check_error() |
| 145 | |
| 146 | def _cleanup(self): |
| 147 | if bb.utils.contains("IMAGE_FEATURES", "package-management", True, False, self.d): |
| 148 | self.pm._invoke_dnf(["clean", "all"]) |