Upgrading OpenWrt

Does anyone who use the OpenWrt container have a script they can share for upgrading OpenWrt that creates a new container, copies over the config/user packages that works well with Incus?

have you tried doing OpenWRT built-in backup and restoring it on a new container?

You could try using a custom volume thats mounted to /etc/config/users to hold the relevant config independently of the root disk and then just use incus rebuild to upgrade to a newer OpenWrt container image. That way you might not even need a script that interacts with OpenWrt guest instance at all.

Create and attach custom Volume:
incus storage volume create default openwrt-config-vol --type=filesystem size=50MiB
incus storage volume attach default custom/openwrt-config-vol openwrt-instance /etc/config/users

Rebuild instance :
incus rebuild images:openwrt/24.10 local:openwrt-instance

Haven’t tested this myself but would expect it to work unless OpenWrt changes it’s config file layout drastically between releases.

I’ve got a few scripts that I use for this process.


To create a backup and restore it:

create_backup.sh

#!/bin/bash
set -eux

NAME=“router1”
REMOTE=“server1”

incus exec $REMOTE:$NAME – sysupgrade -b /tmp/config_backup.tar.gz
incus file pull $REMOTE:$NAME/tmp/config_backup.tar.gz ./

restore_backup.sh

#!/bin/bash
set -eux

NAME=“router1”
REMOTE=“server1”

incus file push ./config_backup.tar.gz $REMOTE:$NAME/tmp/config_backup.tar.gz --uid 0 --gid 0 --mode 644
incus exec $REMOTE:$NAME -- sysupgrade -r /tmp/config_backup.tar.gz
incus restart $REMOTE:$NAME

For packages, I keep a list of what is installed and located in a file on the OpenWRT instance:
/etc/freehand/my_packages

nano
htop
openssh-sftp-server
iperf3
tcpdump
bind-dig
luci-proto-wireguard
luci-app-acme
acme-acmesh-dnsapi

That file gets automatically backed up in the above tar.gz file because I added a line in /etc/sysupgrade.conf:

/etc/freehand/

To reinstall my selection of packages (and upgrade present packages), I have:

install_packages.sh

#!/bin/bash
set -eux

NAME=“router1”
REMOTE=“server1”

# Wait for an ipv6 link to be up
while ! incus exec $REMOTE:$NAME -- ping -6 -c 1 2606:4700:4700::1111; do
  sleep 1
done

# Push in a DNS server if the flag --dns is provided
# Also stop dnsmasq from updating and replacing the resolv.conf file (via mechanisms like DHCP).
if [[ "${1:-}" == "--dns" ]]; then
  incus exec $REMOTE:$NAME -- /etc/init.d/dnsmasq stop
  sleep 1
  incus exec $REMOTE:$NAME -- ash -c 'echo "nameserver 2606:4700:4700::1111" > /etc/resolv.conf'
fi

# Wait for ipv6 gateway and DNS to be working
while ! incus exec $REMOTE:$NAME -- ping -6 -c 1 downloads.openwrt.org; do
  sleep 1
done

# Progress with installing packages
incus exec $REMOTE:$NAME -- opkg update
incus exec $REMOTE:$NAME -- ash -c 'opkg list-upgradable | cut -f 1 -d " " | xargs opkg upgrade'
incus exec $REMOTE:$NAME -- ash -c 'grep -v "^\(#\|$\)" /etc/freehand/my_packages | xargs opkg install'

sleep 1
incus restart $REMOTE:$NAME

Using these scripts, my general workflow is

  1. incus image refresh
  2. ./create_backup.sh
  3. incus stop && incus delete
  4. incus create && incus start
  5. ./restore_backup.sh
  6. ./install_packages.sh --dns

Thanks I’ll give this a shot. You can use sysupgrade -k to save the list of packages:

        -k           include in backup a list of current installed packages at
                     /etc/backup/installed_packages.txt

Unfortunately rebuild won’t work if there are snapshots

I’ve found that -k flag to include a bit more than I would like.
I also treat my routers as ephemeral containers and like being able to blow them back to a defined state, which is why I’ve opted for the custom/manual package tracking.

1 Like