From 4803e8ec249a452d6d748be671d1541367868bfd Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Tue, 30 Jun 2009 01:29:33 +0000 Subject: [PATCH] modules/freifunk: add remote-update cli utility --- modules/freifunk/root/etc/config/freifunk | 2 + modules/freifunk/root/usr/sbin/remote-update | 295 +++++++++++++++++++++++++++ 2 files changed, 297 insertions(+) create mode 100755 modules/freifunk/root/usr/sbin/remote-update diff --git a/modules/freifunk/root/etc/config/freifunk b/modules/freifunk/root/etc/config/freifunk index 5c6f1ac79..49112894c 100644 --- a/modules/freifunk/root/etc/config/freifunk +++ b/modules/freifunk/root/etc/config/freifunk @@ -76,6 +76,8 @@ config defaults olsr_interface config defaults time option rdate_servers "128.138.140.44 171.64.7.77 171.64.7.99 81.169.154.44 130.133.1.10" +config defaults upgrade + option repository "http://dev.luci.freifunk-halle.net/freifunk-snapshots" config community leipzig option name "Freifunk Leipzig" diff --git a/modules/freifunk/root/usr/sbin/remote-update b/modules/freifunk/root/usr/sbin/remote-update new file mode 100755 index 000000000..3cf085c11 --- /dev/null +++ b/modules/freifunk/root/usr/sbin/remote-update @@ -0,0 +1,295 @@ +#!/bin/sh + +local tempfile=/tmp/remote-upgrade.img +local D2='\([0-9]\{2\}\)' +local D4='\([0-9]\{4\}\)' +local NL=' +' + +find_architecture() +{ + opkg list_installed 'base-files-*' | \ + sed -ne 's/base-files-\([^ ]\+\).*/\1/p' +} + +find_image() +{ + case "$1" in + atheros) + if grep -q '"vmlinux.bin.l7"' /proc/mtd; then + echo "openwrt-fonera-combined.img" + else + echo "openwrt-ubiquity-combined.img" + fi + ;; + brcm-2.4) + echo "openwrt-brcm-2.4-squashfs.trx" + ;; + esac +} + +check_image() +{ + local file; for file in /lib/upgrade/*.sh; do . $file; done + if platform_check_image "$1" >/dev/null 2>/dev/null; then + return 0 + fi + return 1 +} + +find_remote_checksum() +{ + wget -qO- ${1%/*}/md5sums 2>/dev/null | \ + sed -ne '/'$2'/ { s/ .*//p }' +} + +find_local_checksum() +{ + set -- $(md5sum "$tempfile") + echo $1 +} + +find_remote_version() +{ + wget -qO- "${1%/*}/VERSION.txt" 2>/dev/null | \ + sed -ne "s!.*$D4/$D2/$D2 $D2:$D2.*!\\1\\2\\3\\4\\5!p;t" +} + +find_local_version() +{ + if [ -f /rom/etc/banner ]; then + sed -ne "s!.*$D4/$D2/$D2 $D2:$D2.*!\\1\\2\\3\\4\\5!p;t" \ + /rom/etc/banner + else + date +"%Y%m%d%H%M" -r /bin/sh + fi +} + +stop_service() +{ + [ -x /etc/init.d/$1 ] && { + echo -n "Stopping service $1 ... " + /etc/init.d/$1 stop >/dev/null 2>/dev/null + echo "done" + } +} + +do_wait() +{ + if [ ${1:-0} -gt 0 ]; then + echo -n "${2:-Waiting} " + for i in $(seq 1 $1); do + printf "%-2dseconds" $(($1-$i)) + sleep 1 + echo -en "\b\b\b\b\b\b\b\b\b" + done + echo "${NL}" + fi +} + +version_compare() +{ + local v1="$1" + local v2="$2" + + while [ -n "$v1" -o -n "$v2" ]; do + if [ -z "${v2:0:4}" -o "${v1:0:4}" -gt "${v2:0:4}" ]; then + return 1 + elif [ -z "${v1:0:4}" -o "${v1:0:4}" -lt "${v2:0:4}" ]; then + return 2 + fi + + v1="${v1:4}" + v2="${v2:4}" + done + + return 0 +} + +usage() +{ + cat <] [-u ] + +Actions: + -h Display this help message and exit. + -c Check for firmware update and exit. + -w Fetch image and exit, do not perform flash write. + +Options: + -d Do not detach from terminal. + -n Do not backup configuration. + -v Skip verification of downloaded image. + -y Assume defaults for all questions. + + -s + Sleep given amount of seconds before invoking firmware burn. + If ommitted and '-y' is not used, 5 seconds are assumed. + + -u + Fetch firmware image from given url. A file "md5sums" is expected + in the same remote directory. If there is no such file, use -v to + suppress verification. + +EOT + + exit 1 +} + + +while getopts "s:u:cdnvwyh" flag; do + case $flag in + s) sleeptime="$OPTARG";; + u) updateurl="$OPTARG";; + c) checkupdate=1;; + d) nodetach=1;; + n) nobackup=1;; + v) noverify=1;; + w) noflash=1;; + y) noquestions=1;; + *) usage;; + esac +done + + +local image_url="$updateurl" +local image_name="${image_url##*/}" + +[ -z "$image_url" ] && { + local arch=$(find_architecture) + local image=$(find_image "$arch") + local repo=$(uci get freifunk.upgrade.repository 2>/dev/null) + + [ -z "$arch" ] && { + echo "Can not determine the current architecture." + exit 1 + } + + [ -z "$repo" ] && { + echo "No repository configured in 'freifunk.upgrade.repository'." + echo "Use the '-u' flag to specify an image location." + exit 1 + } + + [ -z "$image" ] && { + echo "No suitable image for the '$arch' architecture." + echo "Your platform is not supported." + exit 1 + } + + echo "Architecture: $arch" + echo "Repository: $repo" + + image_name="$image" + image_url="${repo%/}/$arch/$image" +} + + +if [ "$checkupdate" = 1 ]; then + local v1=$(find_local_version) + local v2=$(find_remote_version "$image_url") + + [ -n "$v1" -a -n "$v2" ] && { + version_compare "$v1" "$v2" + [ $? == 2 ] && { + echo "Update available! $v1 -> $v2" + } || { + echo "Local version $v1 is up to date" + } + } || { + echo "No remote time stamp found." + exit 1 + } +else + if [ "$noquestions" != 1 ]; then + echo -n "${NL}About to download $image_name. Continue? [y] " + read answer + case "$answer" in + [nN]) exit 1;; + esac + fi + + echo -n "Downloading $image_name ... " + rm -f $tempfile + wget -qO $tempfile "$image_url" 2>/dev/null + [ $? == 0 ] && echo done || { + echo failed + rm -f $tempfile + exit 1 + } + + if [ "$noverify" != 1 ]; then + echo -n "Verifying $image_name ... " + + local md5_remote=$(find_remote_checksum "$image_url" "$image_name") + local md5_local=$(find_local_checksum) + + check_image "$tempfile" + local image_ok=$? + + if [ $image_ok = 0 -a -n "$md5_remote" -a -n "$md5_local" -a "$md5_remote" = "$md5_local" ]; then + echo "done" + else + if [ $image_ok != 0 ]; then + echo "unsupported image type" + else + echo "checksum mismatch! (local:${md5_local:-(none)} remote:${md5_remote:-(none)})" + fi + + local answer=n + if [ "$noquestions" != 1 ]; then + echo -n "${NL}Verification failed. Continue anyway? [n] " + read answer + fi + + case "$answer" in + [yYjJ]*) : ;; + *) + echo "Aborting." + rm -f $tempfile + exit 1 + ;; + esac + fi + fi + + if [ "$noflash" != 1 ]; then + if [ -f "$tempfile" ]; then + if [ "$noquestions" == 1 ]; then + do_wait ${sleeptime:-5} "${NL}About to start flashing, hit to abort!${NL}${NL}Starting in" + else + if [ -z "$nobackup" ]; then + echo -n "${NL}Keep configuration files? [y] " + read answer + case "$answer" in + [nN]) nobackup=1;; + esac + fi + + echo -n "${NL}About to start flashing!${NL}Hit to continue or to abort.${NL}" + read answer + fi + + for s in lucid collectd; do stop_service $s; done + + if [ "$nodetach" != 1 ]; then + echo -n "Starting sysupgrade in background ... " + /bin/busybox start-stop-daemon -S -b -x /sbin/sysupgrade -- ${nobackup:+-n} "$tempfile" + echo "done" + else + echo "Executing sysupgrade ... " + exec /sbin/sysupgrade ${nobackup:+-n} "$tempfile" + fi + else + echo "No upgrade image found!" + exit 1 + fi + else + echo "Image saved in '$tempfile'" + fi +fi -- 2.11.0