blob: c156607bfa352df8388e78452fd9aa1546676de0 [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
147 bb.note(" Rename debug rootfs...")
148 try:
149 shutil.rmtree(self.image_rootfs + '-dbg')
150 except:
151 pass
152 os.rename(self.image_rootfs, self.image_rootfs + '-dbg')
153
154 bb.note(" Restoreing original rootfs...")
155 os.rename(self.image_rootfs + '-orig', self.image_rootfs)
156
157 def _exec_shell_cmd(self, cmd):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500158 fakerootcmd = self.d.getVar('FAKEROOT')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500159 if fakerootcmd is not None:
160 exec_cmd = [fakerootcmd, cmd]
161 else:
162 exec_cmd = cmd
163
164 try:
165 subprocess.check_output(exec_cmd, stderr=subprocess.STDOUT)
166 except subprocess.CalledProcessError as e:
167 return("Command '%s' returned %d:\n%s" % (e.cmd, e.returncode, e.output))
168
169 return None
170
171 def create(self):
172 bb.note("###### Generate rootfs #######")
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500173 pre_process_cmds = self.d.getVar("ROOTFS_PREPROCESS_COMMAND")
174 post_process_cmds = self.d.getVar("ROOTFS_POSTPROCESS_COMMAND")
175 rootfs_post_install_cmds = self.d.getVar('ROOTFS_POSTINSTALL_COMMAND')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500176
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500177 bb.utils.mkdirhier(self.image_rootfs)
178
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600179 bb.utils.mkdirhier(self.deploydir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500180
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500181 execute_pre_post_process(self.d, pre_process_cmds)
182
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600183 if self.progress_reporter:
184 self.progress_reporter.next_stage()
185
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500186 # call the package manager dependent create method
187 self._create()
188
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500189 sysconfdir = self.image_rootfs + self.d.getVar('sysconfdir')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500190 bb.utils.mkdirhier(sysconfdir)
191 with open(sysconfdir + "/version", "w+") as ver:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500192 ver.write(self.d.getVar('BUILDNAME') + "\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500193
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500194 execute_pre_post_process(self.d, rootfs_post_install_cmds)
195
Brad Bishop316dfdd2018-06-25 12:45:53 -0400196 self.pm.run_intercepts()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500197
198 execute_pre_post_process(self.d, post_process_cmds)
199
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600200 if self.progress_reporter:
201 self.progress_reporter.next_stage()
202
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500203 if bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
204 True, False, self.d):
205 delayed_postinsts = self._get_delayed_postinsts()
206 if delayed_postinsts is not None:
207 bb.fatal("The following packages could not be configured "
208 "offline and rootfs is read-only: %s" %
209 delayed_postinsts)
210
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500211 if self.d.getVar('USE_DEVFS') != "1":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500212 self._create_devfs()
213
214 self._uninstall_unneeded()
215
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600216 if self.progress_reporter:
217 self.progress_reporter.next_stage()
218
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500219 self._insert_feed_uris()
220
221 self._run_ldconfig()
222
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500223 if self.d.getVar('USE_DEPMOD') != "0":
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500224 self._generate_kernel_module_deps()
225
226 self._cleanup()
227 self._log_check()
228
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600229 if self.progress_reporter:
230 self.progress_reporter.next_stage()
231
232
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500233 def _uninstall_unneeded(self):
234 # Remove unneeded init script symlinks
235 delayed_postinsts = self._get_delayed_postinsts()
236 if delayed_postinsts is None:
237 if os.path.exists(self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/init.d/run-postinsts")):
238 self._exec_shell_cmd(["update-rc.d", "-f", "-r",
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500239 self.d.getVar('IMAGE_ROOTFS'),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500240 "run-postinsts", "remove"])
241
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500242 image_rorfs = bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs",
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500243 True, False, self.d)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500244 image_rorfs_force = self.d.getVar('FORCE_RO_REMOVE')
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600245
246 if image_rorfs or image_rorfs_force == "1":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500247 # Remove components that we don't need if it's a read-only rootfs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500248 unneeded_pkgs = self.d.getVar("ROOTFS_RO_UNNEEDED").split()
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500249 pkgs_installed = image_list_installed_packages(self.d)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500250 # Make sure update-alternatives is removed last. This is
251 # because its database has to available while uninstalling
252 # other packages, allowing alternative symlinks of packages
253 # to be uninstalled or to be managed correctly otherwise.
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500254 provider = self.d.getVar("VIRTUAL-RUNTIME_update-alternatives")
255 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 -0500256
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500257 # update-alternatives provider is removed in its own remove()
258 # call because all package managers do not guarantee the packages
259 # are removed in the order they given in the list (which is
260 # passed to the command line). The sorting done earlier is
261 # utilized to implement the 2-stage removal.
262 if len(pkgs_to_remove) > 1:
263 self.pm.remove(pkgs_to_remove[:-1], False)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500264 if len(pkgs_to_remove) > 0:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500265 self.pm.remove([pkgs_to_remove[-1]], False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500266
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500267 if delayed_postinsts:
268 self._save_postinsts()
269 if image_rorfs:
270 bb.warn("There are post install scripts "
271 "in a read-only rootfs")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500272
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500273 post_uninstall_cmds = self.d.getVar("ROOTFS_POSTUNINSTALL_COMMAND")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500274 execute_pre_post_process(self.d, post_uninstall_cmds)
275
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500276 runtime_pkgmanage = bb.utils.contains("IMAGE_FEATURES", "package-management",
277 True, False, self.d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500278 if not runtime_pkgmanage:
279 # Remove the package manager data files
280 self.pm.remove_packaging_data()
281
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500282 def _run_ldconfig(self):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500283 if self.d.getVar('LDCONFIGDEPEND'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500284 bb.note("Executing: ldconfig -r" + self.image_rootfs + "-c new -v")
285 self._exec_shell_cmd(['ldconfig', '-r', self.image_rootfs, '-c',
286 'new', '-v'])
287
288 def _check_for_kernel_modules(self, modules_dir):
289 for root, dirs, files in os.walk(modules_dir, topdown=True):
290 for name in files:
291 found_ko = name.endswith(".ko")
292 if found_ko:
293 return found_ko
294 return False
295
296 def _generate_kernel_module_deps(self):
297 modules_dir = os.path.join(self.image_rootfs, 'lib', 'modules')
298 # if we don't have any modules don't bother to do the depmod
299 if not self._check_for_kernel_modules(modules_dir):
300 bb.note("No Kernel Modules found, not running depmod")
301 return
302
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500303 kernel_abi_ver_file = oe.path.join(self.d.getVar('PKGDATA_DIR'), "kernel-depmod",
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500304 'kernel-abiversion')
305 if not os.path.exists(kernel_abi_ver_file):
306 bb.fatal("No kernel-abiversion file found (%s), cannot run depmod, aborting" % kernel_abi_ver_file)
307
308 kernel_ver = open(kernel_abi_ver_file).read().strip(' \n')
309 versioned_modules_dir = os.path.join(self.image_rootfs, modules_dir, kernel_ver)
310
311 bb.utils.mkdirhier(versioned_modules_dir)
312
313 self._exec_shell_cmd(['depmodwrapper', '-a', '-b', self.image_rootfs, kernel_ver])
314
315 """
316 Create devfs:
317 * IMAGE_DEVICE_TABLE is the old name to an absolute path to a device table file
318 * IMAGE_DEVICE_TABLES is a new name for a file, or list of files, seached
319 for in the BBPATH
320 If neither are specified then the default name of files/device_table-minimal.txt
321 is searched for in the BBPATH (same as the old version.)
322 """
323 def _create_devfs(self):
324 devtable_list = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500325 devtable = self.d.getVar('IMAGE_DEVICE_TABLE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500326 if devtable is not None:
327 devtable_list.append(devtable)
328 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500329 devtables = self.d.getVar('IMAGE_DEVICE_TABLES')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500330 if devtables is None:
331 devtables = 'files/device_table-minimal.txt'
332 for devtable in devtables.split():
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500333 devtable_list.append("%s" % bb.utils.which(self.d.getVar('BBPATH'), devtable))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500334
335 for devtable in devtable_list:
336 self._exec_shell_cmd(["makedevs", "-r",
337 self.image_rootfs, "-D", devtable])
338
339
340class RpmRootfs(Rootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500341 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
342 super(RpmRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500343 self.log_check_regex = '(unpacking of archive failed|Cannot find package'\
344 '|exit 1|ERROR: |Error: |Error |ERROR '\
345 '|Failed |Failed: |Failed$|Failed\(\d+\):)'
346 self.manifest = RpmManifest(d, manifest_dir)
347
348 self.pm = RpmPM(d,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500349 d.getVar('IMAGE_ROOTFS'),
350 self.d.getVar('TARGET_VENDOR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500351 )
352
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500353 self.inc_rpm_image_gen = self.d.getVar('INC_RPM_IMAGE_GEN')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500354 if self.inc_rpm_image_gen != "1":
355 bb.utils.remove(self.image_rootfs, True)
356 else:
357 self.pm.recovery_packaging_data()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500358 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500359
360 self.pm.create_configs()
361
362 '''
363 While rpm incremental image generation is enabled, it will remove the
364 unneeded pkgs by comparing the new install solution manifest and the
365 old installed manifest.
366 '''
367 def _create_incremental(self, pkgs_initial_install):
368 if self.inc_rpm_image_gen == "1":
369
370 pkgs_to_install = list()
371 for pkg_type in pkgs_initial_install:
372 pkgs_to_install += pkgs_initial_install[pkg_type]
373
374 installed_manifest = self.pm.load_old_install_solution()
375 solution_manifest = self.pm.dump_install_solution(pkgs_to_install)
376
377 pkg_to_remove = list()
378 for pkg in installed_manifest:
379 if pkg not in solution_manifest:
380 pkg_to_remove.append(pkg)
381
382 self.pm.update()
383
384 bb.note('incremental update -- upgrade packages in place ')
385 self.pm.upgrade()
386 if pkg_to_remove != []:
387 bb.note('incremental removed: %s' % ' '.join(pkg_to_remove))
388 self.pm.remove(pkg_to_remove)
389
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500390 self.pm.autoremove()
391
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500392 def _create(self):
393 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500394 rpm_pre_process_cmds = self.d.getVar('RPM_PREPROCESS_COMMANDS')
395 rpm_post_process_cmds = self.d.getVar('RPM_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500396
397 # update PM index files
398 self.pm.write_index()
399
400 execute_pre_post_process(self.d, rpm_pre_process_cmds)
401
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600402 if self.progress_reporter:
403 self.progress_reporter.next_stage()
404
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500405 if self.inc_rpm_image_gen == "1":
406 self._create_incremental(pkgs_to_install)
407
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600408 if self.progress_reporter:
409 self.progress_reporter.next_stage()
410
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500411 self.pm.update()
412
413 pkgs = []
414 pkgs_attempt = []
415 for pkg_type in pkgs_to_install:
416 if pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY:
417 pkgs_attempt += pkgs_to_install[pkg_type]
418 else:
419 pkgs += pkgs_to_install[pkg_type]
420
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600421 if self.progress_reporter:
422 self.progress_reporter.next_stage()
423
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500424 self.pm.install(pkgs)
425
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600426 if self.progress_reporter:
427 self.progress_reporter.next_stage()
428
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500429 self.pm.install(pkgs_attempt, True)
430
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600431 if self.progress_reporter:
432 self.progress_reporter.next_stage()
433
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500434 self.pm.install_complementary()
435
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600436 if self.progress_reporter:
437 self.progress_reporter.next_stage()
438
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500439 self._setup_dbg_rootfs(['/etc', '/var/lib/rpm', '/var/cache/dnf', '/var/lib/dnf'])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500440
441 execute_pre_post_process(self.d, rpm_post_process_cmds)
442
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500443 if self.inc_rpm_image_gen == "1":
444 self.pm.backup_packaging_data()
445
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600446 if self.progress_reporter:
447 self.progress_reporter.next_stage()
448
449
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500450 @staticmethod
451 def _depends_list():
452 return ['DEPLOY_DIR_RPM', 'INC_RPM_IMAGE_GEN', 'RPM_PREPROCESS_COMMANDS',
453 'RPM_POSTPROCESS_COMMANDS', 'RPM_PREFER_ELF_ARCH']
454
455 def _get_delayed_postinsts(self):
456 postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/rpm-postinsts")
457 if os.path.isdir(postinst_dir):
458 files = os.listdir(postinst_dir)
459 for f in files:
460 bb.note('Delayed package scriptlet: %s' % f)
461 return files
462
463 return None
464
465 def _save_postinsts(self):
466 # this is just a stub. For RPM, the failed postinstalls are
467 # already saved in /etc/rpm-postinsts
468 pass
469
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500470 def _log_check(self):
471 self._log_check_warn()
472 self._log_check_error()
473
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500474 def _cleanup(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500475 self.pm._invoke_dnf(["clean", "all"])
476
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500477
478class DpkgOpkgRootfs(Rootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500479 def __init__(self, d, progress_reporter=None, logcatcher=None):
480 super(DpkgOpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500481
482 def _get_pkgs_postinsts(self, status_file):
483 def _get_pkg_depends_list(pkg_depends):
484 pkg_depends_list = []
485 # filter version requirements like libc (>= 1.1)
486 for dep in pkg_depends.split(', '):
487 m_dep = re.match("^(.*) \(.*\)$", dep)
488 if m_dep:
489 dep = m_dep.group(1)
490 pkg_depends_list.append(dep)
491
492 return pkg_depends_list
493
494 pkgs = {}
495 pkg_name = ""
496 pkg_status_match = False
497 pkg_depends = ""
498
499 with open(status_file) as status:
500 data = status.read()
501 status.close()
502 for line in data.split('\n'):
503 m_pkg = re.match("^Package: (.*)", line)
504 m_status = re.match("^Status:.*unpacked", line)
505 m_depends = re.match("^Depends: (.*)", line)
506
507 if m_pkg is not None:
508 if pkg_name and pkg_status_match:
509 pkgs[pkg_name] = _get_pkg_depends_list(pkg_depends)
510
511 pkg_name = m_pkg.group(1)
512 pkg_status_match = False
513 pkg_depends = ""
514 elif m_status is not None:
515 pkg_status_match = True
516 elif m_depends is not None:
517 pkg_depends = m_depends.group(1)
518
519 # remove package dependencies not in postinsts
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600520 pkg_names = list(pkgs.keys())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500521 for pkg_name in pkg_names:
522 deps = pkgs[pkg_name][:]
523
524 for d in deps:
525 if d not in pkg_names:
526 pkgs[pkg_name].remove(d)
527
528 return pkgs
529
530 def _get_delayed_postinsts_common(self, status_file):
531 def _dep_resolve(graph, node, resolved, seen):
532 seen.append(node)
533
534 for edge in graph[node]:
535 if edge not in resolved:
536 if edge in seen:
537 raise RuntimeError("Packages %s and %s have " \
538 "a circular dependency in postinsts scripts." \
539 % (node, edge))
540 _dep_resolve(graph, edge, resolved, seen)
541
542 resolved.append(node)
543
544 pkg_list = []
545
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500546 pkgs = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500547 if not self.d.getVar('PACKAGE_INSTALL').strip():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500548 bb.note("Building empty image")
549 else:
550 pkgs = self._get_pkgs_postinsts(status_file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500551 if pkgs:
552 root = "__packagegroup_postinst__"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600553 pkgs[root] = list(pkgs.keys())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500554 _dep_resolve(pkgs, root, pkg_list, [])
555 pkg_list.remove(root)
556
557 if len(pkg_list) == 0:
558 return None
559
560 return pkg_list
561
562 def _save_postinsts_common(self, dst_postinst_dir, src_postinst_dir):
563 num = 0
564 for p in self._get_delayed_postinsts():
565 bb.utils.mkdirhier(dst_postinst_dir)
566
567 if os.path.exists(os.path.join(src_postinst_dir, p + ".postinst")):
568 shutil.copy(os.path.join(src_postinst_dir, p + ".postinst"),
569 os.path.join(dst_postinst_dir, "%03d-%s" % (num, p)))
570
571 num += 1
572
573class DpkgRootfs(DpkgOpkgRootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500574 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
575 super(DpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500576 self.log_check_regex = '^E:'
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600577 self.log_check_expected_regexes = \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500578 [
579 "^E: Unmet dependencies."
580 ]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500581
582 bb.utils.remove(self.image_rootfs, True)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500583 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500584 self.manifest = DpkgManifest(d, manifest_dir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500585 self.pm = DpkgPM(d, d.getVar('IMAGE_ROOTFS'),
586 d.getVar('PACKAGE_ARCHS'),
587 d.getVar('DPKG_ARCH'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500588
589
590 def _create(self):
591 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500592 deb_pre_process_cmds = self.d.getVar('DEB_PREPROCESS_COMMANDS')
593 deb_post_process_cmds = self.d.getVar('DEB_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500594
595 alt_dir = self.d.expand("${IMAGE_ROOTFS}/var/lib/dpkg/alternatives")
596 bb.utils.mkdirhier(alt_dir)
597
598 # update PM index files
599 self.pm.write_index()
600
601 execute_pre_post_process(self.d, deb_pre_process_cmds)
602
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600603 if self.progress_reporter:
604 self.progress_reporter.next_stage()
605 # Don't support incremental, so skip that
606 self.progress_reporter.next_stage()
607
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500608 self.pm.update()
609
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600610 if self.progress_reporter:
611 self.progress_reporter.next_stage()
612
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500613 for pkg_type in self.install_order:
614 if pkg_type in pkgs_to_install:
615 self.pm.install(pkgs_to_install[pkg_type],
616 [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
617
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600618 if self.progress_reporter:
619 # Don't support attemptonly, so skip that
620 self.progress_reporter.next_stage()
621 self.progress_reporter.next_stage()
622
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500623 self.pm.install_complementary()
624
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600625 if self.progress_reporter:
626 self.progress_reporter.next_stage()
627
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500628 self._setup_dbg_rootfs(['/var/lib/dpkg'])
629
630 self.pm.fix_broken_dependencies()
631
632 self.pm.mark_packages("installed")
633
634 self.pm.run_pre_post_installs()
635
636 execute_pre_post_process(self.d, deb_post_process_cmds)
637
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600638 if self.progress_reporter:
639 self.progress_reporter.next_stage()
640
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500641 @staticmethod
642 def _depends_list():
643 return ['DEPLOY_DIR_DEB', 'DEB_SDK_ARCH', 'APTCONF_TARGET', 'APT_ARGS', 'DPKG_ARCH', 'DEB_PREPROCESS_COMMANDS', 'DEB_POSTPROCESS_COMMANDS']
644
645 def _get_delayed_postinsts(self):
646 status_file = self.image_rootfs + "/var/lib/dpkg/status"
647 return self._get_delayed_postinsts_common(status_file)
648
649 def _save_postinsts(self):
650 dst_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/deb-postinsts")
651 src_postinst_dir = self.d.expand("${IMAGE_ROOTFS}/var/lib/dpkg/info")
652 return self._save_postinsts_common(dst_postinst_dir, src_postinst_dir)
653
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500654 def _log_check(self):
655 self._log_check_warn()
656 self._log_check_error()
657
658 def _cleanup(self):
659 pass
660
661
662class OpkgRootfs(DpkgOpkgRootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500663 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
664 super(OpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500665 self.log_check_regex = '(exit 1|Collected errors)'
666
667 self.manifest = OpkgManifest(d, manifest_dir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500668 self.opkg_conf = self.d.getVar("IPKGCONF_TARGET")
669 self.pkg_archs = self.d.getVar("ALL_MULTILIB_PACKAGE_ARCHS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500670
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500671 self.inc_opkg_image_gen = self.d.getVar('INC_IPK_IMAGE_GEN') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500672 if self._remove_old_rootfs():
673 bb.utils.remove(self.image_rootfs, True)
674 self.pm = OpkgPM(d,
675 self.image_rootfs,
676 self.opkg_conf,
677 self.pkg_archs)
678 else:
679 self.pm = OpkgPM(d,
680 self.image_rootfs,
681 self.opkg_conf,
682 self.pkg_archs)
683 self.pm.recover_packaging_data()
684
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500685 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500686
687 def _prelink_file(self, root_dir, filename):
688 bb.note('prelink %s in %s' % (filename, root_dir))
689 prelink_cfg = oe.path.join(root_dir,
690 self.d.expand('${sysconfdir}/prelink.conf'))
691 if not os.path.exists(prelink_cfg):
692 shutil.copy(self.d.expand('${STAGING_DIR_NATIVE}${sysconfdir_native}/prelink.conf'),
693 prelink_cfg)
694
695 cmd_prelink = self.d.expand('${STAGING_DIR_NATIVE}${sbindir_native}/prelink')
696 self._exec_shell_cmd([cmd_prelink,
697 '--root',
698 root_dir,
699 '-amR',
700 '-N',
701 '-c',
702 self.d.expand('${sysconfdir}/prelink.conf')])
703
704 '''
705 Compare two files with the same key twice to see if they are equal.
706 If they are not equal, it means they are duplicated and come from
707 different packages.
708 1st: Comapre them directly;
709 2nd: While incremental image creation is enabled, one of the
710 files could be probaly prelinked in the previous image
711 creation and the file has been changed, so we need to
712 prelink the other one and compare them.
713 '''
714 def _file_equal(self, key, f1, f2):
715
716 # Both of them are not prelinked
717 if filecmp.cmp(f1, f2):
718 return True
719
720 if self.image_rootfs not in f1:
721 self._prelink_file(f1.replace(key, ''), f1)
722
723 if self.image_rootfs not in f2:
724 self._prelink_file(f2.replace(key, ''), f2)
725
726 # Both of them are prelinked
727 if filecmp.cmp(f1, f2):
728 return True
729
730 # Not equal
731 return False
732
733 """
734 This function was reused from the old implementation.
735 See commit: "image.bbclass: Added variables for multilib support." by
736 Lianhao Lu.
737 """
738 def _multilib_sanity_test(self, dirs):
739
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500740 allow_replace = self.d.getVar("MULTILIBRE_ALLOW_REP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500741 if allow_replace is None:
742 allow_replace = ""
743
744 allow_rep = re.compile(re.sub("\|$", "", allow_replace))
745 error_prompt = "Multilib check error:"
746
747 files = {}
748 for dir in dirs:
749 for root, subfolders, subfiles in os.walk(dir):
750 for file in subfiles:
751 item = os.path.join(root, file)
752 key = str(os.path.join("/", os.path.relpath(item, dir)))
753
754 valid = True
755 if key in files:
756 #check whether the file is allow to replace
757 if allow_rep.match(key):
758 valid = True
759 else:
760 if os.path.exists(files[key]) and \
761 os.path.exists(item) and \
762 not self._file_equal(key, files[key], item):
763 valid = False
764 bb.fatal("%s duplicate files %s %s is not the same\n" %
765 (error_prompt, item, files[key]))
766
767 #pass the check, add to list
768 if valid:
769 files[key] = item
770
771 def _multilib_test_install(self, pkgs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500772 ml_temp = self.d.getVar("MULTILIB_TEMP_ROOTFS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500773 bb.utils.mkdirhier(ml_temp)
774
775 dirs = [self.image_rootfs]
776
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500777 for variant in self.d.getVar("MULTILIB_VARIANTS").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500778 ml_target_rootfs = os.path.join(ml_temp, variant)
779
780 bb.utils.remove(ml_target_rootfs, True)
781
782 ml_opkg_conf = os.path.join(ml_temp,
783 variant + "-" + os.path.basename(self.opkg_conf))
784
785 ml_pm = OpkgPM(self.d, ml_target_rootfs, ml_opkg_conf, self.pkg_archs)
786
787 ml_pm.update()
788 ml_pm.install(pkgs)
789
790 dirs.append(ml_target_rootfs)
791
792 self._multilib_sanity_test(dirs)
793
794 '''
795 While ipk incremental image generation is enabled, it will remove the
796 unneeded pkgs by comparing the old full manifest in previous existing
797 image and the new full manifest in the current image.
798 '''
799 def _remove_extra_packages(self, pkgs_initial_install):
800 if self.inc_opkg_image_gen == "1":
801 # Parse full manifest in previous existing image creation session
802 old_full_manifest = self.manifest.parse_full_manifest()
803
804 # Create full manifest for the current image session, the old one
805 # will be replaced by the new one.
806 self.manifest.create_full(self.pm)
807
808 # Parse full manifest in current image creation session
809 new_full_manifest = self.manifest.parse_full_manifest()
810
811 pkg_to_remove = list()
812 for pkg in old_full_manifest:
813 if pkg not in new_full_manifest:
814 pkg_to_remove.append(pkg)
815
816 if pkg_to_remove != []:
817 bb.note('decremental removed: %s' % ' '.join(pkg_to_remove))
818 self.pm.remove(pkg_to_remove)
819
820 '''
821 Compare with previous existing image creation, if some conditions
822 triggered, the previous old image should be removed.
823 The conditions include any of 'PACKAGE_EXCLUDE, NO_RECOMMENDATIONS
824 and BAD_RECOMMENDATIONS' has been changed.
825 '''
826 def _remove_old_rootfs(self):
827 if self.inc_opkg_image_gen != "1":
828 return True
829
830 vars_list_file = self.d.expand('${T}/vars_list')
831
832 old_vars_list = ""
833 if os.path.exists(vars_list_file):
834 old_vars_list = open(vars_list_file, 'r+').read()
835
836 new_vars_list = '%s:%s:%s\n' % \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500837 ((self.d.getVar('BAD_RECOMMENDATIONS') or '').strip(),
838 (self.d.getVar('NO_RECOMMENDATIONS') or '').strip(),
839 (self.d.getVar('PACKAGE_EXCLUDE') or '').strip())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500840 open(vars_list_file, 'w+').write(new_vars_list)
841
842 if old_vars_list != new_vars_list:
843 return True
844
845 return False
846
847 def _create(self):
848 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500849 opkg_pre_process_cmds = self.d.getVar('OPKG_PREPROCESS_COMMANDS')
850 opkg_post_process_cmds = self.d.getVar('OPKG_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500851
Brad Bishop004d4992018-10-02 23:54:45 +0200852 # update PM index files
853 self.pm.write_index()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500854
855 execute_pre_post_process(self.d, opkg_pre_process_cmds)
856
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600857 if self.progress_reporter:
858 self.progress_reporter.next_stage()
859 # Steps are a bit different in order, skip next
860 self.progress_reporter.next_stage()
861
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500862 self.pm.update()
863
864 self.pm.handle_bad_recommendations()
865
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600866 if self.progress_reporter:
867 self.progress_reporter.next_stage()
868
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500869 if self.inc_opkg_image_gen == "1":
870 self._remove_extra_packages(pkgs_to_install)
871
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600872 if self.progress_reporter:
873 self.progress_reporter.next_stage()
874
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500875 for pkg_type in self.install_order:
876 if pkg_type in pkgs_to_install:
877 # For multilib, we perform a sanity test before final install
878 # If sanity test fails, it will automatically do a bb.fatal()
879 # and the installation will stop
880 if pkg_type == Manifest.PKG_TYPE_MULTILIB:
881 self._multilib_test_install(pkgs_to_install[pkg_type])
882
883 self.pm.install(pkgs_to_install[pkg_type],
884 [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
885
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600886 if self.progress_reporter:
887 self.progress_reporter.next_stage()
888
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500889 self.pm.install_complementary()
890
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600891 if self.progress_reporter:
892 self.progress_reporter.next_stage()
893
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500894 opkg_lib_dir = self.d.getVar('OPKGLIBDIR')
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500895 opkg_dir = os.path.join(opkg_lib_dir, 'opkg')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500896 self._setup_dbg_rootfs([opkg_dir])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500897
898 execute_pre_post_process(self.d, opkg_post_process_cmds)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500899
900 if self.inc_opkg_image_gen == "1":
901 self.pm.backup_packaging_data()
902
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600903 if self.progress_reporter:
904 self.progress_reporter.next_stage()
905
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500906 @staticmethod
907 def _depends_list():
908 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']
909
910 def _get_delayed_postinsts(self):
911 status_file = os.path.join(self.image_rootfs,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500912 self.d.getVar('OPKGLIBDIR').strip('/'),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500913 "opkg", "status")
914 return self._get_delayed_postinsts_common(status_file)
915
916 def _save_postinsts(self):
917 dst_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/ipk-postinsts")
918 src_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${OPKGLIBDIR}/opkg/info")
919 return self._save_postinsts_common(dst_postinst_dir, src_postinst_dir)
920
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500921 def _log_check(self):
922 self._log_check_warn()
923 self._log_check_error()
924
925 def _cleanup(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500926 self.pm.remove_lists()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500927
928def get_class_for_type(imgtype):
929 return {"rpm": RpmRootfs,
930 "ipk": OpkgRootfs,
931 "deb": DpkgRootfs}[imgtype]
932
933def variable_depends(d, manifest_dir=None):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500934 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500935 cls = get_class_for_type(img_type)
936 return cls._depends_list()
937
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500938def create_rootfs(d, manifest_dir=None, progress_reporter=None, logcatcher=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500939 env_bkp = os.environ.copy()
940
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500941 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500942 if img_type == "rpm":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500943 RpmRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500944 elif img_type == "ipk":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500945 OpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500946 elif img_type == "deb":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500947 DpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500948
949 os.environ.clear()
950 os.environ.update(env_bkp)
951
952
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500953def image_list_installed_packages(d, rootfs_dir=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500954 if not rootfs_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500955 rootfs_dir = d.getVar('IMAGE_ROOTFS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500956
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500957 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500958 if img_type == "rpm":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500959 return RpmPkgsList(d, rootfs_dir).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500960 elif img_type == "ipk":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500961 return OpkgPkgsList(d, rootfs_dir, d.getVar("IPKGCONF_TARGET")).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500962 elif img_type == "deb":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500963 return DpkgPkgsList(d, rootfs_dir).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500964
965if __name__ == "__main__":
966 """
967 We should be able to run this as a standalone script, from outside bitbake
968 environment.
969 """
970 """
971 TBD
972 """