Last active
February 5, 2025 03:24
-
-
Save patrakov/8fca04e0bec139e9a9e169dc4b9783f4 to your computer and use it in GitHub Desktop.
Automatically reinstall OpenWRT packages after firmware upgrades
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The script helps you restore all installed OpenWRT packages after upgrading the main firmware image via sysupgrade. It works | |
ONLY if the default firmware image provided by the OpenWRT project is sufficient to get connected to the Internet, but you | |
want some extra packages for additional functionality. In other words, it WILL NOT WORK if connecting to the Internet | |
requires installing extra packages (e.g., a kernel module for your LTE modem). | |
The script has been tested for upgrading from OpenWRT 18.06.1 to 18.06.2 and to a development snapshot, as well as between | |
development snapshots. On LEDE 17.01.x, "flock" is not a part of the default image, so has to be installed manually. | |
Initial setup: | |
1. Save the script to /etc/package-list/persist.sh | |
2. chmod 755 /etc/package-list/persist.sh | |
3. echo "*/5 * * * * flock -n /var/lock/persist.lock /etc/package-list/persist.sh" > /etc/crontabs/root | |
4. Edit /etc/sysupgrade.conf to mention /etc/package-list/ and other files that should be preserved, e.g. /etc/firewall.user | |
5. touch /usr/.extra-pakages-installed | |
6. Reboot the router | |
7. Wait for it to come up again and to create /etc/package-list/extra-packages.txt | |
If there is anything ($BADPACKAGE) listed that you think should only be installed as a dependency: | |
opkg flag ok $BADPACKAGE | |
sed -i "/^$BADPACKAGE\$/d" /etc/package-list/extra-packages.txt | |
If you plan to use snapshots, add luci to /etc/package-list/extra-packages.txt. | |
Further on, the script will automatically track any extra packages that you install or remove. | |
At this point, you can upgrade firmware as usual, and all the extra packages will be automatically reinstalled after a | |
reboot - just wait 10 minutes (more if you have a slow connection). It is possible to watch the progress in | |
/var/log/persist-packages.log. | |
After the installation, the script will reboot the router once more, just in case, e.g. to apply firewall settings that | |
depend on the new packages. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
exec > /var/log/persist-packages.log 2>&1 | |
set -x | |
PKGS=/etc/package-list/extra-packages.txt | |
# https://github.com/openwrt/packages/issues/6744, not fixed in 18.06.x | |
fix_route53() { | |
if grep -q CURL_SSL /usr/lib/ddns/update_route53_v1.sh 2>/dev/null ; then | |
sed -i /CURL_SSL/d /usr/lib/ddns/update_route53_v1.sh | |
fi | |
} | |
list_extra_packages() { | |
if [ ! -f $PKGS ] || [ /usr/lib/opkg/status -nt $PKGS ] ; then | |
# Find the latest package in the ROM | |
PROG=' | |
$1 == "Installed-Time:" && ($2 < NEWEST || NEWEST=="") { | |
NEWEST=$2 | |
} | |
END { | |
print NEWEST | |
} | |
' | |
FLASH_TIME="$( awk "$PROG" /rom/usr/lib/opkg/status )" | |
# All user-installed packages minus those from ROM mistakenly marked as such | |
# plus (those explicitly marked previously minus those not installed) | |
MARKED=`awk '{RE=RE "|" $0} END { print RE }' $PKGS` | |
MARKED='^('${MARKED#|}')$' | |
PROG=' | |
$1 == "Package:" { | |
PKG=$2 | |
USR="" | |
} | |
$1 == "Status:" && $3 ~ "user" { | |
USR=1 | |
} | |
$1 == "Installed-Time:" && $2 > FT && ( USR || ( PKG ~ MARKED ) ) { | |
print PKG | |
} | |
' | |
awk -v FT="$FLASH_TIME" -v MARKED="$MARKED" "$PROG" /usr/lib/opkg/status | sort > $PKGS.tmp | |
mv $PKGS.tmp $PKGS | |
# Maybe somebody updated it and OpenWRT team forgot to propagate the fix? | |
fix_route53 | |
fi | |
} | |
install_extra_packages() { | |
set -e | |
opkg update | |
UPGRADE=`opkg list-upgradable | cut -d ' ' -f 1` | |
if [ -n "$UPGRADE" ] ; then | |
opkg upgrade $UPGRADE | |
opkg flag ok $UPGRADE | |
fi | |
INSTALL_CANDIDATES=`cat $PKGS` | |
# Weed out packages that don't exist anymore | |
INSTALL="" | |
for CANDIDATE in $INSTALL_CANDIDATES ; do | |
if [ -n "`opkg list $CANDIDATE`" ] ; then | |
INSTALL="$INSTALL $CANDIDATE" | |
fi | |
done | |
if [ -n "$INSTALL" ] ; then | |
opkg install $INSTALL | |
fi | |
fix_route53 | |
find /etc -name \*-opkg -exec rm '{}' ';' | |
touch /usr/.extra-pakages-installed | |
sleep 70 | |
reboot | |
} | |
if [ -f /usr/.extra-pakages-installed ] ; then | |
list_extra_packages | |
elif [ -f $PKGS ] ; then | |
install_extra_packages | |
fi |
I was not aware of the "sysupgrade runscript" based approach.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is great, thanks for posting it! Neat trick to use
Install-Time
to weed out "user" packages from /rom.Have you considered running
persist.sh
as a sysupgrade runscript (like Rafciq's approach) instead of every 5 minutes via cron? Might be a bit snappier and more efficient if it's workable.