Compare commits
14 Commits
c032d5d528
...
40e8786391
Author | SHA1 | Date | |
---|---|---|---|
40e8786391 | |||
3586951772 | |||
71bc436a8c | |||
c1938c5b53 | |||
bcc503d59c | |||
c1eca2b7bf | |||
35600ec429 | |||
a9003c5073 | |||
89ef5c69b6 | |||
086a2c1585 | |||
fd40ba31a1 | |||
fa41ed36ab | |||
b1d22acdd6 | |||
8763eccab3 |
@ -1,11 +1,10 @@
|
||||
{
|
||||
"fifo_dir" : "/tmp",
|
||||
"fifo" : "update_controller_fifo",
|
||||
"workspace" : "workspace",
|
||||
"GIT_SSL_NO_VERIFY" : true,
|
||||
"working_directory" : ".",
|
||||
"workspace_dir" : "workspace",
|
||||
"customer_location" : "szeged",
|
||||
"customer_id" : "281",
|
||||
"zone_group" : "1",
|
||||
"zone" : "1",
|
||||
"customer_location" : "szeged",
|
||||
"repository_path" : "https://git.mimbach49.de/GerhardHoffmann"
|
||||
}
|
||||
|
@ -1,396 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
|
||||
fifo=""
|
||||
customer_id=""
|
||||
customer_repository=""
|
||||
customer_location=""
|
||||
customer_base_dir=""
|
||||
|
||||
source ./log_helpers.sh
|
||||
source ./update_helpers.sh
|
||||
source ./git_helpers.sh
|
||||
source ./opkg_helpers.sh
|
||||
|
||||
init_fifo () {
|
||||
trap "rm -f $fifo" EXIT
|
||||
if [ $? -eq 0 ]; then
|
||||
# set trap
|
||||
if [[ ! -p "$fifo" ]]; then
|
||||
mkfifo "$fifo"
|
||||
if [ $? -eq 0 ]; then
|
||||
# fifo created
|
||||
echo "created fifo=$fifo"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
read_config() {
|
||||
local func="${FUNCNAME[0]}"
|
||||
|
||||
# check fifo settings
|
||||
fifo_dir=$(cat "$1" | jq -r .fifo_dir)
|
||||
if [ -z "$fifo_dir" ]; then
|
||||
log_fatal "$func: fifo_dir not set in $1"
|
||||
fi
|
||||
|
||||
fifo=$(cat "$1" | jq -r .fifo)
|
||||
if [ -z "$fifo" ]; then
|
||||
log_fatal "$func: fifo not set in $1"
|
||||
fi
|
||||
|
||||
fifo="${fifo_dir}/$fifo"
|
||||
log_debug "$func:${LINENO}: fifo is $fifo"
|
||||
|
||||
# check customer_id
|
||||
customer_id="$(cat "$1" | jq -r .customer_id)"
|
||||
if [ -z "$customer_id" ]; then
|
||||
log_fatal "$func:${LINENO} customer_id not set in $1"
|
||||
fi
|
||||
customer_id="customer_$customer_id"
|
||||
log_info "$func:${LINENO}: customer-id is $customer_id"
|
||||
|
||||
# check customer_repository
|
||||
repository_path="$(cat "$1" | jq -r .repository_path)"
|
||||
if [ -z "$repository_path" ]; then
|
||||
log_fatal "$func:${LINENO}: repository path not set in $1"
|
||||
fi
|
||||
repository_path="${repository_path}/${customer_id}.git"
|
||||
log_info "$func:${LINENO}: repository path is $repository_path"
|
||||
|
||||
# check zone_group
|
||||
local zone_group="$(cat "$1" | jq -r .zone_group)"
|
||||
if [ -z "$zone_group" ]; then
|
||||
log_fatal "$func:${LINENO}: zone_group not set in $1"
|
||||
fi
|
||||
|
||||
# check zone
|
||||
local zone="$(cat "$1" | jq -r .zone)"
|
||||
if [ -z "$zone" ]; then
|
||||
log_fatal "$func:${LINENO}: zone not set in $1"
|
||||
fi
|
||||
|
||||
# check customer_location
|
||||
local customer_location="$(cat "$1" | jq -r .customer_location)"
|
||||
if [ -z "$customer_location" ]; then
|
||||
log_fatal "$func:${LINENO}: customer_location not set in $1"
|
||||
fi
|
||||
|
||||
customer_base_dir="$PWD/workspace/${customer_id}/${customer_location}"
|
||||
customer_base_dir="${customer_base_dir}/${zone_group}/${zone}"
|
||||
|
||||
log_info "$func:${LINENO}: customer-base-dir is $customer_base_dir"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
wait_for_trigger() {
|
||||
local func="${FUNCNAME[0]}"
|
||||
if [[ "$1" -eq -1 ]]; then
|
||||
# wait for external impulse
|
||||
log_debug "$func:${LINENO}: waiting on $fifo"
|
||||
if read line <$fifo; then
|
||||
if [ "$line" = "quit" ] || [ "$line" = "update" ]; then
|
||||
log_debug "$func:${LINENO}: received=$line"
|
||||
printf "%s\n" $line
|
||||
fi
|
||||
fi
|
||||
else
|
||||
sleep $1
|
||||
log_debug "$func:${LINENO}: sleep"
|
||||
fi
|
||||
}
|
||||
|
||||
# APISM has al least two TCP-ports open: 7778 and 7779. To check for a running
|
||||
# APISM it is therefore enough to check for the port 7778. netcat will return 0
|
||||
# if the port 7778 is open.
|
||||
check_for_apism() {
|
||||
return 0
|
||||
|
||||
nc localhost 7778
|
||||
if [ $? -eq 0 ]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
######################### send_to_ismas.txt ###################################
|
||||
# #M=GH_APP
|
||||
# #C=REQ_ISMASParameter
|
||||
# #J={}
|
||||
# {
|
||||
# "DEV_ID": {
|
||||
# "Device_Type": "2020",
|
||||
# "Custom_ID": 999,
|
||||
# "Device_ID": 1
|
||||
# },
|
||||
# "REQ_ISMASParameter_#1": {}
|
||||
# }
|
||||
#
|
||||
# APISM should respond with (something like this):
|
||||
#
|
||||
# {
|
||||
# "REQ_ISMASPARAMETER#69553_Response": {
|
||||
# "Aknoledge": "OK"
|
||||
# },
|
||||
# "Dev_ID": {
|
||||
# "Device_Type": "ISMAS",
|
||||
# "Custom_ID": 999,
|
||||
# "Device_ID": 2
|
||||
# },
|
||||
# "Fileupload": [
|
||||
# { "IPK": "BladiBlupp.Zip",
|
||||
# "MD5": "01234567890123456789012345678901"}
|
||||
# ],
|
||||
# "Parameter": {
|
||||
# "Location": "An der Bahn 11",
|
||||
# "Group": "G1",
|
||||
# "Zone": "Z1",
|
||||
# "Name": "Bruno",
|
||||
# "SecNumber": "0",
|
||||
# "LastAcc": "1",
|
||||
# "GPSLat": "49,6019",
|
||||
# "GPSLon": "12,1258"
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# where the interesting part is contained in "FileUpload".
|
||||
#
|
||||
check_for_updates() {
|
||||
# ismas_response=$(cat send_to_ismas.txt; sleep 1) | nc localhost 7778)
|
||||
if ! pull_customer_repository customer_281; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
backup_previous_version() {
|
||||
return 0
|
||||
}
|
||||
|
||||
fetch_updates() {
|
||||
return 0
|
||||
}
|
||||
|
||||
check_updates() {
|
||||
return 0
|
||||
}
|
||||
|
||||
revert_updates() {
|
||||
return 0
|
||||
}
|
||||
|
||||
lock_before_installing_updates() {
|
||||
return 0
|
||||
}
|
||||
|
||||
do_update_dry_run() {
|
||||
return 0
|
||||
}
|
||||
|
||||
do_update() {
|
||||
return 0
|
||||
}
|
||||
|
||||
fallback_to_previous_version() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unlock_after_installing_updates() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cleanup_previous_version() {
|
||||
return 0
|
||||
}
|
||||
|
||||
send_reboot_message_to_system_controller() {
|
||||
return 0
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# UPDATE CONTROLLER
|
||||
#
|
||||
###############################################################################
|
||||
UpdateController() {
|
||||
local trigger_reboot=false
|
||||
local check_apism_count=0
|
||||
local try_update_count=0
|
||||
local try_lock_count=0
|
||||
local try_unlock_count=0
|
||||
local trigger_timeout=-1
|
||||
local func="${FUNCNAME[0]}"
|
||||
|
||||
# read config parameters
|
||||
# read_config
|
||||
|
||||
# By default (trigger_timeout==-1), UpdateController can only be triggered
|
||||
# from some external source to perform an update.
|
||||
while :
|
||||
do
|
||||
trigger=$(wait_for_trigger $trigger_timeout)
|
||||
echo "trigger=$trigger"
|
||||
if [ "$trigger" = "quit" ]; then
|
||||
$trigger_reboot = true
|
||||
elif [ "$trigger" != "update" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if $trigger_reboot; then
|
||||
log_crit "$func:${LINENO}: send message to reboot the PSA"
|
||||
send_reboot_message_to_system_controller
|
||||
continue
|
||||
fi
|
||||
|
||||
# Is APISM running, listening on the correct ports etc. ?
|
||||
while :
|
||||
do
|
||||
if ! check_for_apism; then
|
||||
var=$((var+1))
|
||||
check_apism_count=$((check_apism_count+1))
|
||||
if [[ "$check_apism_count" -eq 5 ]]; then
|
||||
trigger_reboot=true
|
||||
check_apism_count=0
|
||||
log_crit "$func:${LINENO}: ERROR APISM not working"
|
||||
continue 2
|
||||
fi
|
||||
log_debug "$func:${LINENO}: [$check_apism_count]: check APISM"
|
||||
sleep 60s
|
||||
else
|
||||
# APISM up and working
|
||||
check_apism_count=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
log_debug "$func:${LINENO}: checking for updates..."
|
||||
# exit 1
|
||||
|
||||
# Are there new updates available ?
|
||||
if ! check_for_updates; then
|
||||
log_info "$func:${LINENO}: DEBUG no updates available"
|
||||
extract_changed_files
|
||||
continue
|
||||
fi
|
||||
|
||||
log_debug "$func:${LINENO}: fetching updates..."
|
||||
exit 1
|
||||
|
||||
# Fetch new updates (using git)
|
||||
while :
|
||||
do
|
||||
if ! fetch_updates; then
|
||||
try_updates_count=$((try_updates_count+1))
|
||||
if [[ "$try_updates_count" -eq 5 ]]; then
|
||||
trigger_reboot=true
|
||||
echo "ERROR fetching updates"
|
||||
continue 2
|
||||
fi
|
||||
sleep 60s
|
||||
else
|
||||
# Fetched updates successfully
|
||||
try_updates_count=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Check the updates for:
|
||||
# * correct MD5
|
||||
# * compatibility with PSA
|
||||
# ...
|
||||
if ! check_updates; then
|
||||
echo "ERROR check_updates"
|
||||
revert_updates
|
||||
trigger_reboot=true
|
||||
continue
|
||||
fi
|
||||
|
||||
# perform a dry-run and check if everything might work as expected.
|
||||
if ! do_update_dry_run; then
|
||||
echo "ERROR do_update_dry_run"
|
||||
revert_updates
|
||||
trigger_reboot=true
|
||||
continue
|
||||
fi
|
||||
|
||||
# Backup before any updates in case some previous test was wrong
|
||||
if ! backup_previous_version; then
|
||||
echo "ERROR backup_previous_version"
|
||||
revert_updates
|
||||
trigger_reboot=true
|
||||
continue
|
||||
fi
|
||||
|
||||
# Lock the PSA so all other tasks on the PSA are in sync with the update
|
||||
while :
|
||||
do
|
||||
if ! lock_before_installing_updates; then
|
||||
try_lock_count=$((try_lock_count+1))
|
||||
if [[ "$try_lock_count" -eq 5 ]]; then
|
||||
revert_updates
|
||||
fallback_to_previous_version
|
||||
trigger_reboot=true
|
||||
echo "ERROR locking PSA"
|
||||
continue 2
|
||||
fi
|
||||
sleep 60s
|
||||
else
|
||||
# Locked PSA successfully
|
||||
try_lock_count=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Actually do the update
|
||||
if ! do_update; then
|
||||
echo "ERROR do_update"
|
||||
revert_updates
|
||||
fallback_to_previous_version
|
||||
trigger_reboot=true
|
||||
continue
|
||||
fi
|
||||
|
||||
while :
|
||||
do
|
||||
# If all went well, the PSA can return to normal operation
|
||||
if ! unlock_after_installing_updates; then
|
||||
try_unlock_count=$((try_unlock_count+1))
|
||||
if [[ "$try_unlock_count" -eq 5 ]]; then
|
||||
revert_updates
|
||||
fallback_to_previous_version
|
||||
trigger_reboot=true
|
||||
echo "ERROR unlocking PSA"
|
||||
continue 2
|
||||
fi
|
||||
sleep 60s
|
||||
else
|
||||
# Unlocked PSA successfully
|
||||
try_unlock_count=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Cleanup.
|
||||
if ! cleanup_previous_version; then
|
||||
echo "ERROR cleanup_previous_version"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
||||
if [ $# -ne 1 ] ; then
|
||||
echo "Usage: $0 filename"
|
||||
exit 1
|
||||
else
|
||||
if read_config "$1" ; then
|
||||
|
||||
init_fifo
|
||||
UpdateController
|
||||
fi
|
||||
fi
|
@ -1,17 +1,25 @@
|
||||
#!/bin/bash
|
||||
# set -x
|
||||
|
||||
source ./log_helpers.sh
|
||||
# if [ ${git_helpers_sourced:-1} = "1" ]; then
|
||||
# readonly git_helpers_sourced=${BASH_SOURCE[0]}
|
||||
#else
|
||||
# return 0
|
||||
#fi
|
||||
|
||||
GIT_SSL_NO_VERIFY=true
|
||||
|
||||
# source ./log_helpers
|
||||
|
||||
readonly GIT_SSL_NO_VERIFY=true
|
||||
readonly repository_already_up_to_date=2
|
||||
|
||||
#
|
||||
exec_git_command () {
|
||||
local func="${FUNCNAME[0]}"
|
||||
|
||||
log_debug "$func:${LINENO} exec-ing $1"
|
||||
log_debug "$func:${LINENO} exec-ing [$*]"
|
||||
|
||||
exec {fd}< <($1)
|
||||
exec {fd}< <($@)
|
||||
local ps_pid=$! # remember pid of process substitution
|
||||
|
||||
local git_result=""
|
||||
@ -35,15 +43,13 @@ latest_commit () {
|
||||
local c=$(git reflog | grep "HEAD@{0}" | cut -d" " -f1)
|
||||
if ! [ -z "$c" ]; then
|
||||
if grep -qE "^[[:xdigit:]]{6,}$" <<< $c; then
|
||||
log_debug "$func: commit -> $c"
|
||||
log_debug "$func:${LINENO} commit -> $c"
|
||||
printf "%s\n" $c
|
||||
else
|
||||
log_crit "$func: wrong format for commit c=$c"
|
||||
printf ""
|
||||
log_crit "$func:${LINENO} wrong format for commit c=$c"
|
||||
fi
|
||||
else
|
||||
log_crit "$func: 'git reflog' result empty"
|
||||
printf ""
|
||||
log_crit "$func:${LINENO} 'git reflog' result empty"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -79,10 +85,22 @@ clone_customer_repository () {
|
||||
# check if the directory is empty. If so, clone the
|
||||
# customer repository
|
||||
if ! find ./workspace -mindepth 1 -maxdepth 1 | read; then
|
||||
log_debug "$func: cloning ${1} ..."
|
||||
( cd ./workspace && git clone "$1" ; )
|
||||
log_debug "$func:${LINENO} cloning ${1} ..."
|
||||
if { cd ./workspace ; }; then
|
||||
$(exec_git_command git clone "$1")
|
||||
if [ $? -eq 0 ]; then
|
||||
log_debug "$func: cloning ${1} done"
|
||||
log_debug "$func:${LINENO} cloning ${1} done"
|
||||
cd - ; return 0
|
||||
fi
|
||||
cd -
|
||||
fi
|
||||
else
|
||||
# the directory is not empty, so we assume the customer-repository
|
||||
# has been cloned alread
|
||||
if ! [[ -d ./workspace/$customer_id ]]; then
|
||||
local m="wrong repository: $(ls -d './workspace/*')"
|
||||
log_fatal "$func:${LINENO} $m"
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
@ -104,7 +122,7 @@ cd_customer_repository () {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! cd $repository_dir; then
|
||||
if ! { cd $repository_dir; } ; then
|
||||
log_crit "$func:${LINENO}: cannot change to $repository_dir!"
|
||||
return 1
|
||||
fi
|
||||
@ -137,28 +155,21 @@ pull_customer_repository () {
|
||||
|
||||
log_debug "$func:${LINENO}: commit_before_pull=$commit_before_pull"
|
||||
|
||||
exec {fd}< <(git pull)
|
||||
local ps_pid=$! # remember pid of process substitution
|
||||
|
||||
local git_result=""
|
||||
while read t <&$fd; do
|
||||
if ! [ -z "$t" ]; then
|
||||
git_result="${git_result}$t"
|
||||
fi
|
||||
done
|
||||
|
||||
exec {fd}>&- # close fd (i.e. process substitution)
|
||||
wait $ps_pid # wait for the subshell to finish
|
||||
local git_result=$(exec_git_command 'git pull')
|
||||
|
||||
if [ -z "$git_result" ]; then
|
||||
log_warn "$func:${LINENO}: git result empty" ; cd_home;
|
||||
return 1
|
||||
fi
|
||||
|
||||
# see 'man -Pless\ +/parameter/pattern/string/bash'
|
||||
git_result=${git_result//[$'\r\n\t']/ }
|
||||
|
||||
log_debug "$func:${LINENO} git-pull-result=${git_result}"
|
||||
|
||||
if [ "$git_result" = "Already up to date." ]; then
|
||||
log_warn "$func:${LINENO}: $PWD already up to date."
|
||||
if grep -qE "^Already\s+\up\s+\to\s+date.*$" <<< $git_result; then
|
||||
log_warn "$func:${LINENO}: repository $PWD already up to date."
|
||||
read $1 <<< 'yes'
|
||||
cd_home ; return 1
|
||||
fi
|
||||
|
||||
@ -228,14 +239,26 @@ pull_customer_repository () {
|
||||
cd_home ; return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
cd_home ; return 0
|
||||
}
|
||||
# pull_customer_repository customer_281
|
||||
|
||||
changed_files () {
|
||||
changed_file_names () {
|
||||
local func="${FUNCNAME[0]}"
|
||||
if cd_customer_repository ; then
|
||||
printf "%s\n" $(exec_git_command 'git diff --stat master@{1} master')
|
||||
cd_home
|
||||
local git_res=$(exec_git_command 'git diff --stat master@{1} master')
|
||||
git_res=${git_res//[$'\r\n\t']/ }
|
||||
log_debug "$func:${LINENO}: git_res=$git_res"
|
||||
local file_names=""
|
||||
for f in 'update.conf' 'opkg_commands' ; do
|
||||
if grep -qE ".*${f}.*?" <<< $git_res; then
|
||||
file_names="$f $file_names"
|
||||
fi
|
||||
done
|
||||
|
||||
cd_home ; printf "$file_names"
|
||||
else
|
||||
log_crit "$func:${LINENO}: cannot cd to $customer_repository "\
|
||||
"while in $PWD"
|
||||
fi
|
||||
}
|
@ -1,12 +1,24 @@
|
||||
#!/bin/bash
|
||||
# set -x
|
||||
|
||||
#if [ ${log_helpers_sourced:-1} = "1" ]; then
|
||||
# readonly log_helpers_sourced=${BASH_SOURCE[0]}
|
||||
#else
|
||||
# return 0
|
||||
#fi
|
||||
|
||||
readonly log_file=/var/log/update_controller.log
|
||||
if ! [ -f "$log_file" ]; then
|
||||
touch $log_file
|
||||
fi
|
||||
|
||||
readonly DEBUG=0
|
||||
readonly INFO=1
|
||||
readonly WARN=2
|
||||
readonly CRIT=3
|
||||
readonly FATAL=4
|
||||
readonly MAX_DEBUG_LEVEL=5
|
||||
readonly ERROR=4
|
||||
readonly FATAL=5
|
||||
readonly MAX_DEBUG_LEVEL=6
|
||||
|
||||
log_level=0
|
||||
|
||||
@ -21,17 +33,12 @@ dbg_level () {
|
||||
}
|
||||
|
||||
log() {
|
||||
local log_file=/var/log/update_controller.log
|
||||
if [ -f "$log_file" ]; then
|
||||
touch $log_file
|
||||
fi
|
||||
|
||||
if [[ "$(wc -l < $log_file)" > "100000" ]]; then
|
||||
if [[ $(("$(wc -l < $log_file)")) -ge $((100000)) ]]; then
|
||||
# remove first line
|
||||
sed -e 1d -i $log_file
|
||||
fi
|
||||
local msg="$(date +'%Y-%m-%d_%T'): $*"
|
||||
printf "$msg\n" >&2
|
||||
printf "log:$msg\n" >&2
|
||||
printf "$msg\n" >> $log_file
|
||||
}
|
||||
|
||||
@ -59,6 +66,12 @@ log_crit() {
|
||||
fi
|
||||
}
|
||||
|
||||
log_error() {
|
||||
if [ $log_level -le $ERROR ]; then
|
||||
log "ERROR $*"
|
||||
fi
|
||||
}
|
||||
|
||||
log_fatal() {
|
||||
if [ $log_level -le $FATAL ]; then
|
||||
log "FATAL $*"
|
283
opkg.sh
283
opkg.sh
@ -1,283 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# set -x
|
||||
|
||||
compute_md5 () {
|
||||
execdownload_opkg {fd}< <(md5sum "$1") # open fd readable for P.S.
|
||||
cs_pid=$! # remember pid of P.S.
|
||||
md5=""
|
||||
while read t <&$fd; do
|
||||
if ! [ -z "$t" ]; then
|
||||
t=($t) # md5sum returns two values:
|
||||
# the hash plus the filename
|
||||
md5="${md5}$t"
|
||||
fi
|
||||
done
|
||||
|
||||
exec {fd}>&- # close fd (i.e. process substitution)
|
||||
wait $cs_pid # wait for the subshell to finish
|
||||
echo $md5
|
||||
}
|
||||
|
||||
md5_for_ini_files() {
|
||||
ini_directory="$1"
|
||||
ini_files=("ISMASMgr.ini" "sysconfig.ini" "SystemControl.ini")
|
||||
|
||||
local data="\"ini\": {"$'\n'
|
||||
|
||||
for f in "${ini_files[@]}"; do
|
||||
ini_file=${ini_directory}/$f
|
||||
md5=`compute_md5 $ini_file`
|
||||
data+="\"$ini_file\":\"$md5\","
|
||||
done
|
||||
|
||||
if [[ "$data" =~ ^.*,$ ]]; then
|
||||
data=${data%?}
|
||||
fi
|
||||
|
||||
data+="},"
|
||||
echo $data
|
||||
}
|
||||
|
||||
md5_for_conf_files() {
|
||||
conf_directory="$1"
|
||||
conf_files=("emp.conf" "printer.conf" "device.conf")
|
||||
|
||||
local data="\"conf\": {"$'\n'
|
||||
|
||||
for f in "${conf_files[@]}"; do
|
||||
conf_file=${conf_directory}/$f
|
||||
md5=`compute_md5 $conf_file`
|
||||
data+="\"$conf_file\":\"$md5\","
|
||||
done
|
||||
|
||||
if [[ "$data" =~ ^.*,$ ]]; then
|
||||
data=${data%?}
|
||||
fi
|
||||
|
||||
data+="},"
|
||||
echo $data
|
||||
}
|
||||
|
||||
write_config() {
|
||||
local path="$1"
|
||||
if [ "${path: -1}" == "/" ]; then # remove trailing '/'
|
||||
path=${path%?}
|
||||
fi
|
||||
|
||||
local data="{ "$'\n'
|
||||
data+=`md5_for_ini_files "$path/opt/app/sysconfig"`
|
||||
data+=`md5_for_conf_files "$path/etc/psa_config"`
|
||||
data+="
|
||||
\"opkg\" : {"
|
||||
local cnt=0
|
||||
for package_name in $(opkg list-installed); # list names of installed packages
|
||||
do
|
||||
if ! grep -q "^[a-zA-Z]" <<< $package_name; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -z "$package_name" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
cnt=$((cnt+1))
|
||||
|
||||
printf "%3d:%s\n" "$cnt" "$package_name"
|
||||
|
||||
# Format of package info:
|
||||
#
|
||||
# Package: openssh-scp
|
||||
# Version: 7.8p1+git-r0
|
||||
# Depends: libc6 (>= 2.28), update-alternatives-opkg
|
||||
# Status: install ok installed
|
||||
# Section: console/network
|
||||
# Architecture: cortexa9t2hf-neon
|
||||
# Maintainer: Poky <poky@yoctoproject.org>
|
||||
# MD5Sum: dfffcbb088cd5f180be5e9ee2ad030fe
|
||||
# Size: 32700
|
||||
# Filename: openssh-scp_7.8p1+git-r0_cortexa9t2hf-neon.ipk
|
||||
# Source: openssh_7.8p1+git.bb
|
||||
# Description: A suite of security-related network....
|
||||
# Installed-Size: 58920
|
||||
# Installed-Time: 1654699615
|
||||
#
|
||||
# process substitution (P.S):
|
||||
# run 'opkg info' synchronously to parent script
|
||||
|
||||
exec {fd}< <(opkg info "$package_name") # open fd readable for P.S.
|
||||
cs_pid=$! # remember pid of P.S.
|
||||
|
||||
while read package_info_line <&$fd; do
|
||||
if [[ $package_info_line == Package* ]]; then
|
||||
package=(${package_info_line// / })
|
||||
package="\"${package[1]}\": {"
|
||||
elif [[ $package_info_line == MD5Sum* ]]; then
|
||||
md5sum=(${package_info_line// / })
|
||||
md5sum="\"${md5sum[0]%?}\": \"${md5sum[1]}\","
|
||||
elif [[ $package_info_line == Filename* ]]; then
|
||||
filename=(${package_info_line// / })
|
||||
filename="\"${filename[0]%?}\": \"${filename[1]}\","
|
||||
elif [[ $package_info_line == Installed-Time* ]]; then
|
||||
installed_time=(${package_info_line// / })
|
||||
installed_time="\"${installed_time[0]%?}\": \"${installed_time[1]}\"
|
||||
},"
|
||||
fi
|
||||
done
|
||||
|
||||
exec {fd}>&- # close fd (i.e. process substitution)
|
||||
wait $cs_pid # wait for the subshell to finish
|
||||
|
||||
# use 8 spaces
|
||||
data="$data
|
||||
$package
|
||||
$md5sum
|
||||
$filename
|
||||
$installed_time"
|
||||
|
||||
# break
|
||||
done
|
||||
|
||||
if [[ "$data" =~ ^.*,$ ]]; then
|
||||
data=${data%?}
|
||||
fi
|
||||
|
||||
data="$data
|
||||
}
|
||||
}"
|
||||
echo "$data" > "${path}/$2"
|
||||
# echo $(cat "/tmp/test.txt" | jq -C --indent 4 '.') > /tmp/test2.txt
|
||||
}
|
||||
# write_config "/home/root/szeged/customer_281/szeged/1/1/" "test.txt"
|
||||
|
||||
# Download opkg-package. After the download, extract data.tar.gz to
|
||||
# access e.g. atbqt.
|
||||
download_opkg_package () {
|
||||
|
||||
case "$1" in
|
||||
atbqt) # hier weitere packete eintragen
|
||||
;;
|
||||
|
||||
*)
|
||||
printf "ERROR $1 has wrong format\n" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exec {fdd}< <(opkg --download-only download "$1") # open fd readable for P.S.
|
||||
cs_pid=$! # remember pid of P.S.
|
||||
|
||||
opkg_result=""
|
||||
while read result <&$fdd; do
|
||||
if ! [ -z "$result" ]; then
|
||||
opkg_result+="$result"
|
||||
fi
|
||||
done
|
||||
|
||||
exec {fdd}>&- # close fd (i.e. process substitution)
|
||||
wait $cs_pid # wait for the subshell to finish
|
||||
|
||||
if [ -z "$opkg_result" ]; then
|
||||
printf "ERROR empty opkg_result\n" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! grep -qF "$1" <<< $opkg_result; then
|
||||
printf "ERROR opkg_result [$opkg_result] does not contain $1\n" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! grep -qF "$2" <<< $opkg_result; then
|
||||
printf "ERROR opkg_result [$opkg_result] does not contain $2\n" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# printf "%s\n" $opkg_result
|
||||
return 0
|
||||
}
|
||||
# download_opkg_package "atbqt" "atbqt_1.0.0-r1_cortexa9t2hf-neon.ipk"
|
||||
|
||||
ar_extract_opkg_package_data () {
|
||||
return 0
|
||||
|
||||
cp $1 "/tmp"
|
||||
# mv $1 "/tmp"
|
||||
cd /tmp
|
||||
# ar -x $1
|
||||
#if [ $? ne 0 ]; then
|
||||
data_file="data.tar.xz"
|
||||
if ! [ -f "$data_file" ]; then
|
||||
printf "ERROR %s does not exist\n" "$data_file" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
cd -
|
||||
return 0
|
||||
|
||||
tar -qxvf $data_file
|
||||
|
||||
|
||||
echo $pwd
|
||||
}
|
||||
# ar_extract_opkg_package_data "atbqt_1.0.0-r1_cortexa9t2hf-neon.ipk"
|
||||
|
||||
tar_extract_opkg_package_data () {
|
||||
exec {ftar}< <(tar -xvf "$2" -C "$1") # use process substitution
|
||||
cs_pid=$!
|
||||
exec {ftar}>&-
|
||||
wait $cs_pid
|
||||
|
||||
binary="$1/$3"
|
||||
if ! [ -f "$binary" ]; then
|
||||
printf "ERROR %s does not exist\n" "$binary" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
# tar_extract_opkg_package_data "/tmp" "data.tar.xz" "opt/app/ATBAPP/ATBQT"
|
||||
|
||||
read_atbqt_version () {
|
||||
version=$(/tmp/opt/app/ATBAPP/ATBQT -v)
|
||||
version=(${version// / })
|
||||
|
||||
# ATB APP: Version: 20221220_1038_00318q git describe: 4.5.2-65-gf1799aa3_00318/Nexobility_dev
|
||||
# printf "%s\n" "${version[@]}"
|
||||
|
||||
if [ ${#version[@]} -lt 7 ]; then
|
||||
printf "ERROR %s has wrong format\n" "${version[@]}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "${version[3]} ${version[6]}"
|
||||
}
|
||||
# xxx=`read_atbqt_version`
|
||||
# echo $xxx
|
||||
# set -x
|
||||
check_atbqt_version () {
|
||||
if ! `download_opkg_package "$1" "$2"`; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! `ar_extract_opkg_package_data "$2"`; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! `tar_extract_opkg_package_data "/tmp" "data.tar.xz" "opt/app/ATBAPP/ATBQT"`; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
version=`read_atbqt_version`
|
||||
version=(${version// / })
|
||||
|
||||
if [ "${version[0]}" = "$3" ] && [ "${version[1]}" = "$4" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
# check_atbqt_version "atbqt" \
|
||||
# "atbqt_1.0.0-r1_cortexa9t2hf-neon.ipk" \
|
||||
# "20221220_1038_00318q" \
|
||||
# "4.5.2-65-gf1799aa3_00318/Nexobility_dev"
|
||||
|
64
read_config
Executable file
64
read_config
Executable file
@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
# set -x
|
||||
|
||||
#if [ ${read_config_sourced:-1} = "1" ]; then
|
||||
# readonly read_config_sourced=${BASH_SOURCE[0]}
|
||||
#else
|
||||
# return 0
|
||||
#fi
|
||||
|
||||
# source ./log_helpers
|
||||
|
||||
# read config file (JSON syntax)
|
||||
#
|
||||
read_config() {
|
||||
local func="${FUNCNAME[0]}"
|
||||
|
||||
# check customer_id
|
||||
__customer_id="$(cat "$1" | jq -r .customer_id)"
|
||||
if [ -z "$__customer_id" ]; then
|
||||
log_fatal "$func:${LINENO} customer_id not set in $1"
|
||||
fi
|
||||
readonly customer_id="customer_${__customer_id}"
|
||||
log_info "$func:${LINENO}: customer-id is $customer_id"
|
||||
|
||||
# check customer_repository
|
||||
__repository_path="$(cat "$1" | jq -r .repository_path)"
|
||||
if [ -z "$__repository_path" ]; then
|
||||
log_fatal "$func:${LINENO}: repository path not set in $1"
|
||||
fi
|
||||
readonly repository_path="${__repository_path}/${customer_id}.git"
|
||||
log_info "$func:${LINENO}: repository path is $repository_path"
|
||||
|
||||
# check zone_group
|
||||
local zone_group="$(cat "$1" | jq -r .zone_group)"
|
||||
if [ -z "$zone_group" ]; then
|
||||
log_fatal "$func:${LINENO}: zone_group not set in $1"
|
||||
fi
|
||||
|
||||
# check zone
|
||||
local zone="$(cat "$1" | jq -r .zone)"
|
||||
if [ -z "$zone" ]; then
|
||||
log_fatal "$func:${LINENO}: zone not set in $1"
|
||||
fi
|
||||
|
||||
# check customer_location
|
||||
local customer_location="$(cat "$1" | jq -r .customer_location)"
|
||||
if [ -z "$customer_location" ]; then
|
||||
log_fatal "$func:${LINENO}: customer_location not set in $1"
|
||||
fi
|
||||
|
||||
local workspace="$(cat "$1" | jq -r .workspace_dir)"
|
||||
__customer_base_dir="$PWD/${workspace}/${customer_id}/${customer_location}"
|
||||
|
||||
readonly customer_base_dir="${__customer_base_dir}/${zone_group}/${zone}"
|
||||
log_info "$func:${LINENO}: customer-base-dir is $customer_base_dir"
|
||||
|
||||
readonly opkg_cmds_file="${customer_base_dir}/etc/psa_update/opkg_commands"
|
||||
log_info "$func:${LINENO}: opkg_cmds_file is $opkg_cmds_file"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# read_config UpdateController.conf
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
# set -x
|
||||
|
||||
source ./log_helpers.sh
|
||||
source ./git_helpers.sh
|
||||
source ./log_helpers
|
||||
source ./git_helpers
|
||||
|
||||
extract_changed_files () {
|
||||
local func="${FUNCNAME[0]}"
|
||||
|
163
update_psa
Executable file
163
update_psa
Executable file
@ -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
|
157
update_psa_helpers
Normal file
157
update_psa_helpers
Normal file
@ -0,0 +1,157 @@
|
||||
#!/bin/bash
|
||||
|
||||
# if [ ${git_helpers_sourced:-1} = "1" ]; then
|
||||
# readonly git_helpers_sourced=${BASH_SOURCE[0]}
|
||||
#else
|
||||
# return 0
|
||||
#fi
|
||||
|
||||
exec_opkg_command () {
|
||||
local func="${FUNCNAME[0]}"
|
||||
|
||||
log_debug "$func:${LINENO} exec-ing [$*]"
|
||||
|
||||
exec {fd}< <($@)
|
||||
local ps_pid=$! # remember pid of process substitution
|
||||
|
||||
local opkg_result=""
|
||||
while read tmp <&$fd; do
|
||||
if ! [ -z "$tmp" ]; then
|
||||
opkg_result="${opkg_result}$tmp"
|
||||
fi
|
||||
done
|
||||
|
||||
exec {fd}>&- # close fd (i.e. process substitution)
|
||||
wait $ps_pid # wait for the subshell to finish
|
||||
|
||||
printf '%s' "$opkg_result"
|
||||
}
|
||||
|
||||
# Fetch/merge updates from predefined repository using git.
|
||||
#
|
||||
fetch_customer_updates() {
|
||||
local func="${FUNCNAME[0]}"
|
||||
if ! pull_customer_repository $1; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Check if the fetched/merged files have the correct md5 and are
|
||||
# valid for the PSA.
|
||||
#
|
||||
check_md5_for_changed_customer_files () {
|
||||
local func="${FUNCNAME[0]}"
|
||||
#for file in ($1); do
|
||||
# Check the updates for correct MD5
|
||||
# log_error "$func:${LINENO}: new customer files wrong"
|
||||
# revert_customer_repository ; exit 1
|
||||
# fi
|
||||
#done
|
||||
return 0
|
||||
}
|
||||
|
||||
check_md5_for_opkg_packages () {
|
||||
local func="${FUNCNAME[0]}"
|
||||
local -n opkg_output_ref=$1
|
||||
local package=""
|
||||
local md5sum=""
|
||||
local filename=""
|
||||
for line in ${opkg_output_ref[@]}; do
|
||||
if grep -qE "^\s*Package\s*:.*?$" <<< "$line"; then
|
||||
package=${line#*:* }
|
||||
printf 'package=%s\n' "$package"
|
||||
elif grep -qE "^\s*MD5Sum\s*:.*?$" <<< "$line"; then
|
||||
md5sum=${line#*:* }
|
||||
printf 'md5sum=%s\n' "$md5sum"
|
||||
elif grep -qE "^\s*Filename\s*:.*?$" <<< "$line"; then
|
||||
filename=${line#*:* }
|
||||
printf 'filename=%s\n' "$filename"
|
||||
fi
|
||||
done
|
||||
|
||||
log_debug "$func:${LINENO}: $package | $md5sum | $filename"
|
||||
return 0
|
||||
}
|
||||
|
||||
# In case the new checked-out files are not correct, revert the git
|
||||
# repository to its previous state.
|
||||
#
|
||||
revert_customer_repository() {
|
||||
local func="${FUNCNAME[0]}"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Backup before the update-process.
|
||||
#
|
||||
backup_previous_version () {
|
||||
local func="${FUNCNAME[0]}"
|
||||
return 0
|
||||
}
|
||||
|
||||
exec_opkg_info () {
|
||||
local func="${FUNCNAME[0]}"
|
||||
log_info "$func:${LINENO}: executing $opkg_command"
|
||||
|
||||
opkg_result=$(exec_opkg_command "opkg info $1")
|
||||
|
||||
# make sure the keywords start with '\n'
|
||||
opkg_result=$(sed -E -e "s/(^.*)(Package)(.*$)/\n\2\3/g"\
|
||||
-e "s/(^.*)(Version)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Depends)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Status)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Architecture)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Maintainer)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(MD5Sum)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Filename)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Source)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Description)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Installed-Size)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Section)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*[^-])(Size)(.*$)/\1\n\2\3/g"\
|
||||
-e "s/(^.*)(Installed-Time)(.*$)/\1\n\2\3/g" <<< "$opkg_result")
|
||||
|
||||
local -n output_ref=$2
|
||||
|
||||
readarray -d $'\n' output_ref < <(printf '%s' "$opkg_result")
|
||||
if [ $? -ne 0 ]; then
|
||||
log_error "$func:${LINENO}: readarray finished with error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "$func:${LINENO}: ... done"
|
||||
log_info "$func:${LINENO}: opkg_result=${output_ref[@]}"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Try to install new opkg-packages (in case the are some
|
||||
# in the new git-checkout).
|
||||
#
|
||||
exec_opkg_no_action() {
|
||||
local func="${FUNCNAME[0]}"
|
||||
local opkg_command_no_action="opkg --noaction $1"
|
||||
log_info "$func:${LINENO}: executing $opkg_command_no_action"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Install the new packages using opkg.
|
||||
#
|
||||
exec_opkg () {
|
||||
local func="${FUNCNAME[0]}"
|
||||
return 0
|
||||
}
|
||||
|
||||
# In case there was some error, re-install the previous package(s)
|
||||
# and use the backup to restore any conf/ini-files.
|
||||
#
|
||||
fallback_to_previous_version() {
|
||||
local func="${FUNCNAME[0]}"
|
||||
return 0;
|
||||
}
|
||||
|
||||
# If all went well, then execute all necessary cleanup steps.
|
||||
#
|
||||
cleanup_previous_version() {
|
||||
local func="${FUNCNAME[0]}"
|
||||
return 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user