summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMing Liu <liu.ming50@gmail.com>2018-11-20 09:03:25 +0100
committerMing Liu <liu.ming50@gmail.com>2018-11-24 14:24:26 +0100
commite97975d6113ca1ffa6cbe9b005bd518bd146fd9c (patch)
tree0c1df1f626bfd3d1819661dda5fb6ff7c4877210
parentf4cf0698a88631af150782dce9b3dafcb0dbc5d5 (diff)
downloadmeta-updater-e97975d6113ca1ffa6cbe9b005bd518bd146fd9c.tar.gz
image_types_ostree/ota.bbclass: refactor ostree task
There are several flaws with ostree tasks, as follows: - ${IMAGE_NAME}.rootfs.ostree.tar.bz2 is generated, but it's not being used during ostree commit, so it should be removed if it's just a intermittent artifact. Or if we intend to deploy this tar.bz2 file, it should be tracked by sstate cache, that is to day, it should be generated in ${IMGDEPLOYDIR} rather than in ${DEPLOY_DIR_IMAGE}. - There are quite a few redundant code like mktemp/cd/rm a directory, which can be replaced by setting 'dirs', 'cleandirs' varflags. - There are some redundant variable check logic in image_types_ostree and image_types_ota bbclass. To fix the above, we make the following changes: - Introduce a new conversion image type 'tar', it could convert ostree and ota to ostree.tar, ota.tar, hence we can drop the code generating ostree.tar.bz2 in image_types_ostree.bbclass, and also drop the do_image_ota-tar task. To let this conversion type take effect, the otasetup task needs to be changed to ota. - Introduce BUILD_OSTREE_TARBALL variable, when being set to 1, a ostree.tar.bz2 tarball would be built, BUILD_OSTREE_TARBALL defaults to be 1, to be consistent with original behavior. - Replace 'ota-tar ota-tar.xz' with ota.tar.xz in IMAGE_FSTYPES. - Add a sanity check bbclass sota_sanity.bbclass, to ensure ostree or ota is not in OVERRIDES, this is to prevent potential naming pollution with other meta layers, and also check the required variables are not empty. This sota_sanity.bbclass is a common class that could be extended easily in furture, and one of its most advantages is that all the check are done in bb.event.SanityCheck event handler, so the end users could get the error message at very beginning of the recipe parsing time. Signed-off-by: Ming Liu <liu.ming50@gmail.com>
-rw-r--r--classes/image_types_ostree.bbclass50
-rw-r--r--classes/image_types_ota.bbclass60
-rw-r--r--classes/sota.bbclass8
-rw-r--r--classes/sota_sanity.bbclass54
4 files changed, 88 insertions, 84 deletions
diff --git a/classes/image_types_ostree.bbclass b/classes/image_types_ostree.bbclass
index 44a3aa4..41b8d0d 100644
--- a/classes/image_types_ostree.bbclass
+++ b/classes/image_types_ostree.bbclass
@@ -1,35 +1,28 @@
1# OSTree deployment 1# OSTree deployment
2 2
3do_image_ostree[depends] += "ostree-native:do_populate_sysroot \
4 coreutils-native:do_populate_sysroot \
5 virtual/kernel:do_deploy \
6 ${INITRAMFS_IMAGE}:do_image_complete \
7"
8do_image_ostree[lockfiles] += "${OSTREE_REPO}/ostree.lock"
9
10OSTREE_KERNEL ??= "${KERNEL_IMAGETYPE}" 3OSTREE_KERNEL ??= "${KERNEL_IMAGETYPE}"
4OSTREE_ROOTFS ??= "${WORKDIR}/ostree-rootfs"
11OSTREE_COMMIT_SUBJECT ??= "Commit-id: ${IMAGE_NAME}" 5OSTREE_COMMIT_SUBJECT ??= "Commit-id: ${IMAGE_NAME}"
12OSTREE_COMMIT_BODY ??= "" 6OSTREE_COMMIT_BODY ??= ""
13OSTREE_UPDATE_SUMMARY ??= "0" 7OSTREE_UPDATE_SUMMARY ??= "0"
14 8
15SYSTEMD_USED = "${@oe.utils.ifelse(d.getVar('VIRTUAL-RUNTIME_init_manager', True) == 'systemd', 'true', '')}" 9BUILD_OSTREE_TARBALL ??= "1"
16 10
17IMAGE_CMD_ostree () { 11SYSTEMD_USED = "${@oe.utils.ifelse(d.getVar('VIRTUAL-RUNTIME_init_manager', True) == 'systemd', 'true', '')}"
18 if [ -z "$OSTREE_REPO" ]; then
19 bbfatal "OSTREE_REPO should be set in your local.conf"
20 fi
21 12
22 if [ -z "$OSTREE_BRANCHNAME" ]; then 13IMAGE_CMD_TAR = "tar --xattrs --xattrs-include=*"
23 bbfatal "OSTREE_BRANCHNAME should be set in your local.conf" 14CONVERSION_CMD_tar = "touch ${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}; ${IMAGE_CMD_TAR} --numeric-owner -cf ${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}.tar -C ${OTA_IMAGE_ROOTFS} . || [ $? -eq 1 ]"
24 fi 15CONVERSIONTYPES_append = " tar"
25 16
26 OSTREE_ROOTFS=`mktemp -du ${WORKDIR}/ostree-root-XXXXX` 17OTA_IMAGE_ROOTFS_task-image-ostree = "${OSTREE_ROOTFS}"
27 cp -a ${IMAGE_ROOTFS} ${OSTREE_ROOTFS} 18do_image_ostree[dirs] = "${OSTREE_ROOTFS}"
19do_image_ostree[cleandirs] = "${OSTREE_ROOTFS}"
20do_image_ostree[depends] = "coreutils-native:do_populate_sysroot virtual/kernel:do_deploy ${INITRAMFS_IMAGE}:do_image_complete"
21IMAGE_CMD_ostree () {
22 cp -a ${IMAGE_ROOTFS}/* ${OSTREE_ROOTFS}
28 chmod a+rx ${OSTREE_ROOTFS} 23 chmod a+rx ${OSTREE_ROOTFS}
29 sync 24 sync
30 25
31 cd ${OSTREE_ROOTFS}
32
33 for d in var/*; do 26 for d in var/*; do
34 if [ "${d}" != "var/local" ]; then 27 if [ "${d}" != "var/local" ]; then
35 rm -rf ${d} 28 rm -rf ${d}
@@ -132,17 +125,12 @@ IMAGE_CMD_ostree () {
132 125
133 # Copy image manifest 126 # Copy image manifest
134 cat ${IMAGE_MANIFEST} | cut -d " " -f1,3 > usr/package.manifest 127 cat ${IMAGE_MANIFEST} | cut -d " " -f1,3 > usr/package.manifest
128}
135 129
136 cd ${WORKDIR} 130IMAGE_TYPEDEP_ostreecommit = "ostree"
137 131do_image_ostreecommit[depends] += "ostree-native:do_populate_sysroot"
138 # Create a tarball that can be then commited to OSTree repo 132do_image_ostreecommit[lockfiles] += "${WORKDIR}/${OSTREE_REPO}-commit.lock"
139 OSTREE_TAR=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.ostree.tar.bz2 133IMAGE_CMD_ostreecommit () {
140 tar -C ${OSTREE_ROOTFS} --xattrs --xattrs-include='*' -cjf ${OSTREE_TAR} .
141 sync
142
143 rm -f ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.rootfs.ostree.tar.bz2
144 ln -s ${IMAGE_NAME}.rootfs.ostree.tar.bz2 ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.rootfs.ostree.tar.bz2
145
146 if ! ostree --repo=${OSTREE_REPO} refs 2>&1 > /dev/null; then 134 if ! ostree --repo=${OSTREE_REPO} refs 2>&1 > /dev/null; then
147 ostree --repo=${OSTREE_REPO} init --mode=archive-z2 135 ostree --repo=${OSTREE_REPO} init --mode=archive-z2
148 fi 136 fi
@@ -158,11 +146,9 @@ IMAGE_CMD_ostree () {
158 if [ "${OSTREE_UPDATE_SUMMARY}" = "1" ]; then 146 if [ "${OSTREE_UPDATE_SUMMARY}" = "1" ]; then
159 ostree --repo=${OSTREE_REPO} summary -u 147 ostree --repo=${OSTREE_REPO} summary -u
160 fi 148 fi
161
162 rm -rf ${OSTREE_ROOTFS}
163} 149}
164 150
165IMAGE_TYPEDEP_ostreepush = "ostree" 151IMAGE_TYPEDEP_ostreepush = "ostreecommit"
166do_image_ostreepush[depends] += "aktualizr-native:do_populate_sysroot ca-certificates-native:do_populate_sysroot" 152do_image_ostreepush[depends] += "aktualizr-native:do_populate_sysroot ca-certificates-native:do_populate_sysroot"
167IMAGE_CMD_ostreepush () { 153IMAGE_CMD_ostreepush () {
168 # Print warnings if credetials are not set or if the file has not been found. 154 # Print warnings if credetials are not set or if the file has not been found.
diff --git a/classes/image_types_ota.bbclass b/classes/image_types_ota.bbclass
index 79de909..09f1095 100644
--- a/classes/image_types_ota.bbclass
+++ b/classes/image_types_ota.bbclass
@@ -1,15 +1,9 @@
1# Image to use with u-boot as BIOS and OSTree deployment system 1# Image to use with u-boot as BIOS and OSTree deployment system
2 2
3#inherit image_types
4
5# Boot filesystem size in MiB 3# Boot filesystem size in MiB
6# OSTree updates may require some space on boot file system for 4# OSTree updates may require some space on boot file system for
7# boot scripts, kernel and initramfs images 5# boot scripts, kernel and initramfs images
8# 6#
9
10
11do_image_ota_ext4[depends] += "e2fsprogs-native:do_populate_sysroot"
12
13calculate_size () { 7calculate_size () {
14 BASE=$1 8 BASE=$1
15 SCALE=$2 9 SCALE=$2
@@ -44,26 +38,13 @@ calculate_size () {
44} 38}
45 39
46OTA_SYSROOT = "${WORKDIR}/ota-sysroot" 40OTA_SYSROOT = "${WORKDIR}/ota-sysroot"
47 41OTA_IMAGE_ROOTFS_task-image-ota = "${OTA_SYSROOT}"
48## Common OTA image setup 42IMAGE_TYPEDEP_ota = "ostreecommit"
49fakeroot do_otasetup () { 43do_image_ota[dirs] = "${OTA_SYSROOT}"
50 44do_image_ota[cleandirs] = "${OTA_SYSROOT}"
51 if [ -z "$OSTREE_REPO" ]; then 45do_image_ota[depends] = "${@'grub:do_populate_sysroot' if d.getVar('OSTREE_BOOTLOADER', True) == 'grub' else ''} \
52 bbfatal "OSTREE_REPO should be set in your local.conf" 46 ${@'virtual/bootloader:do_deploy' if d.getVar('OSTREE_BOOTLOADER', True) == 'u-boot' else ''}"
53 fi 47IMAGE_CMD_ota () {
54
55 if [ -z "$OSTREE_OSNAME" ]; then
56 bbfatal "OSTREE_OSNAME should be set in your local.conf"
57 fi
58
59 if [ -z "$OSTREE_BRANCHNAME" ]; then
60 bbfatal "OSTREE_BRANCHNAME should be set in your local.conf"
61 fi
62
63 # HaX! Since we are using a peristent directory, we need to be sure to clean it on run.
64 mkdir -p ${OTA_SYSROOT}
65 rm -rf ${OTA_SYSROOT}/*
66
67 ostree admin --sysroot=${OTA_SYSROOT} init-fs ${OTA_SYSROOT} 48 ostree admin --sysroot=${OTA_SYSROOT} init-fs ${OTA_SYSROOT}
68 ostree admin --sysroot=${OTA_SYSROOT} os-init ${OSTREE_OSNAME} 49 ostree admin --sysroot=${OTA_SYSROOT} os-init ${OSTREE_OSNAME}
69 mkdir -p ${OTA_SYSROOT}/boot/loader.0 50 mkdir -p ${OTA_SYSROOT}/boot/loader.0
@@ -88,19 +69,14 @@ fakeroot do_otasetup () {
88 69
89 ostree admin --sysroot=${OTA_SYSROOT} deploy ${kargs_list} --os=${OSTREE_OSNAME} ${ostree_target_hash} 70 ostree admin --sysroot=${OTA_SYSROOT} deploy ${kargs_list} --os=${OSTREE_OSNAME} ${ostree_target_hash}
90 71
91 # Copy deployment /home and /var/sota to sysroot
92 HOME_TMP=`mktemp -d ${WORKDIR}/home-tmp-XXXXX`
93
94 tar --xattrs --xattrs-include='*' -C ${HOME_TMP} -xf ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.rootfs.ostree.tar.bz2 ./usr/homedirs ./var/local || true
95
96 cp -a ${IMAGE_ROOTFS}/var/sota ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/ || true 72 cp -a ${IMAGE_ROOTFS}/var/sota ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/ || true
97 # Create /var/sota if it doesn't exist yet 73 # Create /var/sota if it doesn't exist yet
98 mkdir -p ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota 74 mkdir -p ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota
99 # Ensure the permissions are correctly set 75 # Ensure the permissions are correctly set
100 chmod 700 ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota 76 chmod 700 ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota
101 77
102 mv ${HOME_TMP}/var/local ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/ || true 78 cp -a ${OSTREE_ROOTFS}/var/local ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/ || true
103 mv ${HOME_TMP}/usr/homedirs/home ${OTA_SYSROOT}/ || true 79 cp -a ${OSTREE_ROOTFS}/usr/homedirs/home ${OTA_SYSROOT}/ || true
104 # Ensure that /var/local exists (AGL symlinks /usr/local to /var/local) 80 # Ensure that /var/local exists (AGL symlinks /usr/local to /var/local)
105 install -d ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/local 81 install -d ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/local
106 # Set package version for the first deployment 82 # Set package version for the first deployment
@@ -112,10 +88,10 @@ fakeroot do_otasetup () {
112 fi 88 fi
113 mkdir -p ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota/import 89 mkdir -p ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota/import
114 echo "{\"${ostree_target_hash}\":\"${GARAGE_TARGET_NAME}-${target_version}\"}" > ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota/import/installed_versions 90 echo "{\"${ostree_target_hash}\":\"${GARAGE_TARGET_NAME}-${target_version}\"}" > ${OTA_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota/import/installed_versions
115 echo "All done. Cleaning up dir: ${HOME_TMP}"
116 rm -rf ${HOME_TMP}
117} 91}
118 92
93IMAGE_TYPEDEP_ota-ext4 = "ota"
94do_image_ota_ext4[depends] = "e2fsprogs-native:do_populate_sysroot"
119IMAGE_CMD_ota-ext4 () { 95IMAGE_CMD_ota-ext4 () {
120 # Calculate image type 96 # Calculate image type
121 OTA_ROOTFS_SIZE=$(calculate_size `du -ks $OTA_SYSROOT | cut -f 1` "${IMAGE_OVERHEAD_FACTOR}" "${IMAGE_ROOTFS_SIZE}" "${IMAGE_ROOTFS_MAXSIZE}" `expr ${IMAGE_ROOTFS_EXTRA_SPACE}` "${IMAGE_ROOTFS_ALIGNMENT}") 97 OTA_ROOTFS_SIZE=$(calculate_size `du -ks $OTA_SYSROOT | cut -f 1` "${IMAGE_OVERHEAD_FACTOR}" "${IMAGE_ROOTFS_SIZE}" "${IMAGE_ROOTFS_MAXSIZE}" `expr ${IMAGE_ROOTFS_EXTRA_SPACE}` "${IMAGE_ROOTFS_ALIGNMENT}")
@@ -133,17 +109,3 @@ IMAGE_CMD_ota-ext4 () {
133 dd if=/dev/zero of=${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.ota-ext4 seek=${OTA_ROOTFS_SIZE} count=$COUNT bs=1024 109 dd if=/dev/zero of=${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.ota-ext4 seek=${OTA_ROOTFS_SIZE} count=$COUNT bs=1024
134 mkfs.ext4 -O ^64bit ${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.ota-ext4 -L otaroot -d ${OTA_SYSROOT} 110 mkfs.ext4 -O ^64bit ${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.ota-ext4 -L otaroot -d ${OTA_SYSROOT}
135} 111}
136
137IMAGE_CMD_ota-tar () {
138 tar -cf ${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.ota-tar -C ${OTA_SYSROOT} .
139}
140
141do_otasetup[doc] = "Sets up the base ota rootfs used for subsequent image generation"
142do_otasetup[depends] += "virtual/fakeroot-native:do_populate_sysroot \
143 ${@'grub:do_populate_sysroot' if d.getVar('OSTREE_BOOTLOADER', True) == 'grub' else ''} \
144 ${@'virtual/bootloader:do_deploy' if d.getVar('OSTREE_BOOTLOADER', True) == 'u-boot' else ''}"
145
146addtask do_otasetup after do_image_ostree before do_image_ota_ext4 do_image_ota_tar
147
148IMAGE_TYPEDEP_ota-ext4 = "ostree"
149IMAGE_TYPEDEP_ota-tar = "ostree"
diff --git a/classes/sota.bbclass b/classes/sota.bbclass
index e654071..7118807 100644
--- a/classes/sota.bbclass
+++ b/classes/sota.bbclass
@@ -16,7 +16,8 @@ IMAGE_INSTALL_append_sota = " ostree os-release ${SOTA_CLIENT} ${SOTA_CLIENT_PRO
16IMAGE_CLASSES += " image_types_ostree image_types_ota" 16IMAGE_CLASSES += " image_types_ostree image_types_ota"
17 17
18IMAGE_FSTYPES += "${@bb.utils.contains('DISTRO_FEATURES', 'sota', 'ostreepush garagesign garagecheck ota-ext4 wic', ' ', d)}" 18IMAGE_FSTYPES += "${@bb.utils.contains('DISTRO_FEATURES', 'sota', 'ostreepush garagesign garagecheck ota-ext4 wic', ' ', d)}"
19IMAGE_FSTYPES += "${@bb.utils.contains('BUILD_OTA_TARBALL', '1', 'ota-tar ota-tar.xz', ' ', d)}" 19IMAGE_FSTYPES += "${@bb.utils.contains('BUILD_OSTREE_TARBALL', '1', 'ostree.tar.bz2', ' ', d)}"
20IMAGE_FSTYPES += "${@bb.utils.contains('BUILD_OTA_TARBALL', '1', 'ota.tar.xz', ' ', d)}"
20 21
21PACKAGECONFIG_append_pn-curl = " ssl" 22PACKAGECONFIG_append_pn-curl = " ssl"
22PACKAGECONFIG_remove_pn-curl = "gnutls" 23PACKAGECONFIG_remove_pn-curl = "gnutls"
@@ -50,6 +51,7 @@ SOTA_MACHINE_intel-corei7-64 ?= "minnowboard"
50SOTA_MACHINE_qemux86-64 ?= "qemux86-64" 51SOTA_MACHINE_qemux86-64 ?= "qemux86-64"
51SOTA_MACHINE_am335x-evm ?= "am335x-evm-wifi" 52SOTA_MACHINE_am335x-evm ?= "am335x-evm-wifi"
52 53
53inherit sota_${SOTA_MACHINE} 54SOTA_OVERRIDES_BLACKLIST = "ostree ota"
55SOTA_REQUIRED_VARIABLES = "OSTREE_REPO OSTREE_BRANCHNAME OSTREE_OSNAME OSTREE_BOOTLOADER OSTREE_BOOT_PARTITION GARAGE_SIGN_REPO GARAGE_TARGET_NAME"
54 56
55inherit image_repo_manifest 57inherit sota_sanity sota_${SOTA_MACHINE} image_repo_manifest
diff --git a/classes/sota_sanity.bbclass b/classes/sota_sanity.bbclass
new file mode 100644
index 0000000..e47de19
--- /dev/null
+++ b/classes/sota_sanity.bbclass
@@ -0,0 +1,54 @@
1# Sanity check the sota setup for common misconfigurations
2
3def sota_check_overrides(status, d):
4 for var in (d.getVar('SOTA_OVERRIDES_BLACKLIST', True) or "").split():
5 if var in d.getVar('OVERRIDES', True).split(':'):
6 status.addresult("%s should not be a overrides, because it is a image fstype in updater layer, please check your OVERRIDES setting.\n" % var)
7
8def sota_check_required_variables(status, d):
9 for var in (d.getVar('SOTA_REQUIRED_VARIABLES', True) or "").split():
10 if not d.getVar(var, True):
11 status.addresult("%s should be set in your local.conf.\n" % var)
12
13def sota_raise_sanity_error(msg, d):
14 if d.getVar("SANITY_USE_EVENTS", True) == "1":
15 bb.event.fire(bb.event.SanityCheckFailed(msg), d)
16 return
17
18 bb.fatal("Sota's config sanity checker detected a potential misconfiguration.\n"
19 "Please fix the cause of this error then you can continue to build.\n"
20 "Following is the list of potential problems / advisories:\n"
21 "\n%s" % msg)
22
23def sota_check_sanity(sanity_data):
24 class SanityStatus(object):
25 def __init__(self):
26 self.messages = ""
27 self.reparse = False
28
29 def addresult(self, message):
30 if message:
31 self.messages = self.messages + message
32
33 status = SanityStatus()
34
35 sota_check_overrides(status, sanity_data)
36 sota_check_required_variables(status, sanity_data)
37
38 if status.messages != "":
39 sota_raise_sanity_error(sanity_data.expand(status.messages), sanity_data)
40
41addhandler sota_check_sanity_eventhandler
42sota_check_sanity_eventhandler[eventmask] = "bb.event.SanityCheck"
43
44python sota_check_sanity_eventhandler() {
45 if bb.event.getName(e) == "SanityCheck":
46 sanity_data = copy_data(e)
47 if e.generateevents:
48 sanity_data.setVar("SANITY_USE_EVENTS", "1")
49 reparse = sota_check_sanity(sanity_data)
50 e.data.setVar("BB_INVALIDCONF", reparse)
51 bb.event.fire(bb.event.SanityCheckPassed(), e.data)
52
53 return
54}