aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--classes/swupd-client.bbclass109
-rw-r--r--classes/swupd-image.bbclass147
-rw-r--r--conf/swupd/swupd-config.inc55
3 files changed, 167 insertions, 144 deletions
diff --git a/classes/swupd-client.bbclass b/classes/swupd-client.bbclass
new file mode 100644
index 0000000..f380eb3
--- /dev/null
+++ b/classes/swupd-client.bbclass
@@ -0,0 +1,109 @@
+# Class for swupd client integration -- adds necessary bits to
+# rootfs images that contain the swupd-client, i.e. setting the
+# expected format version, URLs, and public keys.
+#
+# Usage:
+# * inherit this class if you wish to create an image that contains the
+# swupd-client, but where the image itself is not subject to any
+# swupd based processing
+#
+# An example would be an initramfs that contains the client, but that
+# initramfs itself is a regular file in a different (outer) file system
+# (image). The outer image would be subject to swupd processing, and the
+# inner initramfs is simply responsible to update the outer file system
+# during system (re)start.
+
+require conf/swupd/swupd-config.inc
+
+PACKAGE_INSTALL_append = " swupd-client-format${SWUPD_TOOLS_FORMAT}"
+
+# The information about where to find version information and actual
+# content is needed in several places:
+# - the swupd client in the image gets configured such that it uses that as default
+# - swupd server needs information about the previous build
+#
+# The version URL determines what the client picks as the version that it updates to.
+# The content URL must have all builds ever produced and is expected to also
+# have the corresponding version information.
+#
+# To build the very first version of an image, set these to empty.
+# Errors while accessing the server (as the non-existent download.example.com)
+# or not having any previous build on that server are fatal. The latter
+# is necessary to detect misconfiguration.
+SWUPD_VERSION_URL ??= "http://download.example.com/updates/my-distro/milestone/${MACHINE}/${SWUPD_IMAGE_PN}"
+SWUPD_CONTENT_URL ??= "http://download.example.com/updates/my-distro/builds/${MACHINE}/${SWUPD_IMAGE_PN}"
+
+# An absolute path for a file containing the SSL certificate that is
+# is to be used for verifying https connections to the version and content
+# derver.
+SWUPD_PINNED_PUBKEY ??= ""
+
+
+# swupd-client checks VERSION_ID, which must match the OS_VERSION
+# used for generating swupd bundles in the current build.
+#
+# We patch this during image creation and exclude OS_VERSION from the
+# dependencies because doing it during the compilation of os-release.bb
+# would trigger a rebuild even if all that changed is the OS_VERSION.
+# It would also affect builds of images where swupd is not active. Both
+# is undesirable.
+#
+# If triggering a rebuild on each OS_VERSION change is desired,
+# then this can be achieved by influencing the os-release package
+# by setting in local.conf:
+# VERSION_ID = "${OS_VERSION}"
+PACKAGE_INSTALL_append = " os-release"
+swupd_patch_os_release () {
+ sed -i -e 's/^VERSION_ID *=.*/VERSION_ID="${OS_VERSION}"/' ${IMAGE_ROOTFS}/usr/lib/os-release
+}
+swupd_patch_os_release[vardepsexclude] = "OS_VERSION"
+ROOTFS_POSTPROCESS_COMMAND += "swupd_patch_os_release; "
+
+
+def hash_swupd_pinned_pubkey(d):
+ pubkey = d.getVar('SWUPD_PINNED_PUBKEY', True)
+ if pubkey:
+ import hashlib
+ bb.parse.mark_dependency(d, pubkey)
+ with open(pubkey, 'rb') as f:
+ hash = hashlib.sha256()
+ hash.update(f.read())
+ return hash.hexdigest()
+ else:
+ return ''
+
+SWUPD_PINNED_PUBKEY_HASH := "${@ hash_swupd_pinned_pubkey(d)}"
+
+# The swupd client must be configured on a per-image basis.
+# Different images might need different settings.
+configure_swupd_client () {
+ # Write default values to the configuration hierarchy (since 3.4.0)
+ install -d ${IMAGE_ROOTFS}/usr/share/defaults/swupd
+ echo "${SWUPD_VERSION_URL}" >> ${IMAGE_ROOTFS}/usr/share/defaults/swupd/versionurl
+ echo "${SWUPD_CONTENT_URL}" >> ${IMAGE_ROOTFS}/usr/share/defaults/swupd/contenturl
+ echo "${SWUPD_FORMAT}" >> ${IMAGE_ROOTFS}/usr/share/defaults/swupd/format
+ # Changing content of the pubkey also changes the hash and thus ensures
+ # that this method and thus do_rootfs run again.
+ #
+ # TODO: does not actually work. Recipe gets reparsed when the file
+ # changes ("bitbake -e ostro-image-swupd | SWUPD_PINNED_PUBKEY_HASH" changes)
+ # but the task does not get re-executed. Forcing that leads to:
+ #
+ # ERROR: ostro-image-swupd-1.0-r0 do_rootfs: Taskhash mismatch 8762bf20b997ac29dd6793fd11e609c3 versus cb40afac8ca291e31022d5ffd9a9bbac for /work/ostro-os/meta-ostro/recipes-image/images/ostro-image-swupd.bb.do_rootfs
+ # ERROR: Taskhash mismatch 8762bf20b997ac29dd6793fd11e609c3 versus cb40afac8ca291e31022d5ffd9a9bbac for /work/ostro-os/meta-ostro/recipes-image/images/ostro-image-swupd.bb.do_rootfs
+ #
+ # $ bitbake-diffsigs tmp-glibc/stamps/qemux86-ostro-linux/ostro-image-swupd/1.0-r0.do_rootfs.sigdata.c8a9371831f58ce4f8b49a73211f66aa tmp-glibc/stamps/qemux86-ostro-linux/ostro-image-swupd/1.0-r0.do_rootfs.sigdata.cb40afac8ca291e31022d5ffd9a9bbac
+ # basehash changed from 02de100ee7baa348e224f21844fdaa06 to e3bb23a069673a09afee4994522991d3
+ # Variable SWUPD_PINNED_PUBKEY_HASH value changed from 'b9ffbe0963f3f7ab3f3c1af5cd8471c121cb601eb4294ad4b211f1e206746a0a' to '8d172423eb0162feb8c7fb2f2d7da28a6effdf3e95184114c62e6b0efdeae89a'
+ # Taint (by forced/invalidated task) changed from None to 2c8e3b43-5e70-4c96-bf6e-741f0b344731
+ #
+ # There's no sigdata for 8762b. c8a93 is from before changing the file.
+ if [ "${SWUPD_PINNED_PUBKEY_HASH}" ]; then
+ install -d ${IMAGE_ROOTFS}${datadir}/clear/update-ca
+ install -m 0644 '${SWUPD_PINNED_PUBKEY}' ${IMAGE_ROOTFS}${datadir}/clear/update-ca/
+ echo "${datadir}/clear/update-ca/$(basename '${SWUPD_PINNED_PUBKEY}')" > ${IMAGE_ROOTFS}/usr/share/defaults/swupd/pinnedpubkey
+ fi
+ chown -R root:root ${IMAGE_ROOTFS}/usr/share/defaults/swupd
+ chmod 0644 ${IMAGE_ROOTFS}/usr/share/defaults/swupd/*
+}
+ROOTFS_POSTPROCESS_COMMAND_append = " configure_swupd_client;"
diff --git a/classes/swupd-image.bbclass b/classes/swupd-image.bbclass
index 645adab..dd56a34 100644
--- a/classes/swupd-image.bbclass
+++ b/classes/swupd-image.bbclass
@@ -15,6 +15,8 @@
#
# See docs/Guide.md for more information.
+inherit swupd-client
+
# Created for each bundle (including os-core) and the "full" directory,
# describing files and directories that swupd-server needs to include in the update
# mechanism (i.e. without SWUPD_FILE_BLACKLIST entries). Used by swupd-server.
@@ -32,69 +34,6 @@ SWUPD_IMAGE_PN = "${@ d.getVar('PN_BASE', True) or d.getVar('PN', True)}"
# to be published will be in the "www" sub-directory.
DEPLOY_DIR_SWUPD = "${DEPLOY_DIR}/swupd/${MACHINE}/${SWUPD_IMAGE_PN}"
-# The "format" needs to be bumped for different reasons:
-# - the output of the swupd-server changes in a way that
-# a swupd-client currently installed on devices will not
-# understand it (example: changing file names or using
-# a new compression method for archives)
-# - the content of the distro changes such that a device
-# cannot update directly to the latest build (example:
-# the distro changes the boot loader and some swupd postinst
-# helper which knows about that change must be installed on
-# the device first before actually switching)
-#
-# meta-swupd handles the first case with SWUPD_TOOLS_FORMAT.
-# The default value matches the default versions of the swupd-server
-# and swupd-client. Distros can override this if they need to pick
-# non-default versions of the tools, but that is not tested.
-#
-# Distros need to handle the second case by preparing and releasing
-# a build that devices can update to (i.e. the version URL the devices
-# check must have that update), then make the incompatible change and
-# in the next build bump the SWUPD_DISTRO_FORMAT.
-#
-# In both cases, SWUPD_FORMAT gets bumped. meta-swupd notices that
-# and then prepares a special transitional update:
-# - the rootfs is configured to use the new SWUUPD_FORMAT and
-# OS_VERSION
-# - a fake OS_VERSION-1 release is built using a swupd-server that is
-# compatible with the swupd-client before the bump
-# - the OS_VERSION release then is the first one using the new format
-#
-# This way, devices are forced to update to OS_VERSION-1 because that
-# will forever be the "latest" version for their current format.
-# Once they have updated, the device really is on OS_VERSION, configured
-# to use the new format, and the next update check will see future
-# releases again.
-#
-# For this to work, "swupd-client" should always be invoked without
-# explicit format parameter.
-SWUPD_TOOLS_FORMAT ?= "4"
-SWUPD_DISTRO_FORMAT ?= "0"
-SWUPD_FORMAT = "${@ str(int('${SWUPD_TOOLS_FORMAT}') + int('${SWUPD_DISTRO_FORMAT}')) }"
-IMAGE_INSTALL_append = " swupd-client-format${SWUPD_TOOLS_FORMAT}"
-
-# The information about where to find version information and actual
-# content is needed in several places:
-# - the swupd client in the image gets configured such that it uses that as default
-# - swupd server needs information about the previous build
-#
-# The version URL determines what the client picks as the version that it updates to.
-# The content URL must have all builds ever produced and is expected to also
-# have the corresponding version information.
-#
-# To build the very first version of an image, set these to empty.
-# Errors while accessing the server (as the non-existent download.example.com)
-# or not having any previous build on that server are fatal. The latter
-# is necessary to detect misconfiguration.
-SWUPD_VERSION_URL ??= "http://download.example.com/updates/my-distro/milestone/${MACHINE}/${SWUPD_IMAGE_PN}"
-SWUPD_CONTENT_URL ??= "http://download.example.com/updates/my-distro/builds/${MACHINE}/${SWUPD_IMAGE_PN}"
-
-# An absolute path for a file containing the SSL certificate that is
-# is to be used for verifying https connections to the version and content
-# derver.
-SWUPD_PINNED_PUBKEY ??= ""
-
# User configurable variables to disable all swupd processing or deltapack
# generation.
SWUPD_GENERATE ??= "1"
@@ -102,13 +41,9 @@ SWUPD_DELTAPACK_VERSIONS ??= ""
SWUPD_LOG_FN ??= "bbdebug 1"
-# This version number *must* map to VERSION_ID in /etc/os-release and *must* be
-# a non-negative integer that fits in an int.
-OS_VERSION ??= "${DISTRO_VERSION}"
-
# When doing format changes, this version number is used for the intermediate
# release. Default is OS_VERSION - 1. There's a separate sanity check for
-# OS_VERSION below, so this code should always work.
+# OS_VERSION in the .inc file, so this code should always work.
OS_VERSION_INTERIM ?= "${@ ${OS_VERSION} - 1 }"
# We need to preserve xattrs, which works with bsdtar out of the box.
@@ -125,14 +60,6 @@ REQUIRED_DISTRO_FEATURES = "systemd"
python () {
import os
- ver = d.getVar('OS_VERSION', True) or 'invalid'
- try:
- ver = int(ver)
- except ValueError:
- bb.fatal("Invalid value for OS_VERSION (%s), must be a non-negative integer value." % ver)
- if ver <= 0 or ver > 2147483647:
- bb.fatal('OS_VERSION outside of valid range (> 0, <= 2147483647): %d' % ver)
-
havebundles = (d.getVar('SWUPD_BUNDLES', True) or '') != ''
deploy_dir = d.getVar('DEPLOY_DIR_SWUPD', True)
@@ -642,26 +569,6 @@ python swupd_replace_hardlinks () {
}
ROOTFS_POSTPROCESS_COMMAND += "swupd_replace_hardlinks; "
-# swupd-client checks VERSION_ID, which must match the OS_VERSION
-# used for generating swupd bundles in the current build.
-#
-# We patch this during image creation and exclude OS_VERSION from the
-# dependencies because doing it during the compilation of os-release.bb
-# would trigger a rebuild even if all that changed is the OS_VERSION.
-# It would also affect builds of images where swupd is not active. Both
-# is undesirable.
-#
-# If triggering a rebuild on each OS_VERSION change is desired,
-# then this can be achieved by influencing the os-release package
-# by setting in local.conf:
-# VERSION_ID = "${OS_VERSION}"
-IMAGE_INSTALL_append = " os-release"
-swupd_patch_os_release () {
- sed -i -e 's/^VERSION_ID *=.*/VERSION_ID="${OS_VERSION}"/' ${IMAGE_ROOTFS}/usr/lib/os-release
-}
-swupd_patch_os_release[vardepsexclude] = "OS_VERSION"
-ROOTFS_POSTPROCESS_COMMAND += "swupd_patch_os_release; "
-
# Check whether the constructed image contains any dangling symlinks, these
# are likely to indicate deeper issues.
# NOTE: you'll almost certainly want to override these for your distro.
@@ -721,51 +628,3 @@ i.e. the link is to a file which only exists at runtime, such as files in /proc,
SWUPD_IMAGE_SYMLINK_WHITELIST to resolve this error.'
raise ImageQAFailed(message, swupd_check_dangling_symlinks)
}
-
-def hash_swupd_pinned_pubkey(d):
- pubkey = d.getVar('SWUPD_PINNED_PUBKEY', True)
- if pubkey:
- import hashlib
- bb.parse.mark_dependency(d, pubkey)
- with open(pubkey, 'rb') as f:
- hash = hashlib.sha256()
- hash.update(f.read())
- return hash.hexdigest()
- else:
- return ''
-
-SWUPD_PINNED_PUBKEY_HASH := "${@ hash_swupd_pinned_pubkey(d)}"
-
-# The swupd client must be configured on a per-image basis.
-# Different images might need different settings.
-configure_swupd_client () {
- # Write default values to the configuration hierarchy (since 3.4.0)
- install -d ${IMAGE_ROOTFS}/usr/share/defaults/swupd
- echo "${SWUPD_VERSION_URL}" >> ${IMAGE_ROOTFS}/usr/share/defaults/swupd/versionurl
- echo "${SWUPD_CONTENT_URL}" >> ${IMAGE_ROOTFS}/usr/share/defaults/swupd/contenturl
- echo "${SWUPD_FORMAT}" >> ${IMAGE_ROOTFS}/usr/share/defaults/swupd/format
- # Changing content of the pubkey also changes the hash and thus ensures
- # that this method and thus do_rootfs run again.
- #
- # TODO: does not actually work. Recipe gets reparsed when the file
- # changes ("bitbake -e ostro-image-swupd | SWUPD_PINNED_PUBKEY_HASH" changes)
- # but the task does not get re-executed. Forcing that leads to:
- #
- # ERROR: ostro-image-swupd-1.0-r0 do_rootfs: Taskhash mismatch 8762bf20b997ac29dd6793fd11e609c3 versus cb40afac8ca291e31022d5ffd9a9bbac for /work/ostro-os/meta-ostro/recipes-image/images/ostro-image-swupd.bb.do_rootfs
- # ERROR: Taskhash mismatch 8762bf20b997ac29dd6793fd11e609c3 versus cb40afac8ca291e31022d5ffd9a9bbac for /work/ostro-os/meta-ostro/recipes-image/images/ostro-image-swupd.bb.do_rootfs
- #
- # $ bitbake-diffsigs tmp-glibc/stamps/qemux86-ostro-linux/ostro-image-swupd/1.0-r0.do_rootfs.sigdata.c8a9371831f58ce4f8b49a73211f66aa tmp-glibc/stamps/qemux86-ostro-linux/ostro-image-swupd/1.0-r0.do_rootfs.sigdata.cb40afac8ca291e31022d5ffd9a9bbac
- # basehash changed from 02de100ee7baa348e224f21844fdaa06 to e3bb23a069673a09afee4994522991d3
- # Variable SWUPD_PINNED_PUBKEY_HASH value changed from 'b9ffbe0963f3f7ab3f3c1af5cd8471c121cb601eb4294ad4b211f1e206746a0a' to '8d172423eb0162feb8c7fb2f2d7da28a6effdf3e95184114c62e6b0efdeae89a'
- # Taint (by forced/invalidated task) changed from None to 2c8e3b43-5e70-4c96-bf6e-741f0b344731
- #
- # There's no sigdata for 8762b. c8a93 is from before changing the file.
- if [ "${SWUPD_PINNED_PUBKEY_HASH}" ]; then
- install -d ${IMAGE_ROOTFS}${datadir}/clear/update-ca
- install -m 0644 '${SWUPD_PINNED_PUBKEY}' ${IMAGE_ROOTFS}${datadir}/clear/update-ca/
- echo "${datadir}/clear/update-ca/$(basename '${SWUPD_PINNED_PUBKEY}')" > ${IMAGE_ROOTFS}/usr/share/defaults/swupd/pinnedpubkey
- fi
- chown -R root:root ${IMAGE_ROOTFS}/usr/share/defaults/swupd
- chmod 0644 ${IMAGE_ROOTFS}/usr/share/defaults/swupd/*
-}
-ROOTFS_POSTPROCESS_COMMAND_append = " configure_swupd_client;"
diff --git a/conf/swupd/swupd-config.inc b/conf/swupd/swupd-config.inc
new file mode 100644
index 0000000..bb9eaa5
--- /dev/null
+++ b/conf/swupd/swupd-config.inc
@@ -0,0 +1,55 @@
+# The "format" needs to be bumped for different reasons:
+# - the output of the swupd-server changes in a way that
+# a swupd-client currently installed on devices will not
+# understand it (example: changing file names or using
+# a new compression method for archives)
+# - the content of the distro changes such that a device
+# cannot update directly to the latest build (example:
+# the distro changes the boot loader and some swupd postinst
+# helper which knows about that change must be installed on
+# the device first before actually switching)
+#
+# meta-swupd handles the first case with SWUPD_TOOLS_FORMAT.
+# The default value matches the default versions of the swupd-server
+# and swupd-client. Distros can override this if they need to pick
+# non-default versions of the tools, but that is not tested.
+#
+# Distros need to handle the second case by preparing and releasing
+# a build that devices can update to (i.e. the version URL the devices
+# check must have that update), then make the incompatible change and
+# in the next build bump the SWUPD_DISTRO_FORMAT.
+#
+# In both cases, SWUPD_FORMAT gets bumped. meta-swupd notices that
+# and then prepares a special transitional update:
+# - the rootfs is configured to use the new SWUUPD_FORMAT and
+# OS_VERSION
+# - a fake OS_VERSION-1 release is built using a swupd-server that is
+# compatible with the swupd-client before the bump
+# - the OS_VERSION release then is the first one using the new format
+#
+# This way, devices are forced to update to OS_VERSION-1 because that
+# will forever be the "latest" version for their current format.
+# Once they have updated, the device really is on OS_VERSION, configured
+# to use the new format, and the next update check will see future
+# releases again.
+#
+# For this to work, "swupd-client" should always be invoked without
+# explicit format parameter.
+SWUPD_TOOLS_FORMAT ?= "4"
+SWUPD_DISTRO_FORMAT ?= "0"
+SWUPD_FORMAT = "${@ str(int('${SWUPD_TOOLS_FORMAT}') + int('${SWUPD_DISTRO_FORMAT}')) }"
+
+
+# This version number *must* map to VERSION_ID in /etc/os-release and *must* be
+# a non-negative integer that fits in an int.
+OS_VERSION ??= "${DISTRO_VERSION}"
+
+python () {
+ ver = d.getVar('OS_VERSION', True) or 'invalid'
+ try:
+ ver = int(ver)
+ except ValueError:
+ bb.fatal("Invalid value for OS_VERSION (%s), must be a non-negative integer value." % ver)
+ if ver <= 0 or ver > 2147483647:
+ bb.fatal('OS_VERSION outside of valid range (> 0, <= 2147483647): %d' % ver)
+}