#!/bin/sh
set -e
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB 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 of the License, or
# (at your option) any later version.
#
# GRUB 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 GRUB. If not, see .
grub_mkconfig="/usr/sbin/grub2-mkconfig"
grub_mkrelpath="/usr/bin/grub2-mkrelpath"
grub_setting="/etc/default/grub"
grub_cfg="/boot/grub2/grub.cfg"
grub_snapshot_cfg="/boot/grub2/snapshot_submenu.cfg"
snapshot_submenu_name="snapshot_submenu.cfg"
snapshot_menuentry_name="snapshot_menuentry.cfg"
snapshot_menuentry_cfg="boot/grub2/${snapshot_menuentry_name}"
rel_root=`"$grub_mkrelpath" /`
snapshot_submenu_refresh () {
for s_dir in /.snapshots/*; do
snapshot="${s_dir}/snapshot"
snapper_cfg="${s_dir}/${snapshot_submenu_name}"
if [ ! -d "$snapshot" ]; then
rm -f "${snapper_cfg}"
rm -f "${s_dir}/${snapshot_menuentry_name}"
continue
fi
# bnc#864842 Important snapshots are not marked as such in grub2 menu
# the format is "important distribution version (kernel_version, timestamp, pre/post)"
cfgs="${s_dir}/${snapshot_menuentry_name} ${snapshot}/${snapshot_menuentry_cfg}"
date=`xmllint --xpath '/snapshot/date/text()' "${s_dir}/info.xml" || echo ""`
date=`echo $date | sed 's/\(.*\) \(.*\):.*/\1,\2/'`
important=`xmllint --xpath "/snapshot/userdata[key='important']/value/text()" "${s_dir}/info.xml" || echo ""`
stype=`xmllint --xpath '/snapshot/type/text()' "${s_dir}/info.xml" || echo ""`
kernel_ver=`readlink /boot/vmlinuz | sed 's/vmlinuz-\([^-]*\).*/\1/'`
eval `cat ${snapshot}/etc/os-release`
test "$important" = "yes" && important="*" || important=""
test "$stype" = "single" && stype=""
if test -n "$stype"; then
title="${important}${NAME} $VERSION ($kernel_ver,$date,$stype)"
else
title="${important}${NAME} $VERSION ($kernel_ver,$date)"
fi
cat < "${snapper_cfg}.new"
for x in $cfgs; do
snap="${rel_root}${snapshot}"
snap_cfg="${rel_root}\$x"
if [ -f "\$snap_cfg" ]; then
snapshot_found=true
submenu "$title" "\$snap" "\$snap_cfg" {
set subvol="\$2"
export subvol
source "\$3"
}
break
fi
done
EOF
if grub2-script-check "${snapper_cfg}.new"; then
mv -f "${snapper_cfg}.new" "${snapper_cfg}"
fi
done
}
grub_snapshot_cfg_refresh () {
: > "${grub_snapshot_cfg}.tmp"
for s_dir in /.snapshots/*; do
snapshot="${s_dir}/snapshot"
snapper_cfg="${s_dir}/${snapshot_submenu_name}"
if [ -f "${snapper_cfg}" ]; then
echo "source ${rel_root}${snapper_cfg}" >>"${grub_snapshot_cfg}.tmp"
continue
fi
done
cat <"${grub_snapshot_cfg}.new"
submenu "Bootable snapshots" {
`sort -V "${grub_snapshot_cfg}.tmp"`
if [ x\$snapshot_found != xtrue ]; then
submenu "Not Found" {true}
fi
}
EOF
if grub2-script-check "${grub_snapshot_cfg}.new"; then
mv -f "${grub_snapshot_cfg}.new" "${grub_snapshot_cfg}"
fi
}
snapshot_submenu_clean () {
for s_dir in /.snapshots/*; do
snapshot="${s_dir}/snapshot"
snapper_cfg="${s_dir}/${snapshot_submenu_name}"
if [ -f "$snapper_cfg" ]; then
rm -f "$snapper_cfg"
fi
done
}
set_grub_setting () {
name=$1
val=$2
if grep -q "$name" "$grub_setting"; then
sed -i -e "s/.*\($name\)=.*/\1=$val/" "$grub_setting"
else
echo "$name=$val" >> "$grub_setting"
fi
}
update_grub_cfg () {
"$grub_mkconfig" -o "$grub_cfg"
}
# Check the arguments.
while test $# -gt 0
do
option=$1
shift
case "$option" in
-e | --enable)
opt_enable=true
;;
-d | --disable)
opt_enable=false
;;
-r | --refresh)
opt_refresh=true
;;
-c | --clean)
opt_clean=true
;;
-*)
;;
esac
done
if [ "x${opt_enable}" = "xtrue" ]; then
set_grub_setting SUSE_DISABLE_BOOTING_SNAPSHOT false
set_grub_setting SUSE_ENABLE_CUSTOM_SNAPSHOT_SUBMENU true
update_grub_cfg
snapshot_submenu_refresh
grub_snapshot_cfg_refresh
elif [ "x${opt_enable}" = "xfalse" ]; then
snapshot_submenu_clean
set_grub_setting SUSE_DISABLE_BOOTING_SNAPSHOT true
set_grub_setting SUSE_ENABLE_CUSTOM_SNAPSHOT_SUBMENU false
update_grub_cfg
fi
if [ x${opt_refresh} = "xtrue" ]; then
snapshot_submenu_refresh
grub_snapshot_cfg_refresh
fi
if [ x${opt_clean} = "xtrue" ]; then
snapshot_submenu_clean
grub_snapshot_cfg_refresh
fi