OpenWRT is a great open-source operating system for embedded devices (especially routers). One of its strong points is its high extensibility, benefiting from “more than 27000 packages ready to be browsed and installed in an app store-like environment”. These packages can add plenty of extra functionality on top of the default networking features.
These additional programs can normally be installed on the device’s own storage (similar to installing apps on a phone) – when such storage is available. For those situations where the storage space is limited (and you haven’t upgraded it yet), OpenWRT can also install those extra packages in RAM memory instead of flash storage – with the side-effect of such installations not surviving reboots (RAM memory content is ephemeral, after all).
This is done by including the -d ram parameter to opkg install calls, for example:
opkg -d ram nano
The new packages (and files) get installed to the temporary (/tmp) RAM storage though and are not readily available to the system as commands. To address that we need symlinks from /tmp to the default binary locations:
ln -s /tmp/usr/lib/*.so* /usr/lib/ ln -s /tmp/usr/bin/* /usr/bin/
Having to manually symlink files from RAM to the storage overlay and the lack of the extra destination parameter in LuCI makes these commands usable in the console only.
Startup
To avoid having to log-in back into the router’s console after every reboot to manually re-install packages, the commands can be saved for automatic run at boot:
sleep 60 opkg update opkg -d ram install speedtestpp htop ln -s /tmp/usr/lib/*.so* /usr/lib/ ln -s /tmp/usr/bin/* /usr/bin/
Make sure any commands you want run at startup are placed before the exit 0 line (which must also exist). Adjust the sleep time (in seconds) to a value bigger than the expected delay before an internet connection becomes available to the device and edit the packages list to whatever you require.
This will delay the startup until the script is complete so OpenWrt will not end its LEDs blinking sequence until then. To avoid that it would have been easy to replace everything with a one-line cron job, unfortunately OpenWrt’s cron does not ship with @reboot support by default.
That leaves writing a custom interface event detection script the only alternative.
Iface detection
Create the file /etc/hotplug.d/iface/99-ifup-wan and add the following content:
#!/bin/sh [ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ] && [ ! -f /var/opkg-lists/openwrt_base ] && { logger "opkg2ram: uplink interface up event detected - installing packages..." sleep 5 /bin/opkg update /bin/opkg -d ram install speedtestpp htop nano /bin/ln -s /tmp/usr/lib/*.so* /usr/lib/ /bin/ln -s /tmp/usr/bin/* /usr/bin/ logger "opkg2ram: packages update and install complete." } exit 0
Mwan3
Alternatively, if your device uses mwan3 for multi-wan capability add the following at the end of the /etc/mwan3.user file:
logger "mwan3-opkg2ram: uplink interface up event detected for interface $INTERFACE / device $DEVICE" if [ "$ACTION" = "connected" ] && [ "$DEVICE" = "wwan0" ] && [ ! -f /var/opkg-lists/openwrt_base ]; then logger "mwan3-opkg2ram: uplink interface up event detected - installing packages..." sleep 5 /bin/opkg update /bin/opkg -d ram install speedtestpp htop nano /bin/ln -s /tmp/usr/lib/*.so* /usr/lib/ /bin/ln -s /tmp/usr/bin/* /usr/bin/ logger "mwan3-opkg2ram: packages update and install complete." fi
Adjust any instances (in both filename and script) of wan to the current name of the interface that provides the uplink to the internet – for example wwan for a wireless/LTE wan or trm_wan for an interface controlled by travelmate. This ensure that the installation is attempted only once the internet connection is established.
With mwan3 check the log of the device to find the name of the device (usually wwan0 for a wireless/lte wan).
Also edit the packages list to suit your needs, just don’t throw everything at it and leave some RAM memory for actual operational needs.