From: Antoni Date: Tue, 21 May 2024 14:13:52 +0000 (+0200) Subject: Allow for up to two deltas to be given to upgrade scripts. X-Git-Tag: accepted/tizen/unified/20240611.122417~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F73%2F311573%2F8;p=platform%2Fcore%2Fsystem%2Fupgrade.git Allow for up to two deltas to be given to upgrade scripts. If a single delta is provided, it has to be either delta-platform or regular delta. The second delta is optional, and it has to be delta-boot. The script does not check the type of deltas, it is up to the script user. Change-Id: Ia112cc2f95e41a06a337dc0a3a504ab953436208 --- diff --git a/scripts/upgrade-support/upgrade-common.inc b/scripts/upgrade-support/upgrade-common.inc index 3b304b8..5bf1ea8 100644 --- a/scripts/upgrade-support/upgrade-common.inc +++ b/scripts/upgrade-support/upgrade-common.inc @@ -84,8 +84,8 @@ retrap() { } check_if_file_in_archive() { - ARCHIVE_NAME="$1" - FILE_NAME="$2" + local ARCHIVE_NAME="$1" + local FILE_NAME="$2" local RET=0 tar tf "${ARCHIVE_NAME}" "${FILE_NAME}" >/dev/null 2>&1 || RET=$? @@ -96,33 +96,55 @@ check_if_file_in_archive() { fi } +merge_config_files_and_delete() { + local FILE_A="$1" + local FILE_B="$2" + local FILE_OUT="$3" + + cat "$FILE_A" > "$FILE_OUT" + cat "$FILE_B" >> "$FILE_OUT" + + rm -f "$FILE_A" "$FILE_B" +} + verify_file_internal() { FILE_NAME="$1" - FILE_PATH="$FOTA_DIR/$FILE_NAME" - VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$FOTA_DIR/checksum.SHA1") + FILE_PATH="$2" + local CHECKSUM_FILE_PATH="$3" + VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$CHECKSUM_FILE_PATH") if [ "$VALID_CHECKSUM" == "" ]; then - log "[Error] No $FILE_NAME in checksum.SHA1" + critical_log "[Error] No $FILE_NAME in $CHECKSUM_FILE_PATH" return $FALSE fi if ! echo "$VALID_CHECKSUM $FILE_PATH" | sha1sum --check --status; then - log "[Error] Checksum for file $FILE_NAME is invalid" + critical_log "[Error] Checksum for file $FILE_NAME is invalid [$CHECKSUM_FILE_PATH]" return $FALSE fi - log "[Info] Checksum of $FILE_NAME is OK" + log "[Info] Checksum of $FILE_NAME is OK [$CHECKSUM_FILE_PATH]" return $TRUE } +# Default dir to unpack is FOTA_DIR (pass anon-empty 4th param to override) unpack_file() { - ARCHIVE_NAME="$1" - FILE_NAME="$2" - tar xpf "${ARCHIVE_NAME}" -C "${FOTA_DIR}" "${FILE_NAME}" 2> /dev/null - if [ ! -e "${FOTA_DIR}/${FILE_NAME}" ]; then - log "[Error] There is no ${FILE_NAME}" + local ARCHIVE_PATH="$1" + local FILE_NAME="$2" + local CHECKSUM_FILE_A_PATH="$3" + local UNPACK_DIR="$4" + + if [ -z "$UNPACK_DIR" ]; then + UNPACK_DIR="$FOTA_DIR" + fi + + local FILE_PATH="$UNPACK_DIR/$FILE_NAME" + + tar xpf "${ARCHIVE_PATH}" -C "${UNPACK_DIR}" "${FILE_NAME}" 2> /dev/null + if [ ! -e "$FILE_PATH" ]; then + log "[Error] There is no $FILE_NAME in $ARCHIVE_PATH" fi - if ! verify_file_internal "$FILE_NAME"; then + if ! verify_file_internal "$FILE_NAME" "$FILE_PATH" "$CHECKSUM_FILE_A_PATH"; then exit_error fi } @@ -400,11 +422,14 @@ load_background_copy_list() { run_upgrade_binary() { log "[Info] Running $1" $1 2>&1 | tee -a "$LOG_FILE" - return ${PIPESTATUS[0]} + return "${PIPESTATUS[0]}" } upgrade_images() { - DELTA_TAR="$1" + DELTA_TAR_A="$1" + DELTA_TAR_B="$2" + local TARGET_ARCHIVE + log "[Info] Flash images for update..." LABEL_MAP_PATH=${HAL_UPGRADE_CFG_DIR}/${HAL_} @@ -412,7 +437,7 @@ upgrade_images() { declare "LABEL_MAP_${LABEL}=${PARTLABEL}" done < <(sed -e '/^#/d' -e '/^$/d' "${LABEL_MAP_PATH}/${HAL_PART_MAP_FILE}") - local PROGRESS_INFO_FILE_PATH="$2" + local PROGRESS_INFO_FILE_PATH="$3" local PROGRESS_INFO_FILE_ARG if [ -n "$PROGRESS_INFO_FILE_PATH" ]; then PROGRESS_INFO_FILE_ARG="--progress-info-file $PROGRESS_INFO_FILE_PATH" @@ -439,11 +464,23 @@ upgrade_images() { continue fi - if ! /bin/tar tf "$DELTA_TAR" "$DELTA_NAME"; then - log "[Error] There is no delta $DELTA_NAME for label $LABEL_NAME from part $PART_NAME" - exit_error + if [ -n "$DELTA_TAR_B" ]; then + if check_if_file_in_archive "$DELTA_TAR_A" "$DELTA_NAME"; then + TARGET_ARCHIVE="$DELTA_TAR_A" + elif check_if_file_in_archive "$DELTA_TAR_B" "$DELTA_NAME"; then + TARGET_ARCHIVE="$DELTA_TAR_B" + else + critical_log "[Error] There is no delta $DELTA_NAME for label $LABEL_NAME from part $PART_NAME in either archive" + exit_error + fi + else + # If there is only one archive delta has to be found + if ! check_if_file_in_archive "$DELTA_TAR_A" "$DELTA_NAME"; then + critical_log "[Error] There is no delta $DELTA_NAME for label $LABEL_NAME from part $PART_NAME" + exit_error + fi + TARGET_ARCHIVE="$DELTA_TAR_A" fi - local CURR_PARTITION="" local NEXT_PARTITION="" @@ -462,7 +499,7 @@ upgrade_images() { case "${TYPE_S[0]}" in FULL_IMAGE) run_upgrade_binary "$FOTA_DIR/upgrade-apply "` - `"--archive $DELTA_TAR "` + `"--archive $TARGET_ARCHIVE "` `"--dest $NEXT_PARTITION "` `"--dest-size $NEW_SIZE "` `"--archive-file $DELTA_NAME "` @@ -472,7 +509,7 @@ upgrade_images() { ;; DELTA_IMAGE) run_upgrade_binary "$FOTA_DIR/upgrade-apply "` - `"--archive $DELTA_TAR "` + `"--archive $TARGET_ARCHIVE "` `"--dest $NEXT_PARTITION "` `"--dest-size $NEW_SIZE "` `"--archive-file $DELTA_NAME "` @@ -488,7 +525,7 @@ upgrade_images() { mount "$NEXT_PARTITION" "$FOTA_DIR/partition_mnt" run_upgrade_binary "$FOTA_DIR/upgrade-apply-deltafs "` - `"--archive $DELTA_TAR "` + `"--archive $TARGET_ARCHIVE "` `"--dest $FOTA_DIR/partition_mnt "` `"--archive-file $DELTA_NAME/" UP_RES=$? diff --git a/scripts/upgrade-support/upgrade-fota.sh b/scripts/upgrade-support/upgrade-fota.sh index 04c16d5..98b550c 100755 --- a/scripts/upgrade-support/upgrade-fota.sh +++ b/scripts/upgrade-support/upgrade-fota.sh @@ -11,6 +11,9 @@ fi PATH=/bin:/usr/bin:/sbin:/usr/sbin FOTA_DIR="/opt/usr/data/fota" +DELTA_A_DIR="$FOTA_DIR/delta_a" +DELTA_B_DIR="$FOTA_DIR/delta_b" + . "$FOTA_DIR"/upgrade-common.inc set_script_name_and_log_file "${BASH_SOURCE[0]}" @@ -28,6 +31,11 @@ cleanup_files() { rm -f -- "$FOTA_DIR/$CONFIG_FILE" rm -f -- "$FOTA_DIR/upgrade-trigger.sh" rm -f -- "$FOTA_DIR/checksum.SHA1" + rm -rf -- "$DELTA_A_DIR" + + if [ -d "$DELTA_B_DIR" ]; then + rm -rf -- "$DELTA_B_DIR" + fi } mount() { diff --git a/scripts/upgrade-support/upgrade-partial.sh b/scripts/upgrade-support/upgrade-partial.sh index 22826a9..0001bae 100755 --- a/scripts/upgrade-support/upgrade-partial.sh +++ b/scripts/upgrade-support/upgrade-partial.sh @@ -9,18 +9,35 @@ fi PATH=/bin:/usr/bin:/sbin:/usr/sbin FOTA_DIR="/opt/usr/data/fota" +DELTA_A_DIR="$FOTA_DIR/delta_a" +DELTA_B_DIR="$FOTA_DIR/delta_b" +DELTA_A_CHECKSUM_FILE="$DELTA_A_DIR/checksum.SHA1" +DELTA_B_CHECKSUM_FILE="$DELTA_B_DIR/checksum.SHA1" . "$FOTA_DIR"/upgrade-common.inc set_script_name_and_log_file "${BASH_SOURCE[0]}" check_args() { - DELTA_TAR="$1" - if [ ! -f "$DELTA_TAR" ]; then - log "[Error] Usage: $0 path_to_delta.tar[.gz]" + DELTA_TAR_A="$1" + DELTA_TAR_B="$2" + + SINGLE_DELTA=true + if [ -n "$DELTA_TAR_B" ]; then + SINGLE_DELTA=false + fi + + if [[ (( $SINGLE_DELTA = true ) && ( ! -f "$DELTA_TAR_A" )) || \ + (( $SINGLE_DELTA = false ) && (( ! -f "$DELTA_TAR_A" ) || ( ! -f "$DELTA_TAR_B"))) ]]; then + log "[Error] Usage: $0 path_to_delta.tar[.gz] [path_to_second_delta.tar[.gz]]" exit 1 fi - log "[Info] Using <$DELTA_TAR> delta file." + if [ $SINGLE_DELTA = true ]; then + log "[Info] Using <$DELTA_TAR_A> delta file." + DELTA_B_CHECKSUM_FILE="" + else + log "[Info] Using <$DELTA_TAR_A> and <$DELTA_TAR_B> delta files." + fi } FOTA_UPDATE_PREFIX="/run/upgrade-sysroot" @@ -31,8 +48,18 @@ cleanup() { } cleanup_files() { - rm -f -- "$DELTA_TAR" + rm -f -- "$DELTA_TAR_A" + + if [ $SINGLE_DELTA = false ]; then + rm -f -- "$DELTA_TAR_B" + fi + + if [ -f "$FOTA_DIR/update-progress-info.ini" ]; then + rm -f -- "$FOTA_DIR/update-progress-info.ini" + fi + rm -f -- "$FOTA_DIR/upgrade-apply" + rm -f -- "$FOTA_DIR/upgrade-apply-deltafs" rm -f -- "$FOTA_DIR/$SCRIPT_NAME" } @@ -44,26 +71,51 @@ prepare_fota_update_dir check_ab_partition_scheme check_used_block_device check_args "$@" - -unpack_file "$DELTA_TAR" "upgrade-apply" +unpack_file "$DELTA_TAR_A" "upgrade-apply" "$DELTA_A_CHECKSUM_FILE" "" /bin/chmod +x "$FOTA_DIR/upgrade-apply" -unpack_file "$DELTA_TAR" "upgrade-apply-deltafs" +unpack_file "$DELTA_TAR_A" "upgrade-apply-deltafs" "$DELTA_A_CHECKSUM_FILE" "" /bin/chmod +x "$FOTA_DIR/upgrade-apply-deltafs" -if check_if_file_in_archive "$DELTA_TAR" "update-progress-info.ini"; then - unpack_file "$DELTA_TAR" "update-progress-info.ini" - PROGRESS_INFO_FILE_PATH="$FOTA_DIR/update-progress-info.ini" +if [ $SINGLE_DELTA = true ]; then + if check_if_file_in_archive "$DELTA_TAR_A" "update-progress-info.ini"; then + unpack_file "$DELTA_TAR_A" "update-progress-info.ini" "$DELTA_A_CHECKSUM_FILE" "" + PROGRESS_INFO_FILE_PATH="$FOTA_DIR/update-progress-info.ini" + else + PROGRESS_INFO_FILE_PATH="" + fi else - PROGRESS_INFO_FILE_PATH="" + FOUND_IN_DELTA_A=false + FOUND_IN_DELTA_B=false + + if check_if_file_in_archive "$DELTA_TAR_A" "update-progress-info.ini"; then + unpack_file "$DELTA_TAR_A" "update-progress-info.ini" "$DELTA_A_CHECKSUM_FILE" "$DELTA_A_DIR" + FOUND_IN_DELTA_A=true + fi + + if check_if_file_in_archive "$DELTA_TAR_B" "update-progress-info.ini"; then + unpack_file "$DELTA_TAR_B" "update-progress-info.ini" "$DELTA_B_CHECKSUM_FILE" "$DELTA_B_DIR" + FOUND_IN_DELTA_B=true + fi + + PROGRESS_INFO_FILE_PATH="$FOTA_DIR/update-progress-info.ini" + if [ $FOUND_IN_DELTA_A = true ] && [ $FOUND_IN_DELTA_B = true ]; then + merge_config_files_and_delete "$DELTA_A_DIR/update-progress-info.ini" "$DELTA_B_DIR/update-progress-info.ini" "$FOTA_DIR/update-progress-info.ini" + elif [ $FOUND_IN_DELTA_A = true ]; then + mv "$DELTA_A_DIR/update-progress-info.ini" "$FOTA_DIR/update-progress-info.ini" + elif [ $FOUND_IN_DELTA_B = true ]; then + mv "$DELTA_B_DIR/update-progress-info.ini" "$FOTA_DIR/update-progress-info.ini" + else + PROGRESS_INFO_FILE_PATH="" + fi fi -if ! upgrade_images "$DELTA_TAR" "$PROGRESS_INFO_FILE_PATH"; then +if ! upgrade_images "$DELTA_TAR_A" "$DELTA_TAR_B" "$PROGRESS_INFO_FILE_PATH"; then critical_log "[Error] Unable to upgrade_images" cleanup exit_error fi -if ! run_setup_script "$DELTA_TAR"; then +if ! run_setup_script "$DELTA_TAR_A"; then critical_log "[Error] Unable to run_setup_script" cleanup exit_error diff --git a/scripts/upgrade-support/upgrade-trigger.sh b/scripts/upgrade-support/upgrade-trigger.sh index 4f4f019..d29876f 100644 --- a/scripts/upgrade-support/upgrade-trigger.sh +++ b/scripts/upgrade-support/upgrade-trigger.sh @@ -16,10 +16,15 @@ ERR_FINISH_BEFORE_RO_UPDATE_COMPLETE=3 PATH=/bin:/usr/bin:/sbin:/usr/sbin FOTA_DIR="/opt/usr/data/fota" +DELTA_A_DIR="$FOTA_DIR/delta_a" +DELTA_B_DIR="$FOTA_DIR/delta_b" +DELTA_A_CHECKSUM_FILE="$DELTA_A_DIR/checksum.SHA1" +DELTA_B_CHECKSUM_FILE="$DELTA_B_DIR/checksum.SHA1" STATUS_DIR="/opt/data/update" SCRIPT_UPGRADE_PREPARE_PARTITIONS="upgrade-prepare-partitions.sh" SCRIPT_UPGRADE_PARTIAL="upgrade-partial.sh" SCRIPT_UPGRADE_FOTA="upgrade-fota.sh" +SCRIPT_UPGRADE_TRIGGER="upgrade-trigger.sh" BLKID_PRINT_FILE="blkid-print" RESIZE_DYNPARTS_FILE="resize-dynparts" COPY_BLOCKDEV_FILE="copy-blockdev" @@ -29,22 +34,47 @@ export RESIZE_DYNPARTS="$FOTA_DIR/$RESIZE_DYNPARTS_FILE" export COPY_BLOCKDEV="$FOTA_DIR/$COPY_BLOCKDEV_FILE" prepare_fota_dir() { + # Cleanup FOTA dir. If provided delta(s) are inside, keep them + # This could delete the deltas if they are placed in DELTA_X_DIR. But since the script + # creates/deletes them (and doesn't place them there), it is unlikely. Some vital scripts + # and files (like this script or checksum file) will be deleted, but + # it's not an issue since they will be exctraced again later. if [ -d "$FOTA_DIR" ]; then - # Cleanup FOTA_DIR - if [ "$(dirname "$DOWNLOAD_DELTA")" = "$FOTA_DIR" ]; then - # If provided delta is from inside the FOTA_DIR, delete everything else - DELTA_FILE_NAME=$(basename "$DOWNLOAD_DELTA") - rm -rf -- "$FOTA_DIR/!($DELTA_FILE_NAME)" + local DELTA_A_PARENT_DIR="$(readlink -e "$(dirname "$DELTA_A")")" + + if [ $SINGLE_DELTA = true ]; then + if [ "$DELTA_A_PARENT_DIR" = "$FOTA_DIR" ]; then + find "$FOTA_DIR" -maxdepth 1 -not -wholename "$FOTA_DIR" -not -wholename "$(readlink -e "$DELTA_A")" -exec rm -r "{}" \; + else + rm -rf -- ${FOTA_DIR:?}/* + fi else - # If provided delta is from outside the FOTA_DIR delete everything - rm -rf -- "${FOTA_DIR:?}/*" + local DELTA_B_PARENT_DIR="$(readlink -e "$(dirname "$DELTA_B")")" + + if [ "$DELTA_A_PARENT_DIR" = "$FOTA_DIR" ] && [ "$DELTA_B_PARENT_DIR" = "$FOTA_DIR" ]; then + find "$FOTA_DIR" -maxdepth 1 -not -wholename "$FOTA_DIR" -not -wholename "$(readlink -e "$DELTA_A")" \ + -not -wholename "$(readlink -e "$DELTA_B")" -exec rm -r "{}" \; + elif [ "$DELTA_A_PARENT_DIR" = "$FOTA_DIR" ]; then + find "$FOTA_DIR" -maxdepth 1 -not -wholename "$FOTA_DIR" -not -wholename "$(readlink -e "$DELTA_A")" -exec rm -r "{}" \; + elif [ "$DELTA_B_PARENT_DIR" = "$FOTA_DIR" ]; then + find "$FOTA_DIR" -maxdepth 1 -not -wholename "$FOTA_DIR" -not -wholename "$(readlink -e "$DELTA_B")" -exec rm -r "{}" \; + else + rm -rf -- ${FOTA_DIR:?}/* + fi fi - # `echo` commands below are intentional as upgrade-common.inc is not sourced yet (no access to logging functions) else - echo "[Info] Create fota dir..." + echo "[Info] Create FOTA dir..." mkdir -p "$FOTA_DIR" fi + echo "[Info] Create subdir for delta..." + mkdir "$DELTA_A_DIR" + + if [ $SINGLE_DELTA = false ]; then + echo "[Info] Create subdir for second delta..." + mkdir "$DELTA_B_DIR" + fi + if [ ! -d "$STATUS_DIR" ]; then echo "[Info] Create status dir..." mkdir -p "$STATUS_DIR" @@ -68,21 +98,27 @@ do_update() { if is_ab_upgrade; then set_upgrade_status 5 - unpack_file "${DOWNLOAD_DELTA}" "${BLKID_PRINT_FILE}" + unpack_file "${DELTA_A}" "${BLKID_PRINT_FILE}" "${DELTA_A_CHECKSUM_FILE}" "" chmod +x "$FOTA_DIR/$BLKID_PRINT_FILE" - unpack_file "${DOWNLOAD_DELTA}" "${RESIZE_DYNPARTS_FILE}" + unpack_file "${DELTA_A}" "${RESIZE_DYNPARTS_FILE}" "${DELTA_A_CHECKSUM_FILE}" "" chmod +x "$FOTA_DIR/$RESIZE_DYNPARTS_FILE" - unpack_file "${DOWNLOAD_DELTA}" "${COPY_BLOCKDEV_FILE}" + unpack_file "${DELTA_A}" "${COPY_BLOCKDEV_FILE}" "${DELTA_A_CHECKSUM_FILE}" "" chmod +x "$FOTA_DIR/$COPY_BLOCKDEV_FILE" - unpack_file "$DOWNLOAD_DELTA" "$CONFIG_FILE" + if [ $SINGLE_DELTA = false ]; then + unpack_file "$DELTA_A" "$CONFIG_FILE" "$DELTA_A_CHECKSUM_FILE" "$DELTA_A_DIR" + unpack_file "$DELTA_B" "$CONFIG_FILE" "$DELTA_B_CHECKSUM_FILE" "$DELTA_B_DIR" + merge_config_files_and_delete "$DELTA_A_DIR/$CONFIG_FILE" "$DELTA_B_DIR/$CONFIG_FILE" "$FOTA_DIR/$CONFIG_FILE" + else + unpack_file "$DELTA_A" "$CONFIG_FILE" "$DELTA_A_CHECKSUM_FILE" "" + fi if [ "$(device_board_get_partition_ab_cloned)" -eq 0 ]; then log "[Info] Starting to prepare the partitions for upgrade.." - unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_PREPARE_PARTITIONS}" + unpack_file "${DELTA_A}" "${SCRIPT_UPGRADE_PREPARE_PARTITIONS}" "${DELTA_A_CHECKSUM_FILE}" "" run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_PREPARE_PARTITIONS} $PROGRESS_AFTER_CLONING" if [ $RET -ne 0 ]; then @@ -98,7 +134,7 @@ do_update() { device_board_clear_partition_ab_cloned - run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_PARTIAL} ${DOWNLOAD_DELTA}" + run_script "${FOTA_DIR}/${SCRIPT_UPGRADE_PARTIAL} ${DELTA_A} ${DELTA_B}" if [ $RET -ne 0 ] ; then log "[Error] Failed to run $SCRIPT_UPGRADE_PARTIAL ${DOWNLOAD_DELTA}" "$LOG_FILE" @@ -144,26 +180,41 @@ do_finish() { verify_file() { FILE_PATH="$1" FILE_NAME=$(basename "$FILE_PATH") + local CHECKSUM_FILE="$2" - VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$FOTA_DIR/checksum.SHA1") + VALID_CHECKSUM=$(awk "\$2 ~ /^$FILE_NAME\$/ {print \$1}" "$CHECKSUM_FILE") if [ "$VALID_CHECKSUM" == "" ]; then - log "[Error] No $FILE_NAME in checksum.SHA1" + log "[Error] No $FILE_NAME in $CHECKSUM_FILE" device_board_set_upgrade_status -1 exit 1 fi if ! echo "$VALID_CHECKSUM $FILE_PATH" | sha1sum --check --status; then - log "[Error] Checksum for file $FILE_NAME is invalid" + log "[Error] Checksum for file $FILE_NAME is invalid [$CHECKSUM_FILE]" device_board_set_upgrade_status -1 exit 1 fi - log "[Info] Checksum of $FILE_NAME is OK" + log "[Info] Checksum of $FILE_NAME is OK [$CHECKSUM_FILE]" } MODE_RO_UPDATE=false MODE_FINISH_UPDATE=false +# DELTA_A variable will be the path to the delta containing all binaries/scripts +# neccessary to perform upgrade. This could either be a "platform" delta, or a +# "platform" + "boot" delta. If two deltas are to be used, the script has to be +# given this delta first. Calling this script with "boot" delta only or giving it +# the "boot" delta as first path parameter is not recommended and it is up to +# the caller to ensure this doesn't happen. +SINGLE_DELTA=true +DELTA_A="" +DELTA_B="" + +printf "[Start] Running %s: " "$0" +printf "[%s] " "$@" +printf "\n" + while [[ $# -gt 0 ]]; do case "$1" in --ro-update) @@ -172,8 +223,20 @@ while [[ $# -gt 0 ]]; do --finish) MODE_FINISH_UPDATE=true ;; + --ro-update-and-finish) + MODE_RO_UPDATE=true + MODE_FINISH_UPDATE=true + ;; + # Just a precausion + "") + ;; *) - DOWNLOAD_DELTA="$1" + if [ -z "$DELTA_A" ]; then + DELTA_A="$1" + else + DELTA_B="$1" + SINGLE_DELTA=false + fi ;; esac shift @@ -184,12 +247,12 @@ if [ $MODE_RO_UPDATE = false ] && [ $MODE_FINISH_UPDATE = false ]; then MODE_FINISH_UPDATE=true fi -if [ $MODE_RO_UPDATE = true ] && [ ! -f "$DOWNLOAD_DELTA" ]; then - echo "[Error] Usage: $0 [--ro_update ] [--finish]" +if [[ ( $MODE_RO_UPDATE = true ) && ((( $SINGLE_DELTA = true ) && ( ! -f "$DELTA_A" )) \ + || (( $SINGLE_DELTA = false ) && (( ! -f "$DELTA_A" ) || ( ! -f "$DELTA_B" )))) ]]; then + echo "[Error] Usage: $0 [--ro_update [] ] [--finish]" exit 1 fi - ( if [ $MODE_RO_UPDATE = false ] && [ $MODE_FINISH_UPDATE = true ]; then if ! flock -n 9; then @@ -200,37 +263,53 @@ else flock 9 fi -# if [ "$#" != "1" ] || [ ! -f "$1" ]; then -# echo "[Error] Usage: $0 path_to_delta.tar[.gz]" -# exit 1 -# fi if [ $MODE_RO_UPDATE = true ]; then prepare_fota_dir - tar xfp "$DOWNLOAD_DELTA" -C "$FOTA_DIR" checksum.SHA1 + tar xfp "$DELTA_A" -C "$DELTA_A_DIR" checksum.SHA1 + # Copy in case script is later called in "--finish" mode (prepare_fota_dir() deletes it) + cp "$DELTA_A_DIR/checksum.SHA1" "$FOTA_DIR/checksum.SHA1" + + # Untar this file in case script is later called in "--finish mode" (prepare_fota_dir() deletes it) + if [ ! -f "$FOTA_DIR/$SCRIPT_UPGRADE_TRIGGER" ]; then + tar xfp "$DELTA_A" -C "$FOTA_DIR" "$SCRIPT_UPGRADE_TRIGGER" + fi - tar xfp "$DOWNLOAD_DELTA" -C "$FOTA_DIR" upgrade-common.inc + tar xfp "$DELTA_A" -C "$FOTA_DIR" upgrade-common.inc + + if [ $SINGLE_DELTA = false ]; then + tar xfp "$DELTA_B" -C "$DELTA_B_DIR" checksum.SHA1 + else + DELTA_B_CHECKSUM_FILE="" + fi fi if [ ! -f "$FOTA_DIR/upgrade-common.inc" ]; then - echo "[Error] upgrade-common.inc not exist" + echo "[Error] upgrade-common.inc does not exist" device_board_set_upgrade_status -1 exit 1 fi - . "$FOTA_DIR"/upgrade-common.inc +. "$FOTA_DIR"/upgrade-common.inc if [ $MODE_RO_UPDATE = true ]; then upgrade_log_init - set_script_name_and_log_file "${BASH_SOURCE[0]} $*" + set_script_name_and_log_file "${BASH_SOURCE[0]}" + + verify_file "$FOTA_DIR/upgrade-common.inc" "$DELTA_A_CHECKSUM_FILE" + verify_file "$0" "$DELTA_A_CHECKSUM_FILE" - verify_file "$FOTA_DIR/upgrade-common.inc" + unpack_file "${DELTA_A}" delta-verifier "$DELTA_A_CHECKSUM_FILE" "" + unpack_file "${DELTA_A}" "${SCRIPT_UPGRADE_PARTIAL}" "$DELTA_A_CHECKSUM_FILE" "" + unpack_file "${DELTA_A}" "${SCRIPT_UPGRADE_FOTA}" "$DELTA_A_CHECKSUM_FILE" "" - verify_file "$0" - unpack_file "${DOWNLOAD_DELTA}" update-info.ini - unpack_file "${DOWNLOAD_DELTA}" delta-verifier - unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_PARTIAL}" - unpack_file "${DOWNLOAD_DELTA}" "${SCRIPT_UPGRADE_FOTA}" + if [ $SINGLE_DELTA = false ]; then + unpack_file "${DELTA_A}" update-info.ini "$DELTA_A_CHECKSUM_FILE" "$DELTA_A_DIR" + unpack_file "${DELTA_B}" update-info.ini "$DELTA_B_CHECKSUM_FILE" "$DELTA_B_DIR" + merge_config_files_and_delete "$DELTA_A_DIR/update-info.ini" "$DELTA_B_DIR/update-info.ini" "$FOTA_DIR/update-info.ini" + else + unpack_file "${DELTA_A}" update-info.ini "$DELTA_A_CHECKSUM_FILE" "" + fi log "[Info] Begin delta verification" RET=0 @@ -247,15 +326,22 @@ if [ $MODE_RO_UPDATE = true ]; then log "[Info] Delta verification success" set_upgrade_status 1 - verify_img "${DOWNLOAD_DELTA}" + + verify_img "$DELTA_A" + if [ $SINGLE_DELTA = false ]; then + verify_img "$DELTA_B" + fi + do_update fi if [ $MODE_FINISH_UPDATE = true ]; then set_script_name_and_log_file "${BASH_SOURCE[0]}" - verify_file "$0" - verify_file "$FOTA_DIR/upgrade-common.inc" + # Even if there are two deltas, verifying with one is enough as if there was some + # mismatch we wouldn't have reached this point + verify_file "$0" "$DELTA_A_CHECKSUM_FILE" + verify_file "$FOTA_DIR/upgrade-common.inc" "$DELTA_A_CHECKSUM_FILE" do_finish fi