File: //lib/systemd/systemd-versions-ctrl
#!/bin/bash
set -e
SYSTEMD_BACKUP_VERSIONS_DIR="/var/systemd/versions/"
LOG_FILE=$SYSTEMD_BACKUP_VERSIONS_DIR/log
function atomic_cp_to_root() {
for f in $(find -type f); do
cp --preserve=all $f $f.bak
mkdir -p $(dirname /$f)
mv $f.bak /$f
done
}
function record() {
case $1 in
list)
versions=$(ls -t -I log ${SYSTEMD_BACKUP_VERSIONS_DIR} | tr "\n" " ")
echo "$(date "+%Y-%m-%d %H:%M:%S") [LIST] $versions" >> $LOG_FILE
;;
switch)
echo "$(date "+%Y-%m-%d %H:%M:%S") [SWITCH] $2 -> $3" >> $LOG_FILE
;;
remove)
echo "$(date "+%Y-%m-%d %H:%M:%S") [REMOVE] $2" >> $LOG_FILE
;;
esac
}
echo -e "------!
Be careful to execute this tool, you MUST know what you are doing!
------!\n"
action="${1}"
case ${action} in
list)
if [ ${#} != 1 ]; then
echo "Too many arguments."
exit 1
fi
if [ ! -d ${SYSTEMD_BACKUP_VERSIONS_DIR} ] || [ "`ls -A $SYSTEMD_BACKUP_VERSIONS_DIR`" = "" ]; then
echo "No available versions."
exit 1
fi
echo "Versions:"
ls -1t -I log ${SYSTEMD_BACKUP_VERSIONS_DIR}
record list
;;
switch-to)
if [ ${#} -lt 2 ]; then
echo "Too few arguments."
exit 1
fi
if [ ${#} -gt 2 ]; then
echo "Too many arguments."
exit 1
fi
# make sure the user knows what he is doing
echo "NOTE!!!"
echo "After switching versions, \`rpm -q systemd\` will not report the right"
echo "version of the installed systemd, use \`systemctl --version\` instead."
echo ""
read -r -p "Are You Sure To Continue? [Y/n] " input
case $input in
[yY])
;;
*)
exit 1
;;
esac
version="${2}"
if [ ! -d "${SYSTEMD_BACKUP_VERSIONS_DIR}${version}" ]; then
echo "No such systemd version installed: ${version}."
exit 1
fi
if [ `id -u` -ne 0 ]; then
echo "Need to be root."
exit 1
fi
from=$(systemctl --version | sed -n '1p' | awk -F "(" '{print $2}' | awk -F ")" '{print $1}')
cd ${SYSTEMD_BACKUP_VERSIONS_DIR}${version}
atomic_cp_to_root
record switch $from $version
/sbin/ldconfig &>/dev/null || :
systemctl daemon-reexec &>/dev/null || :
systemctl try-restart systemd-udevd.service &>/dev/null || :
;;
remove)
if [ ${#} -lt 2 ]; then
echo "Too few arguments."
exit 1
fi
if [ ${#} -gt 2 ]; then
echo "Too many arguments."
exit 1
fi
version="${2}"
if [ ! -d "${SYSTEMD_BACKUP_VERSIONS_DIR}${version}" ]; then
echo "No such systemd version installed: ${version}."
exit 1
fi
rm -rf "${SYSTEMD_BACKUP_VERSIONS_DIR}${version}"
record remove $version
;;
*)
echo "`basename ${0}`: Usage:"
echo " list List installed systemd versions"
echo " switch-to VERSION Switch to the specified systemd version"
echo " remove VERSION Remove the backup files of the specified systemd version"
exit 1
;;
esac