[OE-core] [PATCH v2 1/1] image-mode.bbclass: common infrastructure for choosing image defaults

Patrick Ohly patrick.ohly at intel.com
Wed May 17 07:58:57 UTC 2017


A distro might want to offer developers different, pre-defined ways of
building an image, for example a "development" mode with easy (but
insecure) login methods and a "production" mode with hardened
settings.

image-mode.bbclass introduces IMAGE_MODE as the switch that defines
how developers want to build an image. It can be set differently for
different images. The intention is that the image recipe checks
IMAGE_MODE when setting the default IMAGE_FEATURES or whether
pre-generated signing keys are to be used for features like dm-verity.

All functionality is opt-in: if a distro does not change the defaults,
then the class only warns when a developer sets IMAGE_MODE althought
it isn't supported. The purpose of having this class in OE-core
although it doesn't do much by default is to achieve consistent
behavior between different distros.

Distros can define different modes (if desired, even differently for
different images) and can define additional text that gets appended to
/etc/motd of an image when a certain mode was used for the image.

The functionality is provided as a separate helper class to ease
copying of the functionality into distros not based on OE-core master
yet and to keep it in one place. The alternative is to copy the code
into image.bbclass and rootfs-postcommands.bbclass.

Signed-off-by: Patrick Ohly <patrick.ohly at intel.com>
---
 meta/classes/image-mode.bbclass | 66 ++++++++++++++++++++++++++++++++++-
 meta/classes/image.bbclass      |  2 +-
 2 files changed, 68 insertions(+)
 create mode 100644 meta/classes/image-mode.bbclass

diff --git a/meta/classes/image-mode.bbclass b/meta/classes/image-mode.bbclass
new file mode 100644
index 0000000..6137010
--- /dev/null
+++ b/meta/classes/image-mode.bbclass
@@ -0,0 +1,66 @@
+# Some distros may want to build images in different modes ("development",
+# "production", etc.). The same image recipe might get built differently
+# based on local configuration, or different image recipes might inherit
+# from the same base and just differ in their mode. This class introduces
+# "IMAGE_MODE" as the per-image variable which controls this mode.
+#
+# IMAGE_MODE is intentionally a separate variable. This way, IMAGE_FEATURES
+# can be set dynamically depending on IMAGE_MODE.
+#
+# There are no pre-defined modes. Distros which want to use modes
+# must set the IMAGE_MODE_VALID variable, either globally or per image.
+# Distros which don't have modes can still use the class to trigger
+# an error message when developers set the variable although it doesn't
+# have an effect.
+
+# The default is to have no fixed mode.
+IMAGE_MODE ??= ""
+
+# Set this in the distro or image to enable mode support. For example:
+# IMAGE_MODE_VALID ??= "production development debugging"
+
+# Optionally this class extends /etc/motd in each image depending on the
+# IMAGE_MODE of the image. To use this, set IMAGE_MODE_MOTD[<image mode>]
+# to a string for that mode or IMAGE_MODE_MOTD[none] for empty or
+# unset IMAGE_MODE. IMAGE_MODE_MOTD is used as default when the varflag
+# is not set.
+#
+# When the motd text is empty, /etc/motd is not touched at all.
+#
+# Example:
+# IMAGE_MODE_MOTD_NOT_PRODUCTION () {
+# *********************************************
+# *** This is a ${IMAGE_MODE} image! ${@ ' ' * (19 - len(d.getVar('IMAGE_MODE')))} ***
+# *** Do not use in production.             ***
+# *********************************************
+# }
+# IMAGE_MODE_MOTD = "${IMAGE_MODE_MOTD_NOT_PRODUCTION}"
+# IMAGE_MODE_MOTD[production] = ""
+
+# Empty when IMAGE_MODE is unset, otherwise -<IMAGE_MODE>.
+IMAGE_MODE_SUFFIX = "${@ '-' + d.getVar('IMAGE_MODE') if d.getVar('IMAGE_MODE') else '' }"
+
+python () {
+    # Sanity checks for IMAGE_MODE.
+    image_mode = d.getVar('IMAGE_MODE')
+    mode = set(image_mode.split())
+    if len(mode) == 0:
+        return
+    if len(mode) > 1:
+        bb.fatal('An image can only be built in exactly one mode: IMAGE_MODE=%s' % image_mode)
+    mode = mode.pop()
+    valid = d.getVar('IMAGE_MODE_VALID') or ''
+    if mode not in valid.split():
+        bb.fatal('Invalid image mode: IMAGE_MODE=%s (not in %s)' % (image_mode, valid))
+}
+
+python image_mode_motd () {
+    image_mode = d.getVar('IMAGE_MODE')
+    motd = d.getVarFlag('IMAGE_MODE_MOTD', image_mode or 'none')
+    if motd is None:
+        motd = d.getVar('IMAGE_MODE_MOTD')
+    if motd:
+        with open(d.expand('${IMAGE_ROOTFS}${sysconfdir}/motd'), 'a') as f:
+            f.write(motd)
+}
+ROOTFS_POSTPROCESS_COMMAND += "image_mode_motd;"
diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index 405fd73..b381d53 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -204,7 +204,9 @@ LINGUAS_INSTALL ?= "${@" ".join(map(lambda s: "locale-base-%s" % s, d.getVar('IM
 # aren't yet available.
 PSEUDO_PASSWD = "${IMAGE_ROOTFS}:${STAGING_DIR_NATIVE}"
 
+# Inherit helper classes.
 inherit rootfs-postcommands
+inherit image-mode
 
 PACKAGE_EXCLUDE ??= ""
 PACKAGE_EXCLUDE[type] = "list"
-- 
git-series 0.9.1



More information about the Openembedded-core mailing list