diff options
Diffstat (limited to 'contrib/package/remote-update')
-rw-r--r-- | contrib/package/remote-update/Makefile | 43 | ||||
-rwxr-xr-x | contrib/package/remote-update/files/usr/sbin/remote-update | 309 |
2 files changed, 352 insertions, 0 deletions
diff --git a/contrib/package/remote-update/Makefile b/contrib/package/remote-update/Makefile new file mode 100644 index 000000000..c8adceeaa --- /dev/null +++ b/contrib/package/remote-update/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> +# +# This is free software, licensed under the Apache 2.0 license. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=remote-update +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/remote-update + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=Freifunk + TITLE:=Freifunk remote update utility. + DEPENDS:=@TARGET_atheros||@TARGET_ar71xx||@TARGET_brcm-2.4 +endef + +define Package/remote-update/description + The freifunk remote-update utility uses sysupgrade to reflash the currently + running firmware while keeping most of the existing configuratio. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/remote-update/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,remote-update)) diff --git a/contrib/package/remote-update/files/usr/sbin/remote-update b/contrib/package/remote-update/files/usr/sbin/remote-update new file mode 100755 index 000000000..bffc449d0 --- /dev/null +++ b/contrib/package/remote-update/files/usr/sbin/remote-update @@ -0,0 +1,309 @@ +#!/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 + ;; + ar71xx) + if grep -q '"kernel"' /proc/mtd; then + echo "openwrt-ar71xx-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_info() +{ + wget -qO- "${1%/*}/VERSION.txt" 2>/dev/null +} + +find_remote_version() +{ + find_remote_info "$1" | \ + 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 <<EOT + +Usage: + remote-update -h + remote-update [-u <update url>] -c + remote-update [-v] [-y] [-u <update url>] -w + remote-update [-d] [-n] [-v] [-y] [-s <sleep seconds>] [-u <update url>] + +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 <seconds> + Sleep given amount of seconds before starting flash write. + If ommitted and '-y' is not used, 5 seconds are assumed. + + -u <url> + 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) + repo=${repo:-$(uci get system.upgrade.repository 2>/dev/null)} + + [ -z "$arch" ] && { + echo "Can not determine the current architecture." + exit 1 + } + + [ -z "$repo" ] && { + echo "No repository configured in 'system.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!${NL}Local: $v1${NL}Remote: $v2${NL}--" + find_remote_info "$image_url" + exit 0 + } || { + echo "Local version $v1 is up to date" + exit 2 + } + } || { + 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 <Ctrl-C> 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 <Enter> to continue or <Ctrl-C> 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 |