1# 2# SPDX-License-Identifier: GPL-2.0-only 3# 4 5from oe.rootfs import Rootfs 6from oe.manifest import Manifest 7from oe.utils import execute_pre_post_process 8from oe.package_manager.rpm.manifest import PkgManifest 9from oe.package_manager.rpm import RpmPM 10 11class PkgRootfs(Rootfs): 12 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None): 13 super(PkgRootfs, self).__init__(d, progress_reporter, logcatcher) 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 18 self.manifest = PkgManifest(d, manifest_dir) 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"]) 149