aboutsummaryrefslogtreecommitdiffstats
path: root/docs/Guide.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/Guide.md')
-rw-r--r--docs/Guide.md279
1 files changed, 279 insertions, 0 deletions
diff --git a/docs/Guide.md b/docs/Guide.md
new file mode 100644
index 0000000..d8e3976
--- /dev/null
+++ b/docs/Guide.md
@@ -0,0 +1,279 @@
+# Building a swupd-based OS
+
+This guide will help introduce the Software Updater (swupd) and how meta-swupd
+can be used to develop a custom Linux-based OS with swupd updates using the
+Yocto Project tools.
+
+## What is swupd?
+
+The [SoftWare UPDater](https://clearlinux.org/features/software-update) — swupd
+— from [Clear Linux](https://clearlinux.org/) provides a new way of adding
+functionality to and updating a Linux-based OS.
+
+swupd uses binary-delta technology to efficiently update only the files that
+have changed between OS updates. This means that updates are small, resulting in
+fast downloads, and fast to apply.
+
+Functionality is added to the OS via bundles, rather than individual packages,
+which compose a set of projects into a logical unit which can be added or
+removed from the OS wholesale.
+
+## swupd concepts
+
+swupd encourages a certain way of constructing a Linux-based OS, via the
+following concepts:
+
+### Bundles
+
+Bundles in swupd are used to define logical units of functionality. All
+swupd-based operating systems will define at least os-core bundle, whilst most
+will also define several other bundles containing complete sets of functionality
+composed of one or more packages generated by the build system.
+
+### Immutable os-core
+
+Building on the bundle concept, swupd requires that the base operating system is
+immutable, enabling software deployed on the system to rely on the base OS not
+changing unexpectedly.
+
+Therefore files which are included in the os-core bundle must be the final
+version of a file which supports all bundles that may be installed on top of it.
+Adding a bundle to the OS *must not* modify a file provided by os-core. Most
+notably this means that the passwd and groups should contain all potential
+account information, regardless of whether or not these users and groups are
+utilised by the base OS.
+
+### Single, atomic, OS-wide version number
+
+swupd based operating systems atomically upgrade the entire OS from one version
+to the next, rather than upgrading at a more granular, package-based, level.
+This means that the entire contents of the OS can be determined from a single
+version number.
+
+### Stateless OS
+
+Clear Linux, the Linux-based OS which hosts swupd development, is a [stateless
+OS](https://clearlinux.org/features/stateless) — that is it comes with an empty
+`/etc` by default and all default OS configuration is enabled until overridden
+by per-system configuration of files in `/etc`.
+
+Due to this swupd by default will not update files `/etc` under the assumption
+that these are local configuration and the default configuration is provided by
+read-only files in other parts of the directory hierarchy in os-core.
+
+### The swupd way
+
+The concepts described above lead to a swupd using OS being constructed a
+certain way which provides several advantages to the OS developer, not least of
+all the reduces test matrix through a much smaller set of combinations of
+software that might be installed on the OS.
+
+### References
+
+For more details see the Clear Linux Project's documentation:
+* [Bundles overview](https://clearlinux.org/documentation/bundles_overview.html).
+* [About software update](https://clearlinux.org/documentation/swupdate_about_sw_update.html)
+* [Stateless feature description](https://clearlinux.org/features/stateless)
+
+## OpenEmbedded/Yocto Project considerations
+
+Several of the concepts in the swupd way contradict the default configuration of
+operating systems built with the Yocto Project tools and OpenEmbedded.
+
+When building a distribution with swupd the OS developer should be aware of the
+following requirements:
+
+### systemd
+
+swupd assumes the use of systemd both by using systemd units to trigger update
+checks and by explicitly calling the systemd binary to restart the
+`update-triggers.target` after an OS update has completed (see the swupd helper
+scripts section for more information about this target).
+
+Therefore at this time one must use systemd as init manager in order to make
+use of swupd.
+
+### Version number
+
+As the OS version number is atomic and identifies an entire OS build we generate
+a new set of swupd update artefacts only when the `OS_VERSION` variable is
+changed (by default refusing to write over an existing set of generated
+artefacts with the same version number).
+
+swupd-client checks the `VERSION_ID` in the the `os-release` file when checking
+for updates and we need to be certain that this is changed when building an
+OS update for deployment, to that end the swupd-image class automatically writes
+the `OS_VERSION` to the `VERSION_ID` field in the `os-release` file on each
+image creation.
+
+### update-alternatives
+
+As the `os-core` bundle must provide an unchanging (at least within the same OS version) which other bundles can't modify we must be wary of recipes which use `update-alternatives`.
+
+Due to the way meta-swupd constructs the swupd-based OS and the resulting images
+and update stream artefacts we can find ourselves in a situation where the
+symlink for an alternative is installed pointing to a file which doesn't exist
+in the os-core (because it's provided by a bundle).
+
+It is recommended that the OS developer carefully review all uses of
+`update-alternatives` in their metadata and ensure that:
+
+1. the `ALTERNATIVE_PRIORITY` is set appropriately so that the desired
+provider of an `ALTERNATIVE_LINK_NAME` is correctly chosen and consistent
+across bundles.
+2. the highest `ALTERNATIVE_PRIORITY` provider for an `ALTERNATIVE_LINK_NAME` is
+included in the os-core bundle.
+
+To help detect the dangling symlink scenario the `swupd-image` class includes a
+mechanism to check for such dangling symlinks in a constructed image, enable it
+by adding the `swupd_check_dangling_symlinks` sanity check to
+`SWUPD_IMAGE_SANITY_CHECKS` i.e.:
+```
+SWUPD_IMAGE_SANITY_CHECKS += " \
+ swupd_check_dangling_symlinks \
+"
+```
+
+### Users and groups
+
+Another aspect of the immutable os-core bundle is that the account information
+in the passwd and group files installed in the os-core bundle must include user
+and group information required for all bundles provided by the OS.
+
+We would also recommend the use of `useradd-staticids` to ensure that the uid
+and gid are consistent across rebuilds so that os-core has better
+reproducibility.
+
+See the Yocto Project Reference Manual section on
+[useradd*.bbclass](http://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#ref-classes-useradd) for more details.
+
+**NOTE**: due to the stateless nature of swupd group and passwd will not be
+updated, for more information see the *stateful* section below.
+
+### Stateful
+
+Linux-based OS built with OpenEmbedded and the Yocto Project Tools are stateful
+OS, that is the default configuration is provided by files in `/etc` and without
+extra work on top of the default packages the OS won't boot without a populated
+`/etc`. This contradicts the swupd way and means that currently any files a
+package installs into `/etc` won't be updated between OS version.
+
+swupd-client checks the `VERSION_ID` in the the `os-release` file when checking
+for updates. As this file is usually installed in `/etc` we include a `bbappend`
+which instead creates this file in `/usr/lib/` (a location swupd-client prefers)
+and symlink it to `/etc`.
+
+In order to support deploying updates to files in `/etc` via swupd we have
+developed patches for both swupd-client and swupd-server to include files in
+`/etc` in updates. These changes are enabled in swupd-server (resulting in swupd
+manifests which list files in `/etc`) but disabled by default in swupd-client.
+
+This is because enabling updating of files in `/etc` requires some forethought
+by the OS developer to ensure that files in `/etc` which shouldn't be updated
+are not included in the bundle directories. For example if you would like users
+of your OS to be able to add users and groups without OS updates overwriting
+those users and groups you would need to ensusre that the passwd and group files
+are not included in the bundle directories during the `do_swupd_update` task.
+
+You might achieve this by having a `prefunc` for the `do_swupd_update` task
+which removes said files from the *os-core* bundle directory.
+
+To enable stateful OS support in swupd-client disable the `stateless`
+`PACKAGE_CONFIG` option for the swupd-client recipe, i.e. with a
+`swupd-client_%.bbappend` file:
+
+```
+PACKAGE_CONFIG_remove = "stateless"
+```
+
+### swupd helper scripts
+
+swupd-client tries to call out to certain helper scripts during an update:
+* before the update `clr_pre_update.sh` is called
+* after the update `systemdboot_updater.sh` and `kernel_updater.sh` are called
+* the systemd `update-triggers.target` is restarted once the update is complete
+
+The `oe-swupd-helpers` recipe provides skeletal implementations of the scripts
+(`clr_pre_update.sh`, `systemdboot_updater.sh` and `kernel_updater.sh`) which
+simply print out that they have been called, these are clearly insufficient for
+a production environment and should be replaced with OS-specific
+implementations.
+
+The systemd units in `oe-swupd-helpers` are a little more useful, being based
+on the units used by the Clear Linux project, but likely need tweaking and
+adding to in order to better accommodate the OS being deployed.
+
+## Quick steps
+1. add the meta-swupd layer to bblayers.conf
+2. designate an image recipe as the base OS image (os-core, in swupd parlance)
+and `inherit swupd-image` in that recipe
+3. ensure the `OS_VERSION` variable is assigned an integer value and that this
+number is increased before each build which should generate swupd update
+artefacts
+4. Vet the os-core bundle to address the considerations documented above:
+* review any included recipes that inherit update-alternatives and ensure that
+the desired provider of a binary is correctly chosen and consistent across
+bundles with the highest priority provider being included in the os-core bundle.
+(we recommend the use of the `swupd_check_dangling_symlinks` to help catch this
+issue at image construction time)
+* ensure all users and groups required by all bundles in the OS are defined in
+the os-core bundle (we recommend the use of `useradd-staticids`).
+5. Implement appropriate versions of the scripts and units in oe-swupd-helpers
+6. (optional) Define additional bundles for any features you want to add
+assign a list of bundle names to `SWUPD_BUNDLES` and for each named bundle,
+assign a list of packages for which their content should be included in the
+bundle to a varflag of `BUNDLE_CONTENTS` which matches the bundle name i.e:
+```
+SWUPD_BUNDLES = "feature_one feature_two"
+BUNDLE_CONTENTS[feature_one] = "package_one package_three package_six"
+```
+**NOTE**: beware of reserved bundle names, both '*full*' and '*mega*' have
+special meaning and cannot be used for bundle names.
+7. (optional) Define extra images, consisting of the os-core with any number of
+additional bundles installed, which can be built. Do this by setting the
+`SWUPD_IMAGES` variable to a list of additional image name suffixes and
+assigning the names of bundles to inclde to a varflag matching the defined name.
+For example:
+```
+SWUPD_IMAGES = "product1"
+SWUPD_IMAGES[product1] = "product1"
+```
+defined in an image named *myco-image-core* would enable bitbake to be invoked
+with the target *myco-image-core-product1*.
+The *myco-image-core-product1* image would consist of the base OS (*os-core*
+bundle) and the contents of the *product1* bundle and might, for example, be
+used to provide an image which can be directly flashed to the product hardware.
+
+## Control variables
+
+Several variables can be set to tune the way swupd-image works:
+
+* `SWUPD_GENERATE` — if set to *0* i.e. `SWUPD_GENERATE = "0"` swupd update
+artefact processing will be skipped but all tasks of the `swupd-image` class
+will be executed. This is useful both for debugging the `swupd-image` class and
+in a scenario where it might be desirable to generate the chroot-like bundle
+directories without performing an processing with swupd.
+* `SWUPD_DELTAPACKS` — if set to *0* i.e. `SWUPD_DELTAPACKS="0"` swupd
+delta-packs will not be generated.
+* `SWUPD_N_DELTAPACKS` — the number of previous releases against which to
+generate delta-packs, defaults to 2.
+* `SWUPD_VERSION_STEP` — Amount the OS_VERSION should be increased by for each
+release. Used by the delta pack looping to generate delta packs going back up to
+SWUPD_N_DELTAPACK releases.
+
+## Using swupd client
+
+The swupd-client package installs a binary named *swupd* which can be used to
+perform updates, etc on the target.
+
+Take extra care with swupd-client versions prior to v3.4.0 as they hard-code the
+update URLs to clearlinux.org. When steps haven't been taken to change the
+default update URLs be sure to operate swupd-client with the **-u** switch and
+pass a URL to your update server.
+
+Examples of swupd-client use follow:
+```
+swupd check-update -u example.com/updates
+swupd update -u example.com/updates
+swupd verify -u example.com/updates
+```