[[meta-swupdate] PATCH 0/9] Refactorize classes and introduce swupdate-image

108 views
Skip to first unread message

Stefano Babic

unread,
Aug 26, 2021, 7:34:20 AM8/26/21
to swup...@googlegroups.com, Stefano Babic

It was discussed on the ML (see : "Extend swupdate class to support swu image fstype")
how to build the SWU directly in the image recipe. Adding a SWU tls IMAGE_FSTYPE led to incompatibilities
and was rejected. This does not change the original logic that can be used again and
guarantees more flexibility, but introduce a simplified class `swupdate-image` that
generates a SWU after the image is generated.

To be used, add in your recipe something like these two lines:

inherit swupdate-image

SWUPDATE_IMAGE_FSTYPES[<your image] = "<format to be packed into SWU"

Stefano Babic (9):
Factorize setup in the common class
swupdate-common: change logic to add sha256
swupdate-common: autoversion should use SWUPDATE_IMAGES
swupdate-common: drop obsolete swupdate_is_hash_needed
swupdate-common: use own deploy for do_swuimage
swupdate-common: drop source parm from prepare-sw-description
swupdate-common: enable do_fetch with SWU generation
swupdate-common: split do_swuimage in smaller function
Create a class to generate SWU from image

classes/swupdate-common.bbclass | 180 ++++++++++++++++++++++++++++----
classes/swupdate-image.bbclass | 35 +++++++
classes/swupdate.bbclass | 117 +--------------------
3 files changed, 198 insertions(+), 134 deletions(-)
create mode 100644 classes/swupdate-image.bbclass

--
2.25.1

Stefano Babic

unread,
Aug 26, 2021, 7:34:21 AM8/26/21
to swup...@googlegroups.com, Stefano Babic
Instead of setting hash just for files going into SWU, scans
sw-description for any occurencies of sha256 attribute.

Signed-off-by: Stefano Babic <sba...@denx.de>
---
classes/swupdate-common.bbclass | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
index 0c08ca9..c95511f 100644
--- a/classes/swupdate-common.bbclass
+++ b/classes/swupdate-common.bbclass
@@ -74,12 +74,20 @@ def swupdate_encrypt_file(f, out, key, ivt):
encargs += ["-K", key, "-iv", ivt, "-nosalt"]
subprocess.run(encargs, check=True)

-def swupdate_write_sha256(s, filename, hash):
+def swupdate_write_sha256(s):
+ import re
write_lines = []
-
with open(os.path.join(s, "sw-description"), 'r') as f:
- for line in f:
- write_lines.append(line.replace("@%s" % (filename), hash))
+ for line in f:
+ shastr = r"sha256.+=.+@(.+\")"
+ #m = re.match(r"^(?P<before_placeholder>.+)sha256.+=.+(?P<filename>\w+)", line)
+ m = re.match(r"^(?P<before_placeholder>.+)sha256.+=.+(?P<quote>[\'\"])@(?P<filename>.*)(?P=quote)", line)
+ if m:
+ filename = m.group('filename')
+ hash = swupdate_get_sha256(s, filename)
+ write_lines.append(line.replace("@%s" % (filename), hash))
+ else:
+ write_lines.append(line)

with open(os.path.join(s, "sw-description"), 'w+') as f:
for line in write_lines:
@@ -192,10 +200,7 @@ def prepare_sw_description(d, s, list_for_cpio):
swupdate_expand_bitbake_variables(d, s)
swupdate_expand_auto_versions(d, s, list_for_cpio)

- for file in list_for_cpio:
- if file != 'sw-description' and swupdate_is_hash_needed(s, file):
- hash = swupdate_get_sha256(s, file)
- swupdate_write_sha256(s, file, hash)
+ swupdate_write_sha256(s)

encrypt = d.getVar('SWUPDATE_ENCRYPT_SWDESC', True)
if encrypt:
--
2.25.1

Stefano Babic

unread,
Aug 26, 2021, 7:34:22 AM8/26/21
to swup...@googlegroups.com, Stefano Babic
This is as preparation to introduce other classes in the layer.

Signed-off-by: Stefano Babic <sba...@denx.de>
---
classes/swupdate-common.bbclass | 117 ++++++++++++++++++++++++++++++++
classes/swupdate.bbclass | 117 +-------------------------------
2 files changed, 118 insertions(+), 116 deletions(-)

diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
index 8cfd11b..0c08ca9 100644
--- a/classes/swupdate-common.bbclass
+++ b/classes/swupdate-common.bbclass
@@ -1,3 +1,20 @@
+DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) else ''}"
+do_swuimage[umask] = "022"
+SSTATETASKS += "do_swuimage"
+SSTATE_SKIP_CREATION_task-swuimage = '1'
+IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
+
+do_swuimage[dirs] = "${TOPDIR}"
+do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
+do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
+do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
+do_swuimage[stamp-extra-info] = "${MACHINE}"
+
+python () {
+ deps = " " + swupdate_getdepends(d)
+ d.appendVarFlag('do_swuimage', 'depends', deps)
+}
+
def swupdate_is_hash_needed(s, filename):
with open(os.path.join(s, "sw-description"), 'r') as f:
for line in f:
@@ -5,6 +22,22 @@ def swupdate_is_hash_needed(s, filename):
return True
return False

+def swupdate_getdepends(d):
+ def adddep(depstr, deps):
+ for i in (depstr or "").split():
+ if i not in deps:
+ deps.append(i)
+
+ deps = []
+ images = (d.getVar('IMAGE_DEPENDS', True) or "").split()
+ for image in images:
+ adddep(image , deps)
+
+ depstr = ""
+ for dep in deps:
+ depstr += " " + dep + ":do_build"
+ return depstr
+
def swupdate_get_sha256(s, filename):
import hashlib

@@ -228,3 +261,87 @@ def prepare_sw_description(d, s, list_for_cpio):
bb.fatal("Failed to sign sw-description with %s" % (privkey))
else:
bb.fatal("Unrecognized SWUPDATE_SIGNING mechanism.");
+
+python do_swuimage () {
+ import shutil
+
+ workdir = d.getVar('WORKDIR', True)
+ images = (d.getVar('SWUPDATE_IMAGES', True) or "").split()
+ s = d.getVar('S', True)
+ shutil.copyfile(os.path.join(workdir, "sw-description"), os.path.join(s, "sw-description"))
+ fetch = bb.fetch2.Fetch([], d)
+ list_for_cpio = ["sw-description"]
+
+ if d.getVar('SWUPDATE_SIGNING', True):
+ list_for_cpio.append('sw-description.sig')
+
+ # Add files listed in SRC_URI to the swu file
+ for url in fetch.urls:
+ local = fetch.localpath(url)
+ filename = os.path.basename(local)
+ aes_file = d.getVar('SWUPDATE_AES_FILE', True)
+ if aes_file:
+ key,iv = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
+ if (filename != 'sw-description') and (os.path.isfile(local)):
+ encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", filename, True) or "")
+ dst = os.path.join(s, "%s" % filename )
+ if encrypted == '1':
+ bb.note("Encryption requested for %s" %(filename))
+ if not key or not iv:
+ bb.fatal("Encryption required, but no key found")
+ swupdate_encrypt_file(local, dst, key, iv)
+ else:
+ shutil.copyfile(local, dst)
+ list_for_cpio.append(filename)
+
+ def add_image_to_swu(deploydir, imagename, s, encrypt):
+ src = os.path.join(deploydir, imagename)
+ if not os.path.isfile(src):
+ return False
+ target_imagename = os.path.basename(imagename) # allow images in subfolders of DEPLOY_DIR_IMAGE
+ dst = os.path.join(s, target_imagename)
+ if encrypt == '1':
+ key,iv = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
+ bb.note("Encryption requested for %s" %(imagename))
+ swupdate_encrypt_file(src, dst, key, iv)
+ else:
+ shutil.copyfile(src, dst)
+ list_for_cpio.append(target_imagename)
+ return True
+
+ # Search for images listed in SWUPDATE_IMAGES in the DEPLOY directory.
+ deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
+ imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
+ for image in images:
+ fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) or "").split()
+ encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", image, True) or "")
+ if fstypes:
+ noappend_machine = d.getVarFlag("SWUPDATE_IMAGES_NOAPPEND_MACHINE", image, True)
+ if noappend_machine == "0": # Search for a file explicitly with MACHINE
+ imagebases = [ image + '-' + d.getVar('MACHINE', True) ]
+ elif noappend_machine == "1": # Search for a file explicitly without MACHINE
+ imagebases = [ image ]
+ else: # None, means auto mode. Just try to find an image file with MACHINE or without MACHINE
+ imagebases = [ image + '-' + d.getVar('MACHINE', True), image ]
+ for fstype in fstypes:
+ image_found = False
+ for imagebase in imagebases:
+ image_found = add_image_to_swu(deploydir, imagebase + fstype, s, encrypted)
+ if image_found:
+ break
+ if not image_found:
+ bb.fatal("swupdate cannot find image file: %s" % os.path.join(deploydir, imagebase + fstype))
+ else: # Allow also complete entries like "image.ext4.gz" in SWUPDATE_IMAGES
+ if not add_image_to_swu(deploydir, image, s, encrypted):
+ bb.fatal("swupdate cannot find %s image file" % image)
+
+ prepare_sw_description(d, s, list_for_cpio)
+
+ line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc >' + os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
+ os.system("cd " + s + ";" + line)
+
+ line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + d.getVar('IMAGE_LINK_NAME', True) + '.swu'
+ os.system("cd " + imgdeploydir + "; " + line)
+}
+
+
diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
index f2f50e7..44542d9 100644
--- a/classes/swupdate.bbclass
+++ b/classes/swupdate.bbclass
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 Stefano Babic <sba...@denx.de>
+# Copyright (C) 2015-2021 Stefano Babic <sba...@denx.de>
#
# Some parts from the patch class
#
@@ -36,36 +36,8 @@ inherit image-artifact-names

S = "${WORKDIR}/${PN}"

-DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) else ''}"
IMAGE_DEPENDS ?= ""

-def swupdate_getdepends(d):
- def adddep(depstr, deps):
- for i in (depstr or "").split():
- if i not in deps:
- deps.append(i)
-
- deps = []
- images = (d.getVar('IMAGE_DEPENDS', True) or "").split()
- for image in images:
- adddep(image , deps)
-
- depstr = ""
- for dep in deps:
- depstr += " " + dep + ":do_build"
- return depstr
-
-IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
-
-do_swuimage[dirs] = "${TOPDIR}"
-do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
-do_swuimage[umask] = "022"
-SSTATETASKS += "do_swuimage"
-SSTATE_SKIP_CREATION_task-swuimage = '1'
-do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
-do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
-do_swuimage[stamp-extra-info] = "${MACHINE}"
-
do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install[noexec] = "1"
@@ -77,93 +49,6 @@ do_package_write_ipk[noexec] = "1"
do_package_write_deb[noexec] = "1"
do_package_write_rpm[noexec] = "1"

-python () {
- deps = " " + swupdate_getdepends(d)
- d.appendVarFlag('do_swuimage', 'depends', deps)
-}
-
-python do_swuimage () {
- import shutil
-
- workdir = d.getVar('WORKDIR', True)
- images = (d.getVar('SWUPDATE_IMAGES', True) or "").split()
- s = d.getVar('S', True)
- shutil.copyfile(os.path.join(workdir, "sw-description"), os.path.join(s, "sw-description"))
- fetch = bb.fetch2.Fetch([], d)
- list_for_cpio = ["sw-description"]
-
- if d.getVar('SWUPDATE_SIGNING', True):
- list_for_cpio.append('sw-description.sig')
-
- # Add files listed in SRC_URI to the swu file
- for url in fetch.urls:
- local = fetch.localpath(url)
- filename = os.path.basename(local)
- aes_file = d.getVar('SWUPDATE_AES_FILE', True)
- if aes_file:
- key,iv = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
- if (filename != 'sw-description') and (os.path.isfile(local)):
- encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", filename, True) or "")
- dst = os.path.join(s, "%s" % filename )
- if encrypted == '1':
- bb.note("Encryption requested for %s" %(filename))
- if not key or not iv:
- bb.fatal("Encryption required, but no key found")
- swupdate_encrypt_file(local, dst, key, iv)
- else:
- shutil.copyfile(local, dst)
- list_for_cpio.append(filename)
-
- def add_image_to_swu(deploydir, imagename, s, encrypt):
- src = os.path.join(deploydir, imagename)
- if not os.path.isfile(src):
- return False
- target_imagename = os.path.basename(imagename) # allow images in subfolders of DEPLOY_DIR_IMAGE
- dst = os.path.join(s, target_imagename)
- if encrypt == '1':
- key,iv = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
- bb.note("Encryption requested for %s" %(imagename))
- swupdate_encrypt_file(src, dst, key, iv)
- else:
- shutil.copyfile(src, dst)
- list_for_cpio.append(target_imagename)
- return True
-
- # Search for images listed in SWUPDATE_IMAGES in the DEPLOY directory.
- deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
- imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
- for image in images:
- fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) or "").split()
- encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", image, True) or "")
- if fstypes:
- noappend_machine = d.getVarFlag("SWUPDATE_IMAGES_NOAPPEND_MACHINE", image, True)
- if noappend_machine == "0": # Search for a file explicitly with MACHINE
- imagebases = [ image + '-' + d.getVar('MACHINE', True) ]
- elif noappend_machine == "1": # Search for a file explicitly without MACHINE
- imagebases = [ image ]
- else: # None, means auto mode. Just try to find an image file with MACHINE or without MACHINE
- imagebases = [ image + '-' + d.getVar('MACHINE', True), image ]
- for fstype in fstypes:
- image_found = False
- for imagebase in imagebases:
- image_found = add_image_to_swu(deploydir, imagebase + fstype, s, encrypted)
- if image_found:
- break
- if not image_found:
- bb.fatal("swupdate cannot find image file: %s" % os.path.join(deploydir, imagebase + fstype))
- else: # Allow also complete entries like "image.ext4.gz" in SWUPDATE_IMAGES
- if not add_image_to_swu(deploydir, image, s, encrypted):
- bb.fatal("swupdate cannot find %s image file" % image)
-
- prepare_sw_description(d, s, list_for_cpio)
-
- line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc >' + os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
- os.system("cd " + s + ";" + line)
-
- line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + d.getVar('IMAGE_LINK_NAME', True) + '.swu'
- os.system("cd " + imgdeploydir + "; " + line)
-}
-
COMPRESSIONTYPES = ""
PACKAGE_ARCH = "${MACHINE_ARCH}"

--
2.25.1

Stefano Babic

unread,
Aug 26, 2021, 7:34:23 AM8/26/21
to swup...@googlegroups.com, Stefano Babic
Autoversion tries to get the name of packages from the list of files for
the CPIO archive, while the list of packages is already set in the
SWUPDATE_IMAGES variable.

Signed-off-by: Stefano Babic <sba...@denx.de>
---
classes/swupdate-common.bbclass | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
index c95511f..1467b74 100644
--- a/classes/swupdate-common.bbclass
+++ b/classes/swupdate-common.bbclass
@@ -129,7 +129,7 @@ def swupdate_expand_bitbake_variables(d, s):
for line in write_lines:
f.write(line)

-def swupdate_expand_auto_versions(d, s, list_for_cpio):
+def swupdate_expand_auto_versions(d, s):
import re
import oe.packagedata
AUTO_VERSION_TAG = "@SWU_AUTO_VERSION"
@@ -169,7 +169,7 @@ def swupdate_expand_auto_versions(d, s, list_for_cpio):

group = data[m.start():m.end()]

- (package, pkg_name_defined) = get_package_name(group, list_for_cpio)
+ (package, pkg_name_defined) = get_package_name(group, (d.getVar('SWUPDATE_IMAGES', True) or "").split())

pkg_info = os.path.join(d.getVar('PKGDATA_DIR'), 'runtime-reverse', package)
pkgdata = oe.packagedata.read_pkgdatafile(pkg_info)
@@ -194,11 +194,11 @@ def swupdate_expand_auto_versions(d, s, list_for_cpio):
with open(os.path.join(s, "sw-description"), 'w+') as f:
f.write(data)

-def prepare_sw_description(d, s, list_for_cpio):
+def prepare_sw_description(d, s):
import shutil

swupdate_expand_bitbake_variables(d, s)
- swupdate_expand_auto_versions(d, s, list_for_cpio)
+ swupdate_expand_auto_versions(d, s)

swupdate_write_sha256(s)

@@ -340,7 +340,7 @@ python do_swuimage () {
if not add_image_to_swu(deploydir, image, s, encrypted):
bb.fatal("swupdate cannot find %s image file" % image)

- prepare_sw_description(d, s, list_for_cpio)
+ prepare_sw_description(d, s)

line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc >' + os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
os.system("cd " + s + ";" + line)
--
2.25.1

Stefano Babic

unread,
Aug 26, 2021, 7:34:24 AM8/26/21
to swup...@googlegroups.com, Stefano Babic
Signed-off-by: Stefano Babic <sba...@denx.de>
---
classes/swupdate-common.bbclass | 9 ---------
1 file changed, 9 deletions(-)

diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
index 1467b74..c584dae 100644
--- a/classes/swupdate-common.bbclass
+++ b/classes/swupdate-common.bbclass
@@ -15,13 +15,6 @@ python () {
d.appendVarFlag('do_swuimage', 'depends', deps)
}

-def swupdate_is_hash_needed(s, filename):
- with open(os.path.join(s, "sw-description"), 'r') as f:
- for line in f:
- if line.find("@%s" % (filename)) != -1:
- return True
- return False
-
def swupdate_getdepends(d):
def adddep(depstr, deps):
for i in (depstr or "").split():
@@ -348,5 +341,3 @@ python do_swuimage () {
line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + d.getVar('IMAGE_LINK_NAME', True) + '.swu'
os.system("cd " + imgdeploydir + "; " + line)
}
-
-
--
2.25.1

Stefano Babic

unread,
Aug 26, 2021, 7:34:26 AM8/26/21
to swup...@googlegroups.com, Stefano Babic
IMGDEPLOYDIR is also used by image recipes, so set a different variable
to avoid conflicts.

Signed-off-by: Stefano Babic <sba...@denx.de>
---
classes/swupdate-common.bbclass | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
index c584dae..e5089f6 100644
--- a/classes/swupdate-common.bbclass
+++ b/classes/swupdate-common.bbclass
@@ -1,12 +1,16 @@
-DEPENDS += "${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) else ''}"
+DEPENDS += "\
+ cpio-native \
+ ${@ 'openssl-native' if d.getVar('SWUPDATE_SIGNING', True) else ''} \
+"
+
do_swuimage[umask] = "022"
SSTATETASKS += "do_swuimage"
SSTATE_SKIP_CREATION_task-swuimage = '1'
-IMGDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"
+SWUDEPLOYDIR = "${WORKDIR}/deploy-${PN}-swuimage"

-do_swuimage[dirs] = "${TOPDIR}"
-do_swuimage[cleandirs] += "${S} ${IMGDEPLOYDIR}"
-do_swuimage[sstate-inputdirs] = "${IMGDEPLOYDIR}"
+do_swuimage[dirs] = "${SWUDEPLOYDIR}"
+do_swuimage[cleandirs] += "${SWUDEPLOYDIR}"
+do_swuimage[sstate-inputdirs] = "${SWUDEPLOYDIR}"
do_swuimage[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
do_swuimage[stamp-extra-info] = "${MACHINE}"

@@ -309,7 +313,7 @@ python do_swuimage () {

# Search for images listed in SWUPDATE_IMAGES in the DEPLOY directory.
deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
- imgdeploydir = d.getVar('IMGDEPLOYDIR', True)
+ imgdeploydir = d.getVar('SWUDEPLOYDIR', True)
for image in images:
fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) or "").split()
encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", image, True) or "")
--
2.25.1

Stefano Babic

unread,
Aug 26, 2021, 7:34:26 AM8/26/21
to swup...@googlegroups.com, Stefano Babic
Value can be easier extracted by reading from database.

Signed-off-by: Stefano Babic <sba...@denx.de>
---
classes/swupdate-common.bbclass | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
index e5089f6..59c186e 100644
--- a/classes/swupdate-common.bbclass
+++ b/classes/swupdate-common.bbclass
@@ -191,9 +191,10 @@ def swupdate_expand_auto_versions(d, s):
with open(os.path.join(s, "sw-description"), 'w+') as f:
f.write(data)

-def prepare_sw_description(d, s):
+def prepare_sw_description(d):
import shutil

+ s = d.getVar('S', True)
swupdate_expand_bitbake_variables(d, s)
swupdate_expand_auto_versions(d, s)

@@ -337,7 +338,7 @@ python do_swuimage () {
if not add_image_to_swu(deploydir, image, s, encrypted):
bb.fatal("swupdate cannot find %s image file" % image)

- prepare_sw_description(d, s)
+ prepare_sw_description(d)

Stefano Babic

unread,
Aug 26, 2021, 7:34:29 AM8/26/21
to swup...@googlegroups.com, Stefano Babic
The metafile sw-description must be provided to generate a SWU, and this
is done via SRC_URI. Be sure then that do_fetch is executed by deleting
the noexec flag.

Signed-off-by: Stefano Babic <sba...@denx.de>
---
classes/swupdate-common.bbclass | 2 ++
1 file changed, 2 insertions(+)

diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
index 59c186e..99b683a 100644
--- a/classes/swupdate-common.bbclass
+++ b/classes/swupdate-common.bbclass
@@ -17,6 +17,8 @@ do_swuimage[stamp-extra-info] = "${MACHINE}"
python () {
deps = " " + swupdate_getdepends(d)
d.appendVarFlag('do_swuimage', 'depends', deps)
+ d.delVarFlag('do_fetch', 'noexec')
+ d.delVarFlag('do_unpack', 'noexec')
}

def swupdate_getdepends(d):
--
2.25.1

Stefano Babic

unread,
Aug 26, 2021, 7:34:29 AM8/26/21
to swup...@googlegroups.com, Stefano Babic
Split do_swuimage in smaller functions, easier to understand and to
maintain.

Signed-off-by: Stefano Babic <sba...@denx.de>
---
classes/swupdate-common.bbclass | 78 +++++++++++++++++++++------------
1 file changed, 51 insertions(+), 27 deletions(-)

diff --git a/classes/swupdate-common.bbclass b/classes/swupdate-common.bbclass
index 99b683a..cbd86ca 100644
--- a/classes/swupdate-common.bbclass
+++ b/classes/swupdate-common.bbclass
@@ -267,18 +267,15 @@ def prepare_sw_description(d):
else:
bb.fatal("Unrecognized SWUPDATE_SIGNING mechanism.");

-python do_swuimage () {
+
+def swupdate_add_src_uri(d, list_for_cpio):
import shutil

- workdir = d.getVar('WORKDIR', True)
- images = (d.getVar('SWUPDATE_IMAGES', True) or "").split()
s = d.getVar('S', True)
- shutil.copyfile(os.path.join(workdir, "sw-description"), os.path.join(s, "sw-description"))
- fetch = bb.fetch2.Fetch([], d)
- list_for_cpio = ["sw-description"]

if d.getVar('SWUPDATE_SIGNING', True):
list_for_cpio.append('sw-description.sig')
+ fetch = bb.fetch2.Fetch([], d)

# Add files listed in SRC_URI to the swu file
for url in fetch.urls:
@@ -299,24 +296,30 @@ python do_swuimage () {
shutil.copyfile(local, dst)
list_for_cpio.append(filename)

- def add_image_to_swu(deploydir, imagename, s, encrypt):
- src = os.path.join(deploydir, imagename)
- if not os.path.isfile(src):
- return False
- target_imagename = os.path.basename(imagename) # allow images in subfolders of DEPLOY_DIR_IMAGE
- dst = os.path.join(s, target_imagename)
- if encrypt == '1':
- key,iv = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
- bb.note("Encryption requested for %s" %(imagename))
- swupdate_encrypt_file(src, dst, key, iv)
- else:
- shutil.copyfile(src, dst)
- list_for_cpio.append(target_imagename)
- return True
+def add_image_to_swu(deploydir, imagename, s, encrypt, list_for_cpio):
+ import shutil

+ src = os.path.join(deploydir, imagename)
+ if not os.path.isfile(src):
+ return False
+ target_imagename = os.path.basename(imagename) # allow images in subfolders of DEPLOY_DIR_IMAGE
+ dst = os.path.join(s, target_imagename)
+ if encrypt == '1':
+ key,iv = swupdate_extract_keys(d.getVar('SWUPDATE_AES_FILE', True))
+ bb.note("Encryption requested for %s" %(imagename))
+ swupdate_encrypt_file(src, dst, key, iv)
+ else:
+ shutil.copyfile(src, dst)
+ list_for_cpio.append(target_imagename)
+ return True
+
+def swupdate_add_artifacts(d, list_for_cpio):
+ import shutil
# Search for images listed in SWUPDATE_IMAGES in the DEPLOY directory.
+ images = (d.getVar('SWUPDATE_IMAGES', True) or "").split()
deploydir = d.getVar('DEPLOY_DIR_IMAGE', True)
imgdeploydir = d.getVar('SWUDEPLOYDIR', True)
+ s = d.getVar('S', True)
for image in images:
fstypes = (d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image, True) or "").split()
encrypted = (d.getVarFlag("SWUPDATE_IMAGES_ENCRYPTED", image, True) or "")
@@ -331,20 +334,41 @@ python do_swuimage () {
for fstype in fstypes:
image_found = False
for imagebase in imagebases:
- image_found = add_image_to_swu(deploydir, imagebase + fstype, s, encrypted)
+ image_found = add_image_to_swu(deploydir, imagebase + fstype, s, encrypted, list_for_cpio)
if image_found:
break
if not image_found:
bb.fatal("swupdate cannot find image file: %s" % os.path.join(deploydir, imagebase + fstype))
else: # Allow also complete entries like "image.ext4.gz" in SWUPDATE_IMAGES
- if not add_image_to_swu(deploydir, image, s, encrypted):
+ if not add_image_to_swu(deploydir, image, s, encrypted, list_for_cpio):
bb.fatal("swupdate cannot find %s image file" % image)

- prepare_sw_description(d)

- line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc >' + os.path.join(imgdeploydir,d.getVar('IMAGE_NAME', True) + '.swu')
- os.system("cd " + s + ";" + line)
+def swupdate_create_cpio(d, swudeploydir, list_for_cpio):
+ s = d.getVar('S', True)
+ os.chdir(s)
+ updateimage = d.getVar('IMAGE_NAME', True) + '.swu'
+ updateimage_link = d.getVar('IMAGE_LINK_NAME', True) + '.swu'
+ line = 'for i in ' + ' '.join(list_for_cpio) + '; do echo $i;done | cpio -ov -H crc > ' + os.path.join(swudeploydir, updateimage)
+ os.system(line)
+ os.chdir(swudeploydir)
+ os.symlink(updateimage, updateimage_link)
+
+python do_swuimage () {
+ import shutil
+
+ list_for_cpio = ["sw-description"]
+ workdir = d.getVar('WORKDIR', True)
+ s = d.getVar('S', True)
+ imgdeploydir = d.getVar('SWUDEPLOYDIR', True)
+ shutil.copyfile(os.path.join(workdir, "sw-description"), os.path.join(s, "sw-description"))
+
+ # Add artifacts added via SRC_URI
+ swupdate_add_src_uri(d, list_for_cpio)
+ # Add artifacts set via SWUPDATE_IMAGES
+ swupdate_add_artifacts(d, list_for_cpio)
+
+ prepare_sw_description(d)

- line = 'ln -sf ' + d.getVar('IMAGE_NAME', True) + '.swu ' + d.getVar('IMAGE_LINK_NAME', True) + '.swu'
- os.system("cd " + imgdeploydir + "; " + line)
+ swupdate_create_cpio(d, imgdeploydir, list_for_cpio)
}
--
2.25.1

Stefano Babic

unread,
Aug 26, 2021, 7:34:31 AM8/26/21
to swup...@googlegroups.com, Stefano Babic
It is currently required a separate recipe to build the SWU from an
image. This is very flexible but it appears overkilling in use cases
where the only artifact is the rootfs. Create a separate class that can
be inherited replacing swupdate.bbclass and that build a SWU from an
image recipe.

Signed-off-by: Stefano Babic <sba...@denx.de>
---
classes/swupdate-image.bbclass | 35 ++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 classes/swupdate-image.bbclass

diff --git a/classes/swupdate-image.bbclass b/classes/swupdate-image.bbclass
new file mode 100644
index 0000000..54d121f
--- /dev/null
+++ b/classes/swupdate-image.bbclass
@@ -0,0 +1,35 @@
+# Copyright (C) 2015-2021 Stefano Babic <sba...@denx.de>
+#
+# This class is thought to be used in an image recipe.
+# It generates a SWU file from the image itself
+# User *must* add a sw-descitpion file
+#
+# To use this class, add the inherit clause of the update image bb file.
+# The generated output file is an swu archive ready to be uploaded to a device running
+# swupdate.
+
+inherit swupdate-common.bbclass
+inherit image-artifact-names
+
+S = "${WORKDIR}/${PN}"
+
+SRC_URI += "file://sw-description"
+SWUPDATE_IMAGES += "${IMAGE_BASENAME}"
+
+python do_swupdate_copy_swdescription() {
+
+ import shutil
+
+ workdir = d.getVar('S', True)
+ image = d.getVar('IMAGE_BASENAME', True)
+ filespath = d.getVar('FILESPATH')
+ sw_desc_path = bb.utils.which(filespath, "sw-description")
+ shutil.copyfile(sw_desc_path, os.path.join(workdir, "sw-description"))
+
+ if d.getVarFlag("SWUPDATE_IMAGES_FSTYPES", image) is None:
+ bb.fatal("SWUPDATE_IMAGES_FSTYPES[%s] is not set !" % image)
+}
+
+do_swupdate_copy_swdescription[nostamp] = "1"
+addtask swupdate_copy_swdescription before do_image_complete after do_unpack
+addtask swuimage after do_swupdate_copy_swdescription do_image_complete before do_build
--
2.25.1

Reply all
Reply to author
Forward
0 new messages