Compare commits
No commits in common. "40e87863912a996f479ebab3fcf72a74c9a4b063" and "c032d5d5287c407fd0aef39d8382a699fb11c5c5" have entirely different histories.
40e8786391
...
c032d5d528
@ -1,10 +1,11 @@
|
|||||||
{
|
{
|
||||||
|
"fifo_dir" : "/tmp",
|
||||||
|
"fifo" : "update_controller_fifo",
|
||||||
|
"workspace" : "workspace",
|
||||||
"GIT_SSL_NO_VERIFY" : true,
|
"GIT_SSL_NO_VERIFY" : true,
|
||||||
"working_directory" : ".",
|
|
||||||
"workspace_dir" : "workspace",
|
|
||||||
"customer_location" : "szeged",
|
|
||||||
"customer_id" : "281",
|
"customer_id" : "281",
|
||||||
"zone_group" : "1",
|
"zone_group" : "1",
|
||||||
"zone" : "1",
|
"zone" : "1",
|
||||||
|
"customer_location" : "szeged",
|
||||||
"repository_path" : "https://git.mimbach49.de/GerhardHoffmann"
|
"repository_path" : "https://git.mimbach49.de/GerhardHoffmann"
|
||||||
}
|
}
|
||||||
|
396
UpdateController.sh
Executable file
396
UpdateController.sh
Executable file
@ -0,0 +1,396 @@
|
|||||||
|
#!/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,25 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# set -x
|
# set -x
|
||||||
|
|
||||||
# if [ ${git_helpers_sourced:-1} = "1" ]; then
|
source ./log_helpers.sh
|
||||||
# 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 () {
|
exec_git_command () {
|
||||||
local func="${FUNCNAME[0]}"
|
local func="${FUNCNAME[0]}"
|
||||||
|
|
||||||
log_debug "$func:${LINENO} exec-ing [$*]"
|
log_debug "$func:${LINENO} exec-ing $1"
|
||||||
|
|
||||||
exec {fd}< <($@)
|
exec {fd}< <($1)
|
||||||
local ps_pid=$! # remember pid of process substitution
|
local ps_pid=$! # remember pid of process substitution
|
||||||
|
|
||||||
local git_result=""
|
local git_result=""
|
||||||
@ -43,13 +35,15 @@ latest_commit () {
|
|||||||
local c=$(git reflog | grep "HEAD@{0}" | cut -d" " -f1)
|
local c=$(git reflog | grep "HEAD@{0}" | cut -d" " -f1)
|
||||||
if ! [ -z "$c" ]; then
|
if ! [ -z "$c" ]; then
|
||||||
if grep -qE "^[[:xdigit:]]{6,}$" <<< $c; then
|
if grep -qE "^[[:xdigit:]]{6,}$" <<< $c; then
|
||||||
log_debug "$func:${LINENO} commit -> $c"
|
log_debug "$func: commit -> $c"
|
||||||
printf "%s\n" $c
|
printf "%s\n" $c
|
||||||
else
|
else
|
||||||
log_crit "$func:${LINENO} wrong format for commit c=$c"
|
log_crit "$func: wrong format for commit c=$c"
|
||||||
|
printf ""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
log_crit "$func:${LINENO} 'git reflog' result empty"
|
log_crit "$func: 'git reflog' result empty"
|
||||||
|
printf ""
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,22 +79,10 @@ clone_customer_repository () {
|
|||||||
# check if the directory is empty. If so, clone the
|
# check if the directory is empty. If so, clone the
|
||||||
# customer repository
|
# customer repository
|
||||||
if ! find ./workspace -mindepth 1 -maxdepth 1 | read; then
|
if ! find ./workspace -mindepth 1 -maxdepth 1 | read; then
|
||||||
log_debug "$func:${LINENO} cloning ${1} ..."
|
log_debug "$func: cloning ${1} ..."
|
||||||
if { cd ./workspace ; }; then
|
( cd ./workspace && git clone "$1" ; )
|
||||||
$(exec_git_command git clone "$1")
|
if [ $? -eq 0 ]; then
|
||||||
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
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -122,7 +104,7 @@ cd_customer_repository () {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! { cd $repository_dir; } ; then
|
if ! cd $repository_dir; then
|
||||||
log_crit "$func:${LINENO}: cannot change to $repository_dir!"
|
log_crit "$func:${LINENO}: cannot change to $repository_dir!"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -154,22 +136,29 @@ pull_customer_repository () {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
log_debug "$func:${LINENO}: commit_before_pull=$commit_before_pull"
|
log_debug "$func:${LINENO}: commit_before_pull=$commit_before_pull"
|
||||||
|
|
||||||
local git_result=$(exec_git_command 'git 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
|
||||||
|
|
||||||
if [ -z "$git_result" ]; then
|
if [ -z "$git_result" ]; then
|
||||||
log_warn "$func:${LINENO}: git result empty" ; cd_home;
|
log_warn "$func:${LINENO}: git result empty" ; cd_home;
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# see 'man -Pless\ +/parameter/pattern/string/bash'
|
|
||||||
git_result=${git_result//[$'\r\n\t']/ }
|
|
||||||
|
|
||||||
log_debug "$func:${LINENO} git-pull-result=${git_result}"
|
log_debug "$func:${LINENO} git-pull-result=${git_result}"
|
||||||
|
|
||||||
if grep -qE "^Already\s+\up\s+\to\s+date.*$" <<< $git_result; then
|
if [ "$git_result" = "Already up to date." ]; then
|
||||||
log_warn "$func:${LINENO}: repository $PWD already up to date."
|
log_warn "$func:${LINENO}: $PWD already up to date."
|
||||||
read $1 <<< 'yes'
|
|
||||||
cd_home ; return 1
|
cd_home ; return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -177,7 +166,7 @@ pull_customer_repository () {
|
|||||||
if [ -z $commit_after_pull ]; then
|
if [ -z $commit_after_pull ]; then
|
||||||
cd_home ; return 1
|
cd_home ; return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_debug "$func:${LINENO}: commit_after_pull=$commit_after_pull"
|
log_debug "$func:${LINENO}: commit_after_pull=$commit_after_pull"
|
||||||
|
|
||||||
# Note: # 'git pull' is a 'git fetch' followed by a 'git merge'.
|
# Note: # 'git pull' is a 'git fetch' followed by a 'git merge'.
|
||||||
@ -239,26 +228,14 @@ pull_customer_repository () {
|
|||||||
cd_home ; return 1
|
cd_home ; return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd_home ; return 0
|
return 0
|
||||||
}
|
}
|
||||||
# pull_customer_repository customer_281
|
# pull_customer_repository customer_281
|
||||||
|
|
||||||
changed_file_names () {
|
changed_files () {
|
||||||
local func="${FUNCNAME[0]}"
|
local func="${FUNCNAME[0]}"
|
||||||
if cd_customer_repository ; then
|
if cd_customer_repository ; then
|
||||||
local git_res=$(exec_git_command 'git diff --stat master@{1} master')
|
printf "%s\n" $(exec_git_command 'git diff --stat master@{1} master')
|
||||||
git_res=${git_res//[$'\r\n\t']/ }
|
cd_home
|
||||||
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
|
fi
|
||||||
}
|
}
|
@ -1,24 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# set -x
|
# 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 DEBUG=0
|
||||||
readonly INFO=1
|
readonly INFO=1
|
||||||
readonly WARN=2
|
readonly WARN=2
|
||||||
readonly CRIT=3
|
readonly CRIT=3
|
||||||
readonly ERROR=4
|
readonly FATAL=4
|
||||||
readonly FATAL=5
|
readonly MAX_DEBUG_LEVEL=5
|
||||||
readonly MAX_DEBUG_LEVEL=6
|
|
||||||
|
|
||||||
log_level=0
|
log_level=0
|
||||||
|
|
||||||
@ -33,12 +21,17 @@ dbg_level () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log() {
|
log() {
|
||||||
if [[ $(("$(wc -l < $log_file)")) -ge $((100000)) ]]; then
|
local log_file=/var/log/update_controller.log
|
||||||
|
if [ -f "$log_file" ]; then
|
||||||
|
touch $log_file
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$(wc -l < $log_file)" > "100000" ]]; then
|
||||||
# remove first line
|
# remove first line
|
||||||
sed -e 1d -i $log_file
|
sed -e 1d -i $log_file
|
||||||
fi
|
fi
|
||||||
local msg="$(date +'%Y-%m-%d_%T'): $*"
|
local msg="$(date +'%Y-%m-%d_%T'): $*"
|
||||||
printf "log:$msg\n" >&2
|
printf "$msg\n" >&2
|
||||||
printf "$msg\n" >> $log_file
|
printf "$msg\n" >> $log_file
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,12 +59,6 @@ log_crit() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
log_error() {
|
|
||||||
if [ $log_level -le $ERROR ]; then
|
|
||||||
log "ERROR $*"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
log_fatal() {
|
log_fatal() {
|
||||||
if [ $log_level -le $FATAL ]; then
|
if [ $log_level -le $FATAL ]; then
|
||||||
log "FATAL $*"
|
log "FATAL $*"
|
283
opkg.sh
Executable file
283
opkg.sh
Executable file
@ -0,0 +1,283 @@
|
|||||||
|
#!/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
64
read_config
@ -1,64 +0,0 @@
|
|||||||
#!/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
|
#!/bin/bash
|
||||||
# set -x
|
# set -x
|
||||||
|
|
||||||
source ./log_helpers
|
source ./log_helpers.sh
|
||||||
source ./git_helpers
|
source ./git_helpers.sh
|
||||||
|
|
||||||
extract_changed_files () {
|
extract_changed_files () {
|
||||||
local func="${FUNCNAME[0]}"
|
local func="${FUNCNAME[0]}"
|
||||||
|
163
update_psa
163
update_psa
@ -1,163 +0,0 @@
|
|||||||
#!/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
|
|
@ -1,157 +0,0 @@
|
|||||||
#!/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