Skip to content

Instantly share code, notes, and snippets.

@whiskerz007
Created September 30, 2024 03:50
Show Gist options
  • Save whiskerz007/a01848c69f6c819fff4512827929da7e to your computer and use it in GitHub Desktop.
Save whiskerz007/a01848c69f6c819fff4512827929da7e to your computer and use it in GitHub Desktop.

OpenWrt sysupgrade Helper

This script will do the following:

  • Gather list of installed packages that does not exist in the ROM
  • Create a script to reinstall the packages
  • Add the newly created script to /etc/rc.local

Run this script before the sysupgrade process. Once flashing has started, wait for the router to reboot two times. The script will remove itself after successful execution.

ash -c "$(wget -qO - https://gist.github.com/whiskerz007/a01848c69f6c819fff4512827929da7e/raw/openwrt_sysupgrade_helper.sh)"
#!/usr/bin/env ash
set -Eeuo pipefail
# Verify supported platform (eg < 23.xx)
sed -ne '/VERSION=/ s/.*"\(.*\)"/\1/p' /etc/os-release | awk -F. '{exit $1 > 23}' || \
{
echo "The OpenWrt version is not supported." >&2
exit 1
}
# Verify root user is executing the script
if [ $(id -u) -ne 0 ]; then
echo "This script must be ran as 'root'. Exiting without making changes." >&2
exit 1
fi
CONTROL_FILE_LIST=$(ls -w 1 /overlay/upper/usr/lib/opkg/info/*.control)
# Process .control files
for CONTROL_FILE in $CONTROL_FILE_LIST; do
# Store package names in variable
PACKAGE_LIST="${PACKAGE_LIST-} $(sed -ne '/Package/ s/.*\: //p' $CONTROL_FILE)"
# Get dependency list
DEPS=$(sed -ne '/Depends/ s/.*: //p' $CONTROL_FILE | sed -e 's/,//g')
for DEP in $DEPS; do
# Store unique dependencies in variable
if ! echo "${NEEDED-}" | grep -Fqe "$DEP"; then
NEEDED="${NEEDED-} $DEP"
fi
done
done
# Get list of packages that are not dependent of another
for PACKAGE in $PACKAGE_LIST; do
if ! echo "$NEEDED" | grep -Fqe "$PACKAGE" && ! [ -f /rom/usr/lib/opkg/info/${PACKAGE}.control ]; then
PACKAGES="${PACKAGES:-} $PACKAGE"
fi
done
# Create firstboot script to reinstall packages
FIRSTBOOT_FILE=/etc/config/__firstboot
RC_LOCAL_FILE=/etc/rc.local
cat << EOF > $FIRSTBOOT_FILE
#!/usr/bin/env ash
set -Eeuo pipefail
opkg update
opkg install $PACKAGES
TEMP_FILE=\$(mktemp)
sed "/${FIRSTBOOT_FILE//\//\\/}/d" $RC_LOCAL_FILE > \$TEMP_FILE
mv \$TEMP_FILE $RC_LOCAL_FILE
rm \$0
reboot
EOF
chmod +x $FIRSTBOOT_FILE
# Append firstboot script to rc.local
RC_LOCAL_LINE_NUMBER=$(awk '/exit 0/{ print NR; exit }' $RC_LOCAL_FILE)
if [ -z ${RC_LOCAL_LINE_NUMBER} ]; then
echo $FIRSTBOOT_FILE >> $RC_LOCAL_FILE
else
TEMP_FILE=$(mktemp)
awk -v line="$RC_LOCAL_LINE_NUMBER" -v file="$FIRSTBOOT_FILE" 'NR==line{1; print file}1' $RC_LOCAL_FILE > $TEMP_FILE
mv $TEMP_FILE $RC_LOCAL_FILE
fi
echo "Successfully created sysupgrade helper script. Proceed to sysupgrade process."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment