summaryrefslogtreecommitdiffstats
path: root/meta/lib/oe/rootfs.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oe/rootfs.py')
-rw-r--r--meta/lib/oe/rootfs.py117
1 files changed, 75 insertions, 42 deletions
diff --git a/meta/lib/oe/rootfs.py b/meta/lib/oe/rootfs.py
index 249c685dcf..14befac8fa 100644
--- a/meta/lib/oe/rootfs.py
+++ b/meta/lib/oe/rootfs.py
@@ -1,4 +1,6 @@
1# 1#
2# Copyright OpenEmbedded Contributors
3#
2# SPDX-License-Identifier: GPL-2.0-only 4# SPDX-License-Identifier: GPL-2.0-only
3# 5#
4from abc import ABCMeta, abstractmethod 6from abc import ABCMeta, abstractmethod
@@ -104,7 +106,7 @@ class Rootfs(object, metaclass=ABCMeta):
104 def _cleanup(self): 106 def _cleanup(self):
105 pass 107 pass
106 108
107 def _setup_dbg_rootfs(self, dirs): 109 def _setup_dbg_rootfs(self, package_paths):
108 gen_debugfs = self.d.getVar('IMAGE_GEN_DEBUGFS') or '0' 110 gen_debugfs = self.d.getVar('IMAGE_GEN_DEBUGFS') or '0'
109 if gen_debugfs != '1': 111 if gen_debugfs != '1':
110 return 112 return
@@ -114,17 +116,18 @@ class Rootfs(object, metaclass=ABCMeta):
114 shutil.rmtree(self.image_rootfs + '-orig') 116 shutil.rmtree(self.image_rootfs + '-orig')
115 except: 117 except:
116 pass 118 pass
117 os.rename(self.image_rootfs, self.image_rootfs + '-orig') 119 bb.utils.rename(self.image_rootfs, self.image_rootfs + '-orig')
118 120
119 bb.note(" Creating debug rootfs...") 121 bb.note(" Creating debug rootfs...")
120 bb.utils.mkdirhier(self.image_rootfs) 122 bb.utils.mkdirhier(self.image_rootfs)
121 123
122 bb.note(" Copying back package database...") 124 bb.note(" Copying back package database...")
123 for dir in dirs: 125 for path in package_paths:
124 if not os.path.isdir(self.image_rootfs + '-orig' + dir): 126 bb.utils.mkdirhier(self.image_rootfs + os.path.dirname(path))
125 continue 127 if os.path.isdir(self.image_rootfs + '-orig' + path):
126 bb.utils.mkdirhier(self.image_rootfs + os.path.dirname(dir)) 128 shutil.copytree(self.image_rootfs + '-orig' + path, self.image_rootfs + path, symlinks=True)
127 shutil.copytree(self.image_rootfs + '-orig' + dir, self.image_rootfs + dir, symlinks=True) 129 elif os.path.isfile(self.image_rootfs + '-orig' + path):
130 shutil.copyfile(self.image_rootfs + '-orig' + path, self.image_rootfs + path)
128 131
129 # Copy files located in /usr/lib/debug or /usr/src/debug 132 # Copy files located in /usr/lib/debug or /usr/src/debug
130 for dir in ["/usr/lib/debug", "/usr/src/debug"]: 133 for dir in ["/usr/lib/debug", "/usr/src/debug"]:
@@ -160,25 +163,26 @@ class Rootfs(object, metaclass=ABCMeta):
160 bb.note(" Install extra debug packages...") 163 bb.note(" Install extra debug packages...")
161 self.pm.install(extra_debug_pkgs.split(), True) 164 self.pm.install(extra_debug_pkgs.split(), True)
162 165
166 bb.note(" Removing package database...")
167 for path in package_paths:
168 if os.path.isdir(self.image_rootfs + path):
169 shutil.rmtree(self.image_rootfs + path)
170 elif os.path.isfile(self.image_rootfs + path):
171 os.remove(self.image_rootfs + path)
172
163 bb.note(" Rename debug rootfs...") 173 bb.note(" Rename debug rootfs...")
164 try: 174 try:
165 shutil.rmtree(self.image_rootfs + '-dbg') 175 shutil.rmtree(self.image_rootfs + '-dbg')
166 except: 176 except:
167 pass 177 pass
168 os.rename(self.image_rootfs, self.image_rootfs + '-dbg') 178 bb.utils.rename(self.image_rootfs, self.image_rootfs + '-dbg')
169 179
170 bb.note(" Restoreing original rootfs...") 180 bb.note(" Restoring original rootfs...")
171 os.rename(self.image_rootfs + '-orig', self.image_rootfs) 181 bb.utils.rename(self.image_rootfs + '-orig', self.image_rootfs)
172 182
173 def _exec_shell_cmd(self, cmd): 183 def _exec_shell_cmd(self, cmd):
174 fakerootcmd = self.d.getVar('FAKEROOT')
175 if fakerootcmd is not None:
176 exec_cmd = [fakerootcmd, cmd]
177 else:
178 exec_cmd = cmd
179
180 try: 184 try:
181 subprocess.check_output(exec_cmd, stderr=subprocess.STDOUT) 185 subprocess.check_output(cmd, stderr=subprocess.STDOUT)
182 except subprocess.CalledProcessError as e: 186 except subprocess.CalledProcessError as e:
183 return("Command '%s' returned %d:\n%s" % (e.cmd, e.returncode, e.output)) 187 return("Command '%s' returned %d:\n%s" % (e.cmd, e.returncode, e.output))
184 188
@@ -190,9 +194,17 @@ class Rootfs(object, metaclass=ABCMeta):
190 post_process_cmds = self.d.getVar("ROOTFS_POSTPROCESS_COMMAND") 194 post_process_cmds = self.d.getVar("ROOTFS_POSTPROCESS_COMMAND")
191 rootfs_post_install_cmds = self.d.getVar('ROOTFS_POSTINSTALL_COMMAND') 195 rootfs_post_install_cmds = self.d.getVar('ROOTFS_POSTINSTALL_COMMAND')
192 196
193 bb.utils.mkdirhier(self.image_rootfs) 197 def make_last(command, commands):
198 commands = commands.split()
199 if command in commands:
200 commands.remove(command)
201 commands.append(command)
202 return " ".join(commands)
194 203
195 bb.utils.mkdirhier(self.deploydir) 204 # We want this to run as late as possible, in particular after
205 # systemd_sysusers_create and set_user_group. Using :append is not enough
206 post_process_cmds = make_last("tidy_shadowutils_files", post_process_cmds)
207 post_process_cmds = make_last("rootfs_reproducible", post_process_cmds)
196 208
197 execute_pre_post_process(self.d, pre_process_cmds) 209 execute_pre_post_process(self.d, pre_process_cmds)
198 210
@@ -250,16 +262,18 @@ class Rootfs(object, metaclass=ABCMeta):
250 262
251 263
252 def _uninstall_unneeded(self): 264 def _uninstall_unneeded(self):
253 # Remove unneeded init script symlinks 265 # Remove the run-postinsts package if no delayed postinsts are found
254 delayed_postinsts = self._get_delayed_postinsts() 266 delayed_postinsts = self._get_delayed_postinsts()
255 if delayed_postinsts is None: 267 if delayed_postinsts is None:
256 if os.path.exists(self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/init.d/run-postinsts")): 268 if os.path.exists(self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/init.d/run-postinsts")) or os.path.exists(self.d.expand("${IMAGE_ROOTFS}${systemd_system_unitdir}/run-postinsts.service")):
257 self._exec_shell_cmd(["update-rc.d", "-f", "-r", 269 self.pm.remove(["run-postinsts"])
258 self.d.getVar('IMAGE_ROOTFS'),
259 "run-postinsts", "remove"])
260 270
261 image_rorfs = bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", 271 image_rorfs = bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
272 True, False, self.d) and \
273 not bb.utils.contains("IMAGE_FEATURES",
274 "read-only-rootfs-delayed-postinsts",
262 True, False, self.d) 275 True, False, self.d)
276
263 image_rorfs_force = self.d.getVar('FORCE_RO_REMOVE') 277 image_rorfs_force = self.d.getVar('FORCE_RO_REMOVE')
264 278
265 if image_rorfs or image_rorfs_force == "1": 279 if image_rorfs or image_rorfs_force == "1":
@@ -304,10 +318,20 @@ class Rootfs(object, metaclass=ABCMeta):
304 self._exec_shell_cmd(['ldconfig', '-r', self.image_rootfs, '-c', 318 self._exec_shell_cmd(['ldconfig', '-r', self.image_rootfs, '-c',
305 'new', '-v', '-X']) 319 'new', '-v', '-X'])
306 320
321 image_rorfs = bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
322 True, False, self.d)
323 ldconfig_in_features = bb.utils.contains("DISTRO_FEATURES", "ldconfig",
324 True, False, self.d)
325 if image_rorfs or not ldconfig_in_features:
326 ldconfig_cache_dir = os.path.join(self.image_rootfs, "var/cache/ldconfig")
327 if os.path.exists(ldconfig_cache_dir):
328 bb.note("Removing ldconfig auxiliary cache...")
329 shutil.rmtree(ldconfig_cache_dir)
330
307 def _check_for_kernel_modules(self, modules_dir): 331 def _check_for_kernel_modules(self, modules_dir):
308 for root, dirs, files in os.walk(modules_dir, topdown=True): 332 for root, dirs, files in os.walk(modules_dir, topdown=True):
309 for name in files: 333 for name in files:
310 found_ko = name.endswith(".ko") 334 found_ko = name.endswith((".ko", ".ko.gz", ".ko.xz", ".ko.zst"))
311 if found_ko: 335 if found_ko:
312 return found_ko 336 return found_ko
313 return False 337 return False
@@ -319,17 +343,31 @@ class Rootfs(object, metaclass=ABCMeta):
319 bb.note("No Kernel Modules found, not running depmod") 343 bb.note("No Kernel Modules found, not running depmod")
320 return 344 return
321 345
322 kernel_abi_ver_file = oe.path.join(self.d.getVar('PKGDATA_DIR'), "kernel-depmod", 346 pkgdatadir = self.d.getVar('PKGDATA_DIR')
323 'kernel-abiversion')
324 if not os.path.exists(kernel_abi_ver_file):
325 bb.fatal("No kernel-abiversion file found (%s), cannot run depmod, aborting" % kernel_abi_ver_file)
326 347
327 kernel_ver = open(kernel_abi_ver_file).read().strip(' \n') 348 # PKGDATA_DIR can include multiple kernels so we run depmod for each
328 versioned_modules_dir = os.path.join(self.image_rootfs, modules_dir, kernel_ver) 349 # one of them.
350 for direntry in os.listdir(pkgdatadir):
351 match = re.match('(.*)-depmod', direntry)
352 if not match:
353 continue
354 kernel_package_name = match.group(1)
355
356 kernel_abi_ver_file = oe.path.join(pkgdatadir, direntry, kernel_package_name + '-abiversion')
357 if not os.path.exists(kernel_abi_ver_file):
358 bb.fatal("No kernel-abiversion file found (%s), cannot run depmod, aborting" % kernel_abi_ver_file)
329 359
330 bb.utils.mkdirhier(versioned_modules_dir) 360 with open(kernel_abi_ver_file) as f:
361 kernel_ver = f.read().strip(' \n')
331 362
332 self._exec_shell_cmd(['depmodwrapper', '-a', '-b', self.image_rootfs, kernel_ver]) 363 versioned_modules_dir = os.path.join(self.image_rootfs, modules_dir, kernel_ver)
364
365 if os.path.exists(versioned_modules_dir):
366 bb.note("Running depmodwrapper for %s ..." % versioned_modules_dir)
367 if self._exec_shell_cmd(['depmodwrapper', '-a', '-b', self.image_rootfs, kernel_ver, kernel_package_name]):
368 bb.fatal("Kernel modules dependency generation failed")
369 else:
370 bb.note("Not running depmodwrapper for %s since directory does not exist" % versioned_modules_dir)
333 371
334 """ 372 """
335 Create devfs: 373 Create devfs:
@@ -378,6 +416,10 @@ def create_rootfs(d, manifest_dir=None, progress_reporter=None, logcatcher=None)
378 416
379 417
380def image_list_installed_packages(d, rootfs_dir=None): 418def image_list_installed_packages(d, rootfs_dir=None):
419 # Theres no rootfs for baremetal images
420 if bb.data.inherits_class('baremetal-image', d):
421 return ""
422
381 if not rootfs_dir: 423 if not rootfs_dir:
382 rootfs_dir = d.getVar('IMAGE_ROOTFS') 424 rootfs_dir = d.getVar('IMAGE_ROOTFS')
383 425
@@ -386,12 +428,3 @@ def image_list_installed_packages(d, rootfs_dir=None):
386 import importlib 428 import importlib
387 cls = importlib.import_module('oe.package_manager.' + img_type) 429 cls = importlib.import_module('oe.package_manager.' + img_type)
388 return cls.PMPkgsList(d, rootfs_dir).list_pkgs() 430 return cls.PMPkgsList(d, rootfs_dir).list_pkgs()
389
390if __name__ == "__main__":
391 """
392 We should be able to run this as a standalone script, from outside bitbake
393 environment.
394 """
395 """
396 TBD
397 """