Auto apply latest package updates on OpenWrt (LEDE Project)

Running Linux on your router and wifi devices is fantastic, but it’s important to keep them up-to-date. This is how I auto-update my devices with the latest packages from OpenWrt (but not firmware, I still do that manually when there’s a new release).

This is a very simple shell script which uses OpenWrt’s package manager to fetch a list of updates, and then install them, rebooting the machine if that was successful. The log file is served up over http, in case you want to get the log easily to see what’s been happening (assuming you’re running uhttpd service).

Make a directory to hold the script.
root@firewall:~# mkdir -p /usr/local/sbin

Make the script.
root@firewall:~# cat > /usr/local/sbin/update-system.sh << \EOF
#!/bin/ash
opkg update
# upgrade netifd first as it causes drop out and system upgrade fails
opkg upgrade netifd
# install luci-ssl, so we get web back after upgrades
opkg install luci-ssl
/etc/init.d/uhttpd restart
# do package upgrades
PACKAGES="$(opkg list-upgradable |awk '{print $1}')"
if [ -n "${PACKAGES}" ]; then
  opkg upgrade ${PACKAGES}
  if [ "$?" -eq 0 ]; then
    echo "$(date -I"seconds") - update success, rebooting" \
>> /www/update.result
    exec reboot
  else
    echo "$(date -I"seconds") - update failed" >> /www/update.result
  fi
else
  echo "$(date -I"seconds") - nothing to update" >> /www/update.result
fi
EOF

Make the script executable and touch the log file.
root@firewall:~# chmod u+x /usr/local/sbin/update-system.sh
root@firewall:~# touch /www/update.result

Make sure the script and results are kept when upgrading the firmware.
root@firewall:~# echo "/usr/local/sbin/" >> /etc/sysupgrade.conf
root@firewall:~# echo "/www/update.result" >> /etc/sysupgrade.conf

Next schedule the script in cron.
root@firewall:~# crontab -e

My cron entry looks like this, to run at 2am every day.

0 2 * * * /usr/local/sbin/update-system.sh

Now just start and enable cron.
root@firewall:~# /etc/init.d/cron start
root@firewall:~# /etc/init.d/cron enable

Give it a run manually, if you want.
root@firewall:~# /usr/local/sbin/update-system.sh

Download a copy of the log from another machine (once the router has finished rebooting).
chris@box:~$ curl http://router/update.result
2018-03-18T10:14:49+1100 - nothing to update

That’s it! Now if you have multiple devices you can do the same, but maybe just set the cron entry for a different time of the night.

13 thoughts on “Auto apply latest package updates on OpenWrt (LEDE Project)

  1. Thanks Chris. This looks really useful.

    I’m a tad unclear on the need to manually create an empty update.result file though.

    No doubt there’s a good reason and I’m overlooking it. 🙂

  2. Hey crash, thanks. Touching the log was really just so that if someone curls the log they won’t get a 404 and think they did something wrong (because the instructions create a cron job and the script won’t have run yet by the time they try to curl the log, unless they chose to run it manually).

  3. Hi,

    Try to test your script with my Xiaomi 3G wiht OpenWRT 18.06.

    Works fine but after an upgrade, I have lost the Wifi. need to reboot the router.

    Possible to had a command in the script to restart the router after an upgrade ? I don’t know how can it’s possible…

    Thnaks for your script

  4. If there are packages to be updated, the script already reboots the router. I think there was some other problem, perhaps the wifi didn’t re-initialise properly after a reboot.

    You can see that at the line:

    exec reboot

  5. Sorry, the script is very good.

    Reboot only if package upgrade….not see…

    It’s working fine.

    Many thanks !!!

  6. Seems pretty good. Now the only issue is the /etc/config/lucy file where the devs never seems to agree if they should use the character ” or ‘ or nothing around lines, or some extra space here and there. It’s extremely annoying when the devs can’t agree on 1 style and stick to it as it makes this autoupdate impossible…. it’s always some really stupid conflict.
    Thanks for your advice though, it’s not your fault that it can’t be used. It’s so close to unattended upgrades.

  7. Hey Justin, yeah, there are risks with updating all packages, but to be clear I’m not talking about auto-flashing the upgrade image, this is just updating packages.

    The main issues with doing it are about either running out of space, or having a new required config that you miss out because the old config doesn’t have that option.

    This is what the OpenWRT page says:

    Like most Linux distributions (or mobile device operating systems like say Android or iOS), the functionality of the system can be upgraded rather significantly by downloading and installing pre-made packages from package repositories (local or on the Internet).

    The OpenWRT page does come with a warning about upgrading all packages, but also provides details on how to do it:

    Mass upgrade of all “upgradable” packages is not a good idea, as opkg only indicates that there is a newer version of the package, but does not do any further evaluation. Exceeding the flash space or failing to download all needed upgrades might brick the router. However, if you want to try that, there is one-liner to do it: opkg list-upgradable | cut -f 1 -d ‘ ‘ | xargs opkg upgrade command upgrades all installed packages that are currently “upgradable”

    At the end of the day, there are not actually very many package updates for a release and to me, automatically updating the packages outweighs the risk of potentially filling up the flash or having a service no-longer start due to a config change. In fact, I’ve never had that happen yet (but probably will now!) 😉

    At the end of the day, these are my systems so I can do what I want with them, but if I break them I get to keep both pieces 🙂 I just put it here in case anyone else wants to try something similar.

Leave a Reply

Your email address will not be published. Required fields are marked *