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