From 086a2c15850eece23b8afd34a02e487e8b8cd789 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 3 Jun 2022 20:42:26 +0200 Subject: [PATCH] replaces UpdateController.sh --- update_psa | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100755 update_psa diff --git a/update_psa b/update_psa new file mode 100755 index 0000000..0c8b95f --- /dev/null +++ b/update_psa @@ -0,0 +1,163 @@ +#!/bin/bash +# set -x + +source ./log_helpers +source ./git_helpers + +# source ./update_helpers.sh +# source ./opkg_helpers.sh +source ./update_psa_helpers + +source ./read_config + +############################################################################### +# update_psa +# +# Implementing the UpdateController (see below). UpdateController is waiting +# for an external trigger by the DeviceController (DC). The trigger is sent via +# an UNIX-pipe (=fifo). When DC triggers UpdateController, it has to check if +# an update is possible, i.e. is has to lock the PSA for the update procedure. +# UpdateController will send back the update-result to DeviceController +# which unlocks the PSA to return to nomal operation. +# +# If UpdateController has been triggered, it checks out a predefined git- +# repository. As a sanity check it makes sure that there are some changes in +# the repository. In case there are no changes, it issues an error message +# to DC and returns to its wait-state. +# +# Otherwise it checks if the changed files are correct (using md5) and if +# the new files are valid for the PSA. If there is some problem, it issues an +# error message to DC, reverts the git-repository to its previous state and +# returns to its wait-state. +# +# Otherwise it makes a backup of the current state of the PSA, and if there +# are opkg-packages to install it runs a dry installation process using opkg. +# In case of error, it issues an error message to DC, deletes the backup, +# reverts # the git-repository to its previous state and returns to its +# wait-state. +# +# Otherwise, it copies all new files to their target locations and in case +# of opkg-packages, it installs the packages. +# +# In case of error it restores the previous state using the backup and +# reinstalls the previous opkg-package(s). It issues an error message to +# DC and returns to its wait-state. +# +# Otherwise the update went well, and it does some cleanup, sends a success +# message to DC and returns to its wait-state. +# +############################################################################### +# +# UPDATE PROCEDURE +# +############################################################################### +update() { + local try_update_count=0 + local func="${FUNCNAME[0]}" + + # read config parameters + # read_config + + log_debug "$func:${LINENO}: fetch/merge updates..." + + # Fetch new updates (using git) + while : + do + local repository_is_already_up_to_date="" + if ! fetch_customer_updates repository_is_already_up_to_date; then + if [ "$repository_is_already_up_to_date" = "yes" ]; then + log_error "$func:${LINENO}: $customer_id is up-to-date"\ + "-> no files to update -> no psa update" + exit 1 + fi + try_updates_count=$((try_updates_count+1)) + if [[ "$try_updates_count" -eq 5 ]]; then + log_error "$func:${LINENO}: fetch/merging failed" ; exit 1 + fi + sleep 60s + else + # Fetched updates successfully + try_updates_count=0 + break + fi + done + + # Backup before any updates in case some previous test was wrong + if ! backup_previous_version; then + log_error "$func:${LINENO}: backup failed" + revert_customer_repository ; exit 1 + fi + + files=$(changed_file_names) + if ! check_md5_for_changed_customer_files $files ; then + log_error "$func:${LINENO}: new customer files wrong" + revert_customer_repository ; exit 1 + fi + + if grep -qE ".*opkg_commands.*?" <<< $files; then + # read opkg_cmds: each line respresents an opkg-command + readarray opkg_commands < <(cat $opkg_cmds_file) + for opkg_command in "${opkg_commands[@]}"; do + if grep -qE "^\s*[#]+.*?$" <<< $opkg_command; then + continue # found comment line + fi + + # FIXME: sollte nicht gebraucht werden + opkg_command=${opkg_command//[$'\r\n\t']/ } + local package=$(printf '%s' "$opkg_command" | awk '{ print $NF }') + + local opkg_output=() + if ! exec_opkg_info "$package" opkg_output; then + log_error "$func:${LINENO}: opkg --noaction $opkg_command failed" + revert_customer_repository ; exit 1 + fi + + # FIXME: sollte am anfang so gesetzt werden + SAVEIFS=$IFS + IFS=$'\n' + if ! check_md5_for_opkg_packages opkg_output; then + log_error "$func:${LINENO}: wrong md5sum for some opkg packages" + revert_customer_repository ; exit 1 + fi + + IFS=$SAVEIFS + + # perform a dry-run and check if everything might work as expected. + + # Actually execute the opkg command + if ! exec_opkg $opkg_command; then + log_error "$func:${LINENO}: do_update failed" + fallback_to_previous_version + revert_customer_repository ; exit 1 + fi + done + else + log_info "$func:${LINENO}: no opkg commnds to execute" + fi + + # Cleanup. + if ! cleanup_previous_version; then + log_error "$func:${LINENO}: cleanup_previous_version failed" + fi + + log_info "$func:${LINENO}: success" + exit 0 +} + +############################################################################### + +if [ $# -ne 1 ] ; then + echo "Usage: $0 filename" + exit 1 +else +# if [ -z $IFS ]; then +# IFS=$'\n' +# fi + + if read_config "$1" ; then + # set -x + if clone_customer_repository $repository_path ; then + update + fi + fi +fi