summaryrefslogtreecommitdiffstats
path: root/meta/classes/image.bbclass
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2016-01-06 22:57:46 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-01-11 23:26:29 +0000
commit0a4e1f968ada5099e3270ed06404d2827e9729aa (patch)
treec805d6d23f593e8647b21de154d8a5fe181cb02c /meta/classes/image.bbclass
parentfdced52387613a09368716d1f3bb7a13a6edd46d (diff)
downloadpoky-0a4e1f968ada5099e3270ed06404d2827e9729aa.tar.gz
image: Create separate tasks for rootfs construction
This patch splits the code in lib/oe/image into separate tasks, one per image type. This removes the need for the simple task graph code and defers to the bitbake task management code to handle this instead. This is a good step forward in splitting up the monolithic code and starting to make it more accessible to people. It should also make it easier for people to hook in other tasks and processes into the rootfs code. Incidentally, the reason this code was all combined originally was due to limitations of fakeroot where if you exited the session, you lost permissions data. With pseudo this constraint was removed. We did start to rework the rootfs/image code previously and got so far with untangling it however we did prioritise some performance tweaks over splitting into separate tasks and in hindsight, this was a mistake and should have been done the other way around. That work was suspended due to changes in the people working on the project but this split has always been intended, now is the time to finish it IMO. There were some side effects of doing this: * The symlink for the manifest moves to the rootfs-postcommands class and into the manifest function. * There is no seperate "symlink removal" and "symlink creation", they are merged * The date/time stamps of the manifest and the built images can now be different since the tasks can be run separately and the datetime stamp will then be different between do_rootfs and the do_image_* tasks. (From OE-Core rev: c2dab181c1cdabac3be6197f4b9ea4235cbbc140) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes/image.bbclass')
-rw-r--r--meta/classes/image.bbclass227
1 files changed, 204 insertions, 23 deletions
diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index ffad5d28d2..5003dacc1c 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -106,21 +106,6 @@ python () {
106 d.setVarFlag(var, 'func', '1') 106 d.setVarFlag(var, 'func', '1')
107} 107}
108 108
109def fstype_variables(d):
110 import oe.image
111
112 image = oe.image.Image(d)
113 alltypes, fstype_groups, cimages = image._get_image_types()
114 fstype_vars = set()
115 for fstype_group in fstype_groups:
116 for fstype in fstype_group:
117 fstype_vars.add('IMAGE_CMD_' + fstype)
118 if fstype in cimages:
119 for ctype in cimages[fstype]:
120 fstype_vars.add('COMPRESS_CMD_' + ctype)
121
122 return sorted(fstype_vars)
123
124def rootfs_variables(d): 109def rootfs_variables(d):
125 from oe.rootfs import variable_depends 110 from oe.rootfs import variable_depends
126 variables = ['IMAGE_DEVICE_TABLES','BUILD_IMAGES_FROM_FEEDS','IMAGE_TYPES_MASKED','IMAGE_ROOTFS_ALIGNMENT','IMAGE_OVERHEAD_FACTOR','IMAGE_ROOTFS_SIZE','IMAGE_ROOTFS_EXTRA_SPACE', 111 variables = ['IMAGE_DEVICE_TABLES','BUILD_IMAGES_FROM_FEEDS','IMAGE_TYPES_MASKED','IMAGE_ROOTFS_ALIGNMENT','IMAGE_OVERHEAD_FACTOR','IMAGE_ROOTFS_SIZE','IMAGE_ROOTFS_EXTRA_SPACE',
@@ -129,7 +114,6 @@ def rootfs_variables(d):
129 'MULTILIB_TEMP_ROOTFS','MULTILIB_VARIANTS','MULTILIBS','ALL_MULTILIB_PACKAGE_ARCHS','MULTILIB_GLOBAL_VARIANTS','BAD_RECOMMENDATIONS','NO_RECOMMENDATIONS','PACKAGE_ARCHS', 114 'MULTILIB_TEMP_ROOTFS','MULTILIB_VARIANTS','MULTILIBS','ALL_MULTILIB_PACKAGE_ARCHS','MULTILIB_GLOBAL_VARIANTS','BAD_RECOMMENDATIONS','NO_RECOMMENDATIONS','PACKAGE_ARCHS',
130 'PACKAGE_CLASSES','TARGET_VENDOR','TARGET_VENDOR','TARGET_ARCH','TARGET_OS','OVERRIDES','BBEXTENDVARIANT','FEED_DEPLOYDIR_BASE_URI','INTERCEPT_DIR','USE_DEVFS', 115 'PACKAGE_CLASSES','TARGET_VENDOR','TARGET_VENDOR','TARGET_ARCH','TARGET_OS','OVERRIDES','BBEXTENDVARIANT','FEED_DEPLOYDIR_BASE_URI','INTERCEPT_DIR','USE_DEVFS',
131 'COMPRESSIONTYPES', 'IMAGE_GEN_DEBUGFS'] 116 'COMPRESSIONTYPES', 'IMAGE_GEN_DEBUGFS']
132 variables.extend(fstype_variables(d))
133 variables.extend(command_variables(d)) 117 variables.extend(command_variables(d))
134 variables.extend(variable_depends(d)) 118 variables.extend(variable_depends(d))
135 return " ".join(variables) 119 return " ".join(variables)
@@ -250,19 +234,13 @@ do_rootfs[umask] = "022"
250addtask rootfs before do_build 234addtask rootfs before do_build
251 235
252fakeroot python do_image () { 236fakeroot python do_image () {
253 from oe.image import create_image
254 from oe.image import Image
255 from oe.utils import execute_pre_post_process 237 from oe.utils import execute_pre_post_process
256 238
257 i = Image(d)
258
259 pre_process_cmds = d.getVar("IMAGE_PREPROCESS_COMMAND", True) 239 pre_process_cmds = d.getVar("IMAGE_PREPROCESS_COMMAND", True)
260 240
261 execute_pre_post_process(d, pre_process_cmds) 241 execute_pre_post_process(d, pre_process_cmds)
262 242
263 i._remove_old_symlinks() 243 write_wic_env(d)
264
265 i.create()
266} 244}
267do_image[dirs] = "${TOPDIR}" 245do_image[dirs] = "${TOPDIR}"
268do_image[umask] = "022" 246do_image[umask] = "022"
@@ -279,6 +257,209 @@ do_image_complete[dirs] = "${TOPDIR}"
279do_image_complete[umask] = "022" 257do_image_complete[umask] = "022"
280addtask do_image_complete after do_image before do_build 258addtask do_image_complete after do_image before do_build
281 259
260#
261# Write environment variables used by wic
262# to tmp/sysroots/<machine>/imgdata/<image>.env
263#
264def write_wic_env(d):
265 wicvars = d.getVar('WICVARS', True)
266 if not wicvars:
267 return
268
269 stdir = d.getVar('STAGING_DIR_TARGET', True)
270 outdir = os.path.join(stdir, 'imgdata')
271 bb.utils.mkdirhier(outdir)
272 basename = d.getVar('IMAGE_BASENAME', True)
273 with open(os.path.join(outdir, basename) + '.env', 'w') as envf:
274 for var in wicvars.split():
275 value = d.getVar(var, True)
276 if value:
277 envf.write('%s="%s"\n' % (var, value.strip()))
278
279def setup_debugfs_variables(d):
280 d.appendVar('IMAGE_ROOTFS', '-dbg')
281 d.appendVar('IMAGE_LINK_NAME', '-dbg')
282 d.appendVar('IMAGE_NAME','-dbg')
283 debugfs_image_fstypes = d.getVar('IMAGE_FSTYPES_DEBUGFS', True)
284 if debugfs_image_fstypes:
285 d.setVar('IMAGE_FSTYPES', debugfs_image_fstypes)
286
287python setup_debugfs () {
288 setup_debugfs_variables(d)
289}
290
291python () {
292 vardeps = set()
293 ctypes = d.getVar('COMPRESSIONTYPES', True).split()
294 old_overrides = d.getVar('OVERRIDES', 0)
295
296 def _image_base_type(type):
297 if type in ["vmdk", "vdi", "qcow2", "live", "iso", "hddimg"]:
298 type = "ext4"
299 basetype = type
300 for ctype in ctypes:
301 if type.endswith("." + ctype):
302 basetype = type[:-len("." + ctype)]
303 break
304
305 return basetype
306
307 basetypes = {}
308 alltypes = d.getVar('IMAGE_FSTYPES', True).split()
309 typedeps = {}
310
311 if d.getVar('IMAGE_GEN_DEBUGFS', True) == "1":
312 debugfs_fstypes = d.getVar('IMAGE_FSTYPES_DEBUGFS', True).split()
313 for t in debugfs_fstypes:
314 alltypes.append("debugfs_" + t)
315
316 def _add_type(t):
317 baset = _image_base_type(t)
318 if baset not in basetypes:
319 basetypes[baset]= []
320 if t not in basetypes[baset]:
321 basetypes[baset].append(t)
322 debug = ""
323 if t.startswith("debugfs_"):
324 t = t[8:]
325 debug = "debugfs_"
326 deps = (d.getVar('IMAGE_TYPEDEP_' + t, True) or "").split()
327 vardeps.add('IMAGE_TYPEDEP_' + t)
328 if baset not in typedeps:
329 typedeps[baset] = set()
330 deps = [debug + dep for dep in deps]
331 for dep in deps:
332 if dep not in alltypes:
333 alltypes.append(dep)
334 _add_type(dep)
335 basedep = _image_base_type(dep)
336 typedeps[baset].add(basedep)
337
338 for t in alltypes[:]:
339 _add_type(t)
340
341 d.appendVarFlag('do_image', 'vardeps', ' '.join(vardeps))
342
343 for t in basetypes:
344 vardeps = set()
345 cmds = []
346 subimages = []
347 realt = t
348
349 localdata = bb.data.createCopy(d)
350 debug = ""
351 if t.startswith("debugfs_"):
352 setup_debugfs_variables(localdata)
353 debug = "setup_debugfs "
354 realt = t[8:]
355 localdata.setVar('OVERRIDES', '%s:%s' % (realt, old_overrides))
356 bb.data.update_data(localdata)
357 localdata.setVar('type', realt)
358
359 image_cmd = localdata.getVar("IMAGE_CMD", True)
360 vardeps.add('IMAGE_CMD_' + realt)
361 if image_cmd:
362 cmds.append("\t" + image_cmd)
363 else:
364 bb.fatal("No IMAGE_CMD defined for IMAGE_FSTYPES entry '%s' - possibly invalid type name or missing support class" % t)
365 cmds.append(localdata.expand("\tcd ${DEPLOY_DIR_IMAGE}"))
366
367 for bt in basetypes[t]:
368 for ctype in ctypes:
369 if bt.endswith("." + ctype):
370 cmds.append("\t" + localdata.getVar("COMPRESS_CMD_" + ctype, True))
371 vardeps.add('COMPRESS_CMD_' + ctype)
372 subimages.append(realt + "." + ctype)
373
374 if realt not in alltypes:
375 cmds.append(localdata.expand("\trm ${IMAGE_NAME}.rootfs.${type}"))
376 else:
377 subimages.append(realt)
378
379 d.setVar('do_image_%s' % t, '\n'.join(cmds))
380 d.setVarFlag('do_image_%s' % t, 'func', '1')
381 d.setVarFlag('do_image_%s' % t, 'fakeroot', '1')
382 d.setVarFlag('do_image_%s' % t, 'prefuncs', debug + 'set_image_size')
383 d.setVarFlag('do_image_%s' % t, 'postfuncs', 'create_symlinks')
384 d.setVarFlag('do_image_%s' % t, 'subimages', subimages)
385 d.appendVarFlag('do_image_%s' % t, 'vardeps', ' '.join(vardeps))
386
387 after = 'do_image'
388 for dep in typedeps[t]:
389 after += ' do_image_%s' % dep
390
391 bb.debug(2, "Adding type %s before %s, after %s" % (t, 'do_image_complete', after))
392 bb.build.addtask('do_image_%s' % t, 'do_image_complete', after, d)
393}
394
395#
396# Compute the rootfs size
397#
398def get_rootfs_size(d):
399 import subprocess
400
401 rootfs_alignment = int(d.getVar('IMAGE_ROOTFS_ALIGNMENT', True))
402 overhead_factor = float(d.getVar('IMAGE_OVERHEAD_FACTOR', True))
403 rootfs_req_size = int(d.getVar('IMAGE_ROOTFS_SIZE', True))
404 rootfs_extra_space = eval(d.getVar('IMAGE_ROOTFS_EXTRA_SPACE', True))
405 rootfs_maxsize = d.getVar('IMAGE_ROOTFS_MAXSIZE', True)
406
407 output = subprocess.check_output(['du', '-ks',
408 d.getVar('IMAGE_ROOTFS', True)])
409 size_kb = int(output.split()[0])
410 base_size = size_kb * overhead_factor
411 base_size = (base_size, rootfs_req_size)[base_size < rootfs_req_size] + \
412 rootfs_extra_space
413
414 if base_size != int(base_size):
415 base_size = int(base_size + 1)
416 else:
417 base_size = int(base_size)
418
419 base_size += rootfs_alignment - 1
420 base_size -= base_size % rootfs_alignment
421
422 # Check the rootfs size against IMAGE_ROOTFS_MAXSIZE (if set)
423 if rootfs_maxsize:
424 rootfs_maxsize_int = int(rootfs_maxsize)
425 if base_size > rootfs_maxsize_int:
426 bb.fatal("The rootfs size %d(K) overrides the max size %d(K)" % \
427 (base_size, rootfs_maxsize_int))
428 return base_size
429
430python set_image_size () {
431 rootfs_size = get_rootfs_size(d)
432 d.setVar('ROOTFS_SIZE', str(rootfs_size))
433 d.setVarFlag('ROOTFS_SIZE', 'export', '1')
434}
435
436#
437# Create symlinks to the newly created image
438#
439python create_symlinks() {
440
441 deploy_dir = d.getVar('DEPLOY_DIR_IMAGE', True)
442 img_name = d.getVar('IMAGE_NAME', True)
443 link_name = d.getVar('IMAGE_LINK_NAME', True)
444 manifest_name = d.getVar('IMAGE_MANIFEST', True)
445 taskname = d.getVar("BB_CURRENTTASK", True)
446 subimages = d.getVarFlag("do_" + taskname, 'subimages', False)
447 os.chdir(deploy_dir)
448
449 if not link_name:
450 return
451 for type in subimages:
452 if os.path.exists(img_name + ".rootfs." + type):
453 dst = deploy_dir + "/" + link_name + "." + type
454 src = img_name + ".rootfs." + type
455 bb.note("Creating symlink: %s -> %s" % (dst, src))
456 if os.path.islink(dst):
457 if d.getVar('RM_OLD_IMAGE', True) == "1" and \
458 os.path.exists(os.path.realpath(dst)):
459 os.remove(os.path.realpath(dst))
460 os.remove(dst)
461 os.symlink(src, dst)
462}
282 463
283MULTILIBRE_ALLOW_REP =. "${base_bindir}|${base_sbindir}|${bindir}|${sbindir}|${libexecdir}|${sysconfdir}|${nonarch_base_libdir}/udev|/lib/modules/[^/]*/modules.*|" 464MULTILIBRE_ALLOW_REP =. "${base_bindir}|${base_sbindir}|${bindir}|${sbindir}|${libexecdir}|${sysconfdir}|${nonarch_base_libdir}/udev|/lib/modules/[^/]*/modules.*|"
284MULTILIB_CHECK_FILE = "${WORKDIR}/multilib_check.py" 465MULTILIB_CHECK_FILE = "${WORKDIR}/multilib_check.py"