blob: b7c0b9c24b91667deed39e9eed662c2ee1cf0593 [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)
Brad Bishop19323692019-04-05 15:28:33 -0400357 self.log_check_regex = r'(unpacking of archive failed|Cannot find package'\
358 r'|exit 1|ERROR: |Error: |Error |ERROR '\
359 r'|Failed |Failed: |Failed$|Failed\(\d+\):)'
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500360 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(', '):
Brad Bishop19323692019-04-05 15:28:33 -0400502 m_dep = re.match(r"^(.*) \(.*\)$", dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500503 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'):
Brad Bishop19323692019-04-05 15:28:33 -0400518 m_pkg = re.match(r"^Package: (.*)", line)
519 m_status = re.match(r"^Status:.*unpacked", line)
520 m_depends = re.match(r"^Depends: (.*)", line)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500521
Brad Bishop19323692019-04-05 15:28:33 -0400522 #Only one of m_pkg, m_status or m_depends is not None at time
523 #If m_pkg is not None, we started a new package
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500524 if m_pkg is not None:
Brad Bishop19323692019-04-05 15:28:33 -0400525 #Get Package name
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500526 pkg_name = m_pkg.group(1)
Brad Bishop19323692019-04-05 15:28:33 -0400527 #Make sure we reset other variables
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500528 pkg_status_match = False
529 pkg_depends = ""
530 elif m_status is not None:
Brad Bishop19323692019-04-05 15:28:33 -0400531 #New status matched
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500532 pkg_status_match = True
533 elif m_depends is not None:
Brad Bishop19323692019-04-05 15:28:33 -0400534 #New depends macthed
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500535 pkg_depends = m_depends.group(1)
Brad Bishop19323692019-04-05 15:28:33 -0400536 else:
537 pass
538
539 #Now check if we can process package depends and postinst
540 if "" != pkg_name and pkg_status_match:
541 pkgs[pkg_name] = _get_pkg_depends_list(pkg_depends)
542 else:
543 #Not enough information
544 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500545
546 # remove package dependencies not in postinsts
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600547 pkg_names = list(pkgs.keys())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500548 for pkg_name in pkg_names:
549 deps = pkgs[pkg_name][:]
550
551 for d in deps:
552 if d not in pkg_names:
553 pkgs[pkg_name].remove(d)
554
555 return pkgs
556
557 def _get_delayed_postinsts_common(self, status_file):
558 def _dep_resolve(graph, node, resolved, seen):
559 seen.append(node)
560
561 for edge in graph[node]:
562 if edge not in resolved:
563 if edge in seen:
564 raise RuntimeError("Packages %s and %s have " \
565 "a circular dependency in postinsts scripts." \
566 % (node, edge))
567 _dep_resolve(graph, edge, resolved, seen)
568
569 resolved.append(node)
570
571 pkg_list = []
572
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500573 pkgs = None
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500574 if not self.d.getVar('PACKAGE_INSTALL').strip():
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500575 bb.note("Building empty image")
576 else:
577 pkgs = self._get_pkgs_postinsts(status_file)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500578 if pkgs:
579 root = "__packagegroup_postinst__"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600580 pkgs[root] = list(pkgs.keys())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500581 _dep_resolve(pkgs, root, pkg_list, [])
582 pkg_list.remove(root)
583
584 if len(pkg_list) == 0:
585 return None
586
587 return pkg_list
588
589 def _save_postinsts_common(self, dst_postinst_dir, src_postinst_dir):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800590 if bb.utils.contains("IMAGE_FEATURES", "package-management",
591 True, False, self.d):
592 return
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500593 num = 0
594 for p in self._get_delayed_postinsts():
595 bb.utils.mkdirhier(dst_postinst_dir)
596
597 if os.path.exists(os.path.join(src_postinst_dir, p + ".postinst")):
598 shutil.copy(os.path.join(src_postinst_dir, p + ".postinst"),
599 os.path.join(dst_postinst_dir, "%03d-%s" % (num, p)))
600
601 num += 1
602
603class DpkgRootfs(DpkgOpkgRootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500604 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
605 super(DpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500606 self.log_check_regex = '^E:'
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600607 self.log_check_expected_regexes = \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500608 [
609 "^E: Unmet dependencies."
610 ]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500611
612 bb.utils.remove(self.image_rootfs, True)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500613 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500614 self.manifest = DpkgManifest(d, manifest_dir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500615 self.pm = DpkgPM(d, d.getVar('IMAGE_ROOTFS'),
616 d.getVar('PACKAGE_ARCHS'),
617 d.getVar('DPKG_ARCH'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500618
619
620 def _create(self):
621 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500622 deb_pre_process_cmds = self.d.getVar('DEB_PREPROCESS_COMMANDS')
623 deb_post_process_cmds = self.d.getVar('DEB_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500624
625 alt_dir = self.d.expand("${IMAGE_ROOTFS}/var/lib/dpkg/alternatives")
626 bb.utils.mkdirhier(alt_dir)
627
628 # update PM index files
629 self.pm.write_index()
630
631 execute_pre_post_process(self.d, deb_pre_process_cmds)
632
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600633 if self.progress_reporter:
634 self.progress_reporter.next_stage()
635 # Don't support incremental, so skip that
636 self.progress_reporter.next_stage()
637
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500638 self.pm.update()
639
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600640 if self.progress_reporter:
641 self.progress_reporter.next_stage()
642
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500643 for pkg_type in self.install_order:
644 if pkg_type in pkgs_to_install:
645 self.pm.install(pkgs_to_install[pkg_type],
646 [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
647
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600648 if self.progress_reporter:
649 # Don't support attemptonly, so skip that
650 self.progress_reporter.next_stage()
651 self.progress_reporter.next_stage()
652
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500653 self.pm.install_complementary()
654
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600655 if self.progress_reporter:
656 self.progress_reporter.next_stage()
657
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500658 self._setup_dbg_rootfs(['/var/lib/dpkg'])
659
660 self.pm.fix_broken_dependencies()
661
662 self.pm.mark_packages("installed")
663
664 self.pm.run_pre_post_installs()
665
666 execute_pre_post_process(self.d, deb_post_process_cmds)
667
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600668 if self.progress_reporter:
669 self.progress_reporter.next_stage()
670
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500671 @staticmethod
672 def _depends_list():
673 return ['DEPLOY_DIR_DEB', 'DEB_SDK_ARCH', 'APTCONF_TARGET', 'APT_ARGS', 'DPKG_ARCH', 'DEB_PREPROCESS_COMMANDS', 'DEB_POSTPROCESS_COMMANDS']
674
675 def _get_delayed_postinsts(self):
676 status_file = self.image_rootfs + "/var/lib/dpkg/status"
677 return self._get_delayed_postinsts_common(status_file)
678
679 def _save_postinsts(self):
680 dst_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/deb-postinsts")
681 src_postinst_dir = self.d.expand("${IMAGE_ROOTFS}/var/lib/dpkg/info")
682 return self._save_postinsts_common(dst_postinst_dir, src_postinst_dir)
683
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500684 def _log_check(self):
685 self._log_check_warn()
686 self._log_check_error()
687
688 def _cleanup(self):
689 pass
690
691
692class OpkgRootfs(DpkgOpkgRootfs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500693 def __init__(self, d, manifest_dir, progress_reporter=None, logcatcher=None):
694 super(OpkgRootfs, self).__init__(d, progress_reporter, logcatcher)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500695 self.log_check_regex = '(exit 1|Collected errors)'
696
697 self.manifest = OpkgManifest(d, manifest_dir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500698 self.opkg_conf = self.d.getVar("IPKGCONF_TARGET")
699 self.pkg_archs = self.d.getVar("ALL_MULTILIB_PACKAGE_ARCHS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500700
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500701 self.inc_opkg_image_gen = self.d.getVar('INC_IPK_IMAGE_GEN') or ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500702 if self._remove_old_rootfs():
703 bb.utils.remove(self.image_rootfs, True)
704 self.pm = OpkgPM(d,
705 self.image_rootfs,
706 self.opkg_conf,
707 self.pkg_archs)
708 else:
709 self.pm = OpkgPM(d,
710 self.image_rootfs,
711 self.opkg_conf,
712 self.pkg_archs)
713 self.pm.recover_packaging_data()
714
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500715 bb.utils.remove(self.d.getVar('MULTILIB_TEMP_ROOTFS'), True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500716
717 def _prelink_file(self, root_dir, filename):
718 bb.note('prelink %s in %s' % (filename, root_dir))
719 prelink_cfg = oe.path.join(root_dir,
720 self.d.expand('${sysconfdir}/prelink.conf'))
721 if not os.path.exists(prelink_cfg):
722 shutil.copy(self.d.expand('${STAGING_DIR_NATIVE}${sysconfdir_native}/prelink.conf'),
723 prelink_cfg)
724
725 cmd_prelink = self.d.expand('${STAGING_DIR_NATIVE}${sbindir_native}/prelink')
726 self._exec_shell_cmd([cmd_prelink,
727 '--root',
728 root_dir,
729 '-amR',
730 '-N',
731 '-c',
732 self.d.expand('${sysconfdir}/prelink.conf')])
733
734 '''
735 Compare two files with the same key twice to see if they are equal.
736 If they are not equal, it means they are duplicated and come from
737 different packages.
738 1st: Comapre them directly;
739 2nd: While incremental image creation is enabled, one of the
740 files could be probaly prelinked in the previous image
741 creation and the file has been changed, so we need to
742 prelink the other one and compare them.
743 '''
744 def _file_equal(self, key, f1, f2):
745
746 # Both of them are not prelinked
747 if filecmp.cmp(f1, f2):
748 return True
749
Brad Bishop19323692019-04-05 15:28:33 -0400750 if bb.data.inherits_class('image-prelink', self.d):
751 if self.image_rootfs not in f1:
752 self._prelink_file(f1.replace(key, ''), f1)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500753
Brad Bishop19323692019-04-05 15:28:33 -0400754 if self.image_rootfs not in f2:
755 self._prelink_file(f2.replace(key, ''), f2)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500756
Brad Bishop19323692019-04-05 15:28:33 -0400757 # Both of them are prelinked
758 if filecmp.cmp(f1, f2):
759 return True
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500760
761 # Not equal
762 return False
763
764 """
765 This function was reused from the old implementation.
766 See commit: "image.bbclass: Added variables for multilib support." by
767 Lianhao Lu.
768 """
769 def _multilib_sanity_test(self, dirs):
770
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500771 allow_replace = self.d.getVar("MULTILIBRE_ALLOW_REP")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500772 if allow_replace is None:
773 allow_replace = ""
774
Brad Bishop19323692019-04-05 15:28:33 -0400775 allow_rep = re.compile(re.sub(r"\|$", r"", allow_replace))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500776 error_prompt = "Multilib check error:"
777
778 files = {}
779 for dir in dirs:
780 for root, subfolders, subfiles in os.walk(dir):
781 for file in subfiles:
782 item = os.path.join(root, file)
783 key = str(os.path.join("/", os.path.relpath(item, dir)))
784
785 valid = True
786 if key in files:
787 #check whether the file is allow to replace
788 if allow_rep.match(key):
789 valid = True
790 else:
791 if os.path.exists(files[key]) and \
792 os.path.exists(item) and \
793 not self._file_equal(key, files[key], item):
794 valid = False
795 bb.fatal("%s duplicate files %s %s is not the same\n" %
796 (error_prompt, item, files[key]))
797
798 #pass the check, add to list
799 if valid:
800 files[key] = item
801
802 def _multilib_test_install(self, pkgs):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500803 ml_temp = self.d.getVar("MULTILIB_TEMP_ROOTFS")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500804 bb.utils.mkdirhier(ml_temp)
805
806 dirs = [self.image_rootfs]
807
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500808 for variant in self.d.getVar("MULTILIB_VARIANTS").split():
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500809 ml_target_rootfs = os.path.join(ml_temp, variant)
810
811 bb.utils.remove(ml_target_rootfs, True)
812
813 ml_opkg_conf = os.path.join(ml_temp,
814 variant + "-" + os.path.basename(self.opkg_conf))
815
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800816 ml_pm = OpkgPM(self.d, ml_target_rootfs, ml_opkg_conf, self.pkg_archs, prepare_index=False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500817
818 ml_pm.update()
819 ml_pm.install(pkgs)
820
821 dirs.append(ml_target_rootfs)
822
823 self._multilib_sanity_test(dirs)
824
825 '''
826 While ipk incremental image generation is enabled, it will remove the
827 unneeded pkgs by comparing the old full manifest in previous existing
828 image and the new full manifest in the current image.
829 '''
830 def _remove_extra_packages(self, pkgs_initial_install):
831 if self.inc_opkg_image_gen == "1":
832 # Parse full manifest in previous existing image creation session
833 old_full_manifest = self.manifest.parse_full_manifest()
834
835 # Create full manifest for the current image session, the old one
836 # will be replaced by the new one.
837 self.manifest.create_full(self.pm)
838
839 # Parse full manifest in current image creation session
840 new_full_manifest = self.manifest.parse_full_manifest()
841
842 pkg_to_remove = list()
843 for pkg in old_full_manifest:
844 if pkg not in new_full_manifest:
845 pkg_to_remove.append(pkg)
846
847 if pkg_to_remove != []:
848 bb.note('decremental removed: %s' % ' '.join(pkg_to_remove))
849 self.pm.remove(pkg_to_remove)
850
851 '''
852 Compare with previous existing image creation, if some conditions
853 triggered, the previous old image should be removed.
854 The conditions include any of 'PACKAGE_EXCLUDE, NO_RECOMMENDATIONS
855 and BAD_RECOMMENDATIONS' has been changed.
856 '''
857 def _remove_old_rootfs(self):
858 if self.inc_opkg_image_gen != "1":
859 return True
860
861 vars_list_file = self.d.expand('${T}/vars_list')
862
863 old_vars_list = ""
864 if os.path.exists(vars_list_file):
865 old_vars_list = open(vars_list_file, 'r+').read()
866
867 new_vars_list = '%s:%s:%s\n' % \
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500868 ((self.d.getVar('BAD_RECOMMENDATIONS') or '').strip(),
869 (self.d.getVar('NO_RECOMMENDATIONS') or '').strip(),
870 (self.d.getVar('PACKAGE_EXCLUDE') or '').strip())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500871 open(vars_list_file, 'w+').write(new_vars_list)
872
873 if old_vars_list != new_vars_list:
874 return True
875
876 return False
877
878 def _create(self):
879 pkgs_to_install = self.manifest.parse_initial_manifest()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500880 opkg_pre_process_cmds = self.d.getVar('OPKG_PREPROCESS_COMMANDS')
881 opkg_post_process_cmds = self.d.getVar('OPKG_POSTPROCESS_COMMANDS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500882
Brad Bishop004d4992018-10-02 23:54:45 +0200883 # update PM index files
884 self.pm.write_index()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500885
886 execute_pre_post_process(self.d, opkg_pre_process_cmds)
887
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600888 if self.progress_reporter:
889 self.progress_reporter.next_stage()
890 # Steps are a bit different in order, skip next
891 self.progress_reporter.next_stage()
892
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500893 self.pm.update()
894
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600895 if self.progress_reporter:
896 self.progress_reporter.next_stage()
897
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500898 if self.inc_opkg_image_gen == "1":
899 self._remove_extra_packages(pkgs_to_install)
900
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600901 if self.progress_reporter:
902 self.progress_reporter.next_stage()
903
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500904 for pkg_type in self.install_order:
905 if pkg_type in pkgs_to_install:
906 # For multilib, we perform a sanity test before final install
907 # If sanity test fails, it will automatically do a bb.fatal()
908 # and the installation will stop
909 if pkg_type == Manifest.PKG_TYPE_MULTILIB:
910 self._multilib_test_install(pkgs_to_install[pkg_type])
911
912 self.pm.install(pkgs_to_install[pkg_type],
913 [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
914
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600915 if self.progress_reporter:
916 self.progress_reporter.next_stage()
917
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500918 self.pm.install_complementary()
919
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600920 if self.progress_reporter:
921 self.progress_reporter.next_stage()
922
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500923 opkg_lib_dir = self.d.getVar('OPKGLIBDIR')
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500924 opkg_dir = os.path.join(opkg_lib_dir, 'opkg')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500925 self._setup_dbg_rootfs([opkg_dir])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500926
927 execute_pre_post_process(self.d, opkg_post_process_cmds)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500928
929 if self.inc_opkg_image_gen == "1":
930 self.pm.backup_packaging_data()
931
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600932 if self.progress_reporter:
933 self.progress_reporter.next_stage()
934
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500935 @staticmethod
936 def _depends_list():
937 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']
938
939 def _get_delayed_postinsts(self):
940 status_file = os.path.join(self.image_rootfs,
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500941 self.d.getVar('OPKGLIBDIR').strip('/'),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500942 "opkg", "status")
943 return self._get_delayed_postinsts_common(status_file)
944
945 def _save_postinsts(self):
946 dst_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${sysconfdir}/ipk-postinsts")
947 src_postinst_dir = self.d.expand("${IMAGE_ROOTFS}${OPKGLIBDIR}/opkg/info")
948 return self._save_postinsts_common(dst_postinst_dir, src_postinst_dir)
949
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500950 def _log_check(self):
951 self._log_check_warn()
952 self._log_check_error()
953
954 def _cleanup(self):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500955 self.pm.remove_lists()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500956
957def get_class_for_type(imgtype):
958 return {"rpm": RpmRootfs,
959 "ipk": OpkgRootfs,
960 "deb": DpkgRootfs}[imgtype]
961
962def variable_depends(d, manifest_dir=None):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500963 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500964 cls = get_class_for_type(img_type)
965 return cls._depends_list()
966
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500967def create_rootfs(d, manifest_dir=None, progress_reporter=None, logcatcher=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500968 env_bkp = os.environ.copy()
969
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500970 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500971 if img_type == "rpm":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500972 RpmRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500973 elif img_type == "ipk":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500974 OpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500975 elif img_type == "deb":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500976 DpkgRootfs(d, manifest_dir, progress_reporter, logcatcher).create()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500977
978 os.environ.clear()
979 os.environ.update(env_bkp)
980
981
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500982def image_list_installed_packages(d, rootfs_dir=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500983 if not rootfs_dir:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500984 rootfs_dir = d.getVar('IMAGE_ROOTFS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500985
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500986 img_type = d.getVar('IMAGE_PKGTYPE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500987 if img_type == "rpm":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500988 return RpmPkgsList(d, rootfs_dir).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500989 elif img_type == "ipk":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500990 return OpkgPkgsList(d, rootfs_dir, d.getVar("IPKGCONF_TARGET")).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500991 elif img_type == "deb":
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500992 return DpkgPkgsList(d, rootfs_dir).list_pkgs()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500993
994if __name__ == "__main__":
995 """
996 We should be able to run this as a standalone script, from outside bitbake
997 environment.
998 """
999 """
1000 TBD
1001 """