Opkg extras not being triggered by hotplug

opkg extras wants to be run after upgrades once internet is available. The page (as of this writing) does so by creating a hotplug script in /etc/hotplug.d/online, but it did not run when I upgraded to 21.02.1 .

Checking procd and netifd sources, I do not see online being mentioned, so I suspect there is just no such event - or at least not in the base system, and having to install external packages for an automated restoration of packages installed before upgrade would defeat the purpose.

Am I missing something ?

If I did not miss anything, should the script be moved to /etc/hotplug.d/iface and extended with something like [ "1" -eq "${IFUPDATE_ROUTES:-0}" ] ? Then, opkg update will anyway complain if there is no available route, so rather than trying to guess if whatever route (dis)appeared gave internet access I guess it is better to just run it.

On a very loosely related note, would it make sense to add a download-only step before the uninstall step of the restore operation, or is this operation guaranteed to not depend on any package being uninstalled to complete ? For example, my uninstall step removes dnsmasq to then be able to install dnsmasq-full, would there be a similar situation with a package required for internet access ? Maybe the issue would only manifest if the interface went down between the start of the uninstall step and the equivalent package being installed during the install step.

(ping @vgaetera )

@vgaetera hasn't been here since January 26th.

Hotplug docs -

Aw :frowning:

I hope everything is fine.

Actually I have edited that page a bit before posting here, to complete the list of values and variables for the inet class of events, now that I have some understanding of it (review welcome).

But sadly, this does not tell me if I am missing something bigger (like some other magic ubus daemon which would in fact trigger some undocumented online class of hotplug events).

Don't see anything about "inet", but did you look at the "iface" directory?


ACTION - ifup
DEVICE - eth0.2 (or whatever the WAN device name is)

Woops, I mistyped. I intended iface, indeed.

Well, I was hesitating about having a condition on this value, because for example I have 2 WAN interfaces (one for IPv4, one for IPv6, both independent), and if I do not presume of which can be used to access the package repositories, I cannot guess which one is sufficient to reach them. Also, I would like my change to opkg-extras to be reusable beyond my device if possible.
Hence my idea at the moment of triggering on whenever some route changes anywhere: the script will put marker files once it has done its job, and it exits if it finds them. I expect route changes to be infrequent enough that not filtering on the interface nor on the device would be tolerable.

Then again, both my upstream interfaces match wan*, maybe it is widespread enough to be tolerable to match the interface with ? I lack experience beyond my own use-cases on this.

Here is my proposal for replacing the hotplug script.

I am reluctant to edit the wiki page directly, I would appreciate some review here. In fact, I would prefer these changes to become a package rather than having to be installed by copy/pasting from a wiki page... But I guess the proper way to package this is to contribute to opkg directly, which is likely too far over my head.

Note the removal of mkdir -p /etc/hotplug.d/online (instead of keeping it with s/online/iface/): I believe this directory should be expected to be already present before install.

# Configure hotplug
cat << "EOF" > /etc/hotplug.d/iface/50-opkg-restore
if [ "1" -eq "${IFUPDATE_ROUTES:-0}" ]; then
OPKG_CONF="init main"
do if [ ! -e /etc/opkg-restore-"${OPKG_CONF}" ] \
&& lock -n /var/lock/opkg-restore \
&& opkg update
then . /etc/profile.d/opkg.sh
opkg restore "${OPKG_CONF/main}" 2>&1 \
| logger -t opkg
touch /etc/opkg-restore-"${OPKG_CONF}"
lock -u /var/lock/opkg-restore
cat << "EOF" >> /etc/sysupgrade.conf

There is no online directory, or environment variable for hotplug.d

From the 21.02.2 release, installed yesterday -

Automatically named wan and wan6 respectively.

Not clear why the environment variables ifup wan or ifup wan6 wouldn't work in iface.

Even though the opkg extras docs shows the online directory being created, it also isn't clear how long ago that script was written.

It may have since been deprecated.

@bobafetthotmail was the last to update that page.

You might ping him.

As you have correctly guessed, the folders in the /hotplug.d folder may exist or not depending on what packages you have installed (as packages can add their own hotplug triggers). The folders shown by OldNavyGuy (and listed in the wiki article) are the ones that are always there because they are created by core packages or something.

So yes, moving the hotplug script to a default folder is probably best.

Adding a script (or multiple scripts) to an existing package isn't particularly hard, just go in this folder https://github.com/openwrt/openwrt/tree/master/package/system/opkg drop your new scripts in the /files folder and edit the Makefile text after the
define Package/opkg/install
to add a line like this
$(INSTALL_BIN) ./files/my_script_name_here $(1)/bin
so it's included in the package and installed by opkg.

the harder part here is follow the correct contribution rules https://openwrt.org/submitting-patches

Since it's a couple scripts the impact on package size would be nearly nothing.

I'm personally recommending to try out luci-attended-sysupgrades package instead, as that will take a list of installed packages, send them to an OpenWrt build server (or your own if you want to set up your own stuff) and receive a flashable image with those packages already integrated.
See its project page for more info and some screenshots

1 Like

I did not know about this. It indeed looks like a more robust solution for my use (having the same packages installed after sysupgrade): it is then possible to enable options not supported by base packages, and avoids the risk of loosing connection mid-package-download after having uninstalled a to-be-replaced essential package.

Thanks a lot for pointing it out.

I start working on integrating opkg-extras to the opkg package.

EDIT: Attended sysupgrades is awesome. I just used it on my old, 8MB flash TD-W8970, and thanks to my package selection being built-in the base image I have 747kB free in /, up from 188kB.

I added a mention of Attended sysUpgrade on the opkg-extras page.

I am having second thoughts about integrating the opkg-extras scripts in the opkg package:

  • the same package providing a binary and then overriding it with a shell function does not looks too nice (OTOH I do not intend to reimplement it in C in opkg, I think this would be above my head).
  • opkg-extras relies on the user triggering opkg save before upgrading (or after changes to the list of installed packages). This seems bound to be forgotten between upgrades and to create issues.

A use-case where I believe opkg-extras is still useful is in applying an upgrade to an extroot: once the sysupgrade has enough packages to have internet connectivity and extroot essentials, an opkg-extras-like mechanism could take over and carry the upgrade on in the extroot. IIRC this requires changing a hidden file in the extroot so it gets mounted over the new version, and there is a need to decide which packages to install there vs. in the base image, so it would require non-trivial extensions to opkg-extras.

yeah, all packages that are "built in" like this are stored in high-compression read-only partition, it's basically a front end for the "Image Builder" tool https://openwrt.org/docs/guide-user/additional-software/imagebuilder but does not require the user to have a Linux system to run it (as now the device can talk to a Linux server)

you can add that command to the default sysupgrade scripts, or add an override to sysupgrade like it's done in the "advanced sysupgrade" script that is redefining "sysupgrade" https://openwrt.org/docs/guide-user/advanced/sysupgrade_extras

1 Like