From 9e2ab32435d6cc821840f084caeb7ae9f111d36e Mon Sep 17 00:00:00 2001 From: Fredrik Eriksson Date: Sat, 20 Jul 2024 16:57:24 +0200 Subject: [PATCH] new method to identify system packages on gentoo System packages are now: * Anything in sys-boot/ category * sys-libs/glibc and sys-libs/musl * any ebuild that uses one of these eclasses: - dist-kernel-utils - linux-mod-r1 - kernel-install --- sau/gentoo.py | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/sau/gentoo.py b/sau/gentoo.py index 3280c80..a028855 100644 --- a/sau/gentoo.py +++ b/sau/gentoo.py @@ -14,9 +14,9 @@ EMAINT_PATH='/usr/sbin/emaint' GRUB_MKCONFIG='/usr/sbin/grub-mkconfig' # parsing output from eix -Ttnc -package_re = re.compile('^\[([^\]])\] ([^ ]*) \((.*)\): .*$') +package_re = re.compile(r'^\[([^\]])\] ([^ ]*) \((.*)\): .*$') # parsing version information from substrings of the above -slot_re = re.compile('^(\(~\))?([^\(]+)(\([^\)]+\))$') +slot_re = re.compile(r'^(\(~\))?([^\(]+)(\([^\)]+\))$') def identify_service_from_bin(exe): log = logging.getLogger(sau.LOGNAME) @@ -109,6 +109,45 @@ def _sync_portage(): for line in err.splitlines(): log.warning("stderr: {}".format(line)) +def is_system_package(atom): + name=re.sub(r'^[<=>]*(.*?)(?:-\d)?(?:::\w+)?$', r'\1', atom) + + # sys-boot/ category should probably always be considered + # system-packages + if name.split('/')[0] == 'sys-boot': + return True + + # libc-packages should be considered system-packages as they generally + # requires the system to be restarted. Not sure if there is a better way + # then just checking for specific packages here, but as far as I know there + # are not many of them anyway... + if re.search(r'^sys-libs/(glibc|musl)', name): + return True + + # anything that requires boot-partition to be mounted should be considered + # system packages. So far I've identified these eclasses that touches + # boot/kernel: + # * dist-kernel-utils + # * linux-mod-r1 + # * kernel-install + test_re = re.compile(r'^\s*inherit\s+.*(dist-kernel-utils|linux-mod|kernel-install)') + cmd=[ EQUERY_PATH, 'w', name ] + ret, out, err = sau.helpers.exec_cmd(cmd) + if not ret == 0: + log.warning(f'Unable to locate ebuild for {atom}') + # better safe than sorry; if we don't know, let's pretend it's a system + # package + return True + path = out.strip() + if not os.path.isfile(path): + log.warning(f"This path doesn't look lika a path to the ebuild for {name}: {path}") + return True + with open(path, 'r', encoding='utf-8') as f: + for line in f.readlines(): + if re.search(test_re, line): + return True + + return False @@ -161,11 +200,12 @@ def pkg_upgrade(): else: log.error('{} -- {} -> {} configured level {} > pkg level {}'.format(name, old, new, sens, common)) do_rebuild = False - if name.startswith('sys-kernel/'): + + if is_system_package(f'{name}-{new}'): if do_system_upgrade: do_grub = True else: - raise sau.errors.UpgradeError(f"Kernel package {name} has an update, but system upgrade is disabled") + raise sau.errors.UpgradeError(f"System package {name} has an update, but system upgrade is disabled") if not do_rebuild: raise sau.errors.UpgradeError('Some packages require manual attention, did not upgrade')