mirror of
https://github.com/motioneye-project/motioneyeos.git
synced 2025-07-28 13:46:32 +00:00
fwupdate script is almost functional
This commit is contained in:
parent
a9b69e0505
commit
d79f4e0f00
327
board/common/overlay/sbin/fwupdate
Normal file → Executable file
327
board/common/overlay/sbin/fwupdate
Normal file → Executable file
@ -1,16 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
#### usage ####
|
||||
|
||||
function exit_usage() {
|
||||
echo "Usage: $0 versions"
|
||||
echo " $0 current"
|
||||
echo " $0 download <version|url>"
|
||||
echo " $0 extract"
|
||||
echo " $0 flashboot"
|
||||
echo " $0 flashreboot"
|
||||
echo " $0 status"
|
||||
|
||||
|
||||
exit -1
|
||||
echo "Usage: fwupdate versions"
|
||||
echo " - lists available versions"
|
||||
echo " fwupdate current"
|
||||
echo " - shows the current version"
|
||||
echo " fwupdate download <version|url>"
|
||||
echo " - downloads a firmware version"
|
||||
echo " fwupdate extract"
|
||||
echo " - extracts the downloaded firmware archive"
|
||||
echo " fwupdate flashboot"
|
||||
echo " - flashes the extracted boot partition"
|
||||
echo " fwupdate flashreboot"
|
||||
echo " - prepares for reboot + root partititon flash"
|
||||
echo " fwupdate status"
|
||||
echo " - shows the current firmware updating status (see below)"
|
||||
echo ""
|
||||
echo "Statuses:"
|
||||
echo " idle"
|
||||
echo " downloading <version>: <percent>%"
|
||||
echo " downloaded <version>"
|
||||
echo " extracting <version>"
|
||||
echo " extracted <version>"
|
||||
echo " flashing boot <version>"
|
||||
echo " boot ready <version>"
|
||||
echo ""
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
@ -18,22 +37,48 @@ if [ -z "$1" ]; then
|
||||
fi
|
||||
|
||||
|
||||
#### configuration ####
|
||||
|
||||
SYS_VERSION_FILE=/etc/version
|
||||
SYS_BOARD_FILE=/etc/board
|
||||
OS_CONF=/data/etc/os.conf
|
||||
|
||||
BOOT_DEV=/dev/mmcblk0p1
|
||||
MIN_FREE_DISK=$((500*1024)) # 500 MB
|
||||
VER_FILE=version
|
||||
ROOT_INFO_FILE=root_info
|
||||
|
||||
FW_DIR=/data/.fwupdate
|
||||
FW_FILE=firmware.img.gz
|
||||
FW_FILE_EXTR=firmware.img
|
||||
|
||||
WGET_LOG_FILE=wget.log
|
||||
WGET_PID_FILE=wget.pid
|
||||
|
||||
GUNZIP_LOG_FILE=gunzip.log
|
||||
GUNZIP_PID_FILE=gunzip.pid
|
||||
|
||||
DD_LOG_FILE=dd.log
|
||||
DD_PID_FILE=dd.pid
|
||||
|
||||
|
||||
#### versions ####
|
||||
|
||||
function show_versions() {
|
||||
source $OS_CONF
|
||||
board=$(cat $SYS_BOARD_FILE)
|
||||
show_url=$1
|
||||
|
||||
# the /usr/libexec/list-versions-* helpers return a table with the following format:
|
||||
# <version>|<prerelease>|<board>|<url>
|
||||
versions=$(FW_USERNAME=$os_firmware_username FW_PASSWORD=$os_firmware_password \
|
||||
/usr/libexec/list-versions-$os_firmware_method $os_firmware_repo)
|
||||
|
||||
for version in $versions:
|
||||
$IFS="|" varr=($version)
|
||||
for version in $versions; do
|
||||
OIFS=$IFS
|
||||
IFS="|"
|
||||
varr=($version)
|
||||
IFS=$OIFS
|
||||
if [ "$os_prereleases" == "false" ] && [ "${varr[1]}" == "true" ]; then
|
||||
continue # skip prereleases
|
||||
fi
|
||||
@ -41,52 +86,255 @@ function show_versions() {
|
||||
continue # skip other boards
|
||||
fi
|
||||
|
||||
echo "${varr[0]}"
|
||||
if [ "$show_url" == "true" ]; then
|
||||
echo ${varr[0]} ${varr[3]}
|
||||
else
|
||||
echo ${varr[0]}
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function show_current() {
|
||||
source $SYS_VERSION_FILE
|
||||
|
||||
echo "Name: $os_name"
|
||||
echo "Short Name: $os_short_name"
|
||||
echo "Prefix: $os_prefix"
|
||||
echo "Version: $os_version"
|
||||
echo $os_version
|
||||
}
|
||||
|
||||
|
||||
#### download ####
|
||||
|
||||
function do_download() {
|
||||
# TODO check space
|
||||
# TODO cleanup download dir
|
||||
# TODO prepare download dir
|
||||
# TODO wget --no-check-certificate
|
||||
echo "downloading..."
|
||||
|
||||
source $OS_CONF
|
||||
board=$(cat $SYS_BOARD_FILE)
|
||||
url=$1
|
||||
version=$1
|
||||
|
||||
if ! [[ "$url" == http* ]]; then # a version was given
|
||||
url=$(show_versions true | grep "^$1" | cut -d ' ' -f 2)
|
||||
else
|
||||
version="custom"
|
||||
fi
|
||||
|
||||
if [ -z "$url" ]; then
|
||||
echo "no such version" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
free_disk=$(df /data | tail -n 1 | tr -s ' ' | cut -d ' ' -f 4)
|
||||
if [ "$free_disk" -lt $MIN_FREE_DISK ]; then
|
||||
echo "not enough disk space" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf $FW_DIR/*
|
||||
mkdir -p $FW_DIR
|
||||
echo $version > $FW_DIR/$VER_FILE
|
||||
|
||||
wget --no-check-certificate -O $FW_DIR/$FW_FILE --quiet --show-progress --progress=dot "$url" &> $FW_DIR/$WGET_LOG_FILE &
|
||||
pid=$!
|
||||
echo $pid > $FW_DIR/$WGET_PID_FILE
|
||||
wait $pid
|
||||
}
|
||||
|
||||
function download_status() {
|
||||
if [ -f $FW_DIR/$WGET_PID_FILE ]; then
|
||||
pid=$(cat $FW_DIR/$WGET_PID_FILE)
|
||||
if kill -0 $pid &>/dev/null; then
|
||||
progress=$(tail -n2 $FW_DIR/$WGET_LOG_FILE | grep -oe '[[:digit:]]*%')
|
||||
if [ -z "$progress" ]; then
|
||||
progress="0%"
|
||||
fi
|
||||
|
||||
progress=($progress)
|
||||
|
||||
echo ${progress[0]}
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f $FW_DIR/$FW_FILE ]; then
|
||||
echo "done"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#### extract ####
|
||||
|
||||
function do_extract() {
|
||||
# TODO gunzip
|
||||
echo "extracting..."
|
||||
|
||||
if ! [ -f $FW_DIR/$FW_FILE ]; then
|
||||
echo "firmware file not downloaded" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -f $FW_DIR/$FW_FILE_EXTR
|
||||
|
||||
gunzip -k -c $FW_DIR/$FW_FILE > $FW_DIR/$FW_FILE_EXTR 2>$FW_DIR/$GUNZIP_LOG_FILE &
|
||||
pid=$!
|
||||
echo $pid > $FW_DIR/$GUNZIP_PID_FILE
|
||||
wait $pid
|
||||
|
||||
# TODO verify hash
|
||||
}
|
||||
|
||||
function flash_boot() {
|
||||
# TODO backup /boot/config.txt
|
||||
# TODO umount /boot
|
||||
# TODO set trap exit cleanup routine
|
||||
# TODO disable rebooting (/sbin/reboot)
|
||||
# TODO remount rw /
|
||||
# TODO read partition table
|
||||
# TODO dd boot.img
|
||||
# TODO mount r/w /boot
|
||||
# TODO restore /boot/config.txt
|
||||
# TODO call cleanup routine
|
||||
function extract_status() {
|
||||
if [ -f $FW_DIR/$GUNZIP_PID_FILE ]; then
|
||||
pid=$(cat $FW_DIR/$GUNZIP_PID_FILE)
|
||||
if kill -0 $pid &>/dev/null; then
|
||||
echo "running"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f $FW_DIR/$FW_FILE_EXTR ]; then
|
||||
echo "done"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#### flash boot ####
|
||||
|
||||
function flash_boot() {
|
||||
echo "flashing boot..."
|
||||
|
||||
set +e
|
||||
board=$(cat $SYS_BOARD_FILE)
|
||||
|
||||
cp -r /boot $FW_DIR/old_boot
|
||||
umount /boot
|
||||
trap flash_cleanup EXIT
|
||||
|
||||
mount -o remount,rw /
|
||||
mv /sbin/reboot /sbin/reboot.bak
|
||||
ln -s /bin/true /sbin/reboot
|
||||
|
||||
boot_info=$(fdisk --bytes -l -o device,start,end,size $FW_DIR/$FW_FILE_EXTR | grep "${FW_FILE_EXTR}1")
|
||||
boot_info=($boot_info)
|
||||
boot_start=$((${boot_info[1]} * 512)) # in bytes
|
||||
boot_size=$((${boot_info[3]} / 1048576)) # in MB
|
||||
|
||||
root_info=$(fdisk --bytes -l -o device,start,end,size $FW_DIR/$FW_FILE_EXTR | grep "${FW_FILE_EXTR}2")
|
||||
root_info=($root_info)
|
||||
root_start=$((${root_info[1]} * 512)) # in bytes
|
||||
root_size=$((${root_info[3]} / 1048576)) # in MB
|
||||
|
||||
echo $root_start $root_size > $FW_DIR/$ROOT_INFO
|
||||
|
||||
dd if=$FW_DIR/$FW_FILE_EXTR skip=$boot_start of=$BOOT_DEV bs=1048576 count=$boot_size &>$FW_DIR/$DD_LOG_FILE &
|
||||
pid=$!
|
||||
echo $pid > $FW_DIR/$DD_PID_FILE
|
||||
wait $pid
|
||||
|
||||
mount -o rw /boot
|
||||
restore_boot_$board $FW_DIR/old_boot 2>/dev/null || true
|
||||
touch $FW_DIR/boot_flash_ready
|
||||
}
|
||||
|
||||
function flash_boot_status() {
|
||||
if [ -f $FW_DIR/$DD_PID_FILE ]; then
|
||||
pid=$(cat $FW_DIR/$DD_PID_FILE)
|
||||
if kill -0 $pid &>/dev/null; then
|
||||
echo "running"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f $FW_DIR/boot_flash_ready ]; then
|
||||
echo "done"
|
||||
fi
|
||||
}
|
||||
|
||||
function flash_cleanup() {
|
||||
if [ -f /sbin/reboot.bak ]; then
|
||||
rm -f /sbin/reboot
|
||||
mv /sbin/reboot.bak /sbin/reboot
|
||||
fi
|
||||
|
||||
mount /boot 2>/dev/null
|
||||
}
|
||||
|
||||
function restore_boot_raspberrypi() {
|
||||
old_boot=$1
|
||||
cp $old_boot/config.txt /boot
|
||||
}
|
||||
|
||||
function restore_boot_raspberrypi2() {
|
||||
restore_boot_raspberrypi
|
||||
}
|
||||
|
||||
function restore_boot_raspberrypi3() {
|
||||
restore_boot_raspberrypi
|
||||
}
|
||||
|
||||
|
||||
#### flash reboot ####
|
||||
|
||||
function flash_reboot() {
|
||||
# TODO sed /boot/config.txt initramfs
|
||||
# TODO sync
|
||||
# TODO umount
|
||||
# TODO busybox reboot || b > sysrq
|
||||
echo "preparing for reboot..."
|
||||
|
||||
board=$(cat $SYS_BOARD_FILE)
|
||||
|
||||
mount -o remount,rw /boot
|
||||
prepare_boot_$board
|
||||
|
||||
sync
|
||||
busybox reboot &
|
||||
sleep 10
|
||||
echo b > /proc/sysrq-trigger
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
function prepare_boot_raspberrypi() {
|
||||
echo "initramfs fwupdater.gz" >> /boot/config.txt
|
||||
}
|
||||
|
||||
function prepare_boot_raspberrypi2() {
|
||||
prepare_boot_raspberrypi
|
||||
}
|
||||
|
||||
function prepare_boot_raspberrypi3() {
|
||||
prepare_boot_raspberrypi
|
||||
}
|
||||
|
||||
|
||||
#### status ####
|
||||
|
||||
function show_status() {
|
||||
status=$(flash_boot_status)
|
||||
if [ "$status" == "running" ]; then
|
||||
echo "flashing boot $(new_version)"
|
||||
return
|
||||
elif [ "$status" == "done" ]; then
|
||||
echo "boot ready $(new_version)"
|
||||
return
|
||||
fi
|
||||
|
||||
status=$(extract_status)
|
||||
if [ "$status" == "running" ]; then
|
||||
echo "extracting $(new_version)"
|
||||
return
|
||||
elif [ "$status" == "done" ]; then
|
||||
echo "extracted $(new_version)"
|
||||
return
|
||||
fi
|
||||
|
||||
status=$(download_status)
|
||||
if [ "$status" == "done" ]; then
|
||||
echo "downloaded $(new_version)"
|
||||
return
|
||||
elif [ -n "$status" ]; then
|
||||
echo "downloading $(new_version): $status"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "idle"
|
||||
}
|
||||
|
||||
function new_version() {
|
||||
cat $FW_DIR/$VER_FILE
|
||||
}
|
||||
|
||||
|
||||
@ -100,19 +348,22 @@ case "$1" in
|
||||
;;
|
||||
|
||||
download)
|
||||
if [ -z "$2" ];
|
||||
if [ -z "$2" ]; then
|
||||
exit_usage
|
||||
fi
|
||||
|
||||
do_download $2
|
||||
show_status
|
||||
;;
|
||||
|
||||
extract)
|
||||
do_extract
|
||||
show_status
|
||||
;;
|
||||
|
||||
flashboot)
|
||||
flash_boot
|
||||
show_status
|
||||
;;
|
||||
|
||||
flashreboot)
|
||||
|
@ -6,9 +6,9 @@ if [ -z "$1" ]; then
|
||||
fi
|
||||
|
||||
opts="-s -S -f"
|
||||
test -n "$BITBUCKET_USERNAME" && opts+=" --user $BITBUCKET_USERNAME:$BITBUCKET_PASSWORD"
|
||||
test -n "$FW_USERNAME" && opts+=" --user $FW_USERNAME:$FW_PASSWORD"
|
||||
url=https://api.bitbucket.org/2.0/repositories/$1/downloads?pagelen=100
|
||||
jq_expr='.values[] | [{a: .name | capture("[^-]+-(?<b>[^-]+)-(?<c>[^-]+)\\.img\\.?.*"), url: .links.self.href}] | map(.a.c, "false", .a.b, .url) | join("|")'
|
||||
jq_expr='.values[] | [{a: .name | split("-"), url: .links.self.href}] | map((.a[2] | rtrimstr(".img.gz") | rtrimstr(".img")), "false", .a[1], .url) | join("|")'
|
||||
|
||||
curl $opts $url | jq --raw-output "$jq_expr"
|
||||
exit ${PIPESTATUS[0]}
|
||||
|
@ -6,9 +6,9 @@ if [ -z "$1" ]; then
|
||||
fi
|
||||
|
||||
opts="-s -S -f"
|
||||
test -n "$GITHUB_USERNAME" && opts+=" --user $GITHUB_USERNAME:$GITHUB_PASSWORD"
|
||||
test -n "$FW_USERNAME" && opts+=" --user $FW_USERNAME:$FW_PASSWORD"
|
||||
url=https://api.github.com/repos/$1/releases
|
||||
jq_expr='.[] | {version: .name, prerelease: .prerelease | tostring, name: .assets[].name | capture("[^-]+-(?<b>[^-]+)") | flatten, asset: .assets[].browser_download_url} | flatten | join("|")'
|
||||
jq_expr='.[] | {version: .name, prerelease: .prerelease | tostring} + (.assets[] | {name: .name | split("-")[1], url: .browser_download_url}) | flatten | join("|")'
|
||||
|
||||
curl $opts $url | jq --raw-output "$jq_expr"
|
||||
exit ${PIPESTATUS[0]}
|
||||
|
Loading…
x
Reference in New Issue
Block a user