From 5db3c837e35b318732476dbd61629d93dbc312a2 Mon Sep 17 00:00:00 2001 From: Markus Hilger Date: Sun, 1 Nov 2026 22:18:13 +0100 Subject: [PATCH] Remove package manager caches from images built by imgutil imgutil build left the downloaded packages and repository metadata in the image: 1.3 GB of .deb archives plus 145 MB of package lists for Ubuntu 26.04, about 100 to 160 MB of dnf metadata for EL and 80 MB of zypp metadata for Leap 16. Untethered nodes copy all of it into memory. Remove them after building. Installing more packages into the image then needs a repository refresh first, as usual for images. --- imgutil/imgutil | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/imgutil/imgutil b/imgutil/imgutil index 0bf73230..ed5fa079 100644 --- a/imgutil/imgutil +++ b/imgutil/imgutil @@ -482,6 +482,8 @@ def get_mydir(oscategory): class OsHandler(object): crossbuild = False selinuxsupport = False + # downloaded packages and repository metadata left by the package manager + pkgcaches = () def __init__(self, name, version, arch, args): self.name = name @@ -516,6 +518,15 @@ class OsHandler(object): except AttributeError: self.addrepos = [] + def clean_pkgcaches(self): + # they only take space in the image, and memory on untethered nodes + for pattern in self.pkgcaches: + for path in glob.glob(os.path.join(self.targpath, pattern)): + if os.path.isdir(path) and not os.path.islink(path): + shutil.rmtree(path) + else: + os.remove(path) + def set_interactive(self, shouldbeinteractive): self._interactive = shouldbeinteractive @@ -587,6 +598,8 @@ class OsHandler(object): return retpkgs class SuseHandler(OsHandler): + pkgcaches = ('var/cache/zypp/*',) + def __init__(self, name, version, arch, args): if not isinstance(version, str): version = version.decode('utf8') @@ -740,6 +753,7 @@ uname_arch_map = { class DebHandler(OsHandler): crossbuild = True + pkgcaches = ('var/cache/apt/archives/*.deb', 'var/cache/apt/*.bin', 'var/lib/apt/lists/*') def set_arch(self, arch): super().set_arch(uname_arch_map.get(arch, arch)) @@ -841,6 +855,7 @@ class DebHandler(OsHandler): class ElHandler(OsHandler): crossbuild = True + pkgcaches = ('var/cache/dnf/*',) selinuxsupport = True def __init__(self, name, version, arch, args, hostpath='/'): @@ -1318,6 +1333,7 @@ def build_root_backend(optargs): oshandler.prep_root_premount(args) _mount_constrained_fs(args, installroot) oshandler.prep_root(args) + oshandler.clean_pkgcaches() mkdirp(os.path.join(installroot, 'etc/')) with open(os.path.join(installroot, 'etc/confluentimg.buildinfo'), 'w') as imginfo: imginfo.write('BUILDDATE={}\n'.format(datetime.datetime.now().strftime('%Y-%m-%dT%H:%M')))