blob: e5512d09efdb905c3ccc3c0f29ca1e2b67b79e72 [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
Patrick Williamsc124f4f2015-09-15 14:41:29 -050095 """
96 The _cleanup() method should be used to clean-up stuff that we don't really
97 want to end up on target. For example, in the case of RPM, the DB locks.
98 The method is called, once, at the end of create() method.
99 """
100 @abstractmethod
101 def _cleanup(self):
102 pass
103
104 def _setup_dbg_rootfs(self, dirs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500105 gen_debugfs = self.d.getVar('IMAGE_GEN_DEBUGFS') or '0'
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500106 if gen_debugfs != '1':
107 return
108
109 bb.note(" Renaming the original rootfs...")
110 try:
111 shutil.rmtree(self.image_rootfs + '-orig')
112 except:
113 pass
114 os.rename(self.image_rootfs, self.image_rootfs + '-orig')
115
116 bb.note(" Creating debug rootfs...")
117 bb.utils.mkdirhier(self.image_rootfs)
118
119 bb.note(" Copying back package database...")
120 for dir in dirs:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600121 if not os.path.isdir(self.image_rootfs + '-orig' + dir):
122 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500123 bb.utils.mkdirhier(self.image_rootfs + os.path.dirname(dir))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600124 shutil.copytree(self.image_rootfs + '-orig' + dir, self.image_rootfs + dir, symlinks=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500125
126 cpath = oe.cachedpath.CachedPath()
127 # Copy files located in /usr/lib/debug or /usr/src/debug
128 for dir in ["/usr/lib/debug", "/usr/src/debug"]:
129 src = self.image_rootfs + '-orig' + dir
130 if cpath.exists(src):
131 dst = self.image_rootfs + dir
132 bb.utils.mkdirhier(os.path.dirname(dst))
133 shutil.copytree(src, dst)
134
135 # Copy files with suffix '.debug' or located in '.debug' dir.
136 for root, dirs, files in cpath.walk(self.image_rootfs + '-orig'):
137 relative_dir = root[len(self.image_rootfs + '-orig'):]
138 for f in files:
139 if f.endswith('.debug') or '/.debug' in relative_dir:
140 bb.utils.mkdirhier(self.image_rootfs + relative_dir)
141 shutil.copy(os.path.join(root, f),
142 self.image_rootfs + relative_dir)
143
144 bb.note(" Install complementary '*-dbg' packages...")
145 self.pm.install_complementary('*-dbg')
146
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800147 if self.d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
148 bb.note(" Install complementary '*-src' packages...")
149 self.pm.install_complementary('*-src')
150
151 """
152 Install additional debug packages. Possibility to install additional packages,
153 which are not automatically installed as complementary package of
154 standard one, e.g. debug package of static libraries.
155 """
156 extra_debug_pkgs = self.d.getVar('IMAGE_INSTALL_DEBUGFS')
157 if extra_debug_pkgs:
158 bb.note(" Install extra debug packages...")
159 self.pm.install(extra_debug_pkgs.split(), True)
160
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500161 bb.note(" Rename debug rootfs...")
162 try:
163 shutil.rmtree(self.image_rootfs + '-dbg')
164 except:
165 pass
166 os.rename(self.image_rootfs, self.image_rootfs + '-dbg')
167
168 bb.note(" Restoreing original rootfs...")
169 os.rename(self.image_rootfs + '-orig', self.image_rootfs)
170
171 def _exec_shell_cmd(self, cmd):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500172 fakerootcmd = self.d.getVar('FAKEROOT')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500173 if fakerootcmd is not None:
174 exec_cmd = [fakerootcmd, cmd]
175 else:
176 exec_cmd = cmd
177
178 try:
179 subprocess.check_output(exec_cmd, stderr=subprocess.STDOUT)
180 except subprocess.CalledProcessError as e:
181 return("Command '%s' returned %d:\n%s" % (e.cmd, e.returncode, e.output))
182
183 return None
184
185 def create(self):
186 bb.note("###### Generate rootfs #######")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500187 pre_process_cmds = self.d.getVar("ROOTFS_PREPROCESS_COMMAND")
188 post_process_cmds = self.d.getVar("ROOTFS_POSTPROCESS_COMMAND")
189 rootfs_post_install_cmds = self.d.getVar('ROOTFS_POSTINSTALL_COMMAND')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500190
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500191 bb.utils.mkdirhier(self.image_rootfs)
192
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600193 bb.utils.mkdirhier(self.deploydir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500194
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
Brad Bishop316dfdd2018-06-25 12:45:53 -0400210 self.pm.run_intercepts()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500211
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 Bishopd7bf8c12018-02-25 22:55:05 -0500264 # Make sure update-alternatives is removed last. This is
265 # because its database has to available while uninstalling
266 # other packages, allowing alternative symlinks of packages
267 # to be uninstalled or to be managed correctly otherwise.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500268 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
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500271 # update-alternatives provider is removed in its own remove()
272 # call because all package managers do not guarantee the packages
273 # are removed in the order they given in the list (which is
274 # passed to the command line). The sorting done earlier is
275 # utilized to implement the 2-stage removal.
276 if len(pkgs_to_remove) > 1:
277 self.pm.remove(pkgs_to_remove[:-1], False)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500278 if len(pkgs_to_remove) > 0:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500279 self.pm.remove([pkgs_to_remove[-1]], False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500280
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500281 if delayed_postinsts:
282 self._save_postinsts()
283 if image_rorfs:
284 bb.warn("There are post install scripts "
285 "in a read-only rootfs")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500286
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500287 post_uninstall_cmds = self.d.getVar("ROOTFS_POSTUNINSTALL_COMMAND")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500288 execute_pre_post_process(self.d, post_uninstall_cmds)
289
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500290 runtime_pkgmanage = bb.utils.contains("IMAGE_FEATURES", "package-management",
291 True, False, self.d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500292 if not runtime_pkgmanage:
293 # Remove the package manager data files
294 self.pm.remove_packaging_data()
295
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500296 def _run_ldconfig(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500297 if self.d.getVar('LDCONFIGDEPEND'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500298 bb.note("Executing: ldconfig -r" + self.image_rootfs + "-c new -v")
299 self._exec_shell_cmd(['ldconfig', '-r', self.image_rootfs, '-c',
300 'new', '-v'])
301
302 def _check_for_kernel_modules(self, modules_dir):
303 for root, dirs, files in os.walk(modules_dir, topdown=True):
304 for name in files:
305 found_ko = name.endswith(".ko")
306 if found_ko:
307 return found_ko
308 return False
309
310 def _generate_kernel_module_deps(self):
311 modules_dir = os.path.join(self.image_rootfs, 'lib', 'modules')
312 # if we don't have any modules don't bother to do the depmod
313 if not self._check_for_kernel_modules(modules_dir):
314 bb.note("No Kernel Modules found, not running depmod")
315 return
316
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500317 kernel_abi_ver_file = oe.path.join(self.d.getVar('PKGDATA_DIR'), "kernel-depmod",
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500318 'kernel-abiversion')
319 if not os.path.exists(kernel_abi_ver_file):
320 bb.fatal("No kernel-abiversion file found (%s), cannot run depmod, aborting" % kernel_abi_ver_file)
321
322 kernel_ver = open(kernel_abi_ver_file).read().strip(' \n')
323 versioned_modules_dir = os.path.join(self.image_rootfs, modules_dir, kernel_ver)
324
325 bb.utils.mkdirhier(versioned_modules_dir)
326
327 self._exec_shell_cmd(['depmodwrapper', '-a', '-b', self.image_rootfs, kernel_ver])
328
329 """
330 Create devfs:
331 * IMAGE_DEVICE_TABLE is the old name to an absolute path to a device table file
332 * IMAGE_DEVICE_TABLES is a new name for a file, or list of files, seached
333 for in the BBPATH
334 If neither are specified then the default name of files/device_table-minimal.txt
335 is searched for in the BBPATH (same as the old version.)
336 """
337 def _create_devfs(self):
338 devtable_list = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500339 devtable = self.d.getVar('IMAGE_DEVICE_TABLE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500340 if devtable is not None:
341 devtable_list.append(devtable)
342 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500343 devtables = self.d.getVar('IMAGE_DEVICE_TABLES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500344 if devtables is None:
345 devtables = 'files/device_table-minimal.txt'
346 for devtable in devtables.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500347 devtable_list.append("%s" % bb.utils.which(self.d.getVar('BBPATH'), devtable))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500348
349 for devtable in devtable_list:
350 self._exec_shell_cmd(["makedevs", "-r",
351 self.image_rootfs, "-D", devtable])
352
353
354class RpmRootfs(Rootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500355 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
356 super(RpmRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500357 self.log_check_regex = '(unpacking of archive failed|Cannot find package'\
358 '|exit 1|ERROR: |Error: |Error |ERROR '\
359 '|Failed |Failed: |Failed$|Failed\(\d+\):)'
360 self.manifest = RpmManifest(d, manifest_dir)
361
362 self.pm = RpmPM(d,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500363 d.getVar('IMAGE_ROOTFS'),
364 self.d.getVar('TARGET_VENDOR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500365 )
366
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500367 self.inc_rpm_image_gen = self.d.getVar('INC_RPM_IMAGE_GEN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500368 if self.inc_rpm_image_gen != "1":
369 bb.utils.remove(self.image_rootfs, True)
370 else:
371 self.pm.recovery_packaging_data()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500372 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500373
374 self.pm.create_configs()
375
376 '''
377 While rpm incremental image generation is enabled, it will remove the
378 unneeded pkgs by comparing the new install solution manifest and the
379 old installed manifest.
380 '''
381 def _create_incremental(self, pkgs_initial_install):
382 if self.inc_rpm_image_gen == "1":
383
384 pkgs_to_install = list()
385 for pkg_type in pkgs_initial_install:
386 pkgs_to_install += pkgs_initial_install[pkg_type]
387
388 installed_manifest = self.pm.load_old_install_solution()
389 solution_manifest = self.pm.dump_install_solution(pkgs_to_install)
390
391 pkg_to_remove = list()
392 for pkg in installed_manifest:
393 if pkg not in solution_manifest:
394 pkg_to_remove.append(pkg)
395
396 self.pm.update()
397
398 bb.note('incremental update -- upgrade packages in place ')
399 self.pm.upgrade()
400 if pkg_to_remove != []:
401 bb.note('incremental removed: %s' % ' '.join(pkg_to_remove))
402 self.pm.remove(pkg_to_remove)
403
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500404 self.pm.autoremove()
405
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500406 def _create(self):
407 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500408 rpm_pre_process_cmds = self.d.getVar('RPM_PREPROCESS_COMMANDS')
409 rpm_post_process_cmds = self.d.getVar('RPM_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500410
411 # update PM index files
412 self.pm.write_index()
413
414 execute_pre_post_process(self.d, rpm_pre_process_cmds)
415
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600416 if self.progress_reporter:
417 self.progress_reporter.next_stage()
418
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500419 if self.inc_rpm_image_gen == "1":
420 self._create_incremental(pkgs_to_install)
421
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600422 if self.progress_reporter:
423 self.progress_reporter.next_stage()
424
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500425 self.pm.update()
426
427 pkgs = []
428 pkgs_attempt = []
429 for pkg_type in pkgs_to_install:
430 if pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY:
431 pkgs_attempt += pkgs_to_install[pkg_type]
432 else:
433 pkgs += pkgs_to_install[pkg_type]
434
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600435 if self.progress_reporter:
436 self.progress_reporter.next_stage()
437
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500438 self.pm.install(pkgs)
439
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600440 if self.progress_reporter:
441 self.progress_reporter.next_stage()
442
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500443 self.pm.install(pkgs_attempt, True)
444
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600445 if self.progress_reporter:
446 self.progress_reporter.next_stage()
447
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500448 self.pm.install_complementary()
449
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600450 if self.progress_reporter:
451 self.progress_reporter.next_stage()
452
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500453 self._setup_dbg_rootfs(['/etc', '/var/lib/rpm', '/var/cache/dnf', '/var/lib/dnf'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500454
455 execute_pre_post_process(self.d, rpm_post_process_cmds)
456
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500457 if self.inc_rpm_image_gen == "1":
458 self.pm.backup_packaging_data()
459
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600460 if self.progress_reporter:
461 self.progress_reporter.next_stage()
462
463
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500464 @staticmethod
465 def _depends_list():
466 return ['DEPLOY_DIR_RPM', 'INC_RPM_IMAGE_GEN', 'RPM_PREPROCESS_COMMANDS',
467 'RPM_POSTPROCESS_COMMANDS', 'RPM_PREFER_ELF_ARCH']
468
469 def _get_delayed_postinsts(self):
470 postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/rpm-postinsts")
471 if os.path.isdir(postinst_dir):
472 files = os.listdir(postinst_dir)
473 for f in files:
474 bb.note('Delayed package scriptlet: %s' % f)
475 return files
476
477 return None
478
479 def _save_postinsts(self):
480 # this is just a stub. For RPM, the failed postinstalls are
481 # already saved in /etc/rpm-postinsts
482 pass
483
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500484 def _log_check(self):
485 self._log_check_warn()
486 self._log_check_error()
487
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500488 def _cleanup(self):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800489 if bb.utils.contains("IMAGE_FEATURES", "package-management", True, False, self.d):
490 self.pm._invoke_dnf(["clean", "all"])
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500491
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500492
493class DpkgOpkgRootfs(Rootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500494 def __init__(self, d, progress_reporter=None, logcatcher=None):
495 super(DpkgOpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500496
497 def _get_pkgs_postinsts(self, status_file):
498 def _get_pkg_depends_list(pkg_depends):
499 pkg_depends_list = []
500 # filter version requirements like libc (>= 1.1)
501 for dep in pkg_depends.split(', '):
502 m_dep = re.match("^(.*) \(.*\)$", dep)
503 if m_dep:
504 dep = m_dep.group(1)
505 pkg_depends_list.append(dep)
506
507 return pkg_depends_list
508
509 pkgs = {}
510 pkg_name = ""
511 pkg_status_match = False
512 pkg_depends = ""
513
514 with open(status_file) as status:
515 data = status.read()
516 status.close()
517 for line in data.split('\n'):
518 m_pkg = re.match("^Package: (.*)", line)
519 m_status = re.match("^Status:.*unpacked", line)
520 m_depends = re.match("^Depends: (.*)", line)
521
522 if m_pkg is not None:
523 if pkg_name and pkg_status_match:
524 pkgs[pkg_name] = _get_pkg_depends_list(pkg_depends)
525
526 pkg_name = m_pkg.group(1)
527 pkg_status_match = False
528 pkg_depends = ""
529 elif m_status is not None:
530 pkg_status_match = True
531 elif m_depends is not None:
532 pkg_depends = m_depends.group(1)
533
534 # remove package dependencies not in postinsts
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600535 pkg_names = list(pkgs.keys())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500536 for pkg_name in pkg_names:
537 deps = pkgs[pkg_name][:]
538
539 for d in deps:
540 if d not in pkg_names:
541 pkgs[pkg_name].remove(d)
542
543 return pkgs
544
545 def _get_delayed_postinsts_common(self, status_file):
546 def _dep_resolve(graph, node, resolved, seen):
547 seen.append(node)
548
549 for edge in graph[node]:
550 if edge not in resolved:
551 if edge in seen:
552 raise RuntimeError("Packages %s and %s have " \
553 "a circular dependency in postinsts scripts." \
554 % (node, edge))
555 _dep_resolve(graph, edge, resolved, seen)
556
557 resolved.append(node)
558
559 pkg_list = []
560
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500561 pkgs = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500562 if not self.d.getVar('PACKAGE_INSTALL').strip():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500563 bb.note("Building empty image")
564 else:
565 pkgs = self._get_pkgs_postinsts(status_file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500566 if pkgs:
567 root = "__packagegroup_postinst__"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600568 pkgs[root] = list(pkgs.keys())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500569 _dep_resolve(pkgs, root, pkg_list, [])
570 pkg_list.remove(root)
571
572 if len(pkg_list) == 0:
573 return None
574
575 return pkg_list
576
577 def _save_postinsts_common(self, dst_postinst_dir, src_postinst_dir):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800578 if bb.utils.contains("IMAGE_FEATURES", "package-management",
579 True, False, self.d):
580 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500581 num = 0
582 for p in self._get_delayed_postinsts():
583 bb.utils.mkdirhier(dst_postinst_dir)
584
585 if os.path.exists(os.path.join(src_postinst_dir, p + ".postinst")):
586 shutil.copy(os.path.join(src_postinst_dir, p + ".postinst"),
587 os.path.join(dst_postinst_dir, "%03d-%s" % (num, p)))
588
589 num += 1
590
591class DpkgRootfs(DpkgOpkgRootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500592 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
593 super(DpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500594 self.log_check_regex = '^E:'
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600595 self.log_check_expected_regexes = \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500596 [
597 "^E: Unmet dependencies."
598 ]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500599
600 bb.utils.remove(self.image_rootfs, True)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500601 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500602 self.manifest = DpkgManifest(d, manifest_dir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500603 self.pm = DpkgPM(d, d.getVar('IMAGE_ROOTFS'),
604 d.getVar('PACKAGE_ARCHS'),
605 d.getVar('DPKG_ARCH'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500606
607
608 def _create(self):
609 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500610 deb_pre_process_cmds = self.d.getVar('DEB_PREPROCESS_COMMANDS')
611 deb_post_process_cmds = self.d.getVar('DEB_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500612
613 alt_dir = self.d.expand("${IMAGE_ROOTFS}/var/lib/dpkg/alternatives")
614 bb.utils.mkdirhier(alt_dir)
615
616 # update PM index files
617 self.pm.write_index()
618
619 execute_pre_post_process(self.d, deb_pre_process_cmds)
620
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600621 if self.progress_reporter:
622 self.progress_reporter.next_stage()
623 # Don't support incremental, so skip that
624 self.progress_reporter.next_stage()
625
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500626 self.pm.update()
627
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600628 if self.progress_reporter:
629 self.progress_reporter.next_stage()
630
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500631 for pkg_type in self.install_order:
632 if pkg_type in pkgs_to_install:
633 self.pm.install(pkgs_to_install[pkg_type],
634 [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
635
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600636 if self.progress_reporter:
637 # Don't support attemptonly, so skip that
638 self.progress_reporter.next_stage()
639 self.progress_reporter.next_stage()
640
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500641 self.pm.install_complementary()
642
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600643 if self.progress_reporter:
644 self.progress_reporter.next_stage()
645
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500646 self._setup_dbg_rootfs(['/var/lib/dpkg'])
647
648 self.pm.fix_broken_dependencies()
649
650 self.pm.mark_packages("installed")
651
652 self.pm.run_pre_post_installs()
653
654 execute_pre_post_process(self.d, deb_post_process_cmds)
655
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600656 if self.progress_reporter:
657 self.progress_reporter.next_stage()
658
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500659 @staticmethod
660 def _depends_list():
661 return ['DEPLOY_DIR_DEB', 'DEB_SDK_ARCH', 'APTCONF_TARGET', 'APT_ARGS', 'DPKG_ARCH', 'DEB_PREPROCESS_COMMANDS', 'DEB_POSTPROCESS_COMMANDS']
662
663 def _get_delayed_postinsts(self):
664 status_file = self.image_rootfs + "/var/lib/dpkg/status"
665 return self._get_delayed_postinsts_common(status_file)
666
667 def _save_postinsts(self):
668 dst_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/deb-postinsts")
669 src_postinst_dir = self.d.expand("${IMAGE_ROOTFS}/var/lib/dpkg/info")
670 return self._save_postinsts_common(dst_postinst_dir, src_postinst_dir)
671
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500672 def _log_check(self):
673 self._log_check_warn()
674 self._log_check_error()
675
676 def _cleanup(self):
677 pass
678
679
680class OpkgRootfs(DpkgOpkgRootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500681 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
682 super(OpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500683 self.log_check_regex = '(exit 1|Collected errors)'
684
685 self.manifest = OpkgManifest(d, manifest_dir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500686 self.opkg_conf = self.d.getVar("IPKGCONF_TARGET")
687 self.pkg_archs = self.d.getVar("ALL_MULTILIB_PACKAGE_ARCHS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500688
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500689 self.inc_opkg_image_gen = self.d.getVar('INC_IPK_IMAGE_GEN') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500690 if self._remove_old_rootfs():
691 bb.utils.remove(self.image_rootfs, True)
692 self.pm = OpkgPM(d,
693 self.image_rootfs,
694 self.opkg_conf,
695 self.pkg_archs)
696 else:
697 self.pm = OpkgPM(d,
698 self.image_rootfs,
699 self.opkg_conf,
700 self.pkg_archs)
701 self.pm.recover_packaging_data()
702
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500703 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500704
705 def _prelink_file(self, root_dir, filename):
706 bb.note('prelink %s in %s' % (filename, root_dir))
707 prelink_cfg = oe.path.join(root_dir,
708 self.d.expand('${sysconfdir}/prelink.conf'))
709 if not os.path.exists(prelink_cfg):
710 shutil.copy(self.d.expand('${STAGING_DIR_NATIVE}${sysconfdir_native}/prelink.conf'),
711 prelink_cfg)
712
713 cmd_prelink = self.d.expand('${STAGING_DIR_NATIVE}${sbindir_native}/prelink')
714 self._exec_shell_cmd([cmd_prelink,
715 '--root',
716 root_dir,
717 '-amR',
718 '-N',
719 '-c',
720 self.d.expand('${sysconfdir}/prelink.conf')])
721
722 '''
723 Compare two files with the same key twice to see if they are equal.
724 If they are not equal, it means they are duplicated and come from
725 different packages.
726 1st: Comapre them directly;
727 2nd: While incremental image creation is enabled, one of the
728 files could be probaly prelinked in the previous image
729 creation and the file has been changed, so we need to
730 prelink the other one and compare them.
731 '''
732 def _file_equal(self, key, f1, f2):
733
734 # Both of them are not prelinked
735 if filecmp.cmp(f1, f2):
736 return True
737
738 if self.image_rootfs not in f1:
739 self._prelink_file(f1.replace(key, ''), f1)
740
741 if self.image_rootfs not in f2:
742 self._prelink_file(f2.replace(key, ''), f2)
743
744 # Both of them are prelinked
745 if filecmp.cmp(f1, f2):
746 return True
747
748 # Not equal
749 return False
750
751 """
752 This function was reused from the old implementation.
753 See commit: "image.bbclass: Added variables for multilib support." by
754 Lianhao Lu.
755 """
756 def _multilib_sanity_test(self, dirs):
757
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500758 allow_replace = self.d.getVar("MULTILIBRE_ALLOW_REP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500759 if allow_replace is None:
760 allow_replace = ""
761
762 allow_rep = re.compile(re.sub("\|$", "", allow_replace))
763 error_prompt = "Multilib check error:"
764
765 files = {}
766 for dir in dirs:
767 for root, subfolders, subfiles in os.walk(dir):
768 for file in subfiles:
769 item = os.path.join(root, file)
770 key = str(os.path.join("/", os.path.relpath(item, dir)))
771
772 valid = True
773 if key in files:
774 #check whether the file is allow to replace
775 if allow_rep.match(key):
776 valid = True
777 else:
778 if os.path.exists(files[key]) and \
779 os.path.exists(item) and \
780 not self._file_equal(key, files[key], item):
781 valid = False
782 bb.fatal("%s duplicate files %s %s is not the same\n" %
783 (error_prompt, item, files[key]))
784
785 #pass the check, add to list
786 if valid:
787 files[key] = item
788
789 def _multilib_test_install(self, pkgs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500790 ml_temp = self.d.getVar("MULTILIB_TEMP_ROOTFS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500791 bb.utils.mkdirhier(ml_temp)
792
793 dirs = [self.image_rootfs]
794
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500795 for variant in self.d.getVar("MULTILIB_VARIANTS").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500796 ml_target_rootfs = os.path.join(ml_temp, variant)
797
798 bb.utils.remove(ml_target_rootfs, True)
799
800 ml_opkg_conf = os.path.join(ml_temp,
801 variant + "-" + os.path.basename(self.opkg_conf))
802
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800803 ml_pm = OpkgPM(self.d, ml_target_rootfs, ml_opkg_conf, self.pkg_archs, prepare_index=False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500804
805 ml_pm.update()
806 ml_pm.install(pkgs)
807
808 dirs.append(ml_target_rootfs)
809
810 self._multilib_sanity_test(dirs)
811
812 '''
813 While ipk incremental image generation is enabled, it will remove the
814 unneeded pkgs by comparing the old full manifest in previous existing
815 image and the new full manifest in the current image.
816 '''
817 def _remove_extra_packages(self, pkgs_initial_install):
818 if self.inc_opkg_image_gen == "1":
819 # Parse full manifest in previous existing image creation session
820 old_full_manifest = self.manifest.parse_full_manifest()
821
822 # Create full manifest for the current image session, the old one
823 # will be replaced by the new one.
824 self.manifest.create_full(self.pm)
825
826 # Parse full manifest in current image creation session
827 new_full_manifest = self.manifest.parse_full_manifest()
828
829 pkg_to_remove = list()
830 for pkg in old_full_manifest:
831 if pkg not in new_full_manifest:
832 pkg_to_remove.append(pkg)
833
834 if pkg_to_remove != []:
835 bb.note('decremental removed: %s' % ' '.join(pkg_to_remove))
836 self.pm.remove(pkg_to_remove)
837
838 '''
839 Compare with previous existing image creation, if some conditions
840 triggered, the previous old image should be removed.
841 The conditions include any of 'PACKAGE_EXCLUDE, NO_RECOMMENDATIONS
842 and BAD_RECOMMENDATIONS' has been changed.
843 '''
844 def _remove_old_rootfs(self):
845 if self.inc_opkg_image_gen != "1":
846 return True
847
848 vars_list_file = self.d.expand('${T}/vars_list')
849
850 old_vars_list = ""
851 if os.path.exists(vars_list_file):
852 old_vars_list = open(vars_list_file, 'r+').read()
853
854 new_vars_list = '%s:%s:%s\n' % \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500855 ((self.d.getVar('BAD_RECOMMENDATIONS') or '').strip(),
856 (self.d.getVar('NO_RECOMMENDATIONS') or '').strip(),
857 (self.d.getVar('PACKAGE_EXCLUDE') or '').strip())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500858 open(vars_list_file, 'w+').write(new_vars_list)
859
860 if old_vars_list != new_vars_list:
861 return True
862
863 return False
864
865 def _create(self):
866 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500867 opkg_pre_process_cmds = self.d.getVar('OPKG_PREPROCESS_COMMANDS')
868 opkg_post_process_cmds = self.d.getVar('OPKG_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500869
Brad Bishop004d4992018-10-02 23:54:45 +0200870 # update PM index files
871 self.pm.write_index()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500872
873 execute_pre_post_process(self.d, opkg_pre_process_cmds)
874
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600875 if self.progress_reporter:
876 self.progress_reporter.next_stage()
877 # Steps are a bit different in order, skip next
878 self.progress_reporter.next_stage()
879
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500880 self.pm.update()
881
882 self.pm.handle_bad_recommendations()
883
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600884 if self.progress_reporter:
885 self.progress_reporter.next_stage()
886
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500887 if self.inc_opkg_image_gen == "1":
888 self._remove_extra_packages(pkgs_to_install)
889
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600890 if self.progress_reporter:
891 self.progress_reporter.next_stage()
892
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500893 for pkg_type in self.install_order:
894 if pkg_type in pkgs_to_install:
895 # For multilib, we perform a sanity test before final install
896 # If sanity test fails, it will automatically do a bb.fatal()
897 # and the installation will stop
898 if pkg_type == Manifest.PKG_TYPE_MULTILIB:
899 self._multilib_test_install(pkgs_to_install[pkg_type])
900
901 self.pm.install(pkgs_to_install[pkg_type],
902 [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
903
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600904 if self.progress_reporter:
905 self.progress_reporter.next_stage()
906
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500907 self.pm.install_complementary()
908
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600909 if self.progress_reporter:
910 self.progress_reporter.next_stage()
911
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500912 opkg_lib_dir = self.d.getVar('OPKGLIBDIR')
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500913 opkg_dir = os.path.join(opkg_lib_dir, 'opkg')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500914 self._setup_dbg_rootfs([opkg_dir])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500915
916 execute_pre_post_process(self.d, opkg_post_process_cmds)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500917
918 if self.inc_opkg_image_gen == "1":
919 self.pm.backup_packaging_data()
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 @staticmethod
925 def _depends_list():
926 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']
927
928 def _get_delayed_postinsts(self):
929 status_file = os.path.join(self.image_rootfs,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500930 self.d.getVar('OPKGLIBDIR').strip('/'),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500931 "opkg", "status")
932 return self._get_delayed_postinsts_common(status_file)
933
934 def _save_postinsts(self):
935 dst_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/ipk-postinsts")
936 src_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${OPKGLIBDIR}/opkg/info")
937 return self._save_postinsts_common(dst_postinst_dir, src_postinst_dir)
938
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500939 def _log_check(self):
940 self._log_check_warn()
941 self._log_check_error()
942
943 def _cleanup(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500944 self.pm.remove_lists()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500945
946def get_class_for_type(imgtype):
947 return {"rpm": RpmRootfs,
948 "ipk": OpkgRootfs,
949 "deb": DpkgRootfs}[imgtype]
950
951def variable_depends(d, manifest_dir=None):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500952 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500953 cls = get_class_for_type(img_type)
954 return cls._depends_list()
955
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500956def create_rootfs(d, manifest_dir=None, progress_reporter=None, logcatcher=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500957 env_bkp = os.environ.copy()
958
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500959 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500960 if img_type == "rpm":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500961 RpmRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500962 elif img_type == "ipk":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500963 OpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500964 elif img_type == "deb":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500965 DpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500966
967 os.environ.clear()
968 os.environ.update(env_bkp)
969
970
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500971def image_list_installed_packages(d, rootfs_dir=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500972 if not rootfs_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500973 rootfs_dir = d.getVar('IMAGE_ROOTFS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500974
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500975 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500976 if img_type == "rpm":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500977 return RpmPkgsList(d, rootfs_dir).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500978 elif img_type == "ipk":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500979 return OpkgPkgsList(d, rootfs_dir, d.getVar("IPKGCONF_TARGET")).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500980 elif img_type == "deb":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500981 return DpkgPkgsList(d, rootfs_dir).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500982
983if __name__ == "__main__":
984 """
985 We should be able to run this as a standalone script, from outside bitbake
986 environment.
987 """
988 """
989 TBD
990 """