diff mbox series

[OpenWrt-Devel,1/2] build: sysupgrade-tar alt-board= for legacy upgrades

Message ID 20191025035753.10050-2-lede@allycomm.com
State Superseded
Headers show
Series build: sysupgrade: Enable Robust NAND Upgrades | expand

Commit Message

Jeff Kletsky Oct. 25, 2019, 3:57 a.m. UTC
From: Jeff Kletsky <git-commits@allycomm.com>

Targets that use nand_do_platform_check() can't use SUPPORTED_DEVICES
as the check requires ./sysupgrade-legacy_boardname/CONTROL to be
non-zero length as extracted from the tar file. Previously, only
./sysupgrade-new_boardname/CONTROL was present.

This prevents upgrade without --force from, for example, ar71xx to ath79

Add an optional alt-board= parameter to parsing of sysupgrade-tar that
creates a directory at the expected location for the alt-board name,
copying over the CONTROL file.

The contents of CONTROL are unmodified by this commit.

Careful ordering of the tar file is required as existing builds
expect the kernel and root assets to be in the first directory
returned by tar -tf that matches sysupgrade-*/

Run-tested-on: EA8300, GL-AR300M, GL-AR750S

Signed-off-by: Jeff Kletsky <git-commits@allycomm.com>
---
 include/image-commands.mk |  1 +
 scripts/sysupgrade-tar.sh | 40 +++++++++++++++++++++++++++++++++------
 2 files changed, 35 insertions(+), 6 deletions(-)

Comments

Daniel Golle Nov. 6, 2019, 10:47 p.m. UTC | #1
Hi Jeff,

On Thu, Oct 24, 2019 at 08:57:52PM -0700, Jeff Kletsky wrote:
> From: Jeff Kletsky <git-commits@allycomm.com>
> 
> Targets that use nand_do_platform_check() can't use SUPPORTED_DEVICES
> as the check requires ./sysupgrade-legacy_boardname/CONTROL to be
> non-zero length as extracted from the tar file. Previously, only
> ./sysupgrade-new_boardname/CONTROL was present.
> 
> This prevents upgrade without --force from, for example, ar71xx to ath79
> 
> Add an optional alt-board= parameter to parsing of sysupgrade-tar that
> creates a directory at the expected location for the alt-board name,
> copying over the CONTROL file.
> 
> The contents of CONTROL are unmodified by this commit.
> 
> Careful ordering of the tar file is required as existing builds
> expect the kernel and root assets to be in the first directory
> returned by tar -tf that matches sysupgrade-*/
> 
> Run-tested-on: EA8300, GL-AR300M, GL-AR750S
> 
> Signed-off-by: Jeff Kletsky <git-commits@allycomm.com>
> ---
>  include/image-commands.mk |  1 +
>  scripts/sysupgrade-tar.sh | 40 +++++++++++++++++++++++++++++++++------
>  2 files changed, 35 insertions(+), 6 deletions(-)
> 
> diff --git a/include/image-commands.mk b/include/image-commands.mk
> index 5dfd6a2c2f..011e30a7e3 100644
> --- a/include/image-commands.mk
> +++ b/include/image-commands.mk
> @@ -321,6 +321,7 @@ endef
>  define Build/sysupgrade-tar
>  	sh $(TOPDIR)/scripts/sysupgrade-tar.sh \
>  		--board $(if $(BOARD_NAME),$(BOARD_NAME),$(DEVICE_NAME)) \
> +		--alt-boards "$(call param_get,alt-board,$(1))" \
>  		--kernel $(call param_get_default,kernel,$(1),$(IMAGE_KERNEL)) \
>  		--rootfs $(call param_get_default,rootfs,$(1),$(IMAGE_ROOTFS)) \
>  		$@
> diff --git a/scripts/sysupgrade-tar.sh b/scripts/sysupgrade-tar.sh
> index b93b2584bb..5071a2f5f8 100755
> --- a/scripts/sysupgrade-tar.sh
> +++ b/scripts/sysupgrade-tar.sh
> @@ -3,11 +3,17 @@
>  . $TOPDIR/scripts/functions.sh
>  
>  board=""
> +alt_boards=""
>  kernel=""
>  rootfs=""
>  outfile=""
>  err=""
>  
> +do_exit() {
> +	[ -d "$tmpdir" ] && rm -rf "$tmpdir"
> +	exit $err
> +}
> +
>  while [ "$1" ]; do
>  	case "$1" in
>  	"--board")
> @@ -16,6 +22,12 @@ while [ "$1" ]; do
>  		shift
>  		continue
>  		;;
> +	"--alt-boards")
> +		alt_boards="$2"
> +		shift
> +		shift
> +		continue
> +		;;
>  	"--kernel")
>  		kernel="$2"
>  		shift
> @@ -39,7 +51,7 @@ while [ "$1" ]; do
>  done
>  
>  if [ ! -n "$board" -o ! -r "$kernel" -a  ! -r "$rootfs" -o ! "$outfile" ]; then
> -	echo "syntax: $0 [--board boardname] [--kernel kernelimage] [--rootfs rootfs] out"
> +	echo "syntax: $0 [--board boardname] [--alt-boards 'alt board list'] [--kernel kernelimage] [--rootfs rootfs] out"
>  	exit 1
>  fi
>  
> @@ -54,6 +66,7 @@ if [ -z "$tmpdir" ]; then
>  fi
>  
>  mkdir -p "${tmpdir}/sysupgrade-${board}"
> +
>  echo "BOARD=${board}" > "${tmpdir}/sysupgrade-${board}/CONTROL"
>  if [ -n "${rootfs}" ]; then
>  	case "$( get_fs_type ${rootfs} )" in
> @@ -67,18 +80,33 @@ if [ -n "${rootfs}" ]; then
>  fi
>  [ -z "${kernel}" ] || cp "${kernel}" "${tmpdir}/sysupgrade-${board}/kernel"
>  
> -mtime=""
> +# "Legacy" nand_upgrade_tar() finds asset directory with
> +# $(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
> +# and doesn't use CONTROL at all; add the "real" files first
> +
> +tar_args="--directory ${tmpdir} --sort=name --owner=0 --group=0 --numeric-owner \
> +	 -vf ${tmpdir}/sysupgrade.tar"
>  if [ -n "$SOURCE_DATE_EPOCH" ]; then
> -	mtime="--mtime=@${SOURCE_DATE_EPOCH}"
> +	tar_args="${tar_args} --mtime=@${SOURCE_DATE_EPOCH}"
>  fi
>  
> -(cd "$tmpdir"; tar --sort=name --owner=0 --group=0 --numeric-owner -cvf sysupgrade.tar sysupgrade-${board} ${mtime})
> +tar -c $tar_args $(ls -A "${tmpdir}")
>  err="$?"
> +[ "$err" != 0 ] && do_exit
> +
> +for ab in $alt_boards ; do
> +	[ "$ab" = "$board" ] && continue
> +	mkdir "${tmpdir}/sysupgrade-${ab}/"
> +	cp -vp "${tmpdir}/sysupgrade-${board}/CONTROL" "${tmpdir}/sysupgrade-${ab}/"

Why not just add a symlink to the tar archive instead of a copy?
I know it doesn't matter much due to compress, jet I'd consider it a
more clean solution.

> +	tar -r $tar_args "sysupgrade-${ab}/CONTROL"
> +	err="$?"
> +	[ "$err" != 0 ] && do_exit
> +done
> +
>  if [ -e "$tmpdir/sysupgrade.tar" ]; then
>  	cp "$tmpdir/sysupgrade.tar" "$outfile"
>  else
>  	err=2
>  fi
> -rm -rf "$tmpdir"
>  
> -exit $err
> +do_exit
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Jeff Kletsky Nov. 7, 2019, 3:09 a.m. UTC | #2
On 11/6/19 2:47 PM, Daniel Golle wrote:

> Hi Jeff,
>
> On Thu, Oct 24, 2019 at 08:57:52PM -0700, Jeff Kletsky wrote:
>> From: Jeff Kletsky <git-commits@allycomm.com>
>>
>> Targets that use nand_do_platform_check() can't use SUPPORTED_DEVICES
>> as the check requires ./sysupgrade-legacy_boardname/CONTROL to be
>> non-zero length as extracted from the tar file. Previously, only
>> ./sysupgrade-new_boardname/CONTROL was present.
>>
>> [...]
>>
>> +
>> +for ab in $alt_boards ; do
>> +	[ "$ab" = "$board" ] && continue
>> +	mkdir "${tmpdir}/sysupgrade-${ab}/"
>> +	cp -vp "${tmpdir}/sysupgrade-${board}/CONTROL" "${tmpdir}/sysupgrade-${ab}/"
> Why not just add a symlink to the tar archive instead of a copy?
> I know it doesn't matter much due to compress, jet I'd consider it a
> more clean solution.
>

Thanks for taking a look at this!

If/when I pick it up again, I'll definitely re-check if symlinks can
be used.

It's been a while since I authored this, but my recollection is that
since the tar is not extracted "in whole" (to preserve space,
I assume), there is no target of the symlink to reference.

From: package/base-files/files/lib/upgrade/nand.sh (master)

nand_do_platform_check() {
         local board_name="$1"
         local tar_file="$2"
         local control_length=`(tar xf $tar_file 
sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null`
         local file_type="$(identify $2)"

         [ "$control_length" = 0 -a "$file_type" != "ubi" -a 
"$file_type" != "ubifs" ] && {
                 echo "Invalid sysupgrade file."
                 return 1
         }

         return 0
}


As this was primarily to handle upgrades from older firmware versions,
the upgrade tar needs to be compatible with previous code, which
`git blame` shows as commit 3dca5a158d, SVN-Revision: 41222, 2014-06-16


Jeff
diff mbox series

Patch

diff --git a/include/image-commands.mk b/include/image-commands.mk
index 5dfd6a2c2f..011e30a7e3 100644
--- a/include/image-commands.mk
+++ b/include/image-commands.mk
@@ -321,6 +321,7 @@  endef
 define Build/sysupgrade-tar
 	sh $(TOPDIR)/scripts/sysupgrade-tar.sh \
 		--board $(if $(BOARD_NAME),$(BOARD_NAME),$(DEVICE_NAME)) \
+		--alt-boards "$(call param_get,alt-board,$(1))" \
 		--kernel $(call param_get_default,kernel,$(1),$(IMAGE_KERNEL)) \
 		--rootfs $(call param_get_default,rootfs,$(1),$(IMAGE_ROOTFS)) \
 		$@
diff --git a/scripts/sysupgrade-tar.sh b/scripts/sysupgrade-tar.sh
index b93b2584bb..5071a2f5f8 100755
--- a/scripts/sysupgrade-tar.sh
+++ b/scripts/sysupgrade-tar.sh
@@ -3,11 +3,17 @@ 
 . $TOPDIR/scripts/functions.sh
 
 board=""
+alt_boards=""
 kernel=""
 rootfs=""
 outfile=""
 err=""
 
+do_exit() {
+	[ -d "$tmpdir" ] && rm -rf "$tmpdir"
+	exit $err
+}
+
 while [ "$1" ]; do
 	case "$1" in
 	"--board")
@@ -16,6 +22,12 @@  while [ "$1" ]; do
 		shift
 		continue
 		;;
+	"--alt-boards")
+		alt_boards="$2"
+		shift
+		shift
+		continue
+		;;
 	"--kernel")
 		kernel="$2"
 		shift
@@ -39,7 +51,7 @@  while [ "$1" ]; do
 done
 
 if [ ! -n "$board" -o ! -r "$kernel" -a  ! -r "$rootfs" -o ! "$outfile" ]; then
-	echo "syntax: $0 [--board boardname] [--kernel kernelimage] [--rootfs rootfs] out"
+	echo "syntax: $0 [--board boardname] [--alt-boards 'alt board list'] [--kernel kernelimage] [--rootfs rootfs] out"
 	exit 1
 fi
 
@@ -54,6 +66,7 @@  if [ -z "$tmpdir" ]; then
 fi
 
 mkdir -p "${tmpdir}/sysupgrade-${board}"
+
 echo "BOARD=${board}" > "${tmpdir}/sysupgrade-${board}/CONTROL"
 if [ -n "${rootfs}" ]; then
 	case "$( get_fs_type ${rootfs} )" in
@@ -67,18 +80,33 @@  if [ -n "${rootfs}" ]; then
 fi
 [ -z "${kernel}" ] || cp "${kernel}" "${tmpdir}/sysupgrade-${board}/kernel"
 
-mtime=""
+# "Legacy" nand_upgrade_tar() finds asset directory with
+# $(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
+# and doesn't use CONTROL at all; add the "real" files first
+
+tar_args="--directory ${tmpdir} --sort=name --owner=0 --group=0 --numeric-owner \
+	 -vf ${tmpdir}/sysupgrade.tar"
 if [ -n "$SOURCE_DATE_EPOCH" ]; then
-	mtime="--mtime=@${SOURCE_DATE_EPOCH}"
+	tar_args="${tar_args} --mtime=@${SOURCE_DATE_EPOCH}"
 fi
 
-(cd "$tmpdir"; tar --sort=name --owner=0 --group=0 --numeric-owner -cvf sysupgrade.tar sysupgrade-${board} ${mtime})
+tar -c $tar_args $(ls -A "${tmpdir}")
 err="$?"
+[ "$err" != 0 ] && do_exit
+
+for ab in $alt_boards ; do
+	[ "$ab" = "$board" ] && continue
+	mkdir "${tmpdir}/sysupgrade-${ab}/"
+	cp -vp "${tmpdir}/sysupgrade-${board}/CONTROL" "${tmpdir}/sysupgrade-${ab}/"
+	tar -r $tar_args "sysupgrade-${ab}/CONTROL"
+	err="$?"
+	[ "$err" != 0 ] && do_exit
+done
+
 if [ -e "$tmpdir/sysupgrade.tar" ]; then
 	cp "$tmpdir/sysupgrade.tar" "$outfile"
 else
 	err=2
 fi
-rm -rf "$tmpdir"
 
-exit $err
+do_exit