From 5beb7ebe843ae4225499c1d2f9ebfebb27698cb8 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 2 Jan 2019 18:53:39 +0200 Subject: libsodium: Support building it natively Add support to build libsodium-native as it will be required for building a newer version of aktualizr-native. Signed-off-by: Leon Anavi --- recipes-crypto/libsodium/libsodium_1.%.bbappend | 1 + 1 file changed, 1 insertion(+) create mode 100644 recipes-crypto/libsodium/libsodium_1.%.bbappend diff --git a/recipes-crypto/libsodium/libsodium_1.%.bbappend b/recipes-crypto/libsodium/libsodium_1.%.bbappend new file mode 100644 index 0000000..608377e --- /dev/null +++ b/recipes-crypto/libsodium/libsodium_1.%.bbappend @@ -0,0 +1 @@ +BBCLASSEXTEND = "native nativesdk" -- cgit v1.2.3-54-g00ecf From 891b967bc74ec8873081d019eda8bbfbb2bc52b7 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 2 Jan 2019 18:56:35 +0200 Subject: asn1c: Backporting from branch Sumo Backport asn1c from branch Sumo because the latest version of Aktualizr depends on it. Signed-off-by: Leon Anavi --- recipes-sota/asn1c/asn1c.bb | 17 +++++++++ recipes-sota/asn1c/files/skeletons_dir_fix.patch | 44 ++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 recipes-sota/asn1c/asn1c.bb create mode 100644 recipes-sota/asn1c/files/skeletons_dir_fix.patch diff --git a/recipes-sota/asn1c/asn1c.bb b/recipes-sota/asn1c/asn1c.bb new file mode 100644 index 0000000..9d1517d --- /dev/null +++ b/recipes-sota/asn1c/asn1c.bb @@ -0,0 +1,17 @@ +SUMMARY = "ASN.1 to C compiler" +DESCRIPTION = "Generates serialization routines from ASN.1 schemas" +HOMEPAGE = "http://lionet.info/asn1c" +SECTION = "base" +LICENSE = "BSD" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ee8bfaaa7d71cf3edb079475e6716d4b" + +inherit autotools native + +PV = "0.9.28" +SRC_URI = "https://github.com/vlm/asn1c/releases/download/v${PV}/asn1c-${PV}.tar.gz \ + file://skeletons_dir_fix.patch" +SRC_URI[sha256sum] = "8007440b647ef2dd9fb73d931c33ac11764e6afb2437dbe638bb4e5fc82386b9" + +BBCLASSEXTEND = "native nativesdk" + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/recipes-sota/asn1c/files/skeletons_dir_fix.patch b/recipes-sota/asn1c/files/skeletons_dir_fix.patch new file mode 100644 index 0000000..f1caa2f --- /dev/null +++ b/recipes-sota/asn1c/files/skeletons_dir_fix.patch @@ -0,0 +1,44 @@ +From 1a1c2c94f700cf0f4dc5dba863950b16477fdc6d Mon Sep 17 00:00:00 2001 +From: Laurent Bonnans +Date: Thu, 25 Jan 2018 09:49:41 +0100 +Subject: [PATCH] Patch the skeletons directory detection + +Detect `share/asn1c` from `bin/` if it exists +--- + asn1c/asn1c.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/asn1c/asn1c.c b/asn1c/asn1c.c +index eb1eff7c..dd9fc832 100644 +--- a/asn1c/asn1c.c ++++ b/asn1c/asn1c.c +@@ -226,22 +226,21 @@ main(int ac, char **av) { + if(skeletons_dir == NULL) { + struct stat sb; + skeletons_dir = DATADIR; +- if((av[-optind][0] == '.' || av[-optind][1] == '/') +- && stat(skeletons_dir, &sb)) { ++ if(stat(skeletons_dir, &sb)) { + /* + * The default skeletons directory does not exist, + * compute it from my file name: +- * ./asn1c/asn1c -> ./skeletons ++ * ./asn1c/asn1c -> ./share/asn1c + */ + char *p; + size_t len; + + p = a1c_dirname(av[-optind]); + +- len = strlen(p) + sizeof("/../skeletons"); ++ len = strlen(p) + sizeof("/../share/asn1c"); + skeletons_dir = malloc(len); + assert(skeletons_dir); +- snprintf(skeletons_dir, len, "%s/../skeletons", p); ++ snprintf(skeletons_dir, len, "%s/../share/asn1c", p); + if(stat(skeletons_dir, &sb)) { + fprintf(stderr, + "WARNING: skeletons are neither in " +-- +2.15.1 + -- cgit v1.2.3-54-g00ecf From f937a223136ec2e1f7699dd6621539aca950d633 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 2 Jan 2019 18:59:00 +0200 Subject: ostree: Bump to v2018.7 Upgrade ostree version from v2017.3 to v2018.7 because this version is known to work with the latest version of Aktualizr. Signed-off-by: Leon Anavi --- recipes-sota/ostree/ostree_git.bb | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/recipes-sota/ostree/ostree_git.bb b/recipes-sota/ostree/ostree_git.bb index 8937e5e..a5cdc9a 100644 --- a/recipes-sota/ostree/ostree_git.bb +++ b/recipes-sota/ostree/ostree_git.bb @@ -2,15 +2,15 @@ SUMMARY = "Tool for managing bootable, immutable, versioned filesystem trees" LICENSE = "GPLv2+" LIC_FILES_CHKSUM = "file://COPYING;md5=5f30f0716dfdd0d91eb439ebec522ec2" -inherit autotools-brokensep pkgconfig systemd gobject-introspection +inherit autotools-brokensep pkgconfig systemd bash-completion gobject-introspection INHERIT_remove_class-native = "systemd" SRC_URI = "gitsm://github.com/ostreedev/ostree.git;branch=master" -SRCREV="3b09620c2738bce4ed45e099cf2e4c5df7671d39" +SRCREV="3e96ec9811b5cfc5481f8b6b06c8d34d9a35408e" -PV = "2017.3-31-g3b09620c" +PV = "v2018.7" S = "${WORKDIR}/git" @@ -22,6 +22,7 @@ DEPENDS_remove_class-native = "systemd-native" RDEPENDS_${PN} = "python util-linux-libuuid util-linux-libblkid util-linux-libmount libcap bash" RDEPENDS_${PN}_remove_class-native = "python-native" +RDEPENDS_${PN}-dracut = "bash" EXTRA_OECONF = "--with-libarchive --disable-gtk-doc --disable-gtk-doc-html --disable-gtk-doc-pdf --disable-man --with-smack --with-builtin-grub2-mkconfig --with-curl" EXTRA_OECONF_append_class-native = " --enable-wrpseudo-compat" @@ -58,6 +59,8 @@ do_compile_prepend() { export HOST_SYS="${HOST_SYS}" } +SYSTEMD_SERVICE_${PN} = "ostree-prepare-root.service ostree-remount.service ostree-finalize-staged.service" + export SYSTEMD_REQUIRED do_install_append() { @@ -73,17 +76,24 @@ do_install_append_class-native() { FILES_${PN} += " \ - ${@'${systemd_unitdir}/system/' if d.getVar('SYSTEMD_REQUIRED', True) else ''} \ - ${@'${libdir}/dracut/modules.d/98ostree/module-setup.sh' if d.getVar('SYSTEMD_REQUIRED', True) else ''} \ - ${datadir}/gir-1.0 \ - ${datadir}/gir-1.0/OSTree-1.0.gir \ - ${libdir}/girepository-1.0 \ - ${libdir}/girepository-1.0/OSTree-1.0.typelib \ + {bindir} \ + ${sysconfdir}/ostree \ + ${datadir}/ostree \ + ${libdir}/*.so.* \ + ${libdir}/ostree/ostree-grub-generator \ + ${libdir}/ostree/ostree-remount \ + ${libdir}/girepository-1.0/* \ + ${@bb.utils.contains('DISTRO_FEATURES','systemd','${libdir}/tmpfiles.d', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES','systemd','${systemd_unitdir}/system-generators', '', d)} \ " -PACKAGES =+ "${PN}-switchroot" +PACKAGES =+ " \ + ${PN}-switchroot \ + ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'ostree-dracut', '', d)} \ +" FILES_${PN}-switchroot = "${libdir}/ostree/ostree-prepare-root" RDEPENDS_${PN}-switchroot = "" DEPENDS_remove_class-native = "systemd-native" - +FILES_${PN}-dev += " ${datadir}/gir-1.0" +FILES_${PN}-dracut = "${sysconfdir}/dracut.conf.d ${libdir}/dracut" -- cgit v1.2.3-54-g00ecf From dad9579e2c1333f3a72ff9a98e06705a61e546c1 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 2 Jan 2019 19:01:34 +0200 Subject: classes: Backporting classes from Sumo Backport SOTA specific classes needed for latest version of Aktualizr from branch Sumo to Morty. Signed-off-by: Leon Anavi --- classes/image_repo_manifest.bbclass | 23 ++ classes/image_types_ostree.bbclass | 411 +++++++++++++++++++++--------------- classes/image_types_ota.bbclass | 41 ++-- classes/sota.bbclass | 30 ++- 4 files changed, 313 insertions(+), 192 deletions(-) create mode 100644 classes/image_repo_manifest.bbclass diff --git a/classes/image_repo_manifest.bbclass b/classes/image_repo_manifest.bbclass new file mode 100644 index 0000000..c2e7056 --- /dev/null +++ b/classes/image_repo_manifest.bbclass @@ -0,0 +1,23 @@ +# Writes the repo manifest to the target filesystem in /etc/manifest.xml +# +# Author: Phil Wise +# Usage: add "inherit image_repo_manifest" to your image file +# To reproduce a build, copy the /etc/manifest.xml to .repo/manifests/yourname.xml +# then run: +# repo init -m yourname.xml +# repo sync +# For more information, see: +# https://web.archive.org/web/20161224194009/https://wiki.cyanogenmod.org/w/Doc:_Using_manifests + +HOSTTOOLS_NONFATAL += " repo " + +# Write build information to target filesystem +buildinfo_manifest () { + if [ $(which repo) ]; then + repo manifest --revision-as-HEAD -o ${IMAGE_ROOTFS}${sysconfdir}/manifest.xml || bbwarn "Android repo tool failed to run; manifest not copied" + else + bbwarn "Android repo tool not found; manifest not copied." + fi +} + +IMAGE_PREPROCESS_COMMAND += "buildinfo_manifest;" diff --git a/classes/image_types_ostree.bbclass b/classes/image_types_ostree.bbclass index 29f267d..0acc786 100644 --- a/classes/image_types_ostree.bbclass +++ b/classes/image_types_ostree.bbclass @@ -1,207 +1,274 @@ # OSTree deployment -inherit image - -IMAGE_DEPENDS_ostree = "ostree-native:do_populate_sysroot \ - openssl-native:do_populate_sysroot \ - zip-native:do_populate_sysroot \ - virtual/kernel:do_deploy \ - ${OSTREE_INITRAMFS_IMAGE}:do_image_complete" +do_image_ostree[depends] += "ostree-native:do_populate_sysroot \ + openssl-native:do_populate_sysroot \ + coreutils-native:do_populate_sysroot \ + unzip-native:do_populate_sysroot \ + virtual/kernel:do_deploy \ + ${OSTREE_INITRAMFS_IMAGE}:do_image_complete" +do_image_ostree[lockfiles] += "${OSTREE_REPO}/ostree.lock" export OSTREE_REPO export OSTREE_BRANCHNAME +export GARAGE_TARGET_NAME -RAMDISK_EXT ?= ".ext4.gz" -RAMDISK_EXT_arm ?= ".ext4.gz.u-boot" +RAMDISK_EXT ?= ".${OSTREE_INITRAMFS_FSTYPES}" OSTREE_KERNEL ??= "${KERNEL_IMAGETYPE}" -export SYSTEMD_USED = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', '', d)}" +OSTREE_COMMIT_SUBJECT ??= "Commit-id: ${IMAGE_NAME}" +OSTREE_COMMIT_BODY ??= "" +OSTREE_UPDATE_SUMMARY ??= "0" + +export SYSTEMD_USED = "${@oe.utils.ifelse(d.getVar('VIRTUAL-RUNTIME_init_manager', True) == 'systemd', 'true', '')}" IMAGE_CMD_ostree () { - if [ -z "$OSTREE_REPO" ]; then - bbfatal "OSTREE_REPO should be set in your local.conf" - fi - - if [ -z "$OSTREE_BRANCHNAME" ]; then - bbfatal "OSTREE_BRANCHNAME should be set in your local.conf" - fi - - OSTREE_ROOTFS=`mktemp -du ${WORKDIR}/ostree-root-XXXXX` - cp -a ${IMAGE_ROOTFS} ${OSTREE_ROOTFS} - chmod a+rx ${OSTREE_ROOTFS} - sync - - cd ${OSTREE_ROOTFS} - - # Create sysroot directory to which physical sysroot will be mounted - mkdir sysroot - ln -sf sysroot/ostree ostree - - rm -rf tmp/* - ln -sf sysroot/tmp tmp - - mkdir -p usr/rootdirs - - mv etc usr/ - # Implement UsrMove - dirs="bin sbin lib" - - for dir in ${dirs} ; do - if [ -d ${dir} ] && [ ! -L ${dir} ] ; then - mv ${dir} usr/rootdirs/ - rm -rf ${dir} - ln -sf usr/rootdirs/${dir} ${dir} - fi - done - - if [ -n "$SYSTEMD_USED" ]; then - mkdir -p usr/etc/tmpfiles.d - tmpfiles_conf=usr/etc/tmpfiles.d/00ostree-tmpfiles.conf - echo "d /var/rootdirs 0755 root root -" >>${tmpfiles_conf} - echo "L /var/rootdirs/home - - - - /sysroot/home" >>${tmpfiles_conf} - else - mkdir -p usr/etc/init.d - tmpfiles_conf=usr/etc/init.d/tmpfiles.sh - echo '#!/bin/sh' > ${tmpfiles_conf} - echo "mkdir -p /var/rootdirs; chmod 755 /var/rootdirs" >> ${tmpfiles_conf} - echo "ln -sf /sysroot/home /var/rootdirs/home" >> ${tmpfiles_conf} - - ln -s ../init.d/tmpfiles.sh usr/etc/rcS.d/S20tmpfiles.sh - fi - - # Preserve OSTREE_BRANCHNAME for future information - mkdir -p usr/share/sota/ - echo -n "${OSTREE_BRANCHNAME}" > usr/share/sota/branchname - - # Preserve data in /home to be later copied to /sysroot/home by - # sysroot generating procedure - mkdir -p usr/homedirs - if [ -d "home" ] && [ ! -L "home" ]; then - mv home usr/homedirs/home - ln -sf var/rootdirs/home home - fi - - # Move cron jobs if exist - if [ -d "var/spool/cron" ] && [ "$(ls -A var/spool/cron)" ] && - [ -d "usr/share/cronie-spool" ] ; then - mv var/spool/cron/* usr/share/cronie-spool/ + if [ -z "$OSTREE_REPO" ]; then + bbfatal "OSTREE_REPO should be set in your local.conf" fi - # Move persistent directories to /var - dirs="opt mnt media srv" - - for dir in ${dirs}; do - if [ -d ${dir} ] && [ ! -L ${dir} ]; then - if [ "$(ls -A $dir)" ]; then - bbwarn "Data in /$dir directory is not preserved by OSTree. Consider moving it under /usr" - fi - - if [ -n "$SYSTEMD_USED" ]; then - echo "d /var/rootdirs/${dir} 0755 root root -" >>${tmpfiles_conf} - else - echo "mkdir -p /var/rootdirs/${dir}; chown 755 /var/rootdirs/${dir}" >>${tmpfiles_conf} - fi - rm -rf ${dir} - ln -sf var/rootdirs/${dir} ${dir} - fi - done - - if [ -d root ] && [ ! -L root ]; then - if [ "$(ls -A root)" ]; then - bberror "Data in /root directory is not preserved by OSTree." - fi - - if [ -n "$SYSTEMD_USED" ]; then - echo "d /var/roothome 0755 root root -" >>${tmpfiles_conf} - else - echo "mkdir -p /var/roothome; chown 755 /var/roothome" >>${tmpfiles_conf} - fi - - rm -rf root - ln -sf var/roothome root - fi - - mkdir -p var/sota - - if [ -n "${SOTA_AUTOPROVISION_CREDENTIALS}" ]; then - bbwarn "SOTA_AUTOPROVISION_CREDENTIALS are ignored. Please use SOTA_PACKED_CREDENTIALS" + if [ -z "$OSTREE_BRANCHNAME" ]; then + bbfatal "OSTREE_BRANCHNAME should be set in your local.conf" fi - if [ -n "${SOTA_AUTOPROVISION_URL}" ]; then - bbwarn "SOTA_AUTOPROVISION_URL is ignored. Please use SOTA_PACKED_CREDENTIALS" + + OSTREE_ROOTFS=`mktemp -du ${WORKDIR}/ostree-root-XXXXX` + cp -a ${IMAGE_ROOTFS} ${OSTREE_ROOTFS} + chmod a+rx ${OSTREE_ROOTFS} + sync + + cd ${OSTREE_ROOTFS} + + for d in var/*; do + if [ "${d}" != "var/local" ]; then + rm -rf ${d} + fi + done + + # Create sysroot directory to which physical sysroot will be mounted + mkdir sysroot + ln -sf sysroot/ostree ostree + + rm -rf tmp/* + ln -sf sysroot/tmp tmp + + mkdir -p usr/rootdirs + + mv etc usr/ + # Implement UsrMove + dirs="bin sbin lib" + + for dir in ${dirs} ; do + if [ -d ${dir} ] && [ ! -L ${dir} ] ; then + mv ${dir} usr/rootdirs/ + rm -rf ${dir} + ln -sf usr/rootdirs/${dir} ${dir} + fi + done + + if [ -n "$SYSTEMD_USED" ]; then + mkdir -p usr/etc/tmpfiles.d + tmpfiles_conf=usr/etc/tmpfiles.d/00ostree-tmpfiles.conf + echo "d /var/rootdirs 0755 root root -" >>${tmpfiles_conf} + echo "L /var/rootdirs/home - - - - /sysroot/home" >>${tmpfiles_conf} + else + mkdir -p usr/etc/init.d + tmpfiles_conf=usr/etc/init.d/tmpfiles.sh + echo '#!/bin/sh' > ${tmpfiles_conf} + echo "mkdir -p /var/rootdirs; chmod 755 /var/rootdirs" >> ${tmpfiles_conf} + echo "ln -sf /sysroot/home /var/rootdirs/home" >> ${tmpfiles_conf} + + ln -s ../init.d/tmpfiles.sh usr/etc/rcS.d/S20tmpfiles.sh fi - if [ -n "${SOTA_AUTOPROVISION_URL_FILE}" ]; then - bbwarn "SOTA_AUTOPROVISION_URL_FILE is ignored. Please use SOTA_PACKED_CREDENTIALS" + + # Preserve OSTREE_BRANCHNAME for future information + mkdir -p usr/share/sota/ + echo -n "${OSTREE_BRANCHNAME}" > usr/share/sota/branchname + + # Preserve data in /home to be later copied to /sysroot/home by sysroot + # generating procedure + mkdir -p usr/homedirs + if [ -d "home" ] && [ ! -L "home" ]; then + mv home usr/homedirs/home + ln -sf var/rootdirs/home home fi - if [ -n "${OSTREE_PUSH_CREDENTIALS}" ]; then - bbwarn "OSTREE_PUSH_CREDENTIALS is ignored. Please use SOTA_PACKED_CREDENTIALS" + + # Move persistent directories to /var + dirs="opt mnt media srv" + + for dir in ${dirs}; do + if [ -d ${dir} ] && [ ! -L ${dir} ]; then + if [ "$(ls -A $dir)" ]; then + bbwarn "Data in /$dir directory is not preserved by OSTree. Consider moving it under /usr" + fi + + if [ -n "$SYSTEMD_USED" ]; then + echo "d /var/rootdirs/${dir} 0755 root root -" >>${tmpfiles_conf} + else + echo "mkdir -p /var/rootdirs/${dir}; chown 755 /var/rootdirs/${dir}" >>${tmpfiles_conf} + fi + rm -rf ${dir} + ln -sf var/rootdirs/${dir} ${dir} + fi + done + + if [ -d root ] && [ ! -L root ]; then + if [ "$(ls -A root)" ]; then + bberror "Data in /root directory is not preserved by OSTree." + exit 1 + fi + + if [ -n "$SYSTEMD_USED" ]; then + echo "d /var/roothome 0755 root root -" >>${tmpfiles_conf} + else + echo "mkdir -p /var/roothome; chown 755 /var/roothome" >>${tmpfiles_conf} + fi + + rm -rf root + ln -sf var/roothome root fi - # deploy SOTA credentials - if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then - if [ -e ${SOTA_PACKED_CREDENTIALS} ]; then - cp ${SOTA_PACKED_CREDENTIALS} var/sota/sota_provisioning_credentials.zip - # Device should not be able to push data to treehub - zip -d var/sota/sota_provisioning_credentials.zip treehub.json - fi - fi + # Creating boot directories is required for "ostree admin deploy" - if [ -n "${SOTA_SECONDARY_ECUS}" ]; then - cp ${SOTA_SECONDARY_ECUS} var/sota/ecus - fi + mkdir -p boot/loader.0 + mkdir -p boot/loader.1 + ln -sf boot/loader.0 boot/loader - # Creating boot directories is required for "ostree admin deploy" + checksum=`sha256sum ${DEPLOY_DIR_IMAGE}/${OSTREE_KERNEL} | cut -f 1 -d " "` - mkdir -p boot/loader.0 - mkdir -p boot/loader.1 - ln -sf boot/loader.0 boot/loader + cp ${DEPLOY_DIR_IMAGE}/${OSTREE_KERNEL} boot/vmlinuz-${checksum} + cp ${DEPLOY_DIR_IMAGE}/${OSTREE_INITRAMFS_IMAGE}-${MACHINE}${RAMDISK_EXT} boot/initramfs-${checksum} - checksum=`sha256sum ${DEPLOY_DIR_IMAGE}/${OSTREE_KERNEL} | cut -f 1 -d " "` + # Copy image manifest + cat ${IMAGE_MANIFEST} | cut -d " " -f1,3 > usr/package.manifest - cp ${DEPLOY_DIR_IMAGE}/${OSTREE_KERNEL} boot/vmlinuz-${checksum} - cp ${DEPLOY_DIR_IMAGE}/${OSTREE_INITRAMFS_IMAGE}-${MACHINE}${RAMDISK_EXT} boot/initramfs-${checksum} + cd ${WORKDIR} - # Copy image manifest - cat ${IMAGE_MANIFEST} | cut -d " " -f1,3 > usr/package.manifest + # Create a tarball that can be then commited to OSTree repo + OSTREE_TAR=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.ostree.tar.bz2 + tar -C ${OSTREE_ROOTFS} --xattrs --xattrs-include='*' -cjf ${OSTREE_TAR} . + sync - cd ${WORKDIR} + rm -f ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.rootfs.ostree.tar.bz2 + ln -s ${IMAGE_NAME}.rootfs.ostree.tar.bz2 ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.rootfs.ostree.tar.bz2 - # Create a tarball that can be then commited to OSTree repo - OSTREE_TAR=${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.rootfs.ostree.tar.bz2 - tar -C ${OSTREE_ROOTFS} --xattrs --xattrs-include='*' -cjf ${OSTREE_TAR} . - sync + if ! ostree --repo=${OSTREE_REPO} refs 2>&1 > /dev/null; then + ostree --repo=${OSTREE_REPO} init --mode=archive-z2 + fi - rm -f ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.rootfs.ostree.tar.bz2 - ln -s ${IMAGE_NAME}.rootfs.ostree.tar.bz2 ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.rootfs.ostree.tar.bz2 - - if [ ! -d ${OSTREE_REPO} ]; then - ostree --repo=${OSTREE_REPO} init --mode=archive-z2 - fi + # Commit the result + ostree --repo=${OSTREE_REPO} commit \ + --tree=dir=${OSTREE_ROOTFS} \ + --skip-if-unchanged \ + --branch=${OSTREE_BRANCHNAME} \ + --subject="${OSTREE_COMMIT_SUBJECT}" \ + --body="${OSTREE_COMMIT_BODY}" - # Commit the result - ostree --repo=${OSTREE_REPO} commit \ - --tree=dir=${OSTREE_ROOTFS} \ - --skip-if-unchanged \ - --branch=${OSTREE_BRANCHNAME} \ - --subject="Commit-id: ${IMAGE_NAME}" + if [ "${OSTREE_UPDATE_SUMMARY}" = "1" ]; then + ostree --repo=${OSTREE_REPO} summary -u + fi - rm -rf ${OSTREE_ROOTFS} + rm -rf ${OSTREE_ROOTFS} } IMAGE_TYPEDEP_ostreepush = "ostree" -IMAGE_DEPENDS_ostreepush = "sota-tools-native:do_populate_sysroot" +do_image_ostreepush[depends] += "aktualizr-native:do_populate_sysroot ca-certificates-native:do_populate_sysroot" IMAGE_CMD_ostreepush () { - # Print warnings if credetials are not set or if the file has not been found. - if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then - if [ -e ${SOTA_PACKED_CREDENTIALS} ]; then - garage-push --repo=${OSTREE_REPO} \ - --ref=${OSTREE_BRANCHNAME} \ - --credentials=${SOTA_PACKED_CREDENTIALS} \ - --cacert=${STAGING_ETCDIR_NATIVE}/ssl/certs/ca-certificates.crt - else - bbwarn "SOTA_PACKED_CREDENTIALS file does not exist." - fi + # Print warnings if credetials are not set or if the file has not been found. + if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then + if [ -e ${SOTA_PACKED_CREDENTIALS} ]; then + garage-push --repo=${OSTREE_REPO} \ + --ref=${OSTREE_BRANCHNAME} \ + --credentials=${SOTA_PACKED_CREDENTIALS} \ + --cacert=${STAGING_ETCDIR_NATIVE}/ssl/certs/ca-certificates.crt else - bbwarn "SOTA_PACKED_CREDENTIALS not set. Please add SOTA_PACKED_CREDENTIALS." - fi + bbwarn "SOTA_PACKED_CREDENTIALS file does not exist." + fi + else + bbwarn "SOTA_PACKED_CREDENTIALS not set. Please add SOTA_PACKED_CREDENTIALS." + fi +} + +IMAGE_TYPEDEP_garagesign = "ostreepush" +do_image_garagesign[depends] += "aktualizr-native:do_populate_sysroot" +IMAGE_CMD_garagesign () { + if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then + # if credentials are issued by a server that doesn't support offline signing, exit silently + unzip -p ${SOTA_PACKED_CREDENTIALS} root.json targets.pub targets.sec tufrepo.url 2>&1 >/dev/null || exit 0 + + java_version=$( java -version 2>&1 | awk -F '"' '/version/ {print $2}' ) + if [ "${java_version}" = "" ]; then + bberror "Java is required for synchronization with update backend, but is not installed on the host machine" + exit 1 + elif [ "${java_version}" \< "1.8" ]; then + bberror "Java version >= 8 is required for synchronization with update backend" + exit 1 + fi + + rm -rf ${GARAGE_SIGN_REPO} + garage-sign init --repo tufrepo \ + --home-dir ${GARAGE_SIGN_REPO} \ + --credentials ${SOTA_PACKED_CREDENTIALS} + + ostree_target_hash=$(cat ${OSTREE_REPO}/refs/heads/${OSTREE_BRANCHNAME}) + + # Use OSTree target hash as version if none was provided by the user + target_version=${ostree_target_hash} + if [ -n "${GARAGE_TARGET_VERSION}" ]; then + target_version=${GARAGE_TARGET_VERSION} + bbwarn "Target version is overriden with GARAGE_TARGET_VERSION variable. It is a dangerous operation, make sure you've read the respective secion in meta-updater/README.adoc" + elif [ -e "${STAGING_DATADIR_NATIVE}/target_version" ]; then + target_version=$(cat "${STAGING_DATADIR_NATIVE}/target_version") + bbwarn "Target version is overriden with target_version file. It is a dangerous operation, make sure you've read the respective secion in meta-updater/README.adoc" + fi + + # Push may fail due to race condition when multiple build machines try to push simultaneously + # in which case targets.json should be pulled again and the whole procedure repeated + push_success=0 + for push_retries in $( seq 3 ); do + garage-sign targets pull --repo tufrepo \ + --home-dir ${GARAGE_SIGN_REPO} + garage-sign targets add --repo tufrepo \ + --home-dir ${GARAGE_SIGN_REPO} \ + --name ${GARAGE_TARGET_NAME} \ + --format OSTREE \ + --version ${target_version} \ + --length 0 \ + --url "${GARAGE_TARGET_URL}" \ + --sha256 ${ostree_target_hash} \ + --hardwareids ${SOTA_HARDWARE_ID} + garage-sign targets sign --repo tufrepo \ + --home-dir ${GARAGE_SIGN_REPO} \ + --key-name=targets + errcode=0 + garage-sign targets push --repo tufrepo \ + --home-dir ${GARAGE_SIGN_REPO} || errcode=$? + if [ "$errcode" -eq "0" ]; then + push_success=1 + break + else + bbwarn "Push to garage repository has failed, retrying" + fi + done + rm -rf ${GARAGE_SIGN_REPO} + + if [ "$push_success" -ne "1" ]; then + bberror "Couldn't push to garage repository" + exit 1 + fi + fi +} + +IMAGE_TYPEDEP_garagecheck = "ostreepush garagesign" +do_image_garagecheck[depends] += "aktualizr-native:do_populate_sysroot" +IMAGE_CMD_garagecheck () { + if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then + # if credentials are issued by a server that doesn't support offline signing, exit silently + unzip -p ${SOTA_PACKED_CREDENTIALS} root.json targets.pub targets.sec tufrepo.url 2>&1 >/dev/null || exit 0 + ostree_target_hash=$(cat ${OSTREE_REPO}/refs/heads/${OSTREE_BRANCHNAME}) + + garage-check --ref=${ostree_target_hash} \ + --credentials=${SOTA_PACKED_CREDENTIALS} \ + --cacert=${STAGING_ETCDIR_NATIVE}/ssl/certs/ca-certificates.crt + fi } +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/classes/image_types_ota.bbclass b/classes/image_types_ota.bbclass index 09c30ff..df3bc7c 100644 --- a/classes/image_types_ota.bbclass +++ b/classes/image_types_ota.bbclass @@ -7,11 +7,7 @@ # boot scripts, kernel and initramfs images # -inherit image - -OSTREE_BOOTLOADER ??= 'u-boot' - -IMAGE_DEPENDS_otaimg = "e2fsprogs-native:do_populate_sysroot \ +do_image_otaimg[depends] += "e2fsprogs-native:do_populate_sysroot \ ${@'grub:do_populate_sysroot' if d.getVar('OSTREE_BOOTLOADER', True) == 'grub' else ''} \ ${@'virtual/bootloader:do_deploy' if d.getVar('OSTREE_BOOTLOADER', True) == 'u-boot' else ''}" @@ -32,7 +28,7 @@ calculate_size () { fi if [ "$SIZE" -lt "$MIN" ]; then - $SIZE=$MIN + SIZE=$MIN fi SIZE=`expr $SIZE \+ $EXTRA` @@ -53,6 +49,8 @@ export OSTREE_BRANCHNAME export OSTREE_REPO export OSTREE_BOOTLOADER +export GARAGE_TARGET_NAME + IMAGE_CMD_otaimg () { if ${@bb.utils.contains('IMAGE_FSTYPES', 'otaimg', 'true', 'false', d)}; then if [ -z "$OSTREE_REPO" ]; then @@ -67,7 +65,6 @@ IMAGE_CMD_otaimg () { bbfatal "OSTREE_BRANCHNAME should be set in your local.conf" fi - PHYS_SYSROOT=`mktemp -d ${WORKDIR}/ota-sysroot-XXXXX` ostree admin --sysroot=${PHYS_SYSROOT} init-fs ${PHYS_SYSROOT} @@ -78,32 +75,48 @@ IMAGE_CMD_otaimg () { if [ "${OSTREE_BOOTLOADER}" = "grub" ]; then mkdir -p ${PHYS_SYSROOT}/boot/grub2 - touch ${PHYS_SYSROOT}/boot/grub2/grub.cfg + ln -s ../loader/grub.cfg ${PHYS_SYSROOT}/boot/grub2/grub.cfg elif [ "${OSTREE_BOOTLOADER}" = "u-boot" ]; then touch ${PHYS_SYSROOT}/boot/loader/uEnv.txt else bberror "Invalid bootloader: ${OSTREE_BOOTLOADER}" fi; - ostree --repo=${PHYS_SYSROOT}/ostree/repo pull-local --remote=${OSTREE_OSNAME} ${OSTREE_REPO} ${OSTREE_BRANCHNAME} + ostree_target_hash=$(cat ${OSTREE_REPO}/refs/heads/${OSTREE_BRANCHNAME}) + + ostree --repo=${PHYS_SYSROOT}/ostree/repo pull-local --remote=${OSTREE_OSNAME} ${OSTREE_REPO} ${ostree_target_hash} export OSTREE_BOOT_PARTITION="/boot" kargs_list="" for arg in ${OSTREE_KERNEL_ARGS}; do kargs_list="${kargs_list} --karg-append=$arg" done - ostree admin --sysroot=${PHYS_SYSROOT} deploy ${kargs_list} --os=${OSTREE_OSNAME} ${OSTREE_BRANCHNAME} + ostree admin --sysroot=${PHYS_SYSROOT} deploy ${kargs_list} --os=${OSTREE_OSNAME} ${ostree_target_hash} # Copy deployment /home and /var/sota to sysroot HOME_TMP=`mktemp -d ${WORKDIR}/home-tmp-XXXXX` - tar --xattrs --xattrs-include='*' -C ${HOME_TMP} -xf ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.rootfs.ostree.tar.bz2 ./usr/homedirs ./var/sota ./var/local || true - mv ${HOME_TMP}/var/sota ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/ || true - mv ${HOME_TMP}/var/local ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/ || true + tar --xattrs --xattrs-include='*' -C ${HOME_TMP} -xf ${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.rootfs.ostree.tar.bz2 ./usr/homedirs ./var/local || true + + cp -a ${IMAGE_ROOTFS}/var/sota ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/ || true # Create /var/sota if it doesn't exist yet - mkdir -p ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota || true + mkdir -p ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota + # Ensure the permissions are correctly set + chmod 700 ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota + + mv ${HOME_TMP}/var/local ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/ || true mv ${HOME_TMP}/usr/homedirs/home ${PHYS_SYSROOT}/ || true # Ensure that /var/local exists (AGL symlinks /usr/local to /var/local) install -d ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/local + # Set package version for the first deployment + target_version=${ostree_target_hash} + if [ -n "${GARAGE_TARGET_VERSION}" ]; then + target_version=${GARAGE_TARGET_VERSION} + elif [ -e "${STAGING_DATADIR_NATIVE}/target_version" ]; then + target_version=$(cat "${STAGING_DATADIR_NATIVE}/target_version") + fi + mkdir -p ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota/import + echo "{\"${ostree_target_hash}\":\"${GARAGE_TARGET_NAME}-${target_version}\"}" > ${PHYS_SYSROOT}/ostree/deploy/${OSTREE_OSNAME}/var/sota/import/installed_versions + rm -rf ${HOME_TMP} # Calculate image type diff --git a/classes/sota.bbclass b/classes/sota.bbclass index 5073e29..070fe72 100644 --- a/classes/sota.bbclass +++ b/classes/sota.bbclass @@ -5,25 +5,41 @@ python __anonymous() { OVERRIDES .= "${@bb.utils.contains('DISTRO_FEATURES', 'sota', ':sota', '', d)}" +HOSTTOOLS_NONFATAL += "java" + SOTA_CLIENT ??= "aktualizr" -IMAGE_INSTALL_append_sota = " ostree os-release ${SOTA_CLIENT}" +SOTA_CLIENT_PROV ??= "aktualizr-auto-prov" +SOTA_DEPLOY_CREDENTIALS ?= "1" +SOTA_HARDWARE_ID ??= "${MACHINE}" + +IMAGE_INSTALL_append_sota = " ostree os-release ${SOTA_CLIENT} ${SOTA_CLIENT_PROV}" IMAGE_CLASSES += " image_types_ostree image_types_ota" -IMAGE_FSTYPES += "${@bb.utils.contains('DISTRO_FEATURES', 'sota', 'ostreepush otaimg wic', ' ', d)}" +IMAGE_FSTYPES += "${@bb.utils.contains('DISTRO_FEATURES', 'sota', 'ostreepush garagesign garagecheck otaimg wic', ' ', d)}" + +PACKAGECONFIG_append_pn-curl = " ssl" +PACKAGECONFIG_remove_pn-curl = "gnutls" WKS_FILE_sota ?= "sdimage-sota.wks" EXTRA_IMAGEDEPENDS_append_sota = " parted-native mtools-native dosfstools-native" +OSTREE_INITRAMFS_FSTYPES ??= 'ext4.gz' + # Please redefine OSTREE_REPO in order to have a persistent OSTree repo OSTREE_REPO ?= "${DEPLOY_DIR_IMAGE}/ostree_repo" -# For UPTANE operation, OSTREE_BRANCHNAME must start with "${MACHINE}-" -OSTREE_BRANCHNAME ?= "${MACHINE}-ota" +OSTREE_BRANCHNAME ?= "${SOTA_HARDWARE_ID}" OSTREE_OSNAME ?= "poky" OSTREE_INITRAMFS_IMAGE ?= "initramfs-ostree-image" +OSTREE_BOOTLOADER ??= 'u-boot' + +GARAGE_SIGN_REPO ?= "${DEPLOY_DIR_IMAGE}/garage_sign_repo" +GARAGE_SIGN_KEYNAME ?= "garage-key" +GARAGE_TARGET_NAME ?= "${OSTREE_BRANCHNAME}" +GARAGE_TARGET_VERSION ?= "" +GARAGE_TARGET_URL ?= "https://example.com/" SOTA_MACHINE ??="none" -SOTA_MACHINE_raspberrypi2 ?= "raspberrypi" -SOTA_MACHINE_raspberrypi3 ?= "raspberrypi" +SOTA_MACHINE_rpi ?= "raspberrypi" SOTA_MACHINE_porter ?= "porter" SOTA_MACHINE_m3ulcb = "m3ulcb" SOTA_MACHINE_intel-corei7-64 ?= "minnowboard" @@ -31,3 +47,5 @@ SOTA_MACHINE_qemux86-64 ?= "qemux86-64" SOTA_MACHINE_am335x-evm ?= "am335x-evm-wifi" inherit sota_${SOTA_MACHINE} + +inherit image_repo_manifest -- cgit v1.2.3-54-g00ecf From 023b75bf3f186752e88d617d7f72939dce374eb5 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 2 Jan 2019 19:04:39 +0200 Subject: aktualizr: Bump to d00d1a04cc2366d1a5f143b84b9f507f8bd32c44 Backport latest Aktualizr and use the same version as in branches Sumo and Thud. Signed-off-by: Leon Anavi --- .../aktualizr/aktualizr-auto-prov-creds.bb | 24 ++++ recipes-sota/aktualizr/aktualizr-auto-prov.bb | 43 +++++++ .../aktualizr/aktualizr-ca-implicit-prov-creds.bb | 51 ++++++++ .../aktualizr/aktualizr-ca-implicit-prov.bb | 31 +++++ recipes-sota/aktualizr/aktualizr-hsm-prov.bb | 28 +++++ .../aktualizr/aktualizr-uboot-env-rollback.bb | 19 +++ recipes-sota/aktualizr/aktualizr_git.bb | 135 +++++++++++++++++---- recipes-sota/aktualizr/credentials.inc | 1 + .../files/aktualizr-autoprovision.service | 13 -- .../files/aktualizr-manual-provision.service | 13 -- .../aktualizr/files/aktualizr-secondary.service | 8 ++ .../aktualizr/files/aktualizr-secondary.socket | 6 + .../aktualizr/files/aktualizr-serialcan.service | 15 +++ recipes-sota/aktualizr/files/aktualizr.service | 11 ++ recipes-sota/aktualizr/files/ca.cnf | 10 ++ recipes-sota/aktualizr/files/sota_autoprov.toml | 14 --- recipes-sota/aktualizr/garage-sign-version.inc | 36 ++++++ 17 files changed, 396 insertions(+), 62 deletions(-) create mode 100644 recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb create mode 100644 recipes-sota/aktualizr/aktualizr-auto-prov.bb create mode 100644 recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb create mode 100644 recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb create mode 100644 recipes-sota/aktualizr/aktualizr-hsm-prov.bb create mode 100644 recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb mode change 100644 => 100755 recipes-sota/aktualizr/aktualizr_git.bb create mode 100644 recipes-sota/aktualizr/credentials.inc delete mode 100644 recipes-sota/aktualizr/files/aktualizr-autoprovision.service delete mode 100644 recipes-sota/aktualizr/files/aktualizr-manual-provision.service create mode 100644 recipes-sota/aktualizr/files/aktualizr-secondary.service create mode 100644 recipes-sota/aktualizr/files/aktualizr-secondary.socket create mode 100644 recipes-sota/aktualizr/files/aktualizr-serialcan.service create mode 100644 recipes-sota/aktualizr/files/aktualizr.service create mode 100644 recipes-sota/aktualizr/files/ca.cnf delete mode 100644 recipes-sota/aktualizr/files/sota_autoprov.toml create mode 100644 recipes-sota/aktualizr/garage-sign-version.inc diff --git a/recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb b/recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb new file mode 100644 index 0000000..34460af --- /dev/null +++ b/recipes-sota/aktualizr/aktualizr-auto-prov-creds.bb @@ -0,0 +1,24 @@ +SUMMARY = "Credentials for autoprovisioning scenario" +SECTION = "base" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" + +DEPENDS = "aktualizr-native zip-native" +ALLOW_EMPTY_${PN} = "1" + +require credentials.inc + +do_install() { + if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then + install -m 0700 -d ${D}${localstatedir}/sota + cp ${SOTA_PACKED_CREDENTIALS} ${D}${localstatedir}/sota/sota_provisioning_credentials.zip + # Device should not be able to push data to treehub + zip -d ${D}${localstatedir}/sota/sota_provisioning_credentials.zip treehub.json + fi +} + +FILES_${PN} = " \ + ${localstatedir}/sota/sota_provisioning_credentials.zip \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/recipes-sota/aktualizr/aktualizr-auto-prov.bb b/recipes-sota/aktualizr/aktualizr-auto-prov.bb new file mode 100644 index 0000000..f506cab --- /dev/null +++ b/recipes-sota/aktualizr/aktualizr-auto-prov.bb @@ -0,0 +1,43 @@ +SUMMARY = "Aktualizr configuration for autoprovisioning" +DESCRIPTION = "Configuration for automatically provisioning Aktualizr, the SOTA Client application written in C++" +HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" +SECTION = "base" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" + +DEPENDS = "aktualizr-native zip-native" +RDEPENDS_${PN}_append = "${@' aktualizr-auto-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}" +PV = "1.0" +PR = "6" + +SRC_URI = "" + +require credentials.inc + +do_install() { + if [ -n "${SOTA_AUTOPROVISION_CREDENTIALS}" ]; then + bbwarn "SOTA_AUTOPROVISION_CREDENTIALS are ignored. Please use SOTA_PACKED_CREDENTIALS" + fi + if [ -n "${SOTA_AUTOPROVISION_URL}" ]; then + bbwarn "SOTA_AUTOPROVISION_URL is ignored. Please use SOTA_PACKED_CREDENTIALS" + fi + if [ -n "${SOTA_AUTOPROVISION_URL_FILE}" ]; then + bbwarn "SOTA_AUTOPROVISION_URL_FILE is ignored. Please use SOTA_PACKED_CREDENTIALS" + fi + if [ -n "${OSTREE_PUSH_CREDENTIALS}" ]; then + bbwarn "OSTREE_PUSH_CREDENTIALS is ignored. Please use SOTA_PACKED_CREDENTIALS" + fi + + install -m 0700 -d ${D}${libdir}/sota/conf.d + aktualizr_toml=${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'secondary-network', 'sota_autoprov_primary.toml', 'sota_autoprov.toml', d)} + + install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/${aktualizr_toml} \ + ${D}${libdir}/sota/conf.d/20-${aktualizr_toml} +} + +FILES_${PN} = " \ + ${libdir}/sota/conf.d \ + ${libdir}/sota/conf.d/20-${aktualizr_toml} \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb new file mode 100644 index 0000000..a729e6b --- /dev/null +++ b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb @@ -0,0 +1,51 @@ +SUMMARY = "Credentials for implicit provisioning with CA certificate" +SECTION = "base" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" + +DEPENDS = "aktualizr aktualizr-native" +ALLOW_EMPTY_${PN} = "1" + +SRC_URI = " \ + file://ca.cnf \ + " + +require credentials.inc + +export SOTA_CACERT_PATH +export SOTA_CAKEY_PATH + +do_install() { + if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then + if [ -z ${SOTA_CACERT_PATH} ]; then + SOTA_CACERT_PATH=${DEPLOY_DIR_IMAGE}/CA/cacert.pem + SOTA_CAKEY_PATH=${DEPLOY_DIR_IMAGE}/CA/ca.private.pem + mkdir -p ${DEPLOY_DIR_IMAGE}/CA + bbwarn "SOTA_CACERT_PATH is not specified, use default one at $SOTA_CACERT_PATH" + + if [ ! -f ${SOTA_CACERT_PATH} ]; then + bbwarn "${SOTA_CACERT_PATH} does not exist, generate a new CA" + SOTA_CACERT_DIR_PATH="$(dirname "$SOTA_CACERT_PATH")" + openssl genrsa -out ${SOTA_CACERT_DIR_PATH}/ca.private.pem 4096 + openssl req -key ${SOTA_CACERT_DIR_PATH}/ca.private.pem -new -x509 -days 7300 -out ${SOTA_CACERT_PATH} -subj "/C=DE/ST=Berlin/O=Reis und Kichererbsen e.V/commonName=meta-updater" -batch -config ${WORKDIR}/ca.cnf -extensions cacert + bbwarn "${SOTA_CACERT_PATH} has been created, you'll need to upload it to the server" + fi + fi + + if [ -z ${SOTA_CAKEY_PATH} ]; then + bberror "SOTA_CAKEY_PATH should be set when using implicit provisioning" + fi + + install -m 0700 -d ${D}${localstatedir}/sota + aktualizr_cert_provider --credentials ${SOTA_PACKED_CREDENTIALS} \ + --device-ca ${SOTA_CACERT_PATH} \ + --device-ca-key ${SOTA_CAKEY_PATH} \ + --root-ca \ + --server-url \ + --local ${D} \ + --config ${STAGING_DIR_HOST}${libdir}/sota/sota_implicit_prov_ca.toml + fi +} + +FILES_${PN} = " \ + ${localstatedir}/sota/*" diff --git a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb new file mode 100644 index 0000000..5893ed2 --- /dev/null +++ b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov.bb @@ -0,0 +1,31 @@ +SUMMARY = "Aktualizr configuration for implicit provisioning with CA" +DESCRIPTION = "Configuration for implicitly provisioning Aktualizr using externally provided or generated CA" + +# WARNING: it is NOT a production solution. The secure way to provision devices is to create certificate request directly on the device +# (either with HSM/TPM or with software) and then sign it with a CA stored on a disconnected machine + +HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" +SECTION = "base" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" + +DEPENDS = "aktualizr aktualizr-native openssl-native" +RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}" + +PV = "1.0" +PR = "1" + +require credentials.inc + +do_install() { + install -m 0700 -d ${D}${libdir}/sota/conf.d + + install -m 0644 ${STAGING_DIR_HOST}${libdir}/sota/sota_implicit_prov_ca.toml \ + ${D}${libdir}/sota/conf.d/20-sota_implicit_prov_ca.toml +} + +FILES_${PN} = " \ + ${libdir}/sota/conf.d/20-sota_implicit_prov_ca.toml \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/recipes-sota/aktualizr/aktualizr-hsm-prov.bb b/recipes-sota/aktualizr/aktualizr-hsm-prov.bb new file mode 100644 index 0000000..08fffe9 --- /dev/null +++ b/recipes-sota/aktualizr/aktualizr-hsm-prov.bb @@ -0,0 +1,28 @@ +SUMMARY = "Aktualizr configuration with HSM support" +DESCRIPTION = "Configuration for HSM provisioning with Aktualizr, the SOTA Client application written in C++" +HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" +SECTION = "base" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" + +DEPENDS = "aktualizr aktualizr-native" +RDEPENDS_${PN}_append = "${@' aktualizr-ca-implicit-prov-creds softhsm-testtoken' if d.getVar('SOTA_DEPLOY_CREDENTIALS', True) == '1' else ''}" + +SRC_URI = "" +PV = "1.0" +PR = "6" + +require credentials.inc + +do_install() { + install -m 0700 -d ${D}${libdir}/sota/conf.d + install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/sota_hsm_prov.toml \ + ${D}${libdir}/sota/conf.d/20-sota_hsm_prov.toml +} + +FILES_${PN} = " \ + ${libdir}/sota/conf.d \ + ${libdir}/sota/conf.d/20-sota_hsm_prov.toml \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb b/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb new file mode 100644 index 0000000..cf75e79 --- /dev/null +++ b/recipes-sota/aktualizr/aktualizr-uboot-env-rollback.bb @@ -0,0 +1,19 @@ +SUMMARY = "Aktualizr configuration snippet to enable uboot bootcount function" +HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" +SECTION = "base" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" +DEPENDS = "aktualizr-native" +RDEPENDS_${PN} = "aktualizr" + +do_install() { + install -m 0700 -d ${D}${libdir}/sota/conf.d + install -m 0644 ${STAGING_DIR_NATIVE}${libdir}/sota/sota_uboot_env.toml ${D}${libdir}/sota/conf.d/30-rollback.toml +} + +FILES_${PN} = " \ + ${libdir}/sota/conf.d \ + ${libdir}/sota/conf.d/30-rollback.toml \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb old mode 100644 new mode 100755 index 8bc580d..e62bdf1 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -4,42 +4,133 @@ HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" SECTION = "base" LICENSE = "MPL-2.0" LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=9741c346eef56131163e13b9db1241b3" -DEPENDS = "boost curl openssl jansson libsodium ostree" -RDEPENDS_${PN} = "lshw" + +DEPENDS = "boost curl openssl libarchive libsodium asn1c-native sqlite3 " +DEPENDS_append_class-target = "ostree ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', ' libp11', '', d)} " +DEPENDS_append_class-native = "glib-2.0-native " + +RDEPENDS_${PN}_class-target = "lshw " +RDEPENDS_${PN}_append_class-target = "${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'serialcan', ' slcand-start', '', d)} " +RDEPENDS_${PN}_append_class-target = " ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'ubootenv', ' u-boot-fw-utils aktualizr-uboot-env-rollback', '', d)} " + +RDEPENDS_${PN}_append_class-target = " ${PN}-tools " +RDEPENDS_${PN}-secondary_append_class-target = " ${PN}-tools " + +PV = "1.0+git${SRCPV}" +PR = "7" SRC_URI = " \ - git://github.com/advancedtelematic/aktualizr \ - file://aktualizr-manual-provision.service \ - file://aktualizr-autoprovision.service \ - file://sota_autoprov.toml \ + gitsm://github.com/advancedtelematic/aktualizr;branch=${BRANCH} \ + file://aktualizr.service \ + file://aktualizr-secondary.service \ + file://aktualizr-secondary.socket \ + file://aktualizr-serialcan.service \ " -SRCREV = "1004efa3f86cef90c012b34620992b5762b741e3" -PV = "1.0+git${SRCPV}" -PR = "6" + +SRCREV = "d00d1a04cc2366d1a5f143b84b9f507f8bd32c44" +BRANCH ?= "master" S = "${WORKDIR}/git" + +inherit cmake + +inherit systemd + +SYSTEMD_PACKAGES = "${PN} ${PN}-secondary" SYSTEMD_SERVICE_${PN} = "aktualizr.service" +SYSTEMD_SERVICE_${PN}-secondary = "aktualizr-secondary.socket" -inherit cmake systemd +BBCLASSEXTEND =+ "native" -EXTRA_OECMAKE = "-DWARNING_AS_ERROR=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF -DBUILD_OSTREE=ON -DAKTUALIZR_VERSION=${PV}" +require garage-sign-version.inc -export SOTA_PACKED_CREDENTIALS +EXTRA_OECMAKE = "-DWARNING_AS_ERROR=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DAKTUALIZR_VERSION=${PV} \ + -DBUILD_LOAD_TESTS=OFF \ + -Dgtest_disable_pthreads=ON" +EXTRA_OECMAKE_append_class-target = " -DBUILD_OSTREE=ON \ + ${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'hsm', '-DBUILD_P11=ON', '', d)} " +EXTRA_OECMAKE_append_class-native = " -DBUILD_SOTA_TOOLS=ON \ + -DBUILD_OSTREE=OFF \ + -DBUILD_SYSTEMD=OFF \ + -DGARAGE_SIGN_VERSION=${GARAGE_SIGN_VERSION} \ + -DGARAGE_SIGN_SHA256=${GARAGE_SIGN_SHA256}" -do_install_append() { - if [ -n "${SOTA_PACKED_CREDENTIALS}" ]; then - install -d ${D}/${systemd_unitdir}/system - install -m 0644 ${WORKDIR}/aktualizr-autoprovision.service ${D}/${systemd_unitdir}/system/aktualizr.service - install -d ${D}/usr/lib/sota - install -m "0644" ${WORKDIR}/sota_autoprov.toml ${D}/usr/lib/sota/sota.toml - else - install -d ${D}/${systemd_unitdir}/system - install -m 0644 ${WORKDIR}/aktualizr-manual-provision.service ${D}/${systemd_unitdir}/system/aktualizr.service +do_install_append () { + install -d ${D}${libdir}/sota + install -m 0644 ${S}/config/sota_autoprov.toml ${D}/${libdir}/sota/sota_autoprov.toml + install -m 0644 ${S}/config/sota_autoprov_primary.toml ${D}/${libdir}/sota/sota_autoprov_primary.toml + install -m 0644 ${S}/config/sota_hsm_prov.toml ${D}/${libdir}/sota/sota_hsm_prov.toml + install -m 0644 ${S}/config/sota_implicit_prov_ca.toml ${D}/${libdir}/sota/sota_implicit_prov_ca.toml + install -m 0644 ${S}/config/sota_secondary.toml ${D}/${libdir}/sota/sota_secondary.toml + install -m 0644 ${S}/config/sota_uboot_env.toml ${D}/${libdir}/sota/sota_uboot_env.toml + install -d ${D}${systemd_unitdir}/system + install -m 0644 ${WORKDIR}/aktualizr-secondary.socket ${D}${systemd_unitdir}/system/aktualizr-secondary.socket + install -m 0644 ${WORKDIR}/aktualizr-secondary.service ${D}${systemd_unitdir}/system/aktualizr-secondary.service + install -m 0700 -d ${D}${libdir}/sota/conf.d + install -m 0700 -d ${D}${sysconfdir}/sota/conf.d + + if [ -n "${SOTA_SECONDARY_CONFIG_DIR}" ]; then + if [ -d "${SOTA_SECONDARY_CONFIG_DIR}" ]; then + install -m 0700 -d ${D}${sysconfdir}/sota/ecus + install -m 0644 "${SOTA_SECONDARY_CONFIG_DIR}"/* ${D}${sysconfdir}/sota/ecus/ + echo "[uptane]\nsecondary_configs_dir = /etc/sota/ecus/\n" > ${D}${libdir}/sota/conf.d/30-secondary-configs-dir.toml + else + bbwarn "SOTA_SECONDARY_CONFIG_DIR is set to an invalid directory (${SOTA_SECONDARY_CONFIG_DIR})" + fi fi + +} + +do_install_append_class-target () { + install -m 0755 -d ${D}${systemd_unitdir}/system + aktualizr_service=${@bb.utils.contains('SOTA_CLIENT_FEATURES', 'serialcan', '${WORKDIR}/aktualizr-serialcan.service', '${WORKDIR}/aktualizr.service', d)} + install -m 0644 ${aktualizr_service} ${D}${systemd_unitdir}/system/aktualizr.service +} + +do_install_append_class-native () { + install -m 0755 ${B}/src/sota_tools/garage-sign/bin/* ${D}${bindir} + install -m 0644 ${B}/src/sota_tools/garage-sign/lib/* ${D}${libdir} } +PACKAGES =+ " ${PN}-examples ${PN}-host-tools ${PN}-tools ${PN}-secondary " + FILES_${PN} = " \ ${bindir}/aktualizr \ + ${bindir}/aktualizr-info \ + ${bindir}/aktualizr-check-discovery \ ${systemd_unitdir}/system/aktualizr.service \ - /usr/lib/sota/sota.toml \ + ${libdir}/sota/conf.d \ + ${sysconfdir}/sota/conf.d \ + ${sysconfdir}/sota/ecus/* \ " + +FILES_${PN}-examples = " \ + ${bindir}/hmi-stub \ + " + +FILES_${PN}-host-tools = " \ + ${bindir}/aktualizr-repo \ + ${bindir}/aktualizr-cert-provider \ + ${bindir}/garage-deploy \ + ${bindir}/garage-push \ + ${libdir}/sota/sota_autoprov.toml \ + ${libdir}/sota/sota_autoprov_primary.toml \ + ${libdir}/sota/sota_hsm_prov.toml \ + ${libdir}/sota/sota_implicit_prov_ca.toml \ + ${libdir}/sota/sota_uboot_env.toml \ + " + +FILES_${PN}-tools = " \ + ${bindir}/aktualizr-check-discovery \ + " + +FILES_${PN}-secondary = " \ + ${bindir}/aktualizr-secondary \ + ${libdir}/sota/sota_secondary.toml \ + ${systemd_unitdir}/system/aktualizr-secondary.socket \ + ${systemd_unitdir}/system/aktualizr-secondary.service \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/recipes-sota/aktualizr/credentials.inc b/recipes-sota/aktualizr/credentials.inc new file mode 100644 index 0000000..256c8ff --- /dev/null +++ b/recipes-sota/aktualizr/credentials.inc @@ -0,0 +1 @@ +SRC_URI_append = "${@('file://' + d.getVar('SOTA_PACKED_CREDENTIALS', True)) if d.getVar('SOTA_PACKED_CREDENTIALS', True) else ''}" diff --git a/recipes-sota/aktualizr/files/aktualizr-autoprovision.service b/recipes-sota/aktualizr/files/aktualizr-autoprovision.service deleted file mode 100644 index 4a595f0..0000000 --- a/recipes-sota/aktualizr/files/aktualizr-autoprovision.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Aktualizr SOTA Client -Wants=network-online.target -After=network.target network-online.target -Requires=network-online.target - -[Service] -RestartSec=10 -Restart=always -ExecStart=/usr/bin/aktualizr --disable-keyid-validation --config /usr/lib/sota/sota.toml - -[Install] -WantedBy=multi-user.target diff --git a/recipes-sota/aktualizr/files/aktualizr-manual-provision.service b/recipes-sota/aktualizr/files/aktualizr-manual-provision.service deleted file mode 100644 index a70f2f9..0000000 --- a/recipes-sota/aktualizr/files/aktualizr-manual-provision.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Aktualizr SOTA Client -Wants=network-online.target -After=network.target network-online.target -Requires=network-online.target - -[Service] -RestartSec=10 -Restart=always -ExecStart=/usr/bin/aktualizr --config /sysroot/boot/sota.toml --loglevel 2 - -[Install] -WantedBy=multi-user.target diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.service b/recipes-sota/aktualizr/files/aktualizr-secondary.service new file mode 100644 index 0000000..9628ee3 --- /dev/null +++ b/recipes-sota/aktualizr/files/aktualizr-secondary.service @@ -0,0 +1,8 @@ +[Unit] +Description=Aktualizr SOTA Client (UPTANE Secondary) + +[Service] +RestartSec=10 +Restart=always +ExecStart=/usr/bin/aktualizr-secondary --config /usr/lib/sota/sota_secondary.toml + diff --git a/recipes-sota/aktualizr/files/aktualizr-secondary.socket b/recipes-sota/aktualizr/files/aktualizr-secondary.socket new file mode 100644 index 0000000..da0ee44 --- /dev/null +++ b/recipes-sota/aktualizr/files/aktualizr-secondary.socket @@ -0,0 +1,6 @@ +[Socket] +ListenStream=9030 +ListenDatagram=9031 + +[Install] +WantedBy=sockets.target \ No newline at end of file diff --git a/recipes-sota/aktualizr/files/aktualizr-serialcan.service b/recipes-sota/aktualizr/files/aktualizr-serialcan.service new file mode 100644 index 0000000..b42f348 --- /dev/null +++ b/recipes-sota/aktualizr/files/aktualizr-serialcan.service @@ -0,0 +1,15 @@ +[Unit] +Description=Aktualizr SOTA Client +Wants=network-online.target slcand@ttyACM0.service +After=network.target network-online.target slcand@ttyACM0.service + +Requires=network-online.target + +[Service] +RestartSec=10 +Restart=always +EnvironmentFile=/usr/lib/sota/sota.env +ExecStart=/bin/sh -c "(ip addr | grep can0) && /usr/bin/aktualizr $AKTUALIZR_CMDLINE_PARAMETERS" + +[Install] +WantedBy=multi-user.target diff --git a/recipes-sota/aktualizr/files/aktualizr.service b/recipes-sota/aktualizr/files/aktualizr.service new file mode 100644 index 0000000..726809e --- /dev/null +++ b/recipes-sota/aktualizr/files/aktualizr.service @@ -0,0 +1,11 @@ +[Unit] +Description=Aktualizr SOTA Client +After=network.target + +[Service] +RestartSec=10 +Restart=always +ExecStart=/usr/bin/aktualizr $AKTUALIZR_CMDLINE_PARAMETERS + +[Install] +WantedBy=multi-user.target diff --git a/recipes-sota/aktualizr/files/ca.cnf b/recipes-sota/aktualizr/files/ca.cnf new file mode 100644 index 0000000..352ec38 --- /dev/null +++ b/recipes-sota/aktualizr/files/ca.cnf @@ -0,0 +1,10 @@ +[req] +req_extensions = cacert +distinguished_name = req_distinguished_name + +[req_distinguished_name] + +[cacert] +basicConstraints = critical,CA:true +keyUsage = keyCertSign + diff --git a/recipes-sota/aktualizr/files/sota_autoprov.toml b/recipes-sota/aktualizr/files/sota_autoprov.toml deleted file mode 100644 index 9fbb093..0000000 --- a/recipes-sota/aktualizr/files/sota_autoprov.toml +++ /dev/null @@ -1,14 +0,0 @@ -[tls] -certificates_directory = "/var/sota/" -ca_file = "root.crt" -client_certificate = "client.pem" -pkey_file = "pkey.pem" - -[uptane] -metadata_path = "/var/sota/metadata" -private_key_path = "ecukey.der" -public_key_path = "ecukey.pub" - -[provision] -provision_path = "/var/sota/sota_provisioning_credentials.zip" - diff --git a/recipes-sota/aktualizr/garage-sign-version.inc b/recipes-sota/aktualizr/garage-sign-version.inc new file mode 100644 index 0000000..1b89a3d --- /dev/null +++ b/recipes-sota/aktualizr/garage-sign-version.inc @@ -0,0 +1,36 @@ + +python () { + if d.getVar("GARAGE_SIGN_VERSION", True) or not d.getVar("SOTA_PACKED_CREDENTIALS", True): + return + import json + import urllib.request + import zipfile + with zipfile.ZipFile(d.getVar("SOTA_PACKED_CREDENTIALS", True), 'r') as zip_ref: + try: + with zip_ref.open('tufrepo.url', mode='r') as url_file: + url = url_file.read().decode().strip(' \t\n') + '/health/version' + except (KeyError, ValueError, RuntimeError): + return + connected = False + tries = 3 + for i in range(tries): + try: + r = urllib.request.urlopen(url) + if r.code == 200: + connected = True + break + else: + print('Bad return code from server ' + url + ': ' + str(r.code) + + ' (attempt ' + str(i + 1) + ' of ' + str(tries) + ')') + except urllib.error.URLError as e: + print('Error connecting to server ' + url + ': ' + str(e) + + ' (attempt ' + str(i + 1) + ' of ' + str(tries) + ')') + if not connected: + return + resp = r.read().decode('utf-8') + j = json.loads(resp) + version = 'cli-' + j['version'] + '.tgz' + d.setVar("GARAGE_SIGN_VERSION", version) +} + +# vim:set ts=4 sw=4 sts=4 expandtab: -- cgit v1.2.3-54-g00ecf From 92acec81196e731edc9a3b3e170e56967215a21b Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 2 Jan 2019 19:06:29 +0200 Subject: scripts: Backporting scripts for QEMU Backporting scripts for running images in QEMU from branch Sumo to branch Morty. Add *.pyc files to .gitignore. Signed-off-by: Leon Anavi --- .gitignore | 1 + scripts/qemucommand.py | 132 +++++++++++++++++++++++++++++++++++++++++++++++++ scripts/run-qemu-ota | 132 ++++++------------------------------------------- 3 files changed, 149 insertions(+), 116 deletions(-) create mode 100644 scripts/qemucommand.py diff --git a/.gitignore b/.gitignore index bee8a64..8d35cb3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ __pycache__ +*.pyc diff --git a/scripts/qemucommand.py b/scripts/qemucommand.py new file mode 100644 index 0000000..86362f7 --- /dev/null +++ b/scripts/qemucommand.py @@ -0,0 +1,132 @@ +from os.path import exists, join, realpath, abspath +from os import listdir +import random +import socket +from subprocess import check_output, CalledProcessError + +EXTENSIONS = { + 'intel-corei7-64': 'wic', + 'qemux86-64': 'otaimg' +} + + +def find_local_port(start_port): + """" + Find the next free TCP port after 'start_port'. + """ + + for port in range(start_port, start_port + 10): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(('', port)) + return port + except socket.error: + print("Skipping port %d" % port) + finally: + s.close() + raise Exception("Could not find a free TCP port") + + +def random_mac(): + """Return a random Ethernet MAC address + @link https://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml#ethernet-numbers-2 + """ + head = "ca:fe:" + hex_digits = '0123456789abcdef' + tail = ':'.join([random.choice(hex_digits) + random.choice(hex_digits) for _ in range(4)]) + return head + tail + + +class QemuCommand(object): + def __init__(self, args): + if args.machine: + self.machine = args.machine + else: + machines = listdir(args.dir) + if len(machines) == 1: + self.machine = machines[0] + else: + raise ValueError("Could not autodetect machine type. More than one entry in %s. Maybe --machine qemux86-64?" % args.dir) + if args.efi: + self.bios = 'OVMF.fd' + else: + uboot = abspath(join(args.dir, self.machine, 'u-boot-qemux86-64.rom')) + if not exists(uboot): + raise ValueError("U-Boot image %s does not exist" % uboot) + self.bios = uboot + if exists(args.imagename): + image = args.imagename + else: + ext = EXTENSIONS.get(self.machine, 'wic') + image = join(args.dir, self.machine, '%s-%s.%s' % (args.imagename, self.machine, ext)) + self.image = realpath(image) + if not exists(self.image): + raise ValueError("OS image %s does not exist" % self.image) + if args.mac: + self.mac_address = args.mac + else: + self.mac_address = random_mac() + self.serial_port = find_local_port(8990) + self.ssh_port = find_local_port(2222) + if args.kvm is None: + # Autodetect KVM using 'kvm-ok' + try: + check_output(['kvm-ok']) + self.kvm = True + except Exception: + self.kvm = False + else: + self.kvm = args.kvm + self.gui = not args.no_gui + self.gdb = args.gdb + self.pcap = args.pcap + self.overlay = args.overlay + self.secondary_network = args.secondary_network + + def command_line(self): + netuser = 'user,hostfwd=tcp:0.0.0.0:%d-:22,restrict=off' % self.ssh_port + if self.gdb: + netuser += ',hostfwd=tcp:0.0.0.0:2159-:2159' + cmdline = [ + "qemu-system-x86_64", + "-bios", self.bios + ] + if not self.overlay: + cmdline += ["-drive", "file=%s,if=ide,format=raw,snapshot=on" % self.image] + cmdline += [ + "-serial", "tcp:127.0.0.1:%d,server,nowait" % self.serial_port, + "-m", "1G", + "-usb", + "-device", "usb-tablet", + "-show-cursor", + "-vga", "std", + "-net", netuser, + "-net", "nic,macaddr=%s" % self.mac_address + ] + if self.pcap: + cmdline += ['-net', 'dump,file=' + self.pcap] + if self.secondary_network: + cmdline += [ + '-net', 'nic,vlan=1,macaddr='+random_mac(), + '-net', 'socket,vlan=1,mcast=230.0.0.1:1234,localaddr=127.0.0.1', + ] + if self.gui: + cmdline += ["-serial", "stdio"] + else: + cmdline.append('-nographic') + if self.kvm: + cmdline += ['-enable-kvm', '-cpu', 'host'] + else: + cmdline += ['-cpu', 'Haswell'] + if self.overlay: + cmdline.append(self.overlay) + return cmdline + + def img_command_line(self): + cmdline = [ + "qemu-img", "create", + "-o", "backing_file=%s" % self.image, + "-f", "qcow2", + self.overlay] + return cmdline + diff --git a/scripts/run-qemu-ota b/scripts/run-qemu-ota index 6a3586c..b2f55e9 100755 --- a/scripts/run-qemu-ota +++ b/scripts/run-qemu-ota @@ -2,127 +2,17 @@ from argparse import ArgumentParser from subprocess import Popen -from os.path import exists, join, realpath -from os import listdir -import random +from os.path import exists import sys -import socket +from qemucommand import QemuCommand DEFAULT_DIR = 'tmp/deploy/images' -EXTENSIONS = { - 'intel-corei7-64': 'wic', - 'qemux86-64': 'otaimg' -} - - -def find_local_port(start_port): - """" - Find the next free TCP port after 'start_port'. - """ - - for port in range(start_port, start_port + 10): - try: - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.bind(('', port)) - return port - except socket.error: - print("Skipping port %d" % port) - finally: - s.close() - raise Exception("Could not find a free TCP port") - - -def random_mac(): - """Return a random Ethernet MAC address - @link https://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml#ethernet-numbers-2 - """ - head = "ca:fe:" - hex_digits = '0123456789abcdef' - tail = ':'.join([random.choice(hex_digits) + random.choice(hex_digits) for _ in range(4)]) - return head + tail - - -class QemuCommand(object): - def __init__(self, args): - if args.machine: - self.machine = args.machine - else: - machines = listdir(args.dir) - if len(machines) == 1: - self.machine = machines[0] - else: - raise ValueError("Could not autodetect machine type from %s" % args.dir) - if args.efi: - self.bios = 'OVMF.fd' - else: - uboot = join(args.dir, self.machine, 'u-boot-qemux86-64.rom') - if not exists(uboot): - raise ValueError("U-Boot image %s does not exist" % uboot) - self.bios = uboot - ext = EXTENSIONS.get(self.machine, 'wic') - image = join(args.dir, self.machine, '%s-%s.%s' % (args.imagename, self.machine, ext)) - self.image = realpath(image) - if not exists(self.image): - raise ValueError("OS image %s does not exist" % self.image) - if args.mac: - self.mac_address = args.mac - else: - self.mac_address = random_mac() - self.serial_port = find_local_port(8990) - self.ssh_port = find_local_port(2222) - self.kvm = not args.no_kvm - self.gui = not args.no_gui - self.gdb = args.gdb - self.pcap = args.pcap - self.overlay = args.overlay - - def command_line(self): - netuser = 'user,hostfwd=tcp:0.0.0.0:%d-:22,restrict=off' % self.ssh_port - if self.gdb: - netuser += ',hostfwd=tcp:0.0.0.0:2159-:2159' - cmdline = [ - "qemu-system-x86_64", - "-bios", self.bios - ] - if not self.overlay: - cmdline += ["-drive", "file=%s,if=ide,format=raw,snapshot=on" % self.image] - cmdline += [ - "-serial", "tcp:127.0.0.1:%d,server,nowait" % self.serial_port, - "-m", "1G", - "-usb", - "-usbdevice", "tablet", - "-show-cursor", - "-vga", "std", - "-net", netuser, - "-net", "nic,macaddr=%s" % self.mac_address - ] - if self.pcap: - cmdline += ['-net', 'dump,file=' + self.pcap] - if self.gui: - cmdline += ["-serial", "stdio"] - else: - cmdline.append('-nographic') - if self.kvm: - cmdline.append('-enable-kvm') - else: - cmdline += ['-cpu', 'Haswell'] - if self.overlay: - cmdline.append(self.overlay) - return cmdline - - def img_command_line(self): - cmdline = [ - "qemu-img", "create", - "-o", "backing_file=%s" % self.image, - "-f", "qcow2", - self.overlay] - return cmdline - def main(): parser = ArgumentParser(description='Run meta-updater image in qemu') - parser.add_argument('imagename', default='core-image-minimal', nargs='?') + parser.add_argument('imagename', default='core-image-minimal', nargs='?', + help="Either the name of the bitbake image target, or a path to the image to run") parser.add_argument('mac', default=None, nargs='?') parser.add_argument('--dir', default=DEFAULT_DIR, help='Path to build directory containing the image and u-boot-qemux86-64.rom') @@ -131,11 +21,21 @@ def main(): 'OSTREE_BOOTLOADER = "grub" and OVMF.fd firmware to be installed (try "apt install ovmf")', action='store_true') parser.add_argument('--machine', default=None, help="Target MACHINE") - parser.add_argument('--no-kvm', help='Disable KVM in QEMU', action='store_true') + kvm_group = parser.add_argument_group() + kvm_group.add_argument('--force-kvm', help='Force use of KVM (default is to autodetect)', + dest='kvm', action='store_true', default=None) + kvm_group.add_argument('--no-kvm', help='Disable KVM in QEMU', + dest='kvm', action='store_false') parser.add_argument('--no-gui', help='Disable GUI', action='store_true') parser.add_argument('--gdb', help='Export gdbserver port 2159 from the image', action='store_true') parser.add_argument('--pcap', default=None, help='Dump all network traffic') - parser.add_argument('-o', '--overlay', type=str, metavar='file.cow', help='Use an overlay storage image file. Will be created if it does not exist. This option lets you have a persistent image without modifying the underlying image file, permitting multiple different persistent machines.') + parser.add_argument('-o', '--overlay', type=str, metavar='file.cow', + help='Use an overlay storage image file. Will be created if it does not exist. ' + + 'This option lets you have a persistent image without modifying the underlying image ' + + 'file, permitting multiple different persistent machines.') + parser.add_argument('--secondary-network', action='store_true', dest='secondary_network', + help='Give the image a second network card connected to a virtual network. ' + + 'This can be used to test Uptane Primary/Secondary communication.') parser.add_argument('-n', '--dry-run', help='Print qemu command line rather then run it', action='store_true') args = parser.parse_args() try: -- cgit v1.2.3-54-g00ecf From 82f13607c1eb9de62576149b3633c59f6e38a1b9 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 2 Jan 2019 19:07:23 +0200 Subject: sota_qemux86-64.bbclass: Increase free space Increase the free space in QEMU images to avoid errors from Aktualizr while pulling updates, such as: object: min-free-space-percent '3%' would be exceeded, at least 10.2 kB requested Signed-off-by: Leon Anavi --- classes/sota_qemux86-64.bbclass | 2 ++ 1 file changed, 2 insertions(+) diff --git a/classes/sota_qemux86-64.bbclass b/classes/sota_qemux86-64.bbclass index 5ec4f69..53e0026 100644 --- a/classes/sota_qemux86-64.bbclass +++ b/classes/sota_qemux86-64.bbclass @@ -9,3 +9,5 @@ UBOOT_MACHINE_sota = "qemu-x86_defconfig" OSTREE_BOOTLOADER ?= "u-boot" OSTREE_KERNEL_ARGS ?= "ramdisk_size=16384 rw rootfstype=ext4 rootwait rootdelay=2 ostree_root=/dev/hda" + +IMAGE_ROOTFS_EXTRA_SPACE = "${@bb.utils.contains('DISTRO_FEATURES', 'sota', '65536', '', d)}" -- cgit v1.2.3-54-g00ecf From 9143a565f9abc125a2137e41183fa5f291a020b8 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Thu, 3 Jan 2019 18:47:57 +0200 Subject: sota.bbclass: Set fs type Set fs type depending on the bootloader and the machine to ext4.gz or ext4.gz.u-boot. Signed-off-by: Leon Anavi --- classes/sota.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/sota.bbclass b/classes/sota.bbclass index 070fe72..bd58d3c 100644 --- a/classes/sota.bbclass +++ b/classes/sota.bbclass @@ -23,7 +23,7 @@ WKS_FILE_sota ?= "sdimage-sota.wks" EXTRA_IMAGEDEPENDS_append_sota = " parted-native mtools-native dosfstools-native" -OSTREE_INITRAMFS_FSTYPES ??= 'ext4.gz' +OSTREE_INITRAMFS_FSTYPES ??= "${@oe.utils.ifelse(d.getVar('OSTREE_BOOTLOADER', True) == 'u-boot' and d.getVar('MACHINE', True) != 'qemux86-64', 'ext4.gz.u-boot', 'ext4.gz')}" # Please redefine OSTREE_REPO in order to have a persistent OSTree repo OSTREE_REPO ?= "${DEPLOY_DIR_IMAGE}/ostree_repo" -- cgit v1.2.3-54-g00ecf From e6bd87cd1b3145b9c19e939ae0d5380d77985730 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Wed, 23 Jan 2019 18:58:49 +0200 Subject: *.adoc: Update CONTRIBUTING and README Add CONTRIBUTING.adoc and update README.adoc to match the versions of both files from branch Rocko. Suggested-by: Patrick Vacek Signed-off-by: Leon Anavi --- CONTRIBUTING.adoc | 28 +++++++++ README.adoc | 166 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 161 insertions(+), 33 deletions(-) create mode 100644 CONTRIBUTING.adoc diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc new file mode 100644 index 0000000..4d9e8f6 --- /dev/null +++ b/CONTRIBUTING.adoc @@ -0,0 +1,28 @@ += Contributing + +We welcome pull requests from anyone. The master branch is the primary branch for development, and if you wish to add new functionality, it probably belongs there. We attempt to maintain recent previous branches and welcome bug fixes and backports for those. Currently, the actively maintained branches are: + +* thud +* sumo +* rocko + +Previously, some older branches were also regularly supported, and while they should still be stable, they have not been updated or actively maintained for a while. These branches include: + +* pyro +* morty + +If you are developing with meta-updater, it may be helpful to read the README and other documentation for link:README.adoc[this repo], https://github.com/advancedtelematic/aktualizr[aktualizr], and the https://github.com/advancedtelematic/updater-repo/[updater-repo], particularly the sections about development and debugging. + +== Contributor checklist + +* OTA-enabled build succeeds for at least one platform, the resulting image boots, and an update can be installed. This check is absolutely necessary for every pull request unless it only touches documentation. +* If your change touches platform code (like `classes/sota_.bbclass`), please check building and updating on this particular platform. +* oe-selftest succeeds. To test meta-updater, run `oe-selftest -r updater` from a build directory with `MACHINE` set to `qemux86-64`. See the link:README.adoc#qa-with-oe-selftest[relevant section of the README] for more details. +* Updates are forwards- and backwards-compatible. You should be able to update an OTA-enabled build before the change is applied to the version with change applied and vice versa. One should pay double attention to the compatibility when bootloader code is affected. +* The patch/branch should be based on the latest version of the target branch. This may mean that rebasing is necessary if other PRs are merged before yours is approved. + +We understand that completing all these tasks might be overly tedious due to build times in Yocto. Please add a comment to your PR describing the tests you've done. + +== Approval + +PR approval should be accompanied by a comment describing what tests have been done by the reviewer. diff --git a/README.adoc b/README.adoc index 9615f65..32630d7 100644 --- a/README.adoc +++ b/README.adoc @@ -1,28 +1,33 @@ = meta-updater +:toc: macro +:toc-title: -This layer enables over-the-air updates (OTA) with https://github.com/ostreedev/ostree[OSTree] and https://github.com/advancedtelematic/rvi_sota_client[RVI SOTA client]. +This layer enables over-the-air updates (OTA) with https://github.com/ostreedev/ostree[OSTree] and https://github.com/advancedtelematic/aktualizr[Aktualizr]. https://github.com/ostreedev/ostree[OSTree] is a tool for atomic full file system upgrades with rollback capability. OSTree has several advantages over traditional dual-bank systems, but the most important one is that it minimizes network bandwidth and data storage footprint by sharing files with the same contents across file system deployments. -https://github.com/advancedtelematic/rvi_sota_client[RVI SOTA client] and/or https://github.com/advancedtelematic/aktualizr[aktualizr] add authentication and provisioning capabilities to OTA and are integrated with OSTree. You can connect with the open-source https://github.com/advancedtelematic/rvi_sota_server[RVI SOTA server] or sign up for a free account at https://app.atsgarage.com[ATS Garage] to get started. +https://github.com/advancedtelematic/aktualizr[Aktualizr] (and https://github.com/advancedtelematic/rvi_sota_client[RVI SOTA client]) add authentication and provisioning capabilities to OTA and are integrated with OSTree. You can connect with these open-source applications or sign up for a free account at https://connect.ota.here.com/[HERE OTA Connect] to get started. + +[discrete] +== Table of Contents + +toc::[] == Build === Quickstart -If you don't already have a Yocto project that you want to add OTA to, you can use the https://docs.atsgarage.com/quickstarts/raspberry-pi.html[ATS Garage Quickstart] project to rapidly get up and running on a Raspberry Pi. It takes a standard https://www.yoctoproject.org/tools-resources/projects/poky[poky] distribution, and adds OTA and OSTree capabilities. +If you don't already have a Yocto project that you want to add OTA to, you can use the https://docs.atsgarage.com/quickstarts/raspberry-pi.html[HERE OTA Connect Quickstart] project to rapidly get up and running on a Raspberry Pi. It takes a standard https://www.yoctoproject.org/tools-resources/projects/poky[poky] distribution, and adds OTA and OSTree capabilities. === Adding meta-updater capabilities to your build If you already have a Yocto-based project and you want to add atomic filesystem updates to it, you just need to do three things: -1. Clone the `meta-updater` layer and add it to your https://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#structure-build-conf-bblayers.conf[bblayers.conf]. -2. Clone BSP integration layer (meta-updater-$\{PLATFORM}, e.g. https://github.com/advancedtelematic/meta-updater-raspberrypi[meta-updater-raspberrypi]) and add it to your conf/bblayers.conf. If your board isn't supported yet, you could write a BSP integration for it yourself. See the <> section for the details. -3. Set up your https://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#var-DISTRO[distro]. If you are using "poky", the default distro in Yocto, you can change it in your conf/local.conf to "poky-sota". Alternatively, if you are using your own or third party distro configuration, you can add 'INHERIT += " sota"' to it, thus combining capabilities of your distro with meta-updater features. - -You can then build your image as usual, with bitbake. After building the root file system, bitbake will then create an https://ostree.readthedocs.io/en/latest/manual/adapting-existing/[OSTree-enabled version] of it, commit it to your local OSTree repo and (optionally) push it to a remote server. Additionally, a live disk image will be created (normally named $\{IMAGE_NAME}.-sdimg-ota e.g. core-image-raspberrypi3.rpi-sdimg-ota). You can control this behaviour through <>. +1. Clone the `meta-updater` layer and add it to your https://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#structure-build-conf-bblayers.conf[bblayers.conf]. +2. Clone BSP integration layer (`meta-updater-$\{PLATFORM}`, e.g. https://github.com/advancedtelematic/meta-updater-raspberrypi[meta-updater-raspberrypi]) and add it to your `conf/bblayers.conf`. If your board isn't supported yet, you could write a BSP integration for it yourself. See the <> section for the details. +3. Set up your https://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-DISTRO[distro]. If you are using "poky", the default distro in Yocto, you can change it in your `conf/local.conf` to "poky-sota". Alternatively, if you are using your own or third party distro configuration, you can add `INHERIT += " sota"` to it, thus combining capabilities of your distro with meta-updater features. -=== Build with OpenIVI +You can then build your image as usual, with bitbake. After building the root file system, bitbake will then create an https://ostree.readthedocs.io/en/latest/manual/adapting-existing/[OSTree-enabled version] of it, commit it to your local OSTree repo and (optionally) push it to a remote server. Additionally, a live disk image will be created (normally named `$\{IMAGE_NAME}.-sdimg-ota` e.g. `core-image-raspberrypi3.rpi-sdimg-ota`). You can control this behaviour through <>. === Build in AGL @@ -32,19 +37,23 @@ With AGL you can just add agl-sota feature while configuring your build environm source meta-agl/scripts/aglsetup.sh -m porter agl-demo agl-appfw-smack agl-devel agl-sota .... -you can then run +You can then run: .... bitbake agl-demo-platform .... -and get as a result an "ostree_repo" folder in your images directory (tmp/deploy/images/$\{MACHINE}/ostree_repo). It will contain +and get as a result an `ostree_repo` folder in your images directory (`tmp/deploy/images/$\{MACHINE}/ostree_repo`). It will contain: * your OSTree repository, with the rootfs committed as an OSTree deployment, -* an 'otaimg' bootstrap image, which is an OSTree physical sysroot as a burnable filesystem image, and optionally -* some machine-dependent live images (e.g. '_.rpi-sdimg-ota' for Raspberry Pi or '_.porter-sdimg-ota' Renesas Porter board). +* an `otaimg` bootstrap image, which is an OSTree physical sysroot as a burnable filesystem image, and optionally +* some machine-dependent live images (e.g. `.wic` for Raspberry Pi or `.porter-sdimg-ota` Renesas Porter board). + +Although `aglsetup.sh` hooks provide reasonable defaults for SOTA-related variables, you may want to tune some of them. + +=== Build problems -Although aglsetup.sh hooks provide reasonable defaults for SOTA-related variables, you may want to tune some of them. +Ubuntu users that encounter an error due to missing `Python.h` should install `libpython2.7-dev` on their host machine. == Supported boards @@ -67,35 +76,39 @@ Although we have used U-Boot so far, other boot loaders can be configured work w == SOTA-related variables in local.conf -* OSTREE_REPO - path to your OSTree repository. Defaults to "$\{DEPLOY_DIR_IMAGE}/ostree_repo" -* OSTREE_BRANCHNAME - the branch your rootfs will be committed to. Defaults to "ota" -* OSTREE_OSNAME - OS deployment name on your target device. For more information about deployments and osnames see the https://ostree.readthedocs.io/en/latest/manual/deployment/[OSTree documentation]. Defaults to "poky". -* OSTREE_INITRAMFS_IMAGE - initramfs/initrd image that is used as a proxy while booting into OSTree deployment. Do not change this setting unless you are sure that your initramfs can serve as such a proxy. -* OSTREE_PUSH_CREDENTIALS - when set, your ostree commit will be pushed to a remote repo as a bitbake step. This should be the path to a JSON credentials file in https://github.com/advancedtelematic/sota-tools#credentials[the format accepted by garage-push]. +* `OSTREE_REPO` - path to your OSTree repository. Defaults to `$\{DEPLOY_DIR_IMAGE}/ostree_repo` +* `OSTREE_OSNAME` - OS deployment name on your target device. For more information about deployments and osnames see the https://ostree.readthedocs.io/en/latest/manual/deployment/[OSTree documentation]. Defaults to "poky". +* `OSTREE_INITRAMFS_IMAGE` - initramfs/initrd image that is used as a proxy while booting into OSTree deployment. Do not change this setting unless you are sure that your initramfs can serve as such a proxy. +* `SOTA_PACKED_CREDENTIALS` - when set, your ostree commit will be pushed to a remote repo as a bitbake step. This should be the path to a zipped credentials file in https://github.com/advancedtelematic/aktualizr/blob/master/docs/credentials.adoc[the format accepted by garage-push]. +* `SOTA_DEPLOY_CREDENTIALS` - when set to '1' (default value), deploys credentials to the built image. Override it in `local.conf` to built a generic image that can be provisioned manually after the build. +* `SOTA_CLIENT_PROV` - which provisioning method to use. Valid options are https://github.com/advancedtelematic/aktualizr/blob/master/docs/automatic-provisioning.adoc[`aktualizr-auto-prov`], https://github.com/advancedtelematic/aktualizr/blob/master/docs/implicit-provisioning.adoc[`aktualizr-ca-implicit-prov`], and https://github.com/advancedtelematic/aktualizr/blob/master/docs/hsm-provisioning.adoc[`aktualizr-hsm-prov`]. The default is `aktualizr-auto-prov`. This can also be set to an empty string to avoid using a provisioning recipe. +* `SOTA_CLIENT_FEATURES` - extensions to aktualizr. The only valid options are `hsm` (to build with HSM support) and `secondary-network` (to set up a simulated 'in-vehicle' network with support for a primary node with a DHCP server and a secondary node with a DHCP client). +* `SOTA_SECONDARY_CONFIG_DIR` - a directory containing JSON configuration files for virtual secondaries on the host. These will be installed into `/etc/sota/ecus` on the device and automatically provided to aktualizr. +* `SOTA_HARDWARE_ID` - a custom hardware ID that will be written to the aktualizr config. Defaults to MACHINE if not set. == Usage === OSTree -OSTree includes its own simple http server. It just exposes the whole OSTree repository to the network so that any remote device can pull data from it to device's local repository. To use the OSTree http server, you will need OSTree installed on your build machine. (Alternatively, you could run version built inside Yocto using bitbake's http://www.openembedded.org/wiki/Devshell[devshell].) - -To expose your repo, run ostree trivial-httpd using any free port: +OSTree used to include a simple HTTP server as part of the ostree binary, but this has been removed in more recent versions. However, OSTree repositories are self-contained directories, and can be trivially served over the network using any HTTP server. For example, you could use Python's SimpleHTTPServer: .... -ostree trivial-httpd tmp/deploy/images/qemux86-64/ostree_repo -P 57556 +cd tmp/deploy/images/qemux86-64/ostree_repo +python -m SimpleHTTPServer # port defaults to 8000 .... You can then run ostree from inside your device by adding your repo: .... -# agl-remote identifies the remote server in your local repo -ostree remote add --no-gpg-verify my-remote http://192.168.7.1:57556 ota +# This behaves like adding a Git remote; you can name it anything +ostree remote add --no-gpg-verify my-remote http://: -# ota is a branch name in the remote repo, set in OSTREE_BRANCHNAME -ostree pull my-remote ota +# If OSTREE_BRANCHNAME is set in local.conf, that will be the name of the +# branch. If not set, it defaults to the value of MACHINE (e.g. qemux86-64). +ostree pull my-remote -# poky is OS name as set in OSTREE_OSNAME -ostree admin deploy --os=poky my-remote:ota +# poky is the OS name as set in OSTREE_OSNAME +ostree admin deploy --os=poky my-remote: .... After restarting, you will boot into the newly deployed OS image. @@ -113,12 +126,99 @@ ostree pull agl-snapshot agl-ota ostree admin deploy --os=agl agl-snapshot:agl-ota .... -=== SOTA tools +=== garage-push -SOTA tools currently contains only one tool, garage-push, which lets you push the changes in OSTree repository generated by bitbake process. It communicates with an http server capable of querying files with HEAD requests and uploading them with POST requests. In particular, this can be used with http://www.atsgarage.com/[ATS Garage]. garage-push is used as follows: +The https://github.com/advancedtelematic/aktualizr[aktualizr repo] contains a tool, garage-push, which lets you push the changes in OSTree repository generated by bitbake process. It communicates with an http server capable of querying files with HEAD requests and uploading them with POST requests. In particular, this can be used with https://connect.ota.here.com/[HERE OTA Connect]. garage-push is used as follows: .... -garage-push --repo=/path/to/ostree-repo --ref=mybranch --credentials=/path/to/credentials.json +garage-push --repo=/path/to/ostree-repo --ref=mybranch --credentials=/path/to/credentials.zip .... -You can set OSTREE_PUSH_CREDENTIALS in your local.conf to make your build results be automatically synchronized with a remote server. Credentials are stored in the JSON format described in the https://github.com/advancedtelematic/sota-tools#credentials[sota-tools README]. +You can set `SOTA_PACKED_CREDENTIALS` in your `local.conf` to automatically synchronize your build results with a remote server. Credentials are stored in an archive as described in the https://github.com/advancedtelematic/aktualizr/blob/master/docs/credentials.adoc[aktualizr documentation]. + +=== aktualizr configuration + +https://github.com/advancedtelematic/aktualizr[Aktualizr] supports a variety of https://github.com/advancedtelematic/aktualizr/blob/master/docs/configuration.adoc[configuration options via a configuration file and the command line]. There are two primary ways to control aktualizr's configuration from meta-updater. + +First, you can set `SOTA_CLIENT_PROV` to control which provisioning recipe is used. Each recipe installs an appropriate `sota.toml` file from aktualizr according to the provisioning needs. See the <> section for more information. + +Second, you can write recipes to install additional config files with customized options. A few recipes already exist to address common needs and provide an example: + +* link:recipes-sota/config/aktualizr-disable-send-ip.bb[aktualizr-disable-send-ip.bb] disables the reporting of networking information to the server. This is enabled by default and supported by https://connect.ota.here.com/[HERE OTA Connect]. However, if you are using a different server that does not support this feature, you may want to disable it in aktualizr. +* link:recipes-sota/config/aktualizr-log-debug.bb[aktualizr-log-debug.bb] sets the log level of aktualizr to 0 (trace). The default is 2 (info). This recipe is intended for development and debugging purposes. + +To use these recipes, you will need to add them to your image with a line such as `IMAGE_INSTALL_append = " aktualizr-log-debug "` in your `local.conf`. + +== Development configuration + +There are a few settings that can be controlled in `local.conf` to simplify the development process: + +[options="header"] +|====================== +| Option | Effect +| `require classes/sota_bleeding.inc` | Build the latest head (by default, using the master branch) of Aktualizr +| `BRANCH_pn-aktualizr = "mybranch"` + +`BRANCH_pn-aktualizr-native = "mybranch"` | Build `mybranch` of Aktualizr. Note that both of these need to be set. This is normally used in conjunction with `require classes/sota_bleeding.inc` +| `SRCREV_pn-aktualizr = "1004efa3f86cef90c012b34620992b5762b741e3"` + +`SRCREV_pn-aktualizr-native = "1004efa3f86cef90c012b34620992b5762b741e3"` | Build the specified revision of Aktualizr. Note that both of these need to be set. This can be used in conjunction with `BRANCH_pn-aktualizr` and `BRANCH_pn-aktualizr-native` but will conflict with `require classes/sota_bleeding.inc` +| `TOOLCHAIN_HOST_TASK_append = " nativesdk-cmake "` | Use with `bitbake -c populate_sdk core-image-minimal` to build an SDK. See the https://github.com/advancedtelematic/aktualizr#developing-against-an-openembedded-system[aktualizr repo] for more information. +|====================== + +=== Overriding target version +*Warning: overriding target version is a dangerous operation, make sure you understand this section completely before doing it.* + +Every time you build an image with `SOTA_PACKED_CREDENTIALS` set, a new entry in your Uptane metadata is created and you can see it in the OTA Garage UI if you're using one. Normally this version will be equal to OSTree hash of your root file system. If you want it to be different though you can override is using one of two methods: + +1. Set `GARAGE_TARGET_VERSION` variable in your `local.conf`. +2. Write a recipe or a bbclass to write the desired version to `${STAGING_DATADIR_NATIVE}/target_version`. An example of such bbclass can be found in `classes/target_version_example.bbclass`. + +Please note that [target name, target version] pairs are expected to be unique in the system. If you build a new target with the same target version as a previously built one, the old package will be overwritten on the update server. It can have unpredictable effect on devices that have this version installed, and it is not guaranteed that information will be reported correctly for such devices or that you will be able to update them (we're doing our best though). The easiest way to avoid problems is to make sure that your overriding version is as unique as an OSTree commit hash. + +== QA with oe-selftest + +This layer relies on the test framework oe-selftest for quality assurance. Currently, you will need to run this in a build directory with `MACHINE` set to `qemux86-64`. Follow the steps below to run the tests: + +1. Append the line below to `conf/local.conf` to disable the warning about supported operating systems: ++ +``` +SANITY_TESTED_DISTROS = "" +``` + +2. If your image does not already include an ssh daemon such as dropbear or openssh, add this line to `conf/local.conf` as well: ++ +``` +IMAGE_INSTALL_append = " dropbear " +``` + +3. Some tests require that `SOTA_PACKED_CREDENTIALS` is set in your `conf/local.conf`. See the <> section. + +4. To be able to build an image for the grub tests, you will need to install https://github.com/tianocore/tianocore.github.io/wiki/OVMF[TianoCore's ovmf] package on your host system. On Debian-like systems, you can do so with this command: ++ +``` +sudo apt install ovmf +``` + +5. Run oe-selftest: ++ +``` +oe-selftest --run-tests updater +``` + +For more information about oe-selftest, including details about how to run individual test modules or classes, please refer to the https://wiki.yoctoproject.org/wiki/Oe-selftest[Yocto Project wiki]. + +== Manual provisoning + +As described in <> section you can set `SOTA_DEPLOY_CREDENTIALS` to `0` to prevent deploying credentials to the built `wic` image. In this case you get a generic image that you can use e.g. on a production line to flash a series of devices. The cost of this approach is that this image is half-baked and should be provisioned before it can connect to the backend. + +Provisioning procedure depends on your provisioning recipe, i.e. the value of `SOTA_CLIENT_PROV` (equal to `aktualizr-auto-prov` by default): + +* For `aktualizr-auto-prov` put your `credentials.zip` to `/var/sota/sota_provisioning_credentials.zip` on the filesystem of a running device. If you have the filesystem of our device mounted to your build machine, prefix all paths with `/ostree/deploy/poky` as in `/ostree/deploy/poky/var/sota/sota_provisioning_credentials.zip`. +* For `aktualizr-ca-implicit-prov` +** put URL to the backend server (together with protocol prefix and port number) at `/var/sota/gateway.url`. If you're using HERE OTA Connect, you can find the URL in the `autoprov.url` file in your credentials archive. +** put client certificate, private key and root CA certificate (for the *server*, not for the *device*) at `/var/sota/import/client.pem`, `/var/sota/import/pkey.pem` and `/var/sota/import/root.crt` respectively. +* For `aktualizr-hsm-prov` +** put URL to the server backend (together with protocol prefix and port number) at `/var/sota/gateway.url`. If you're using HERE OTA Connect, you can find the URL in the `autoprov.url` file in your credentials archive. +** put root CA certificate (for the *server*, not for the *device*) at `/var/sota/import/root.crt`. +** put client certificate and private key to slots 1 and 2 of the PKCS#11-compatible device. -- cgit v1.2.3-54-g00ecf From 573dcfea040c33cf06c4ca315a8211eec9d67063 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Thu, 24 Jan 2019 13:23:36 +0200 Subject: sota.bbclass: add h3ulcb Add h3ulcb to be consistent with other branches. Suggested-by: Patrick Vacek Signed-off-by: Leon Anavi --- classes/sota.bbclass | 1 + 1 file changed, 1 insertion(+) diff --git a/classes/sota.bbclass b/classes/sota.bbclass index bd58d3c..6b53bb6 100644 --- a/classes/sota.bbclass +++ b/classes/sota.bbclass @@ -42,6 +42,7 @@ SOTA_MACHINE ??="none" SOTA_MACHINE_rpi ?= "raspberrypi" SOTA_MACHINE_porter ?= "porter" SOTA_MACHINE_m3ulcb = "m3ulcb" +SOTA_MACHINE_h3ulcb = "h3ulcb" SOTA_MACHINE_intel-corei7-64 ?= "minnowboard" SOTA_MACHINE_qemux86-64 ?= "qemux86-64" SOTA_MACHINE_am335x-evm ?= "am335x-evm-wifi" -- cgit v1.2.3-54-g00ecf From 36c90965b1ade296c6ac69e4ba86ee353dae0ba6 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Thu, 24 Jan 2019 13:29:04 +0200 Subject: aktualizr: handle SOTA_HARDWARE_ID Backport the brief bit of logic for handling SOTA_HARDWARE_ID from the recipe in the branches for newer releases. Suggested-by: Patrick Vacek Signed-off-by: Leon Anavi --- recipes-sota/aktualizr/aktualizr_git.bb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/recipes-sota/aktualizr/aktualizr_git.bb b/recipes-sota/aktualizr/aktualizr_git.bb index e62bdf1..ced8388 100755 --- a/recipes-sota/aktualizr/aktualizr_git.bb +++ b/recipes-sota/aktualizr/aktualizr_git.bb @@ -71,6 +71,10 @@ do_install_append () { install -m 0700 -d ${D}${libdir}/sota/conf.d install -m 0700 -d ${D}${sysconfdir}/sota/conf.d + if [ -n "${SOTA_HARDWARE_ID}" ]; then + echo "[provision]\nprimary_ecu_hardware_id = ${SOTA_HARDWARE_ID}\n" > ${D}${libdir}/sota/conf.d/40-hardware-id.toml + fi + if [ -n "${SOTA_SECONDARY_CONFIG_DIR}" ]; then if [ -d "${SOTA_SECONDARY_CONFIG_DIR}" ]; then install -m 0700 -d ${D}${sysconfdir}/sota/ecus -- cgit v1.2.3-54-g00ecf From 4e8023df199961db8e692ada3c9797124c2755b2 Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Thu, 24 Jan 2019 13:49:08 +0200 Subject: aktualizr-ca-implicit-prov-creds: aktualizr-cert-provider Minor changes because aktualizr_cert_provider has been renamed to aktualizr-cert-provider and some of the name of command-line arguments have been also changed. Suggested-by: Patrick Vacek Signed-off-by: Leon Anavi --- recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb index a729e6b..41af7c0 100644 --- a/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb +++ b/recipes-sota/aktualizr/aktualizr-ca-implicit-prov-creds.bb @@ -37,9 +37,9 @@ do_install() { fi install -m 0700 -d ${D}${localstatedir}/sota - aktualizr_cert_provider --credentials ${SOTA_PACKED_CREDENTIALS} \ - --device-ca ${SOTA_CACERT_PATH} \ - --device-ca-key ${SOTA_CAKEY_PATH} \ + aktualizr-cert-provider --credentials ${SOTA_PACKED_CREDENTIALS} \ + --fleet-ca ${SOTA_CACERT_PATH} \ + --fleet-ca-key ${SOTA_CAKEY_PATH} \ --root-ca \ --server-url \ --local ${D} \ -- cgit v1.2.3-54-g00ecf From 9d4aa221c1ba359e8ebf8c5259478cb80192e11a Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Thu, 24 Jan 2019 18:58:39 +0200 Subject: ostree: cleanup and update init.sh Cleanup of the Yocto/OE recipe for OSTree based on the work from the branches for newer Yocto releases. Use the same version of init.sh as in branch rocko. Suggested-by: Patrick Vacek Signed-off-by: Leon Anavi --- recipes-sota/ostree-initrd/files/init.sh | 2 +- recipes-sota/ostree/ostree_git.bb | 73 ++++++++++---------------------- 2 files changed, 24 insertions(+), 51 deletions(-) diff --git a/recipes-sota/ostree-initrd/files/init.sh b/recipes-sota/ostree-initrd/files/init.sh index 0b0693d..d7e0429 100644 --- a/recipes-sota/ostree-initrd/files/init.sh +++ b/recipes-sota/ostree-initrd/files/init.sh @@ -67,7 +67,7 @@ ostree-prepare-root /sysroot # move mounted devices to new root cd /sysroot -for x in dev proc; do +for x in dev proc run; do log_info "Moving /$x to new rootfs" mount -o move "/$x" "$x" done diff --git a/recipes-sota/ostree/ostree_git.bb b/recipes-sota/ostree/ostree_git.bb index a5cdc9a..6386910 100644 --- a/recipes-sota/ostree/ostree_git.bb +++ b/recipes-sota/ostree/ostree_git.bb @@ -1,8 +1,9 @@ SUMMARY = "Tool for managing bootable, immutable, versioned filesystem trees" -LICENSE = "GPLv2+" +HOMEPAGE = "https://ostree.readthedocs.io/en/latest/" +LICENSE = "LGPLv2+" LIC_FILES_CHKSUM = "file://COPYING;md5=5f30f0716dfdd0d91eb439ebec522ec2" -inherit autotools-brokensep pkgconfig systemd bash-completion gobject-introspection +inherit autotools pkgconfig systemd bash-completion gobject-introspection INHERIT_remove_class-native = "systemd" @@ -16,67 +17,47 @@ S = "${WORKDIR}/git" BBCLASSEXTEND = "native" -DEPENDS += "attr libarchive glib-2.0 pkgconfig gpgme libgsystem fuse libsoup-2.4 e2fsprogs gtk-doc-native curl xz" +DEPENDS += "attr bison-native libarchive libcap glib-2.0 gpgme fuse e2fsprogs curl xz" DEPENDS_append = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', ' systemd', '', d)}" DEPENDS_remove_class-native = "systemd-native" - -RDEPENDS_${PN} = "python util-linux-libuuid util-linux-libblkid util-linux-libmount libcap bash" -RDEPENDS_${PN}_remove_class-native = "python-native" RDEPENDS_${PN}-dracut = "bash" -EXTRA_OECONF = "--with-libarchive --disable-gtk-doc --disable-gtk-doc-html --disable-gtk-doc-pdf --disable-man --with-smack --with-builtin-grub2-mkconfig --with-curl" +CFLAGS_append = " -Wno-error=missing-prototypes" +EXTRA_OECONF = "--disable-gtk-doc --disable-man --with-smack --with-builtin-grub2-mkconfig --with-curl --without-soup" EXTRA_OECONF_append_class-native = " --enable-wrpseudo-compat" +PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd', '', d)}" +PACKAGECONFIG_class-native = "" +PACKAGECONFIG[systemd] = "--with-systemdsystemunitdir=${systemd_unitdir}/system/ --with-dracut" + # Path to ${prefix}/lib/ostree/ostree-grub-generator is hardcoded on the # do_configure stage so we do depend on it SYSROOT_DIR = "${STAGING_DIR_TARGET}" SYSROOT_DIR_class-native = "${STAGING_DIR_NATIVE}" do_configure[vardeps] += "SYSROOT_DIR" -SYSTEMD_REQUIRED = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}" -SYSTEMD_REQUIRED_class-native = "" - -SYSTEMD_SERVICE_${PN} = "ostree-prepare-root.service ostree-remount.service" -SYSTEMD_SERVICE_${PN}_class-native = "" - -PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd', '', d)}" -PACKAGECONFIG_class-native = "" -PACKAGECONFIG[systemd] = "--with-systemdsystemunitdir=${systemd_unitdir}/system/ --with-dracut" - -FILES_${PN} += "${libdir}/ostree/ ${libdir}/ostbuild" +SYSTEMD_SERVICE_${PN} = "ostree-prepare-root.service ostree-remount.service ostree-finalize-staged.service" +export BUILD_SYS +export HOST_SYS export STAGING_INCDIR export STAGING_LIBDIR -do_configure() { - unset docdir - NOCONFIGURE=1 ./autogen.sh - oe_runconf -} - -do_compile_prepend() { - export BUILD_SYS="${BUILD_SYS}" - export HOST_SYS="${HOST_SYS}" -} - -SYSTEMD_SERVICE_${PN} = "ostree-prepare-root.service ostree-remount.service ostree-finalize-staged.service" - -export SYSTEMD_REQUIRED - -do_install_append() { - if [ -n ${SYSTEMD_REQUIRED} ]; then - install -p -D ${S}/src/boot/ostree-prepare-root.service ${D}${systemd_unitdir}/system/ostree-prepare-root.service - install -p -D ${S}/src/boot/ostree-remount.service ${D}${systemd_unitdir}/system/ostree-remount.service - fi +do_configure_prepend() { + unset docdir + NOCONFIGURE=1 "${S}/autogen.sh" } do_install_append_class-native() { - create_wrapper ${D}${bindir}/ostree OSTREE_GRUB2_EXEC="${STAGING_LIBDIR_NATIVE}/ostree/ostree-grub-generator" + create_wrapper ${D}${bindir}/ostree OSTREE_GRUB2_EXEC="${STAGING_LIBDIR_NATIVE}/ostree/ostree-grub-generator" } +PACKAGES += " \ + ${PN}-switchroot \ + ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'ostree-dracut', '', d)} \ +" -FILES_${PN} += " \ - {bindir} \ +FILES_${PN} = "${bindir} \ ${sysconfdir}/ostree \ ${datadir}/ostree \ ${libdir}/*.so.* \ @@ -86,14 +67,6 @@ FILES_${PN} += " \ ${@bb.utils.contains('DISTRO_FEATURES','systemd','${libdir}/tmpfiles.d', '', d)} \ ${@bb.utils.contains('DISTRO_FEATURES','systemd','${systemd_unitdir}/system-generators', '', d)} \ " - -PACKAGES =+ " \ - ${PN}-switchroot \ - ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'ostree-dracut', '', d)} \ -" - -FILES_${PN}-switchroot = "${libdir}/ostree/ostree-prepare-root" -RDEPENDS_${PN}-switchroot = "" -DEPENDS_remove_class-native = "systemd-native" FILES_${PN}-dev += " ${datadir}/gir-1.0" FILES_${PN}-dracut = "${sysconfdir}/dracut.conf.d ${libdir}/dracut" +FILES_${PN}-switchroot = "${libdir}/ostree/ostree-prepare-root" -- cgit v1.2.3-54-g00ecf From c7236fe0bfeab1166addca2d3dd2096936b0fb9c Mon Sep 17 00:00:00 2001 From: Leon Anavi Date: Fri, 25 Jan 2019 10:07:31 +0200 Subject: Backporting supplementary recipes from Rocko Backport additional recipes for sota, support and test from branch rocko as well as the class target_version_example. Suggested-by: Patrick Vacek Signed-off-by: Leon Anavi --- classes/target_version_example.bbclass | 10 +++ recipes-sota/config/aktualizr-disable-send-ip.bb | 22 ++++++ recipes-sota/config/aktualizr-log-debug.bb | 22 ++++++ recipes-sota/config/files/05-log-debug.toml | 2 + recipes-sota/config/files/30-disable-send-ip.toml | 2 + ...und-for-a-buggy-version-of-openssl-1.0.2m.patch | 42 +++++++++++ recipes-support/libp11/libp11_0.4.9.bb | 39 ++++++++++ recipes-support/slcand-start/files/slcand@.service | 8 ++ recipes-support/slcand-start/slcand-start.bb | 21 ++++++ .../softhsm-testtoken/files/createtoken.service | 12 +++ .../softhsm-testtoken/files/createtoken.sh | 27 +++++++ .../softhsm-testtoken/softhsm-testtoken.bb | 25 +++++++ .../files/0001-Cross-compilation-tweaks.patch | 86 ++++++++++++++++++++++ recipes-support/softhsm/softhsm_git.bb | 27 +++++++ .../files/25-dhcp-server.network | 12 +++ .../files/26-dhcp-client.network | 6 ++ .../files/27-dhcp-client-external.network | 6 ++ .../demo-network-config/primary-network-config.bb | 16 ++++ .../secondary-network-config.bb | 20 +++++ recipes-test/images/primary-image.bb | 14 ++++ recipes-test/images/secondary-image.bb | 27 +++++++ 21 files changed, 446 insertions(+) create mode 100644 classes/target_version_example.bbclass create mode 100644 recipes-sota/config/aktualizr-disable-send-ip.bb create mode 100644 recipes-sota/config/aktualizr-log-debug.bb create mode 100644 recipes-sota/config/files/05-log-debug.toml create mode 100644 recipes-sota/config/files/30-disable-send-ip.toml create mode 100644 recipes-support/libp11/files/0001-Workaround-for-a-buggy-version-of-openssl-1.0.2m.patch create mode 100644 recipes-support/libp11/libp11_0.4.9.bb create mode 100644 recipes-support/slcand-start/files/slcand@.service create mode 100644 recipes-support/slcand-start/slcand-start.bb create mode 100644 recipes-support/softhsm-testtoken/files/createtoken.service create mode 100644 recipes-support/softhsm-testtoken/files/createtoken.sh create mode 100644 recipes-support/softhsm-testtoken/softhsm-testtoken.bb create mode 100644 recipes-support/softhsm/files/0001-Cross-compilation-tweaks.patch create mode 100644 recipes-support/softhsm/softhsm_git.bb create mode 100644 recipes-test/demo-network-config/files/25-dhcp-server.network create mode 100644 recipes-test/demo-network-config/files/26-dhcp-client.network create mode 100644 recipes-test/demo-network-config/files/27-dhcp-client-external.network create mode 100644 recipes-test/demo-network-config/primary-network-config.bb create mode 100644 recipes-test/demo-network-config/secondary-network-config.bb create mode 100644 recipes-test/images/primary-image.bb create mode 100644 recipes-test/images/secondary-image.bb diff --git a/classes/target_version_example.bbclass b/classes/target_version_example.bbclass new file mode 100644 index 0000000..ef119fb --- /dev/null +++ b/classes/target_version_example.bbclass @@ -0,0 +1,10 @@ +# Writes target version to be used by garage-sign + +HOSTTOOLS += " git " + +deploy_target_version () { + version=$(git --git-dir=${METADIR}/.repo/manifests/.git/ rev-parse HEAD) + echo -n ${version} > ${STAGING_DATADIR_NATIVE}/target_version +} + +IMAGE_PREPROCESS_COMMAND += "deploy_target_version;" diff --git a/recipes-sota/config/aktualizr-disable-send-ip.bb b/recipes-sota/config/aktualizr-disable-send-ip.bb new file mode 100644 index 0000000..8dd2647 --- /dev/null +++ b/recipes-sota/config/aktualizr-disable-send-ip.bb @@ -0,0 +1,22 @@ +SUMMARY = "Disable IP reporting in Aktualizr" +DESCRIPTION = "Configures aktualizr to disable IP reporting to the server" +HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" +SECTION = "base" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" + +SRC_URI = " \ + file://30-disable-send-ip.toml \ + " + +do_install_append () { + install -m 0700 -d ${D}${libdir}/sota/conf.d + install -m 0644 ${WORKDIR}/30-disable-send-ip.toml ${D}${libdir}/sota/conf.d/30-disable-send-ip.toml +} + +FILES_${PN} = " \ + ${libdir}/sota/conf.d/30-disable-send-ip.toml \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: + diff --git a/recipes-sota/config/aktualizr-log-debug.bb b/recipes-sota/config/aktualizr-log-debug.bb new file mode 100644 index 0000000..098faf4 --- /dev/null +++ b/recipes-sota/config/aktualizr-log-debug.bb @@ -0,0 +1,22 @@ +SUMMARY = "Set debug logging in Aktualizr" +DESCRIPTION = "Configures aktualizr to log at a debugging level" +HOMEPAGE = "https://github.com/advancedtelematic/aktualizr" +SECTION = "base" +LICENSE = "MPL-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad" + +SRC_URI = " \ + file://05-log-debug.toml \ + " + +do_install_append () { + install -m 0700 -d ${D}${libdir}/sota/conf.d + install -m 0644 ${WORKDIR}/05-log-debug.toml ${D}${libdir}/sota/conf.d/05-log-debug.toml +} + +FILES_${PN} = " \ + ${libdir}/sota/conf.d/05-log-debug.toml \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: + diff --git a/recipes-sota/config/files/05-log-debug.toml b/recipes-sota/config/files/05-log-debug.toml new file mode 100644 index 0000000..100a146 --- /dev/null +++ b/recipes-sota/config/files/05-log-debug.toml @@ -0,0 +1,2 @@ +[logger] +loglevel = 0 diff --git a/recipes-sota/config/files/30-disable-send-ip.toml b/recipes-sota/config/files/30-disable-send-ip.toml new file mode 100644 index 0000000..5cd5108 --- /dev/null +++ b/recipes-sota/config/files/30-disable-send-ip.toml @@ -0,0 +1,2 @@ +[telemetry] +report_network = false diff --git a/recipes-support/libp11/files/0001-Workaround-for-a-buggy-version-of-openssl-1.0.2m.patch b/recipes-support/libp11/files/0001-Workaround-for-a-buggy-version-of-openssl-1.0.2m.patch new file mode 100644 index 0000000..902352c --- /dev/null +++ b/recipes-support/libp11/files/0001-Workaround-for-a-buggy-version-of-openssl-1.0.2m.patch @@ -0,0 +1,42 @@ +From ccab5ce63dd5d3dbb4bd02998d21d34407e550f2 Mon Sep 17 00:00:00 2001 +From: Anton Gerasimov +Date: Fri, 19 Jan 2018 12:44:27 +0100 +Subject: [PATCH] Workaround for a buggy version of openssl (1.0.2m) + +--- + src/p11_pkey.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/p11_pkey.c b/src/p11_pkey.c +index 45d5ad3..75625e6 100644 +--- a/src/p11_pkey.c ++++ b/src/p11_pkey.c +@@ -139,8 +139,14 @@ static void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src) + + #endif + +-#if OPENSSL_VERSION_NUMBER < 0x100020d0L || defined(LIBRESSL_VERSION_NUMBER) +-static void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, ++#if OPENSSL_VERSION_NUMBER < 0x10002100L || defined(LIBRESSL_VERSION_NUMBER) ++ ++# if (OPENSSL_VERSION_NUMBER & 0xFFFFFFF0) == 0x100020d0L ++# undef EVP_PKEY_meth_get_sign ++# undef EVP_PKEY_meth_get_decrypt ++# endif ++ ++void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, +@@ -152,7 +158,7 @@ static void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + *psign = pmeth->sign; + } + +-static void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, ++void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, +-- +2.15.1 + diff --git a/recipes-support/libp11/libp11_0.4.9.bb b/recipes-support/libp11/libp11_0.4.9.bb new file mode 100644 index 0000000..6d0165f --- /dev/null +++ b/recipes-support/libp11/libp11_0.4.9.bb @@ -0,0 +1,39 @@ +SUMMARY = "Library for using PKCS" +DESCRIPTION = "\ +Libp11 is a library implementing a small layer on top of PKCS \ +make using PKCS" +HOMEPAGE = "http://www.opensc-project.org/libp11" +SECTION = "Development/Libraries" +LICENSE = "LGPLv2+" +LIC_FILES_CHKSUM = "file://COPYING;md5=fad9b3332be894bab9bc501572864b29" +DEPENDS = "libtool openssl" +RDEPENDS_${PN} += " opensc" + +SRC_URI = "git://github.com/OpenSC/libp11.git \ + file://0001-Workaround-for-a-buggy-version-of-openssl-1.0.2m.patch" +SRCREV = "e1210903291b1de9eabcad26e740a4b2fbcca692" + +S = "${WORKDIR}/git" + +inherit autotools pkgconfig + +# Currently, Makefile dependencies are incorrectly defined which causes build errors +# if the number of jobs is high +# See https://github.com/OpenSC/libp11/issues/94 +PARALLEL_MAKE = "" +EXTRA_OECONF = "--disable-static" + +do_install_append () { + rm -rf ${D}${libdir}/*.la + rm -rf ${D}${docdir}/${BPN} +} + +FILES_${PN} = "${libdir}/engines*/pkcs11.so \ + ${libdir}/engines*/libpkcs11${SOLIBS} \ + ${libdir}/libp11${SOLIBS}" + +FILES_${PN}-dev = " \ + ${libdir}/engines*/libpkcs11${SOLIBSDEV} \ + ${libdir}/libp11${SOLIBSDEV} \ + ${libdir}/pkgconfig/libp11.pc \ + /usr/include" diff --git a/recipes-support/slcand-start/files/slcand@.service b/recipes-support/slcand-start/files/slcand@.service new file mode 100644 index 0000000..c539568 --- /dev/null +++ b/recipes-support/slcand-start/files/slcand@.service @@ -0,0 +1,8 @@ +[Unit] +Description=Serial CAN daemon (can-utils) + +[Service] +Type=forking +ExecStart=/usr/bin/slcand -o -c -s4 %I can0 +ExecStartPost=/bin/sh -c '/bin/sleep 3; /sbin/ip link set can0 up' + diff --git a/recipes-support/slcand-start/slcand-start.bb b/recipes-support/slcand-start/slcand-start.bb new file mode 100644 index 0000000..dfefaea --- /dev/null +++ b/recipes-support/slcand-start/slcand-start.bb @@ -0,0 +1,21 @@ +SUMMARY = "Mock smartcard for aktualizr" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \ + file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" + + +inherit systemd + +RDEPENDS_${PN} = "can-utils" + +SRC_URI = "file://slcand@.service" + +SYSTEMD_SERVICE_${PN} = "slcand@.service" + +do_install() { + install -d ${D}${systemd_unitdir}/system + install -m 0644 ${WORKDIR}/slcand@.service ${D}${systemd_unitdir}/system/slcand@.service +} + +FILES_${PN} = "${systemd_unitdir}/system/createtoken.service" + diff --git a/recipes-support/softhsm-testtoken/files/createtoken.service b/recipes-support/softhsm-testtoken/files/createtoken.service new file mode 100644 index 0000000..23317b9 --- /dev/null +++ b/recipes-support/softhsm-testtoken/files/createtoken.service @@ -0,0 +1,12 @@ +[Unit] +Description=Create a mock smartcard for testing +Before=aktualizr.service +RequiredBy=aktualizr.service + +[Service] +RestartSec=10 +Restart=on-failure +ExecStart=/usr/bin/createtoken.sh + +[Install] +WantedBy=aktualizr.service diff --git a/recipes-support/softhsm-testtoken/files/createtoken.sh b/recipes-support/softhsm-testtoken/files/createtoken.sh new file mode 100644 index 0000000..fa4569d --- /dev/null +++ b/recipes-support/softhsm-testtoken/files/createtoken.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +if pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O; then + # The token has already been initialized, exit + exit 0 +fi + +if ! ls /var/sota/import/pkey.pem /var/sota/import/client.pem; then + # Key/certificate pair is not present, repeat + exit 1 +fi + +mkdir -p /var/lib/softhsm/tokens +softhsm2-util --init-token --slot 0 --label "Virtual token" --pin 1234 --so-pin 1234 + +openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in /var/sota/import/pkey.pem -out /var/sota/import/pkey.p8 +softhsm2-util --import /var/sota/import/pkey.p8 --label "pkey" --id 02 --token 'Virtual token' --pin 1234 +openssl x509 -outform der -in /var/sota/import/client.pem -out /var/sota/import/client.der +pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so --id 1 --write-object /var/sota/import/client.der --type cert --login --pin 1234 + +# Import UPTANE keypair if it exists +if [ -f /var/sota/import/ecukey.pem ]; then + openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in /var/sota/import/ecukey.pem -out /var/sota/import/ecukey.p8 + softhsm2-util --import /var/sota/import/ecukey.p8 --label "uptanekey" --id 03 --token 'Virtual token' --pin 1234 +fi + +exit 0 diff --git a/recipes-support/softhsm-testtoken/softhsm-testtoken.bb b/recipes-support/softhsm-testtoken/softhsm-testtoken.bb new file mode 100644 index 0000000..029fe1c --- /dev/null +++ b/recipes-support/softhsm-testtoken/softhsm-testtoken.bb @@ -0,0 +1,25 @@ +SUMMARY = "Mock smartcard for aktualizr" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +inherit systemd + +RDEPENDS_${PN} = "softhsm libp11" +DEPENDS_append = "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', ' systemd', '', d)}" + + +SRC_URI = "file://createtoken.service \ + file://createtoken.sh" + +SYSTEMD_SERVICE_${PN} = "createtoken.service" + +do_install() { + install -d ${D}${systemd_unitdir}/system + install -m 0644 ${WORKDIR}/createtoken.service ${D}${systemd_unitdir}/system/createtoken.service + install -d ${D}${bindir} + install -m 0744 ${WORKDIR}/createtoken.sh ${D}${bindir}/createtoken.sh +} + +FILES_${PN} = "${bindir}/createtoken.sh \ + ${systemd_unitdir}/system/createtoken.service" + diff --git a/recipes-support/softhsm/files/0001-Cross-compilation-tweaks.patch b/recipes-support/softhsm/files/0001-Cross-compilation-tweaks.patch new file mode 100644 index 0000000..b3a7622 --- /dev/null +++ b/recipes-support/softhsm/files/0001-Cross-compilation-tweaks.patch @@ -0,0 +1,86 @@ +From b6add28acb884b6006216e8422cc18504483c72e Mon Sep 17 00:00:00 2001 +From: Anton Gerasimov +Date: Fri, 8 Sep 2017 15:08:40 +0200 +Subject: [PATCH] Cross-compilation tweaks + +--- + m4/acx_openssl.m4 | 2 ++ + m4/acx_openssl_ecc.m4 | 3 +++ + m4/acx_openssl_fips.m4 | 2 ++ + m4/acx_openssl_gost.m4 | 2 ++ + 4 files changed, 9 insertions(+) + +diff --git a/m4/acx_openssl.m4 b/m4/acx_openssl.m4 +index e90c78f..9de6055 100644 +--- a/m4/acx_openssl.m4 ++++ b/m4/acx_openssl.m4 +@@ -25,6 +25,7 @@ AC_DEFUN([ACX_OPENSSL],[ + AC_CHECK_HEADERS([openssl/ssl.h],,[AC_MSG_ERROR([Can't find OpenSSL headers])]) + AC_CHECK_LIB(crypto, BN_new,,[AC_MSG_ERROR([Can't find OpenSSL library])]) + ++ if test "$cross_compiling" != yes; then + AC_MSG_CHECKING([for OpenSSL version]) + CHECK_OPENSSL_VERSION=m4_format(0x%02x%02x%02x000L, $1, $2, $3) + AC_LANG_PUSH([C]) +@@ -51,6 +52,7 @@ AC_DEFUN([ACX_OPENSSL],[ + AC_MSG_ERROR([OpenSSL library too old ($1.$2.$3 or later required)]) + ],[]) + AC_LANG_POP([C]) ++ fi + + CPPFLAGS=$tmp_CPPFLAGS + LIBS=$tmp_LIBS +diff --git a/m4/acx_openssl_ecc.m4 b/m4/acx_openssl_ecc.m4 +index 612c505..ba2389d 100644 +--- a/m4/acx_openssl_ecc.m4 ++++ b/m4/acx_openssl_ecc.m4 +@@ -1,4 +1,5 @@ + AC_DEFUN([ACX_OPENSSL_ECC],[ ++ if test "$cross_compiling" != yes; then + AC_MSG_CHECKING(for OpenSSL ECC support) + + tmp_CPPFLAGS=$CPPFLAGS +@@ -32,6 +33,8 @@ AC_DEFUN([ACX_OPENSSL_ECC],[ + ],[]) + AC_LANG_POP([C]) + ++ fi ++ + CPPFLAGS=$tmp_CPPFLAGS + LIBS=$tmp_LIBS + ]) +diff --git a/m4/acx_openssl_fips.m4 b/m4/acx_openssl_fips.m4 +index 0491397..896cdbf 100644 +--- a/m4/acx_openssl_fips.m4 ++++ b/m4/acx_openssl_fips.m4 +@@ -1,4 +1,5 @@ + AC_DEFUN([ACX_OPENSSL_FIPS],[ ++ if test "$cross_compiling" != yes; then + AC_MSG_CHECKING(for OpenSSL FIPS capable library) + + tmp_CPPFLAGS=$CPPFLAGS +@@ -47,4 +48,5 @@ AC_DEFUN([ACX_OPENSSL_FIPS],[ + + CPPFLAGS=$tmp_CPPFLAGS + LIBS=$tmp_LIBS ++ fi + ]) +diff --git a/m4/acx_openssl_gost.m4 b/m4/acx_openssl_gost.m4 +index dca489b..34c39d8 100644 +--- a/m4/acx_openssl_gost.m4 ++++ b/m4/acx_openssl_gost.m4 +@@ -1,4 +1,5 @@ + AC_DEFUN([ACX_OPENSSL_GOST],[ ++ if test "$cross_compiling" != yes; then + AC_MSG_CHECKING(for OpenSSL GOST support) + + tmp_CPPFLAGS=$CPPFLAGS +@@ -62,4 +63,5 @@ AC_DEFUN([ACX_OPENSSL_GOST],[ + + CPPFLAGS=$tmp_CPPFLAGS + LIBS=$tmp_LIBS ++ fi + ]) +-- +2.7.4 + diff --git a/recipes-support/softhsm/softhsm_git.bb b/recipes-support/softhsm/softhsm_git.bb new file mode 100644 index 0000000..c26903d --- /dev/null +++ b/recipes-support/softhsm/softhsm_git.bb @@ -0,0 +1,27 @@ +SUMMARY = "HSM emulator" +LICENSE = "BSD" +LIC_FILES_CHKSUM = "file://LICENSE;md5=ef3f77a3507c3d91e75b9f2bdaee4210" + +inherit autotools-brokensep + + +SRC_URI = "git://github.com/opendnssec/SoftHSMv2.git;branch=master \ + file://0001-Cross-compilation-tweaks.patch" +SRCREV="1f7498c0c65b1b1ad5e1bdbd87e9d4b100705745" + +S = "${WORKDIR}/git" + +DEPENDS += " openssl" + +EXTRA_OECONF = "--disable-gost --with-openssl=${STAGING_LIBDIR}/.." + +do_configure() { + unset docdir + sh ./autogen.sh + oe_runconf +} + +FILES_${PN} = "${bindir} \ + ${libdir}/softhsm \ + ${sysconfdir} \ + ${localstatedir}/lib/softhsm " diff --git a/recipes-test/demo-network-config/files/25-dhcp-server.network b/recipes-test/demo-network-config/files/25-dhcp-server.network new file mode 100644 index 0000000..4766f9a --- /dev/null +++ b/recipes-test/demo-network-config/files/25-dhcp-server.network @@ -0,0 +1,12 @@ +[Match] +Name=enp0s4 + +[Network] +Description=Private internal network between aktualizr Primary and Secondary nodes +DHCPServer=yes +Address=10.0.3.1/24 +IPForward=yes +IPMasquerade=yes + +[DHCPServer] +PoolOffset=10 \ No newline at end of file diff --git a/recipes-test/demo-network-config/files/26-dhcp-client.network b/recipes-test/demo-network-config/files/26-dhcp-client.network new file mode 100644 index 0000000..319664f --- /dev/null +++ b/recipes-test/demo-network-config/files/26-dhcp-client.network @@ -0,0 +1,6 @@ +[Match] +Name=enp0s4 + +[Network] +Description=Private internal network between aktualizr Primary and Secondary nodes +DHCP=yes diff --git a/recipes-test/demo-network-config/files/27-dhcp-client-external.network b/recipes-test/demo-network-config/files/27-dhcp-client-external.network new file mode 100644 index 0000000..ba49593 --- /dev/null +++ b/recipes-test/demo-network-config/files/27-dhcp-client-external.network @@ -0,0 +1,6 @@ +[Match] +Name=enp0s3 + +[Network] +Description=External network for secondary +DHCP=yes diff --git a/recipes-test/demo-network-config/primary-network-config.bb b/recipes-test/demo-network-config/primary-network-config.bb new file mode 100644 index 0000000..78678a2 --- /dev/null +++ b/recipes-test/demo-network-config/primary-network-config.bb @@ -0,0 +1,16 @@ +DESCRIPTION = "Sample network configuration for an Uptane Primary" +LICENSE = "CLOSED" + +inherit allarch + +SRC_URI = "file://25-dhcp-server.network" + + +FILES_${PN} = "/usr/lib/systemd/network" + +PR = "1" + +do_install() { + install -d ${D}/usr/lib/systemd/network + install -m 0644 ${WORKDIR}/25-dhcp-server.network ${D}/usr/lib/systemd/network/ +} diff --git a/recipes-test/demo-network-config/secondary-network-config.bb b/recipes-test/demo-network-config/secondary-network-config.bb new file mode 100644 index 0000000..9091c65 --- /dev/null +++ b/recipes-test/demo-network-config/secondary-network-config.bb @@ -0,0 +1,20 @@ +DESCRIPTION = "Sample network configuration for an Uptane Secondary" +LICENSE = "CLOSED" + +inherit allarch + +SRC_URI = "\ + file://26-dhcp-client.network \ + file://27-dhcp-client-external.network \ + " + + +FILES_${PN} = "/usr/lib/systemd/network" + +PR = "1" + +do_install() { + install -d ${D}/usr/lib/systemd/network + install -m 0644 ${WORKDIR}/26-dhcp-client.network ${D}/usr/lib/systemd/network/ + install -m 0644 ${WORKDIR}/27-dhcp-client-external.network ${D}/usr/lib/systemd/network/ +} diff --git a/recipes-test/images/primary-image.bb b/recipes-test/images/primary-image.bb new file mode 100644 index 0000000..6d2df94 --- /dev/null +++ b/recipes-test/images/primary-image.bb @@ -0,0 +1,14 @@ +include recipes-core/images/core-image-minimal.bb + +SUMMARY = "A minimal Uptane Primary image running aktualizr, for testing with a Linux secondary" + +LICENSE = "MIT" + +IMAGE_INSTALL_remove = " \ + " + +IMAGE_INSTALL_append = " \ + primary-network-config \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/recipes-test/images/secondary-image.bb b/recipes-test/images/secondary-image.bb new file mode 100644 index 0000000..1a41169 --- /dev/null +++ b/recipes-test/images/secondary-image.bb @@ -0,0 +1,27 @@ +include recipes-core/images/core-image-minimal.bb + +SUMMARY = "A minimal Uptane Secondary image running aktualizr-secondary" + +LICENSE = "MIT" + + +# Remove default aktualizr primary, and the provisioning configuration (which +# RDEPENDS on aktualizr) +IMAGE_INSTALL_remove = " \ + aktualizr \ + aktualizr-auto-prov \ + aktualizr-auto-prov-creds \ + aktualizr-ca-implicit-prov \ + aktualizr-ca-implicit-prov-creds \ + aktualizr-hsm-prov \ + aktualizr-uboot-env-rollback \ + connman \ + connman-client \ + " + +IMAGE_INSTALL_append = " \ + aktualizr-secondary \ + secondary-network-config \ + " + +# vim:set ts=4 sw=4 sts=4 expandtab: -- cgit v1.2.3-54-g00ecf