Thank you for your donation!


Cloudsmith graciously provides open-source package management and distribution for our project.


Solved: Backup and restore configuration across versions
#22
We already have System info for a comprehensive dump of all the settings, component versions etc but it's rarely used in troubleshooting because the Moode log and other logs contain what we usually need to see. Heres the source https://github.com/moode-player/moode/bl...sysinfo.sh

I might have mentioned this before but one of the challenges with proposals to do backup/restore settings is that most of the settings have code behind them that modifies the underlying system files and resources. Much of this code for the settings exists in worker.php. Heres the source https://github.com/moode-player/moode/bl...worker.php

All the "settings" code would have to be gathered in some other module and then maintained in sync with any changes that happen to same code blocks in worker.php or the other PHP modules that perform settings updates. A tiny bit of this was already done to support the Auto-configure (moodecfg.txt) process.

The other challenge is along the lines of what @swizzle mentioned where the settings themselves change, are deleted or new ones added, or the underlying system files change which require the code behind the setting to change, etc. This has occurred many, many times over the years since moOde was released.

When you take all this into account what seems like a straight forward backup/restore of settings actually becomes a Settings Migration Process. This is exactly what in-place updates do. Heres an example of two in-place update scripts that performed settings migration.

The 6.3.0 to 6.4.0 update

Code:
#!/bin/bash
#
# moOde audio player (C) 2014 Tim Curtis
# http://moodeaudio.org
#
# This Program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This Program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# 2019-11-24 TC moOde 6.3.0
#

MOODEREL="6.3.0"
PKGDATE="2019-11-24"

readYnInput () {
    while true; do
        read -p "$1" YN
        case $YN in
            [y] ) break;;
            [n] ) break;;
            * ) echo "** Valid entries are y|n";;
        esac
    done
}

cancelUpdate () {
    if [ $# -gt 0 ] ; then
        messageLog "$1"
    fi
    messageLog "** Exiting update"
    exit 1
}

messageLog () {
    echo "$1"
    TIME=$(date +'%Y%m%d %H%M%S')
    echo "$TIME updater: $1" >> /var/log/moode.log
}

echo
echo "****************************************************************"
echo "**"
echo "**  This package updates moOde $MOODEREL and contains important"
echo "**  bug fixes and improvements."
echo "**"
echo "**  WARNING: This update is only supported on non-modfied builds"
echo "**  and ISO images of moOde $MOODEREL"
echo "**"
echo "**  NOTE: Reboot after the update completes."
echo "**"
echo "****************************************************************"
echo

messageLog "Start $PKGDATE update for moOde $MOODEREL"

messageLog "** Version check"
REL=$(awk '/Release: /{print $2;}' /var/www/footer.php | sed 's/,//')
if [[ $REL != $MOODEREL ]] ; then
    cancelUpdate "** Error: this update will only run on moOde $MOODEREL"
fi

echo "** File system check"
if [ -f /var/local/moode.sqsh ] ; then
    cancelUpdate "** Error: this update will only run on un-squashed /var/www"
fi

cd /var/local/www

messageLog "** Step 1-9: Update SQL tables"
# cfg_hash
sqlite3 /var/local/www/db/moode-sqlite3.db "DROP TRIGGER ro_columns" 2> /dev/null
sqlite3 /var/local/www/db/moode-sqlite3.db "DELETE FROM cfg_hash"
sqlite3 /var/local/www/db/moode-sqlite3.db -csv ".import update/cfg_hash.csv cfg_hash"
sqlite3 /var/local/www/db/moode-sqlite3.db "CREATE TRIGGER ro_columns BEFORE UPDATE OF param, value, [action] ON cfg_hash FOR EACH ROW BEGIN SELECT RAISE(ABORT, 'read only'); END;"
# HifiBerry DAC/DAC+ Zero
sqlite3 /var/local/www/db/moode-sqlite3.db "UPDATE cfg_audiodev SET name='HiFiBerry DAC/DAC+ Zero' WHERE name='HiFiBerry DAC Zero'"
# Max ALSA volume
sqlite3 /var/local/www/db/moode-sqlite3.db "UPDATE cfg_system SET param='alsavolume_max', value='100' WHERE param='RESERVED_34'"
# FEAT_BLUETOOTH
sqlite3 /var/local/www/db/moode-sqlite3.db "UPDATE cfg_system SET value='31679' WHERE param='feat_bitmask'"
# Wake display
sqlite3 /var/local/www/db/moode-sqlite3.db "INSERT INTO cfg_system VALUES (128, 'wake_display', '0')"

messageLog "** Step 2-9: Update radio stations"
# Jazz24
sqlite3 /var/local/www/db/moode-sqlite3.db "UPDATE cfg_radio SET station='http://live.wostreaming.net/direct/ppm-jazz24aac256-ibc1' WHERE name='Jazz24'"
cp update/mpd/RADIO/Jazz24.pls /var/lib/mpd/music/RADIO
cp "update/mpd/playlists/Default Playlist.m3u" /var/lib/mpd/playlists

messageLog "** Step 3-9: Install packages"

# NOTE: This bumps to Buster 10.2
messageLog "**  pkg 1-3: Update and upgrade"
apt-get update
DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical apt-get -q -y -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" upgrade
apt-get clean

messageLog "**  pkg 2-3: Install xfsprogs"
apt-get -y install xfsprogs
messageLog "**  pkg 3-3: Install libmosquitto-dev"
apt-get -y install libmosquitto-dev

messageLog "** Step 4-9: Install binaries and scripts"
messageLog "**  bin 1-4: Install MPD 0.21.16"
mv update/other/mpd/mpd-0.21.16 /usr/local/bin/mpd
messageLog "**  bin 2-4: Install shairport-sync 3.3.5 w/mqtt"
mv update/other/shairport-sync/shairport-sync-3.3.5-b1a5056 /usr/local/bin/shairport-sync
messageLog "**  bin 3-4: Install rx 0.4"
mv update/other/trx/rx /usr/local/bin
messageLog "**  bin 4-4: Install tx 0.4"
mv update/other/trx/tx /usr/local/bin
messageLog "**  scr 1-2: Install alsa-capabilities 2.0.1"
mv update/usr/local/bin/alsa-capabilities /usr/local/bin
messageLog "**  scr 2-2: Install moodeutl 1.3.1"
mv update/usr/local/bin/moodeutl /usr/local/bin

messageLog "** Step 5-9: Update bluez-alsa to version 2.0.0"
cp update/other/bluetooth/bluez-alsa-master-2.0.0-4af3ebb.zip ./
unzip -q bluez-alsa-master-2.0.0-4af3ebb.zip
cd bluez-alsa-master
autoreconf --install
mkdir build
cd build
../configure --disable-hcitop --with-alsaplugindir=/usr/lib/arm-linux-gnueabihf/alsa-lib
make
make install
cd ../..
rm -rf bluez-alsa-master*
usermod -a -G audio mpd
cp update/usr/etc/alsa/conf.d/20-bluealsa.conf /usr/etc/alsa/conf.d

messageLog "** Step 6-9: Update moOde sources and configs"
# -- Standard --
cp -r update/etc/* /etc
cp -r update/var/local/www/* /var/local/www
# Save radio logos including usr added
cp -r /var/www/images/radio-logos/ ./
# Purge /var/www
find /var/www/* -delete
# Install new
cp -r update/www/* /var/www
# Restore radio logos and remove temp file
cp -r ./radio-logos/* /var/www/images/radio-logos/
rm -rf ./radio-logos
# Permissions
chmod -R 0755 /var/www
chmod -R 0755 /usr/local/bin
# Update browser title in header.php
TITLE=$(sqlite3 /var/local/www/db/moode-sqlite3.db "SELECT value FROM cfg_system WHERE param='browsertitle'")
/var/www/command/util.sh chg-name browsertitle "moOde Player" "$TITLE"
# -- Extra configs --
# HDMI blanking
sed '/hdmi_drive=2/ a hdmi_blanking=1' /boot/config.txt
# Disable swapfile service
dphys-swapfile swapoff
dphys-swapfile uninstall
systemctl disable dphys-swapfile

KERNEL=4.19.83
BUILD=1277
messageLog "** Step 7-9: Install Linux kernel $KERNEL build $BUILD"

# NOTE: This resets from the apt update/upgrade which installs 4.19.75 but does not update the .firmware_revision file :-0
rm /boot/.firmware_revision

echo "y" | sudo PRUNE_MODULES=1 rpi-update d86586926cfca6aa158cab13888194d53ae23d1b
rm -rf /lib/modules.bak
rm -rf /boot.bak
apt-get clean

messageLog "** Step 8-9: Install drivers for Allo USBridge Signature"
# WiFi driver (Comfast CF-912AC, MrEngman stock)
mv update/other/allo/usbridge_sig/$KERNEL-v7+/8812au.ko /lib/modules/$KERNEL"-v7+"/kernel/drivers/net/wireless
mv update/other/allo/usbridge_sig/$KERNEL-v7+/8812au.conf /etc/modprobe.d/
chmod 0644 /lib/modules/$KERNEL"-v7+"/kernel/drivers/net/wireless/8812au.ko
chmod 0644 /etc/modprobe.d/*.conf
# Eth/USB driver v0.1.4 (Allo enhanced)
mv update/other/allo/usbridge_sig/$KERNEL-v7+/ax88179_178a.ko /lib/modules/$KERNEL"-v7+"/kernel/drivers/net/usb
depmod $KERNEL-v7+

messageLog "** Step 9-9: Sync changes to disk"
# Flush cached writes
sync

cd ~/

The 6.5.2 to 6.6.0 update

Code:
#!/bin/bash
#
# moOde audio player (C) 2014 Tim Curtis
# http://moodeaudio.org
#
# This Program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This Program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# 2020-07-09 TC moOde 6.5.2
#

MOODEREL="6.5.2"
PKGDATE="2020-07-09"

readYnInput () {
    while true; do
        read -p "$1" YN
        case $YN in
            [y] ) break;;
            [n] ) break;;
            * ) echo "** Valid entries are y|n";;
        esac
    done
}

cancelUpdate () {
    if [ $# -gt 0 ] ; then
        messageLog "$1"
    fi
    messageLog "** Exiting update"
    exit 1
}

messageLog () {
    echo "$1"
    TIME=$(date +'%Y%m%d %H%M%S')
    echo "$TIME updater: $1" >> /var/log/moode.log
}

echo
echo "****************************************************************"
echo "**"
echo "**  This package updates moOde $MOODEREL and contains important"
echo "**  bug fixes and improvements."
echo "**"
echo "**  WARNING: This update is only supported on non-modfied builds"
echo "**  and ISO images of moOde $MOODEREL"
echo "**"
echo "**  NOTE: Reboot after the update completes."
echo "**"
echo "****************************************************************"
echo

messageLog "Start $PKGDATE update for moOde $MOODEREL"

messageLog "** Version check"
REL=$(awk '/Release: /{print $2}' /var/www/footer-plain.php | cut -d"<" -f 1)

if [[ $REL != $MOODEREL ]] ; then
    cancelUpdate "** Error: this update will only run on moOde $MOODEREL"
fi

echo "** File system check"
if [ -f /var/local/moode.sqsh ] ; then
    cancelUpdate "** Error: this update will only run on un-squashed /var/www"
fi

cd /var/local/www

messageLog "** Step 1-10: Update SQL tables"
# cfg_hash
sqlite3 /var/local/www/db/moode-sqlite3.db "DROP TRIGGER ro_columns" 2> /dev/null
sqlite3 /var/local/www/db/moode-sqlite3.db "DELETE FROM cfg_hash"
sqlite3 /var/local/www/db/moode-sqlite3.db -csv ".import update/cfg_hash.csv cfg_hash"
sqlite3 /var/local/www/db/moode-sqlite3.db "CREATE TRIGGER ro_columns BEFORE UPDATE OF param, value, [action] ON cfg_hash FOR EACH ROW BEGIN SELECT RAISE(ABORT, 'read only'); END;"
# cfg_system
sqlite3 /var/local/www/db/moode-sqlite3.db "INSERT INTO cfg_system VALUES (138, 'library_thumbnail_columns', '6/2 (Default)')"
sqlite3 /var/local/www/db/moode-sqlite3.db "INSERT INTO cfg_system VALUES (139, 'library_encoded_at', '9')"
sqlite3 /var/local/www/db/moode-sqlite3.db "INSERT INTO cfg_system VALUES (140, 'first_use_help', 'y,y')"
# cfg_radio
sqlite3 /var/local/www/db/moode-sqlite3.db "DROP TABLE cfg_radio"
sqlite3 /var/local/www/db/moode-sqlite3.db "CREATE TABLE cfg_radio (id INTEGER PRIMARY KEY, station CHAR (128), name CHAR (128), type CHAR (8), logo CHAR (128), genre CHAR (32), broadcaster CHAR (32), language CHAR (32), country CHAR (32), region CHAR (32), bitrate CHAR (32), format CHAR (32))"
sqlite3 /var/local/www/db/moode-sqlite3.db -csv ".import update/cfg_radio.csv cfg_radio"
#cfg_audiodev
sqlite3 /var/local/www/db/moode-sqlite3.db "DELETE FROM cfg_audiodev"
sqlite3 /var/local/www/db/moode-sqlite3.db -csv ".import update/cfg_audiodev.csv cfg_audiodev"

messageLog "** Step 2-10: Install station PLS files"
rm /var/lib/mpd/music/RADIO/*.pls
cp update/mpd/RADIO/*.pls /var/lib/mpd/music/RADIO

messageLog "** Step 3-10: Install packages"
messageLog "**  Pkg 1-2: Install zip"
apt-get -y install zip
messageLog "**  Pkg 2-2: Install id3v2"
apt-get -y install id3v2

messageLog "** Step 4-10: Install binaries"
messageLog "**  Bin 1-1: Install MPD 0.21.24"
mpc stop
mv update/other/mpd/mpd-0.21.24 /usr/local/bin/mpd
sqlite3 /var/local/www/db/moode-sqlite3.db "UPDATE cfg_system SET value='0.21.24' WHERE param='mpdver'"

messageLog "** Step 5-10: Build bluez-alsa 2.1.0-49ad348"
cp update/other/bluetooth/bluez-alsa-master-2.1.0-49ad348.zip ./
unzip -q ./bluez-alsa-master-2.1.0-49ad348.zip
cd bluez-alsa-master
# NOTE: Ignore warnings from autoreconf and configure
autoreconf --install
mkdir build
cd build
../configure --disable-hcitop --with-alsaplugindir=/usr/lib/arm-linux-gnueabihf/alsa-lib
make
make install
cd ../..
rm -rf bluez-alsa-master*
cp update/etc/systemd/system/bluealsa-aplay@.service /etc/systemd/system
cp update/lib/systemd/system/bthelper@.service /lib/systemd/system

messageLog "** Step 6-10: Build upmpdcli 1.4.12"
messageLog "**  Src 1-5: Compile libnpupnp 4.0.6"
cp update/other/upmpdcli/libnpupnp-4.0.6.tar.gz ./
tar xfz ./libnpupnp-4.0.6.tar.gz
cd libnpupnp-4.0.6
./configure --prefix=/usr --sysconfdir=/etc
make
make install
cd ..
rm -rf ./libnpupnp-4.0.6
rm libnpupnp-4.0.6.tar.gz
messageLog "**  Src 2-5: Compile libupnpp 0.19.1"
cp update/other/upmpdcli/libupnpp-0.19.1.tar.gz ./
tar xfz ./libupnpp-0.19.1.tar.gz
cd libupnpp-0.19.1
./configure --prefix=/usr --sysconfdir=/etc
make
make install
cd ..
rm -rf ./libupnpp-0.19.1
rm libupnpp-0.19.1.tar.gz
messageLog "**  Src 3-5: Compile upmpdcli 1.4.12-7ea91f5d"
cp update/other/upmpdcli/upmpdcli-1.4.12-master-7ea91f5d.tar.gz ./
tar xfz ./upmpdcli-1.4.12-master-7ea91f5d.tar.gz
cd upmpdcli-master
./autogen.sh
./configure --prefix=/usr --sysconfdir=/etc --disable-spotify
make
make install
cd ..
rm -rf ./upmpdcli-master
rm upmpdcli-1.4.12-master-7ea91f5d.tar.gz
#useradd upmpdcli
#cp update/lib/systemd/system/upmpdcli.service /lib/systemd/system
#cp update/etc/upmpdcli.conf /etc
#chmod 0644 /etc/upmpdcli.conf
systemctl daemon-reload
systemctl disable upmpdcli
messageLog "**  Src 4-5: Compile libupnpp-samples (upexplorer)"
cp update/other/upmpdcli/libupnpp-samples-master.zip ./
unzip -q ./libupnpp-samples-master.zip
cd libupnpp-samples-master
./autogen.sh
./configure
make
make install
cd ..
rm -rf ./libupnpp-samples-master
rm libupnpp-samples-master.zip

messageLog "**  Src 5-5: Install patch for gmusic plugin"
# IS THIS PATCH STILL NEEDED?
cp update/other/upmpdcli/session.py /usr/share/upmpdcli/cdplugins/gmusic

KERNEL=5.4.49
BUILD=1323
messageLog "** Step 7-10: Install Linux kernel $KERNEL build $BUILD"

# Ensure rpi-update runs
rm /boot/.firmware_revision

echo "y" | sudo PRUNE_MODULES=1 rpi-update da3752a358a86014cdcce5fc3be5b18d7ec074c4
rm -rf /lib/modules.bak
rm -rf /boot.bak
apt-get clean

messageLog "** Step 8-10: Install drivers for Allo USBridge SIG"
# 32-bit
# WiFi driver (Comfast CF-912AC, MrEngman stock)
mv update/other/allo/usbridge_sig/$KERNEL-v7+/8812au.ko /lib/modules/$KERNEL"-v7+"/kernel/drivers/net/wireless
mv update/other/allo/usbridge_sig/$KERNEL-v7+/8812au.conf /etc/modprobe.d/
chmod 0644 /lib/modules/$KERNEL"-v7+"/kernel/drivers/net/wireless/8812au.ko
chmod 0644 /etc/modprobe.d/*.conf
# ASIX Eth/USB driver v2.0.0 (Allo enhanced)
mv update/other/allo/usbridge_sig/$KERNEL-v7+/ax88179_178a.ko /lib/modules/$KERNEL"-v7+"/kernel/drivers/net/usb
depmod $KERNEL-v7+
# 64-bit
# WiFi driver (Comfast CF-912AC, MrEngman stock)
mv update/other/allo/usbridge_sig/$KERNEL-v8+/8812au.ko /lib/modules/$KERNEL"-v8+"/kernel/drivers/net/wireless
chmod 0644 /lib/modules/$KERNEL"-v8+"/kernel/drivers/net/wireless/8812au.ko
# ASIX Eth/USB driver v2.0.0 (Allo enhanced)
mv update/other/allo/usbridge_sig/$KERNEL-v8+/ax88179_178a.ko /lib/modules/$KERNEL"-v8+"/kernel/drivers/net/usb
depmod $KERNEL-v8+

messageLog "** Step 9-10: Update moOde sources and configs"
# -- Standard --
# Update /etc
cp -r update/etc/* /etc
# Update /var/local/www
rm /var/local/www/db/moode-sqlite3.db.default
rm /var/local/www/db/moode-sqlite3.db.schema
cp -r update/var/local/www/* /var/local/www
# Update /var/www
find /var/www/* -delete
cp -r update/www/* /var/www
# Permissions
chmod -R 0755 /var/www
chmod -R 0755 /usr/local/bin
# Update browser title in header.php
TITLE=$(sqlite3 /var/local/www/db/moode-sqlite3.db "SELECT value FROM cfg_system WHERE param='browsertitle'")
/var/www/command/util.sh chg-name browsertitle "moOde Player" "$TITLE"
# -- Extras --
# Delete Library tag cache
rm /var/local/www/libcache.json

messageLog "** Step 10-10: Sync changes to disk"
# Flush cached writes
sync

cd ~/

If you examine the scripts you will see changes to setting names and values and the addition of new settings. What this means for example is that a backup of settings from 6.3.0 that were restored to a 6.4.0 image would cause breakage because the old value and meaning of cfg_system param='RESERVED_34 and param='feat_bitmask' would overwrite the new ones.

I'm not trying to rain on the parade but rather to show the complexity and challenge of maintaining settings migration across software versions. 

I you think there is a simpler way to do it then I'm all ears.
Enjoy the Music!
moodeaudio.org | Mastodon Feed | GitHub
Reply


Messages In This Thread
RE: Backup and restore configuration across versions - by Tim Curtis - 07-22-2020, 03:10 AM

Forum Jump: