#!/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