blob: 96591f370e63989500aba75a9c292ab00bf5bd30 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001from abc import ABCMeta, abstractmethod
2from oe.utils import execute_pre_post_process
3from oe.package_manager import *
4from oe.manifest import *
5import oe.path
6import filecmp
7import shutil
8import os
9import subprocess
10import re
11
12
Patrick Williamsc0f7c042017-02-23 20:41:17 -060013class Rootfs(object, metaclass=ABCMeta):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050014 """
15 This is an abstract class. Do not instantiate this directly.
16 """
Patrick Williamsc124f4f2015-09-15 14:41:29 -050017
Brad Bishop6e60e8b2018-02-01 10:27:11 -050018 def __init__(self, d, progress_reporter=None, logcatcher=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050019 self.d = d
20 self.pm = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -050021 self.image_rootfs = self.d.getVar('IMAGE_ROOTFS')
22 self.deploydir = self.d.getVar('IMGDEPLOYDIR')
Patrick Williamsc0f7c042017-02-23 20:41:17 -060023 self.progress_reporter = progress_reporter
Brad Bishop6e60e8b2018-02-01 10:27:11 -050024 self.logcatcher = logcatcher
Patrick Williamsc124f4f2015-09-15 14:41:29 -050025
26 self.install_order = Manifest.INSTALL_ORDER
27
28 @abstractmethod
29 def _create(self):
30 pass
31
32 @abstractmethod
33 def _get_delayed_postinsts(self):
34 pass
35
36 @abstractmethod
37 def _save_postinsts(self):
38 pass
39
40 @abstractmethod
41 def _log_check(self):
42 pass
43
Patrick Williamsc0f7c042017-02-23 20:41:17 -060044 def _log_check_common(self, type, match):
45 # Ignore any lines containing log_check to avoid recursion, and ignore
46 # lines beginning with a + since sh -x may emit code which isn't
47 # actually executed, but may contain error messages
48 excludes = [ 'log_check', r'^\+' ]
49 if hasattr(self, 'log_check_expected_regexes'):
50 excludes.extend(self.log_check_expected_regexes)
51 excludes = [re.compile(x) for x in excludes]
52 r = re.compile(match)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050053 log_path = self.d.expand("${T}/log.do_rootfs")
Patrick Williamsc0f7c042017-02-23 20:41:17 -060054 messages = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -050055 with open(log_path, 'r') as log:
56 for line in log:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050057 if self.logcatcher and self.logcatcher.contains(line.rstrip()):
58 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -060059 for ee in excludes:
60 m = ee.search(line)
61 if m:
62 break
63 if m:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050064 continue
65
66 m = r.search(line)
67 if m:
Patrick Williamsc0f7c042017-02-23 20:41:17 -060068 messages.append('[log_check] %s' % line)
69 if messages:
70 if len(messages) == 1:
71 msg = '1 %s message' % type
72 else:
73 msg = '%d %s messages' % (len(messages), type)
74 msg = '[log_check] %s: found %s in the logfile:\n%s' % \
Brad Bishop6e60e8b2018-02-01 10:27:11 -050075 (self.d.getVar('PN'), msg, ''.join(messages))
Patrick Williamsc0f7c042017-02-23 20:41:17 -060076 if type == 'error':
77 bb.fatal(msg)
78 else:
79 bb.warn(msg)
80
81 def _log_check_warn(self):
82 self._log_check_common('warning', '^(warn|Warn|WARNING:)')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050083
84 def _log_check_error(self):
Patrick Williamsc0f7c042017-02-23 20:41:17 -060085 self._log_check_common('error', self.log_check_regex)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050086
87 def _insert_feed_uris(self):
88 if bb.utils.contains("IMAGE_FEATURES", "package-management",
89 True, False, self.d):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050090 self.pm.insert_feeds_uris(self.d.getVar('PACKAGE_FEED_URIS') or "",
91 self.d.getVar('PACKAGE_FEED_BASE_PATHS') or "",
92 self.d.getVar('PACKAGE_FEED_ARCHS'))
93
Patrick Williamsc124f4f2015-09-15 14:41:29 -050094
95 @abstractmethod
96 def _handle_intercept_failure(self, failed_script):
97 pass
98
99 """
100 The _cleanup() method should be used to clean-up stuff that we don't really
101 want to end up on target. For example, in the case of RPM, the DB locks.
102 The method is called, once, at the end of create() method.
103 """
104 @abstractmethod
105 def _cleanup(self):
106 pass
107
108 def _setup_dbg_rootfs(self, dirs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500109 gen_debugfs = self.d.getVar('IMAGE_GEN_DEBUGFS') or '0'
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500110 if gen_debugfs != '1':
111 return
112
113 bb.note(" Renaming the original rootfs...")
114 try:
115 shutil.rmtree(self.image_rootfs + '-orig')
116 except:
117 pass
118 os.rename(self.image_rootfs, self.image_rootfs + '-orig')
119
120 bb.note(" Creating debug rootfs...")
121 bb.utils.mkdirhier(self.image_rootfs)
122
123 bb.note(" Copying back package database...")
124 for dir in dirs:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600125 if not os.path.isdir(self.image_rootfs + '-orig' + dir):
126 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500127 bb.utils.mkdirhier(self.image_rootfs + os.path.dirname(dir))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600128 shutil.copytree(self.image_rootfs + '-orig' + dir, self.image_rootfs + dir, symlinks=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500129
130 cpath = oe.cachedpath.CachedPath()
131 # Copy files located in /usr/lib/debug or /usr/src/debug
132 for dir in ["/usr/lib/debug", "/usr/src/debug"]:
133 src = self.image_rootfs + '-orig' + dir
134 if cpath.exists(src):
135 dst = self.image_rootfs + dir
136 bb.utils.mkdirhier(os.path.dirname(dst))
137 shutil.copytree(src, dst)
138
139 # Copy files with suffix '.debug' or located in '.debug' dir.
140 for root, dirs, files in cpath.walk(self.image_rootfs + '-orig'):
141 relative_dir = root[len(self.image_rootfs + '-orig'):]
142 for f in files:
143 if f.endswith('.debug') or '/.debug' in relative_dir:
144 bb.utils.mkdirhier(self.image_rootfs + relative_dir)
145 shutil.copy(os.path.join(root, f),
146 self.image_rootfs + relative_dir)
147
148 bb.note(" Install complementary '*-dbg' packages...")
149 self.pm.install_complementary('*-dbg')
150
151 bb.note(" Rename debug rootfs...")
152 try:
153 shutil.rmtree(self.image_rootfs + '-dbg')
154 except:
155 pass
156 os.rename(self.image_rootfs, self.image_rootfs + '-dbg')
157
158 bb.note(" Restoreing original rootfs...")
159 os.rename(self.image_rootfs + '-orig', self.image_rootfs)
160
161 def _exec_shell_cmd(self, cmd):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500162 fakerootcmd = self.d.getVar('FAKEROOT')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500163 if fakerootcmd is not None:
164 exec_cmd = [fakerootcmd, cmd]
165 else:
166 exec_cmd = cmd
167
168 try:
169 subprocess.check_output(exec_cmd, stderr=subprocess.STDOUT)
170 except subprocess.CalledProcessError as e:
171 return("Command '%s' returned %d:\n%s" % (e.cmd, e.returncode, e.output))
172
173 return None
174
175 def create(self):
176 bb.note("###### Generate rootfs #######")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500177 pre_process_cmds = self.d.getVar("ROOTFS_PREPROCESS_COMMAND")
178 post_process_cmds = self.d.getVar("ROOTFS_POSTPROCESS_COMMAND")
179 rootfs_post_install_cmds = self.d.getVar('ROOTFS_POSTINSTALL_COMMAND')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500180
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500181 postinst_intercepts_dir = self.d.getVar("POSTINST_INTERCEPTS_DIR")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500182 if not postinst_intercepts_dir:
183 postinst_intercepts_dir = self.d.expand("${COREBASE}/scripts/postinst-intercepts")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500184 intercepts_dir = os.path.join(self.d.getVar('WORKDIR'),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500185 "intercept_scripts")
186
187 bb.utils.remove(intercepts_dir, True)
188
189 bb.utils.mkdirhier(self.image_rootfs)
190
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600191 bb.utils.mkdirhier(self.deploydir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500192
193 shutil.copytree(postinst_intercepts_dir, intercepts_dir)
194
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500195 execute_pre_post_process(self.d, pre_process_cmds)
196
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600197 if self.progress_reporter:
198 self.progress_reporter.next_stage()
199
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500200 # call the package manager dependent create method
201 self._create()
202
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500203 sysconfdir = self.image_rootfs + self.d.getVar('sysconfdir')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500204 bb.utils.mkdirhier(sysconfdir)
205 with open(sysconfdir + "/version", "w+") as ver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500206 ver.write(self.d.getVar('BUILDNAME') + "\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500207
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500208 execute_pre_post_process(self.d, rootfs_post_install_cmds)
209
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500210 self._run_intercepts()
211
212 execute_pre_post_process(self.d, post_process_cmds)
213
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600214 if self.progress_reporter:
215 self.progress_reporter.next_stage()
216
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500217 if bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
218 True, False, self.d):
219 delayed_postinsts = self._get_delayed_postinsts()
220 if delayed_postinsts is not None:
221 bb.fatal("The following packages could not be configured "
222 "offline and rootfs is read-only: %s" %
223 delayed_postinsts)
224
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500225 if self.d.getVar('USE_DEVFS') != "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500226 self._create_devfs()
227
228 self._uninstall_unneeded()
229
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600230 if self.progress_reporter:
231 self.progress_reporter.next_stage()
232
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500233 self._insert_feed_uris()
234
235 self._run_ldconfig()
236
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500237 if self.d.getVar('USE_DEPMOD') != "0":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500238 self._generate_kernel_module_deps()
239
240 self._cleanup()
241 self._log_check()
242
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600243 if self.progress_reporter:
244 self.progress_reporter.next_stage()
245
246
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500247 def _uninstall_unneeded(self):
248 # Remove unneeded init script symlinks
249 delayed_postinsts = self._get_delayed_postinsts()
250 if delayed_postinsts is None:
251 if os.path.exists(self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/init.d/run-postinsts")):
252 self._exec_shell_cmd(["update-rc.d", "-f", "-r",
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500253 self.d.getVar('IMAGE_ROOTFS'),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500254 "run-postinsts", "remove"])
255
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500256 image_rorfs = bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500257 True, False, self.d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500258 image_rorfs_force = self.d.getVar('FORCE_RO_REMOVE')
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600259
260 if image_rorfs or image_rorfs_force == "1":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500261 # Remove components that we don't need if it's a read-only rootfs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500262 unneeded_pkgs = self.d.getVar("ROOTFS_RO_UNNEEDED").split()
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500263 pkgs_installed = image_list_installed_packages(self.d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500264 # Make sure update-alternatives is last on the command line, so
265 # that it is removed last. This makes sure that its database is
266 # available while uninstalling packages, allowing alternative
267 # symlinks of packages to be uninstalled to be managed correctly.
268 provider = self.d.getVar("VIRTUAL-RUNTIME_update-alternatives")
269 pkgs_to_remove = sorted([pkg for pkg in pkgs_installed if pkg in unneeded_pkgs], key=lambda x: x == provider)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500270
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500271 if len(pkgs_to_remove) > 0:
272 self.pm.remove(pkgs_to_remove, False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500273
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500274 if delayed_postinsts:
275 self._save_postinsts()
276 if image_rorfs:
277 bb.warn("There are post install scripts "
278 "in a read-only rootfs")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500279
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500280 post_uninstall_cmds = self.d.getVar("ROOTFS_POSTUNINSTALL_COMMAND")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500281 execute_pre_post_process(self.d, post_uninstall_cmds)
282
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500283 runtime_pkgmanage = bb.utils.contains("IMAGE_FEATURES", "package-management",
284 True, False, self.d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500285 if not runtime_pkgmanage:
286 # Remove the package manager data files
287 self.pm.remove_packaging_data()
288
289 def _run_intercepts(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500290 intercepts_dir = os.path.join(self.d.getVar('WORKDIR'),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500291 "intercept_scripts")
292
293 bb.note("Running intercept scripts:")
294 os.environ['D'] = self.image_rootfs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500295 os.environ['STAGING_DIR_NATIVE'] = self.d.getVar('STAGING_DIR_NATIVE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500296 for script in os.listdir(intercepts_dir):
297 script_full = os.path.join(intercepts_dir, script)
298
299 if script == "postinst_intercept" or not os.access(script_full, os.X_OK):
300 continue
301
302 bb.note("> Executing %s intercept ..." % script)
303
304 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500305 subprocess.check_output(script_full)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500306 except subprocess.CalledProcessError as e:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500307 bb.warn("The postinstall intercept hook '%s' failed (exit code: %d)! See log for details! (Output: %s)" %
308 (script, e.returncode, e.output))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500309
310 with open(script_full) as intercept:
311 registered_pkgs = None
312 for line in intercept.read().split("\n"):
313 m = re.match("^##PKGS:(.*)", line)
314 if m is not None:
315 registered_pkgs = m.group(1).strip()
316 break
317
318 if registered_pkgs is not None:
319 bb.warn("The postinstalls for the following packages "
320 "will be postponed for first boot: %s" %
321 registered_pkgs)
322
323 # call the backend dependent handler
324 self._handle_intercept_failure(registered_pkgs)
325
326 def _run_ldconfig(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500327 if self.d.getVar('LDCONFIGDEPEND'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500328 bb.note("Executing: ldconfig -r" + self.image_rootfs + "-c new -v")
329 self._exec_shell_cmd(['ldconfig', '-r', self.image_rootfs, '-c',
330 'new', '-v'])
331
332 def _check_for_kernel_modules(self, modules_dir):
333 for root, dirs, files in os.walk(modules_dir, topdown=True):
334 for name in files:
335 found_ko = name.endswith(".ko")
336 if found_ko:
337 return found_ko
338 return False
339
340 def _generate_kernel_module_deps(self):
341 modules_dir = os.path.join(self.image_rootfs, 'lib', 'modules')
342 # if we don't have any modules don't bother to do the depmod
343 if not self._check_for_kernel_modules(modules_dir):
344 bb.note("No Kernel Modules found, not running depmod")
345 return
346
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500347 kernel_abi_ver_file = oe.path.join(self.d.getVar('PKGDATA_DIR'), "kernel-depmod",
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500348 'kernel-abiversion')
349 if not os.path.exists(kernel_abi_ver_file):
350 bb.fatal("No kernel-abiversion file found (%s), cannot run depmod, aborting" % kernel_abi_ver_file)
351
352 kernel_ver = open(kernel_abi_ver_file).read().strip(' \n')
353 versioned_modules_dir = os.path.join(self.image_rootfs, modules_dir, kernel_ver)
354
355 bb.utils.mkdirhier(versioned_modules_dir)
356
357 self._exec_shell_cmd(['depmodwrapper', '-a', '-b', self.image_rootfs, kernel_ver])
358
359 """
360 Create devfs:
361 * IMAGE_DEVICE_TABLE is the old name to an absolute path to a device table file
362 * IMAGE_DEVICE_TABLES is a new name for a file, or list of files, seached
363 for in the BBPATH
364 If neither are specified then the default name of files/device_table-minimal.txt
365 is searched for in the BBPATH (same as the old version.)
366 """
367 def _create_devfs(self):
368 devtable_list = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500369 devtable = self.d.getVar('IMAGE_DEVICE_TABLE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500370 if devtable is not None:
371 devtable_list.append(devtable)
372 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500373 devtables = self.d.getVar('IMAGE_DEVICE_TABLES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500374 if devtables is None:
375 devtables = 'files/device_table-minimal.txt'
376 for devtable in devtables.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500377 devtable_list.append("%s" % bb.utils.which(self.d.getVar('BBPATH'), devtable))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500378
379 for devtable in devtable_list:
380 self._exec_shell_cmd(["makedevs", "-r",
381 self.image_rootfs, "-D", devtable])
382
383
384class RpmRootfs(Rootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500385 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
386 super(RpmRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500387 self.log_check_regex = '(unpacking of archive failed|Cannot find package'\
388 '|exit 1|ERROR: |Error: |Error |ERROR '\
389 '|Failed |Failed: |Failed$|Failed\(\d+\):)'
390 self.manifest = RpmManifest(d, manifest_dir)
391
392 self.pm = RpmPM(d,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500393 d.getVar('IMAGE_ROOTFS'),
394 self.d.getVar('TARGET_VENDOR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500395 )
396
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500397 self.inc_rpm_image_gen = self.d.getVar('INC_RPM_IMAGE_GEN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500398 if self.inc_rpm_image_gen != "1":
399 bb.utils.remove(self.image_rootfs, True)
400 else:
401 self.pm.recovery_packaging_data()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500402 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500403
404 self.pm.create_configs()
405
406 '''
407 While rpm incremental image generation is enabled, it will remove the
408 unneeded pkgs by comparing the new install solution manifest and the
409 old installed manifest.
410 '''
411 def _create_incremental(self, pkgs_initial_install):
412 if self.inc_rpm_image_gen == "1":
413
414 pkgs_to_install = list()
415 for pkg_type in pkgs_initial_install:
416 pkgs_to_install += pkgs_initial_install[pkg_type]
417
418 installed_manifest = self.pm.load_old_install_solution()
419 solution_manifest = self.pm.dump_install_solution(pkgs_to_install)
420
421 pkg_to_remove = list()
422 for pkg in installed_manifest:
423 if pkg not in solution_manifest:
424 pkg_to_remove.append(pkg)
425
426 self.pm.update()
427
428 bb.note('incremental update -- upgrade packages in place ')
429 self.pm.upgrade()
430 if pkg_to_remove != []:
431 bb.note('incremental removed: %s' % ' '.join(pkg_to_remove))
432 self.pm.remove(pkg_to_remove)
433
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500434 self.pm.autoremove()
435
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500436 def _create(self):
437 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500438 rpm_pre_process_cmds = self.d.getVar('RPM_PREPROCESS_COMMANDS')
439 rpm_post_process_cmds = self.d.getVar('RPM_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500440
441 # update PM index files
442 self.pm.write_index()
443
444 execute_pre_post_process(self.d, rpm_pre_process_cmds)
445
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600446 if self.progress_reporter:
447 self.progress_reporter.next_stage()
448
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500449 if self.inc_rpm_image_gen == "1":
450 self._create_incremental(pkgs_to_install)
451
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600452 if self.progress_reporter:
453 self.progress_reporter.next_stage()
454
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500455 self.pm.update()
456
457 pkgs = []
458 pkgs_attempt = []
459 for pkg_type in pkgs_to_install:
460 if pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY:
461 pkgs_attempt += pkgs_to_install[pkg_type]
462 else:
463 pkgs += pkgs_to_install[pkg_type]
464
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600465 if self.progress_reporter:
466 self.progress_reporter.next_stage()
467
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500468 self.pm.install(pkgs)
469
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600470 if self.progress_reporter:
471 self.progress_reporter.next_stage()
472
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500473 self.pm.install(pkgs_attempt, True)
474
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600475 if self.progress_reporter:
476 self.progress_reporter.next_stage()
477
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500478 self.pm.install_complementary()
479
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600480 if self.progress_reporter:
481 self.progress_reporter.next_stage()
482
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500483 self._setup_dbg_rootfs(['/etc', '/var/lib/rpm', '/var/cache/dnf', '/var/lib/dnf'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500484
485 execute_pre_post_process(self.d, rpm_post_process_cmds)
486
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500487 if self.inc_rpm_image_gen == "1":
488 self.pm.backup_packaging_data()
489
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600490 if self.progress_reporter:
491 self.progress_reporter.next_stage()
492
493
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500494 @staticmethod
495 def _depends_list():
496 return ['DEPLOY_DIR_RPM', 'INC_RPM_IMAGE_GEN', 'RPM_PREPROCESS_COMMANDS',
497 'RPM_POSTPROCESS_COMMANDS', 'RPM_PREFER_ELF_ARCH']
498
499 def _get_delayed_postinsts(self):
500 postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/rpm-postinsts")
501 if os.path.isdir(postinst_dir):
502 files = os.listdir(postinst_dir)
503 for f in files:
504 bb.note('Delayed package scriptlet: %s' % f)
505 return files
506
507 return None
508
509 def _save_postinsts(self):
510 # this is just a stub. For RPM, the failed postinstalls are
511 # already saved in /etc/rpm-postinsts
512 pass
513
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500514 def _log_check(self):
515 self._log_check_warn()
516 self._log_check_error()
517
518 def _handle_intercept_failure(self, registered_pkgs):
519 rpm_postinsts_dir = self.image_rootfs + self.d.expand('${sysconfdir}/rpm-postinsts/')
520 bb.utils.mkdirhier(rpm_postinsts_dir)
521
522 # Save the package postinstalls in /etc/rpm-postinsts
523 for pkg in registered_pkgs.split():
524 self.pm.save_rpmpostinst(pkg)
525
526 def _cleanup(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500527 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500528
529class DpkgOpkgRootfs(Rootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500530 def __init__(self, d, progress_reporter=None, logcatcher=None):
531 super(DpkgOpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500532
533 def _get_pkgs_postinsts(self, status_file):
534 def _get_pkg_depends_list(pkg_depends):
535 pkg_depends_list = []
536 # filter version requirements like libc (>= 1.1)
537 for dep in pkg_depends.split(', '):
538 m_dep = re.match("^(.*) \(.*\)$", dep)
539 if m_dep:
540 dep = m_dep.group(1)
541 pkg_depends_list.append(dep)
542
543 return pkg_depends_list
544
545 pkgs = {}
546 pkg_name = ""
547 pkg_status_match = False
548 pkg_depends = ""
549
550 with open(status_file) as status:
551 data = status.read()
552 status.close()
553 for line in data.split('\n'):
554 m_pkg = re.match("^Package: (.*)", line)
555 m_status = re.match("^Status:.*unpacked", line)
556 m_depends = re.match("^Depends: (.*)", line)
557
558 if m_pkg is not None:
559 if pkg_name and pkg_status_match:
560 pkgs[pkg_name] = _get_pkg_depends_list(pkg_depends)
561
562 pkg_name = m_pkg.group(1)
563 pkg_status_match = False
564 pkg_depends = ""
565 elif m_status is not None:
566 pkg_status_match = True
567 elif m_depends is not None:
568 pkg_depends = m_depends.group(1)
569
570 # remove package dependencies not in postinsts
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600571 pkg_names = list(pkgs.keys())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500572 for pkg_name in pkg_names:
573 deps = pkgs[pkg_name][:]
574
575 for d in deps:
576 if d not in pkg_names:
577 pkgs[pkg_name].remove(d)
578
579 return pkgs
580
581 def _get_delayed_postinsts_common(self, status_file):
582 def _dep_resolve(graph, node, resolved, seen):
583 seen.append(node)
584
585 for edge in graph[node]:
586 if edge not in resolved:
587 if edge in seen:
588 raise RuntimeError("Packages %s and %s have " \
589 "a circular dependency in postinsts scripts." \
590 % (node, edge))
591 _dep_resolve(graph, edge, resolved, seen)
592
593 resolved.append(node)
594
595 pkg_list = []
596
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500597 pkgs = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500598 if not self.d.getVar('PACKAGE_INSTALL').strip():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500599 bb.note("Building empty image")
600 else:
601 pkgs = self._get_pkgs_postinsts(status_file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500602 if pkgs:
603 root = "__packagegroup_postinst__"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600604 pkgs[root] = list(pkgs.keys())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500605 _dep_resolve(pkgs, root, pkg_list, [])
606 pkg_list.remove(root)
607
608 if len(pkg_list) == 0:
609 return None
610
611 return pkg_list
612
613 def _save_postinsts_common(self, dst_postinst_dir, src_postinst_dir):
614 num = 0
615 for p in self._get_delayed_postinsts():
616 bb.utils.mkdirhier(dst_postinst_dir)
617
618 if os.path.exists(os.path.join(src_postinst_dir, p + ".postinst")):
619 shutil.copy(os.path.join(src_postinst_dir, p + ".postinst"),
620 os.path.join(dst_postinst_dir, "%03d-%s" % (num, p)))
621
622 num += 1
623
624class DpkgRootfs(DpkgOpkgRootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500625 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
626 super(DpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500627 self.log_check_regex = '^E:'
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600628 self.log_check_expected_regexes = \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500629 [
630 "^E: Unmet dependencies."
631 ]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500632
633 bb.utils.remove(self.image_rootfs, True)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500634 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500635 self.manifest = DpkgManifest(d, manifest_dir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500636 self.pm = DpkgPM(d, d.getVar('IMAGE_ROOTFS'),
637 d.getVar('PACKAGE_ARCHS'),
638 d.getVar('DPKG_ARCH'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500639
640
641 def _create(self):
642 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500643 deb_pre_process_cmds = self.d.getVar('DEB_PREPROCESS_COMMANDS')
644 deb_post_process_cmds = self.d.getVar('DEB_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500645
646 alt_dir = self.d.expand("${IMAGE_ROOTFS}/var/lib/dpkg/alternatives")
647 bb.utils.mkdirhier(alt_dir)
648
649 # update PM index files
650 self.pm.write_index()
651
652 execute_pre_post_process(self.d, deb_pre_process_cmds)
653
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600654 if self.progress_reporter:
655 self.progress_reporter.next_stage()
656 # Don't support incremental, so skip that
657 self.progress_reporter.next_stage()
658
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500659 self.pm.update()
660
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600661 if self.progress_reporter:
662 self.progress_reporter.next_stage()
663
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500664 for pkg_type in self.install_order:
665 if pkg_type in pkgs_to_install:
666 self.pm.install(pkgs_to_install[pkg_type],
667 [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
668
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600669 if self.progress_reporter:
670 # Don't support attemptonly, so skip that
671 self.progress_reporter.next_stage()
672 self.progress_reporter.next_stage()
673
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500674 self.pm.install_complementary()
675
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600676 if self.progress_reporter:
677 self.progress_reporter.next_stage()
678
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500679 self._setup_dbg_rootfs(['/var/lib/dpkg'])
680
681 self.pm.fix_broken_dependencies()
682
683 self.pm.mark_packages("installed")
684
685 self.pm.run_pre_post_installs()
686
687 execute_pre_post_process(self.d, deb_post_process_cmds)
688
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600689 if self.progress_reporter:
690 self.progress_reporter.next_stage()
691
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500692 @staticmethod
693 def _depends_list():
694 return ['DEPLOY_DIR_DEB', 'DEB_SDK_ARCH', 'APTCONF_TARGET', 'APT_ARGS', 'DPKG_ARCH', 'DEB_PREPROCESS_COMMANDS', 'DEB_POSTPROCESS_COMMANDS']
695
696 def _get_delayed_postinsts(self):
697 status_file = self.image_rootfs + "/var/lib/dpkg/status"
698 return self._get_delayed_postinsts_common(status_file)
699
700 def _save_postinsts(self):
701 dst_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/deb-postinsts")
702 src_postinst_dir = self.d.expand("${IMAGE_ROOTFS}/var/lib/dpkg/info")
703 return self._save_postinsts_common(dst_postinst_dir, src_postinst_dir)
704
705 def _handle_intercept_failure(self, registered_pkgs):
706 self.pm.mark_packages("unpacked", registered_pkgs.split())
707
708 def _log_check(self):
709 self._log_check_warn()
710 self._log_check_error()
711
712 def _cleanup(self):
713 pass
714
715
716class OpkgRootfs(DpkgOpkgRootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500717 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
718 super(OpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500719 self.log_check_regex = '(exit 1|Collected errors)'
720
721 self.manifest = OpkgManifest(d, manifest_dir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500722 self.opkg_conf = self.d.getVar("IPKGCONF_TARGET")
723 self.pkg_archs = self.d.getVar("ALL_MULTILIB_PACKAGE_ARCHS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500724
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500725 self.inc_opkg_image_gen = self.d.getVar('INC_IPK_IMAGE_GEN') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500726 if self._remove_old_rootfs():
727 bb.utils.remove(self.image_rootfs, True)
728 self.pm = OpkgPM(d,
729 self.image_rootfs,
730 self.opkg_conf,
731 self.pkg_archs)
732 else:
733 self.pm = OpkgPM(d,
734 self.image_rootfs,
735 self.opkg_conf,
736 self.pkg_archs)
737 self.pm.recover_packaging_data()
738
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500739 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500740
741 def _prelink_file(self, root_dir, filename):
742 bb.note('prelink %s in %s' % (filename, root_dir))
743 prelink_cfg = oe.path.join(root_dir,
744 self.d.expand('${sysconfdir}/prelink.conf'))
745 if not os.path.exists(prelink_cfg):
746 shutil.copy(self.d.expand('${STAGING_DIR_NATIVE}${sysconfdir_native}/prelink.conf'),
747 prelink_cfg)
748
749 cmd_prelink = self.d.expand('${STAGING_DIR_NATIVE}${sbindir_native}/prelink')
750 self._exec_shell_cmd([cmd_prelink,
751 '--root',
752 root_dir,
753 '-amR',
754 '-N',
755 '-c',
756 self.d.expand('${sysconfdir}/prelink.conf')])
757
758 '''
759 Compare two files with the same key twice to see if they are equal.
760 If they are not equal, it means they are duplicated and come from
761 different packages.
762 1st: Comapre them directly;
763 2nd: While incremental image creation is enabled, one of the
764 files could be probaly prelinked in the previous image
765 creation and the file has been changed, so we need to
766 prelink the other one and compare them.
767 '''
768 def _file_equal(self, key, f1, f2):
769
770 # Both of them are not prelinked
771 if filecmp.cmp(f1, f2):
772 return True
773
774 if self.image_rootfs not in f1:
775 self._prelink_file(f1.replace(key, ''), f1)
776
777 if self.image_rootfs not in f2:
778 self._prelink_file(f2.replace(key, ''), f2)
779
780 # Both of them are prelinked
781 if filecmp.cmp(f1, f2):
782 return True
783
784 # Not equal
785 return False
786
787 """
788 This function was reused from the old implementation.
789 See commit: "image.bbclass: Added variables for multilib support." by
790 Lianhao Lu.
791 """
792 def _multilib_sanity_test(self, dirs):
793
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500794 allow_replace = self.d.getVar("MULTILIBRE_ALLOW_REP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500795 if allow_replace is None:
796 allow_replace = ""
797
798 allow_rep = re.compile(re.sub("\|$", "", allow_replace))
799 error_prompt = "Multilib check error:"
800
801 files = {}
802 for dir in dirs:
803 for root, subfolders, subfiles in os.walk(dir):
804 for file in subfiles:
805 item = os.path.join(root, file)
806 key = str(os.path.join("/", os.path.relpath(item, dir)))
807
808 valid = True
809 if key in files:
810 #check whether the file is allow to replace
811 if allow_rep.match(key):
812 valid = True
813 else:
814 if os.path.exists(files[key]) and \
815 os.path.exists(item) and \
816 not self._file_equal(key, files[key], item):
817 valid = False
818 bb.fatal("%s duplicate files %s %s is not the same\n" %
819 (error_prompt, item, files[key]))
820
821 #pass the check, add to list
822 if valid:
823 files[key] = item
824
825 def _multilib_test_install(self, pkgs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500826 ml_temp = self.d.getVar("MULTILIB_TEMP_ROOTFS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500827 bb.utils.mkdirhier(ml_temp)
828
829 dirs = [self.image_rootfs]
830
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500831 for variant in self.d.getVar("MULTILIB_VARIANTS").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500832 ml_target_rootfs = os.path.join(ml_temp, variant)
833
834 bb.utils.remove(ml_target_rootfs, True)
835
836 ml_opkg_conf = os.path.join(ml_temp,
837 variant + "-" + os.path.basename(self.opkg_conf))
838
839 ml_pm = OpkgPM(self.d, ml_target_rootfs, ml_opkg_conf, self.pkg_archs)
840
841 ml_pm.update()
842 ml_pm.install(pkgs)
843
844 dirs.append(ml_target_rootfs)
845
846 self._multilib_sanity_test(dirs)
847
848 '''
849 While ipk incremental image generation is enabled, it will remove the
850 unneeded pkgs by comparing the old full manifest in previous existing
851 image and the new full manifest in the current image.
852 '''
853 def _remove_extra_packages(self, pkgs_initial_install):
854 if self.inc_opkg_image_gen == "1":
855 # Parse full manifest in previous existing image creation session
856 old_full_manifest = self.manifest.parse_full_manifest()
857
858 # Create full manifest for the current image session, the old one
859 # will be replaced by the new one.
860 self.manifest.create_full(self.pm)
861
862 # Parse full manifest in current image creation session
863 new_full_manifest = self.manifest.parse_full_manifest()
864
865 pkg_to_remove = list()
866 for pkg in old_full_manifest:
867 if pkg not in new_full_manifest:
868 pkg_to_remove.append(pkg)
869
870 if pkg_to_remove != []:
871 bb.note('decremental removed: %s' % ' '.join(pkg_to_remove))
872 self.pm.remove(pkg_to_remove)
873
874 '''
875 Compare with previous existing image creation, if some conditions
876 triggered, the previous old image should be removed.
877 The conditions include any of 'PACKAGE_EXCLUDE, NO_RECOMMENDATIONS
878 and BAD_RECOMMENDATIONS' has been changed.
879 '''
880 def _remove_old_rootfs(self):
881 if self.inc_opkg_image_gen != "1":
882 return True
883
884 vars_list_file = self.d.expand('${T}/vars_list')
885
886 old_vars_list = ""
887 if os.path.exists(vars_list_file):
888 old_vars_list = open(vars_list_file, 'r+').read()
889
890 new_vars_list = '%s:%s:%s\n' % \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500891 ((self.d.getVar('BAD_RECOMMENDATIONS') or '').strip(),
892 (self.d.getVar('NO_RECOMMENDATIONS') or '').strip(),
893 (self.d.getVar('PACKAGE_EXCLUDE') or '').strip())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500894 open(vars_list_file, 'w+').write(new_vars_list)
895
896 if old_vars_list != new_vars_list:
897 return True
898
899 return False
900
901 def _create(self):
902 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500903 opkg_pre_process_cmds = self.d.getVar('OPKG_PREPROCESS_COMMANDS')
904 opkg_post_process_cmds = self.d.getVar('OPKG_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500905
906 # update PM index files, unless users provide their own feeds
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500907 if (self.d.getVar('BUILD_IMAGES_FROM_FEEDS') or "") != "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500908 self.pm.write_index()
909
910 execute_pre_post_process(self.d, opkg_pre_process_cmds)
911
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600912 if self.progress_reporter:
913 self.progress_reporter.next_stage()
914 # Steps are a bit different in order, skip next
915 self.progress_reporter.next_stage()
916
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500917 self.pm.update()
918
919 self.pm.handle_bad_recommendations()
920
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600921 if self.progress_reporter:
922 self.progress_reporter.next_stage()
923
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500924 if self.inc_opkg_image_gen == "1":
925 self._remove_extra_packages(pkgs_to_install)
926
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600927 if self.progress_reporter:
928 self.progress_reporter.next_stage()
929
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500930 for pkg_type in self.install_order:
931 if pkg_type in pkgs_to_install:
932 # For multilib, we perform a sanity test before final install
933 # If sanity test fails, it will automatically do a bb.fatal()
934 # and the installation will stop
935 if pkg_type == Manifest.PKG_TYPE_MULTILIB:
936 self._multilib_test_install(pkgs_to_install[pkg_type])
937
938 self.pm.install(pkgs_to_install[pkg_type],
939 [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
940
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600941 if self.progress_reporter:
942 self.progress_reporter.next_stage()
943
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500944 self.pm.install_complementary()
945
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600946 if self.progress_reporter:
947 self.progress_reporter.next_stage()
948
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500949 opkg_lib_dir = self.d.getVar('OPKGLIBDIR')
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500950 opkg_dir = os.path.join(opkg_lib_dir, 'opkg')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500951 self._setup_dbg_rootfs([opkg_dir])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500952
953 execute_pre_post_process(self.d, opkg_post_process_cmds)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500954
955 if self.inc_opkg_image_gen == "1":
956 self.pm.backup_packaging_data()
957
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600958 if self.progress_reporter:
959 self.progress_reporter.next_stage()
960
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500961 @staticmethod
962 def _depends_list():
963 return ['IPKGCONF_SDK', 'IPK_FEED_URIS', 'DEPLOY_DIR_IPK', 'IPKGCONF_TARGET', 'INC_IPK_IMAGE_GEN', 'OPKG_ARGS', 'OPKGLIBDIR', 'OPKG_PREPROCESS_COMMANDS', 'OPKG_POSTPROCESS_COMMANDS', 'OPKGLIBDIR']
964
965 def _get_delayed_postinsts(self):
966 status_file = os.path.join(self.image_rootfs,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500967 self.d.getVar('OPKGLIBDIR').strip('/'),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500968 "opkg", "status")
969 return self._get_delayed_postinsts_common(status_file)
970
971 def _save_postinsts(self):
972 dst_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/ipk-postinsts")
973 src_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${OPKGLIBDIR}/opkg/info")
974 return self._save_postinsts_common(dst_postinst_dir, src_postinst_dir)
975
976 def _handle_intercept_failure(self, registered_pkgs):
977 self.pm.mark_packages("unpacked", registered_pkgs.split())
978
979 def _log_check(self):
980 self._log_check_warn()
981 self._log_check_error()
982
983 def _cleanup(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500984 self.pm.remove_lists()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500985
986def get_class_for_type(imgtype):
987 return {"rpm": RpmRootfs,
988 "ipk": OpkgRootfs,
989 "deb": DpkgRootfs}[imgtype]
990
991def variable_depends(d, manifest_dir=None):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500992 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500993 cls = get_class_for_type(img_type)
994 return cls._depends_list()
995
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500996def create_rootfs(d, manifest_dir=None, progress_reporter=None, logcatcher=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500997 env_bkp = os.environ.copy()
998
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500999 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001000 if img_type == "rpm":
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001001 RpmRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001002 elif img_type == "ipk":
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001003 OpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001004 elif img_type == "deb":
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001005 DpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001006
1007 os.environ.clear()
1008 os.environ.update(env_bkp)
1009
1010
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001011def image_list_installed_packages(d, rootfs_dir=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001012 if not rootfs_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001013 rootfs_dir = d.getVar('IMAGE_ROOTFS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001014
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001015 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001016 if img_type == "rpm":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001017 return RpmPkgsList(d, rootfs_dir).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001018 elif img_type == "ipk":
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001019 return OpkgPkgsList(d, rootfs_dir, d.getVar("IPKGCONF_TARGET")).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001020 elif img_type == "deb":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001021 return DpkgPkgsList(d, rootfs_dir).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001022
1023if __name__ == "__main__":
1024 """
1025 We should be able to run this as a standalone script, from outside bitbake
1026 environment.
1027 """
1028 """
1029 TBD
1030 """