swupdate-progress \
"
+EXTRA_IMAGEDEPENDS += "swupdate-ab"
+
# Remove swupdate-www (package with the website, that you can customize with
# your own logo, template and style).
IMAGE_INSTALL:remove = " \
SRC_URI = " \
file://sw-description \
- file://update.sh \
"
# Image(s) and files that will be included in the .swu image
-SWUPDATE_IMAGES = "${IMAGE_DEPENDS}"
+SWUPDATE_IMAGES = "${IMAGE_DEPENDS} swupdate-ab.sh"
UBOOT_PART_VAR ?= "mmcpart"
);
scripts: (
{
- filename = "update.sh";
+ filename = "swupdate-ab.sh";
type = "shellscript";
data = "@@ROOT_PART_PREFIX@@@@ROOT_PART_A_ID@@"; /* Destination partition ID */
- sha256 = "$swupdate_get_sha256(update.sh)";
+ sha256 = "$swupdate_get_sha256(swupdate-ab.sh)";
}
);
bootenv: (
);
scripts: (
{
- filename = "update.sh";
+ filename = "swupdate-ab.sh";
type = "shellscript";
data = "@@ROOT_PART_PREFIX@@@@ROOT_PART_B_ID@@"; /* Destination partition ID */
- sha256 = "$swupdate_get_sha256(update.sh)";
+ sha256 = "$swupdate_get_sha256(swupdate-ab.sh)";
}
);
bootenv: (
+++ /dev/null
-#!/bin/sh
-set -e
-
-# Shell scripts are called via system command. SWUpdate scans for all scripts
-# and calls them before and after installing the images. SWUpdate passes
-# ‘preinst’ or ‘postinst’ as first argument to the script. If the data attribute
-# is defined, its value is passed as the last argument(s) to the script.
-
-FSTYPE="ext4"
-
-echo "${0}: arguments = \"${*}\""
-
-if [ $# -lt 2 ]; then
- exit 1;
-fi
-
-# L'environnement U-Boot doit être valide pour utiliser ce script.
-# Après la programmation initiale avec uuu, il faut effectuer la sauvegarde
-# de l'environnement en mémoire non-volatile (ex: eMMC) dans U-boot avec
-# 'saveenv'. Sinon, fw_saveenv va utiliser l'environnement par défaut contenu
-# dans /etc/u-boot-initial-env
-if fw_printenv 2>&1 | grep -q 'Cannot read environment'; then
- echo "Warning: U-Boot environment cannot be read. Make sure you save the"
- echo " default environment to flash using these U-Boot commands:"
- echo " $> env default -a"
- echo " $> saveenv"
-fi
-
-do_preinst()
-{
- # Find internal parent kernel device name of rootfs.
- # For example:
- # - /dev/sda1 --> /dev/sda
- # - /dev/mmcblk2p2 --> /dev/mmcblk2
- disk="/dev/$(lsblk -ndo pkname $(findmnt -n -o SOURCE /))"
-
- if [ ! -b "${disk}" ]; then
- echo "Error: disk \"${disk}\" not found"
- exit 1
- fi
-
- update_dev="${disk}${next_part}"
-
- if [ ! -b "${update_dev}" ]; then
- echo "Error: destination partition \"${update_dev}\" not found"
- exit 1
- fi
-
- echo "${0}: destination device = ${update_dev}"
-
- # Create temporary mount point:
- tmp_file=$(mktemp -q -d /tmp/swupdate-mount.XXXXXX)
- if [ ${?} -ne 0 ]; then
- echo "Error: cannot create temporary file"
- exit 1
- fi
-
- # Mount update partition:
- mount -t ${FSTYPE} ${update_dev} ${tmp_file}
-
- # Remove old data:
- echo "${0}: erasing old data..."
- rm -rf ${tmp_file}/*
-
- # Finish
- umount ${tmp_file}
- rmdir ${tmp_file}
-
- exit 0
-}
-
-do_postinst()
-{
- exit 0
-}
-
-next_part=${2}
-
-case "$1" in
- preinst)
- do_preinst
- ;;
- postinst)
- do_postinst
- ;;
- *)
- echo "unsupported install mode: \"${1}\""
- exit 1
- ;;
-esac
--- /dev/null
+
+# L'environnement U-Boot doit être valide pour utiliser ce script.
+# Après la programmation initiale avec uuu, il faut effectuer la sauvegarde
+# de l'environnement en mémoire non-volatile (ex: eMMC) dans U-boot avec
+# 'saveenv'. Sinon, fw_saveenv va utiliser l'environnement par défaut contenu
+# dans /etc/u-boot-initial-env
+if fw_printenv 2>&1 | grep -q 'Cannot read environment'; then
+ echo "Warning: U-Boot environment cannot be read. Make sure you save the"
+ echo " default environment to flash using these U-Boot commands:"
+ echo " $> env default -a"
+ echo " $> saveenv"
+fi
+
+# Return the partition device
+get_destination_partition_device()
+{
+ # Find internal parent kernel device name of rootfs.
+ # For example:
+ # - /dev/sda1 --> /dev/sda
+ # - /dev/mmcblk2p2 --> /dev/mmcblk2
+ disk="/dev/$(lsblk -ndo pkname $(findmnt -n -o SOURCE /))"
+
+ if [ ! -b "${disk}" ]; then
+ swulog "Error: disk \"${disk}\" not found"
+ return 1
+ fi
+
+ update_dev="${disk}${next_part}"
+
+ if [ ! -b "${update_dev}" ]; then
+ swulog "Error: destination partition \"${update_dev}\" not found"
+ return 1
+ fi
+
+ echo "${update_dev}"
+ return 0
+}
+
+mount_destination_partition()
+{
+ update_dev=$(get_destination_partition_device)
+
+ # Create temporary mount point:
+ mnt_point=$(mktemp -q -d /tmp/swupdate-mount.XXXXXX)
+ if [ ${?} -ne 0 ]; then
+ swulog "Error: cannot create temporary file"
+ exit 1
+ fi
+
+ # Mount update partition:
+ mount -t ${FSTYPE} ${update_dev} ${mnt_point}
+}
+
+unmount_destination_partition()
+{
+ if mount | grep -q ${mnt_point}; then
+ umount ${mnt_point}
+ fi
+
+ if [ -d ${mnt_point} ]; then
+ rmdir ${mnt_point}
+ fi
+}
+
+do_preinst()
+{
+ update_dev=$(get_destination_partition_device)
+ swulog "Reformat destination partition: ${update_dev}"
+
+ label="$(blkid -s LABEL -o value ${update_dev})"
+
+ # Reformat destination partition:
+ mkfs.${FSTYPE} ${update_dev} -L "${label}"
+
+ exit 0
+}
+
+do_postinst()
+{
+ mount_destination_partition
+
+ # Perform migration of selected files/folders...
+ swulog "migrating existing data..."
+
+ # Migrate files:
+ for f in ${SWU_PRESERVE_FILES}; do
+ if [ ! -f ${f} ]; then
+ swulog "warning: missing source file: ${f} (skipping)"
+ continue
+ fi
+
+ dst_folder="$(dirname ${mnt_point}/${f})"
+
+ # Do not copy file if destination folder doesn't exist.
+ # The destination folder need to be created in your new SWU archive
+ # with the proper ownership and permissions (can be empty)
+ if [ ! -d ${dst_folder} ]; then
+ swulog "warning: missing destination folder for file: ${f} (skipping)"
+ continue
+ fi
+
+ # Copy old file to new partition:
+ cp -a ${f} ${mnt_point}/${f}
+ done
+
+ # Migrate folders:
+ for d in ${SWU_PRESERVE_FOLDERS}; do
+ if [ ! -d ${d} ]; then
+ swulog "warning: missing source folder: ${d} (skipping)"
+ continue
+ fi
+
+ if [ -d ${mnt_point}/${d} ]; then
+ # Remove folder if it exists in new partition:
+ rm -rf ${mnt_point}/${d}
+ fi
+
+ # Copy old folder to new partition:
+ cp -a ${d} ${mnt_point}/${d}
+ done
+
+ unmount_destination_partition
+
+ exit 0
+}
+
+next_part=${2}
+
+case "$1" in
+ preinst)
+ do_preinst
+ ;;
+ postinst)
+ do_postinst
+ ;;
+ *)
+ swulog "unsupported install mode: \"${1}\""
+ exit 1
+ ;;
+esac
--- /dev/null
+#!/bin/sh
+set -e
+
+# Shell scripts are called via system command. SWUpdate scans for all scripts
+# and calls them before and after installing the images. SWUpdate passes
+# ‘preinst’ or ‘postinst’ as first argument to the script. If the data attribute
+# is defined, its value is passed as the last argument(s) to the script.
+
+trap 'catch $?' EXIT
+
+catch()
+{
+ if [ "$1" != "0" ]; then
+ # Error handling goes here
+ echo "Error $1 occurred"
+
+ if mount | grep -q ${mnt_point}; then
+ unmount_destination_partition
+ fi
+ fi
+}
+
+# Arg1: log message/string
+swulog()
+{
+ echo "$(basename ${0}): ${1}"
+}
+
+FSTYPE="ext4"
+
+swulog "arguments = \"${*}\""
+
+if [ $# -lt 2 ]; then
+ exit 1;
+fi
+
+alias cp=cp
+
--- /dev/null
+SUMMARY = "Deploy SWUpdate shell scripts to support A/B update mechanism"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
+
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+
+SRC_URI = " \
+ file://update.header.sh \
+ file://update.footer.sh \
+"
+
+inherit deploy
+
+# Default list of files/folders to preserve between updates, can be extended/overriden by BSP:
+SWU_PRESERVE_FILES ?= "\
+ /etc/hostname \
+ /etc/localtime \
+"
+SWU_PRESERVE_FOLDERS ?= ""
+
+DEST_SCR = "${DEPLOYDIR}/${PN}.sh"
+
+do_deploy() {
+ cat ${WORKDIR}/update.header.sh > ${DEST_SCR}
+
+ # Insert our variable(s) between header and footer:
+ echo "SWU_PRESERVE_FILES=\"\\" >> ${DEST_SCR}
+ for f in ${SWU_PRESERVE_FILES}; do
+ echo " ${f} \\" >> ${DEST_SCR}
+ done
+ echo "\"" >> ${DEST_SCR}
+
+ echo "SWU_PRESERVE_FOLDERS=\"\\" >> ${DEST_SCR}
+ for f in ${SWU_PRESERVE_FOLDERS}; do
+ echo " ${f} \\" >> ${DEST_SCR}
+ done
+ echo "\"" >> ${DEST_SCR}
+
+ cat ${WORKDIR}/update.footer.sh >> ${DEST_SCR}
+}
+
+addtask deploy after do_install