You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
5.6 KiB
Bash

#!/bin/sh
#
# Copyright (C) 2016 devolo AG
#
#implement config migration mechanism
. $MIGTEST/lib/migration/migration.sh
getCurrentFwVersion() {
local version="$($UCI_TOOL get delos.delos.version 2>&1)"
if [ -n "$version" -a -z "$(echo $version | grep "uci")" ];then
echo "$version"
return
fi
echo "version_not_found"
}
evaluateMigration() {
local version=$(getCurrentFwVersion)
local path=""
if [ "$version" != "version_not_found" ]; then
if [ "$version" != "$CURRENT_CONFIG_VERSION" ]; then
path="$(evaluatePath "$version" "$CURRENT_CONFIG_VERSION")"
updateMigrationScripts $path
else
$LOG_TOOL "Migration: no migration necessary"
return
fi
else
version="2.0.0"
path="$(evaluatePath "$version" "$CURRENT_CONFIG_VERSION")"
updateMigrationScripts $path
fi
if [ -z "$path" ]; then
echo "migration_not_possible"
$LOG_TOOL "Migration: could not determine up/downgrade path"
else
$LOG_TOOL "Migration: migrate from $version to $CURRENT_CONFIG_VERSION"
echo "$path"
fi
}
doMigration() {
local path=$(evaluateMigration)
if [ -n "$path" -a "$path" != "migration_not_possible" ]; then
for step in $path; do
local scripts=$(find $MIG_BASE/$step -maxdepth 1 -type f -exec basename {} \; |
grep -v "$step")
for script in $scripts; do
$LOG_TOOL " call $step/$script"
$MIG_BASE/$step/$script > /dev/null
local retCode=$?
if [ $retCode -ne 0 ]; then
echo "migration_not_possible"
$LOG_TOOL "Migration: error during migration"
fi
done
done
migrateVersion
else
echo "$path"
fi
forceCurrentMigrationScripts
}
migrateVersion() {
local version=$(getCurrentFwVersion)
if [ "$version" = "version_not_found" ]; then
$UCI_TOOL set delos.delos=configuration #creates config configuration 'delos'
fi
$UCI_TOOL set delos.delos.version=$CURRENT_CONFIG_VERSION
$UCI_TOOL commit
}
findPath() {
local dest="$1"
local path="$2"
while true; do
local newPath=$(getNewPath "$path")
local unknownElements=""
for newElem in $newPath; do
if [ "$(extractTo "$newElem")" = "$dest" ]; then
cleanupList "$path $newElem"
return
else
if ! isCrossExchangedInList "$newElem" "$path"; then
if ! isDuplicate "$newElem" "$path"; then
unknownElements="$unknownElements $newElem"
fi
fi
fi
done
if [ -z "$unknownElements" ]; then
cleanupList "$path"
return
fi
#findPath "$dest" "$path $unknownElements"
# tail recursion -> loop
path="$path $unknownElements"
done
}
cleanupList() {
echo "$1" | sed -e 's/ */ /g'
}
isDuplicate() {
local elem="$1"
local list="$2"
for item in $list; do
if [ "$item" = "$elem" ]; then
return 0
fi
done
return 1
}
isCrossExchange() {
local elem1="$1"
local elem2="$2"
local ef1="$(extractFrom "$elem1")"
local et1="$(extractTo "$elem1")"
local ef2="$(extractFrom "$elem2")"
local et2="$(extractTo "$elem2")"
if [ $ef1 = $et2 ]; then
if [ $ef2 = $et1 ]; then
return 0
fi
fi
return 1
}
isCrossExchangedInList() {
local elem="$1"
local list="$2"
for item in $list; do
if isCrossExchange "$elem" "$item"; then
return 0
fi
done
return 1
}
extractFrom() {
echo "${1%%To*}"
}
extractTo() {
echo "${1#*To}"
}
getTo() {
local to=$1
for mig in $MIG_DIRS; do
local tov=$(extractTo $mig)
if [ "$fromv" = "$to" ]; then
found="$found $mig"
fi
done
echo $found
}
getFrom() {
local from=$1
for mig in $MIG_DIRS; do
local fromv=$(extractFrom $mig)
if [ "$fromv" = "$from" ]; then
found="$found $mig"
fi
done
echo $found
}
getNewPath() {
local search="$1"
local found=""
for item in $search; do
for mig in $MIG_DIRS; do
if [ "$(extractFrom $mig)" = "$(extractTo $item)" ]; then
found="$found $mig"
fi
done
done
echo $found
}
evaluatePath() {
local from="$1"
local to="$2"
local simple="$from""To""$to"
if [ "$from" = "$to" ]; then
echo ""
return
elif [ -n "$(echo "$MIG_DIRS" | fgrep "$simple")" ]; then
echo $simple
return
else
local firstpath=$(getFrom $from)
#assume upgrade first, assume related to ascending order
a=$(echo "$firstpath" | awk -F' ' '{printf $2}')
path1=$(findPath $to "$a")
targetPath1=$(extractTo "$(echo $path1 | awk -F' ' '{print $NF}')");
if [ "$targetPath1" = "$to" ]; then
echo $path1
return
fi
#downgrade
b=$(echo "$firstpath" | awk -F' ' '{printf $1}')
path2=$(findPath $to "$b")
targetPath2=$(extractTo "$(echo $path2 | awk -F' ' '{print $NF}')");
if [ "$targetPath2" = "$to" ]; then
echo $path2
fi
fi
}
start() {
case "$BOARD" in
dlan-*|\
dvl-*|\
ew-*)
doMigration
;;
esac
if [ -z "$MIGTEST" ];then
# keep this file for the next boot
exit 1
fi
}
if [ -z "$MIGTEST" ];then
start
fi