How to automatically reinstall packages after firmware upgrade

Hello,

I have a bunch of OpenWrt instances that I am managing from remote, for this I am using wireguard.
Since all user installed packages are removed during a firmware upgrade I would lose access to these machines if I would ever do a remote upgrade. BTW: I totally understand why this is necessary.

I just wrote myself a very simple script that reinstalls all packages that I need on these machines.
It might not be the prettiest but it should work based on my testing.

#!/bin/sh

echo Updating package repositories | tee install_log.txt
echo ============================= | tee -a install_log.txt
opkg update | tee -a install_log.txt
echo | tee -a install_log.txt

echo Installing packages | tee -a install_log.txt
echo =================== | tee -a install_log.txt
####opkg install ddns-scripts luci-app-ddns ipset luci-ssl-openssl wireguard luci-app-wireguard | tee -a install_log.txt
opkg install --noaction ddns-scripts luci-app-ddns ipset luci-ssl-openssl wireguard luci-app-wireguard | tee -a install_log.txt
echo | tee -a install_log.txt

echo Enabling packages | tee -a install_log.txt
echo ================= | tee -a install_log.txt
####/etc/init.d/ddns enable
echo | tee -a install_log.txt

echo Fixing WiFi stability | tee -a install_log.txt
echo ===================== | tee -a install_log.txt
####opkg remove ath10k-firmware-qca988x-ct kmod-ath10k-ct | tee -a install_log.txt
####opkg install ath10k-firmware-qca988x kmod-ath10k | tee -a install_log.txt
echo | tee -a install_log.txt

echo Finalizing script | tee -a install_log.txt
echo ================= | tee -a install_log.txt
echo Script finished on $(date) | tee -a install_log.txt 
echo Rebooting system... | tee -a install_log.txt
####reboot

But I need a little help from you guys.

  1. I don't know how to start the script AFTER the internet connection is established.
    How can I achieve this?

  2. Of course I don't need / want that script to be run at every boot.
    So my idea was to either...
    2.1 add it to the cron jobs and enable / disable it with '#' during firmware upgrades
    or
    2.2 add it "System --> Startup" and enable / disable it from there during firmware upgrades
    But I don't know if the settings in "System --> Startup" get reset during a firmware upgrade.

I hope someone can help me here.
Regards
TheHellSite

Have you considered building your own images?

5 Likes

if they are remote... I think @eduperez 's suggestion is the only sensible solution...

that said... to answer your question... probably the wisest/clearest place to insert post upgrade hooks is via a pre-upgrade late (self removing) init.d insert... ( and sysupgrade.conf if needed ) search the forum... there are examples...

of course there are all sorts of other complexities that go along with that;

  • internet detection (you mentioned)
  • service init.d state restoration
  • opkg locks
  • opkg repos down or unavailable
  • package conflicts / renames / removals
  • repeat run on fail ( and/or reboot +/- counter )

the list goes on...

1 Like

@eduperez
I did but I would have to create multiple images for different machines because they are not identical (brand, model, ...).
Using a script would save me quite some time because I can simply use the default images.

@anon50098793
Okay. I will have a look around.

Another way that just crossed my mind would be to open up the SSH port to WAN for the time of the upgrade and then close it once I ran my script manually.
But an automatic call of that script would still be my go to solution.

https://openwrt.org/docs/guide-user/advanced/opkg_extras#automated

4 Likes

I appreciate all the solutions posted.
But I would still like to find out how to run my script at boot.

I tried calling it with /etc/rc.local.
/root/install_after_upgrade.sh and ./root/install_after_upgrade.sh both didn't work.

I then tried calling it using init.d, also without success.

/etc/init.d/install_after_upgrade (permissions 0755)

#!/bin/sh /etc/rc.common
USE_PROCD=1
START=95
STOP=01
start_service() {
    procd_open_instance
    procd_set_param command /bin/sh "/root/install_after_upgrade.sh"
    procd_close_instance
}

I know there are already scripts out there reinstalling ALL user installed packages but I would like to only install specific packages.

Opkg extras from the wiki supports custom package lists including mixed install/remove lists.

2 Likes

I can start the script as often as I want but it is doing nothing at all.

root@AP2:~# /etc/init.d/install_after_upgrade start
{ "name": "install_after_upgrade", "script": "\/etc\/init.d\/install_after_upgrade", "instances": { "instance1": { "command": [ "\/root\/install_after_upgrade.sh" ] } }, "triggers": [ ], "data": { } }
#!/bin/sh /etc/rc.common

# sed -i -e 's/\r//g' /etc/init.d/install_after_upgrade
# --> I have to run this command whenever I edit the file otherwise the service won't start.

USE_PROCD=1
START=95
STOP=01
PROCD_DEBUG=1
start_service() {
    procd_open_instance
    procd_set_param command "/root/install_after_upgrade.sh"
    procd_close_instance
}
chmod +x /root/*.sh
1 Like

@TheHellSite Hi, I've already made this work on my devices including waiting for internet connection at Automatic update script - #3 by Catfriend1

1 Like

I would consider using cron, to run the script regularly to avoid some of the issues that @anon50098793 suggested, especially internet detection

also this script is not a solution, but a good tool and starting point

https://github.com/richb-hanover/OpenWrtScripts/blob/master/opkgscript.sh

I updated Opkg extras replacing cron with hotplug:

Now it triggers automatic restore upon WAN-related hotplug events.
This appears to work pretty well. :wink:

3 Likes

@vgaetera
The script had the permissions to be run already set, I think something else is the problem.

@Catfriend1
That is exactly what I was looking for.
Plain, simple and no extra stuff I won't need.
You should consider chaning the name of your thread to something like mine!

Thank you all for contributing.

1 Like

Works very well for me too. The only issue is that you need the WAN to be connected to the Internet to fetch packages during upgrade. So when I upgraded my mesh network, I plugged each AP to wired Internet using WAN, upgraded and unplugged.

1 Like

Why not just use the Image Builder? Including the packages you need in the PACKAGES variable like so:

make image PACKAGES="pkg1 pkg2 pkg3 -pkg4 -pkg5 -pkg6"

You can get a list of the currently installed packages on your devices using echo $(opkg list_installed | awk '{ print $1 }').

It's relatively quick and easy, much quicker than a build from source, and it outputs a factory image and a sysupgrade image that includes the packages you want. Upgrades are super easy this way, it's what I do, and it's officially supported.

1 Like

Additionally to this, including packages in your own build uses less precious flash space than installing packages afterwards.

Well worth considering, especially for devices with low flash (4 or 8 MB flash).

3 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.