What's the best way to compare old and updated configs in ash?

So I want to capture the last-run-on config and be able to compare it to the new config if the init script is reloaded/restarted.

What's the best way to actually compare the configs? I know there's uci change but can I maybe somehow (with the use of -c) make it compare old config against the current config and then iterate over changes?

Tagging @jow @hnyman @dibdot @neheb.

You can export uci configs to a directory and then compared them.
You could use the same approach to compare two exported config dirs.

I use this scripts in my builds:

Script:

#!/bin/sh
cd /etc/config
for F in *
do
        echo
        echo "===== $F ====="
        uci -c /rom/etc/config export $F >/tmp/$F.default 2>/dev/null
        case $? in 0) ;; *) echo '>> no default in /rom <<' ;; esac
        uci export $F >/tmp/$F.current
        diff /tmp/$F.default /tmp/$F.current
        rm -f /tmp/$F.default /tmp/$F.current
done

That is for manual comparison, but if you want to automate things, you could either parse the full output of that (might be difficult), or if your interest is for a specific 1-2 changes, you might script further to only handle those config items you are interested in.

The prerequisite might be that your init script always saves the right "last-run-on" config somewhere.

1 Like

Thanks for prompt reply. I was hoping for a bit easier to parse (than simple diff) way a-la uci changes, which would provide me with the useable config unique IDs.

You could just hash the old and new configs and compare the hashes.

Hmmm.
Are you looking for "specific changes, 1-2 items" or just for "something has changed" ????

The hash idea of neheb might work for the latter case. Just calculate hash from the config file and store it to flash at the successful end of the init script. Then next time compare the previous stored hash to the current hash first.

And what you aim to do when something has changed?
(I don't yet understand your use case)

Ideally, when (typed) configs are removed or added, I'd like to get their IDs which I could then use in config_get. Something like uci changes, but after the changes have been committed.

So I can optimize (speed up) service reload by iterating over only removed/updated/added configs.

If you want to compare configs manually:
https://openwrt.org/docs/guide-user/advanced/uci_extras

However, it looks like you want to automate the process.
When updating the package, its new config should get the suffix -opkg.
This makes possible to read both old and new configs and loop over their options.

1 Like

So based on replies above, looks like I'll need to write special code to iterate over old and new config files and find differences. Doesn't look like I can get that comparison from uci CLI and looks like diff would not yield the results I wanted.

To be honest, I still do not quite understand your use case.

Do you have a frequently restarting/reloading service that parses uci config for writing an app-specific non-uci config file (for the app itself, like with collectd), and you would like to avoid that re-parsing, if not necessary ???

1 Like

I just install diffutils on every device with >=32 MB flash (yes, CONFIG_BUSYBOX_CONFIG_DIFF=y would be smaller than GNU diff, but I don't want to enable CONFIG_BUSYBOX_CUSTOM=y for just that).

Yes, very similar to that! If a specific config/section hasn't changed, I'd like to avoid processing it/running non-uci app-specific changes.

1 Like

Sounds a bit far-fetching that you would do "per uci item" or "per uci section" section evaluation.

The easy approach would be "per uci file", so that you parse the whole config file if the file has changed at all.

(but if you try "by item/section", the idea of exporting the relevant section, calculating a hash, comparing it to the previous, and storing it for next time, might be feasible.

1 Like