diff --git a/grub2-snapper-plugin.sh b/grub2-snapper-plugin.sh index 1fc7449..c6203e4 100644 --- a/grub2-snapper-plugin.sh +++ b/grub2-snapper-plugin.sh @@ -18,117 +18,148 @@ set -e grub_mkconfig="/usr/sbin/grub2-mkconfig" grub_mkrelpath="/usr/bin/grub2-mkrelpath" +grub_script_check="/usr/bin/grub2-script-check" 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}" +snapper_snapshot_path="/.snapshots" +snapshot_submenu_name="grub-snapshot.cfg" +snapper_snapshots_cfg="${snapper_snapshot_path}/${snapshot_submenu_name}" -rel_root=`"$grub_mkrelpath" /` +# add hotkeys for s390. (bnc#885668) +hotkey= +incr_hotkey() +{ + [ -n "$hotkey" ] || return + expr $hotkey + 1 +} +print_hotkey() +{ + keys="123456789abdfgijklmnoprstuvwyz" + if [ -z "$hotkey" ]||[ $hotkey -eq 0 ]||[ $hotkey -gt 30 ]; then + return + fi + echo "--hotkey=$(expr substr $keys $hotkey 1)" +} -snapshot_submenu_refresh () { -for s_dir in /.snapshots/*; do +snapshot_submenu () { + + s_dir="$1" snapshot="${s_dir}/snapshot" - snapper_cfg="${s_dir}/${snapshot_submenu_name}" + num="`basename $s_dir`" - 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 ""` + date=`echo $date | sed 's/\(.*\) \(.*\):.*/\1T\2/'` + important=`xmllint --xpath "/snapshot/userdata[key='important']/value/text()" "${s_dir}/info.xml" 2>/dev/null || echo ""` stype=`xmllint --xpath '/snapshot/type/text()' "${s_dir}/info.xml" || echo ""` - kernel_ver=`readlink /boot/vmlinuz | sed 's/vmlinuz-\([^-]*\).*/\1/'` + kernel_ver=`readlink ${snapshot}/boot/vmlinuz | sed -e 's/^vmlinuz-//' -e 's/-default$//'` + if [ -z "$kernel_ver" -a -L ${snapshot}/boot/image ]; then + kernel_ver=`readlink ${snapshot}/boot/image | sed -e 's/^image-//' -e 's/-default$//'` + fi eval `cat ${snapshot}/etc/os-release` - test "$important" = "yes" && important="*" || important="" + 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)" + test -z "$stype" || stype=",$stype" + desc=`xmllint --xpath '/snapshot/description/text()' "${s_dir}/info.xml" 2>/dev/null || echo ""` + #test "$desc" = "timeline" && return 1 + test -z "$desc" || desc=",$desc" + title="${important}${NAME} $VERSION ($kernel_ver,$date$stype$desc)" + + cat < "${snapper_cfg}.new" - - for x in $cfgs; do - snap="${rel_root}${snapshot}" - snap_cfg="${rel_root}\$x" +EOF + hotkey=`incr_hotkey` + return 0 +} - if [ -f "\$snap_cfg" ]; then - snapshot_found=true - submenu "$title" "\$snap" "\$snap_cfg" { - set subvol="\$2" - export subvol - source "\$3" - } - break +snapper_snapshots_cfg_refresh () { + + if [ ! -d "$snapper_snapshot_path" ]; then + return + fi + + for s_dir in ${snapper_snapshot_path}/*; do + + snapshot="${s_dir}/snapshot" + + # list only read-only snapshot (bnc#878528) + if [ -w "$snapshot" ]; then + continue fi + if [ -r "${s_dir}/info.xml" -a -r "${s_dir}/snapshot/boot/grub2/grub.cfg" ]; then + cs="${s_dir}\n${cs}" + fi + done -EOF - - if grub2-script-check "${snapper_cfg}.new"; then - mv -f "${snapper_cfg}.new" "${snapper_cfg}" - fi + hk="" + [ -z "$hotkey" ] || hk="--hotkey=s" -done + for c in `echo -e "${cs}" | sort -Vr`; do + if ! snapshot_submenu "$c" > "${c}/${snapshot_submenu_name}"; then + rm -f "${c}/${snapshot_submenu_name}" + continue + fi + snapshot_cfg="${snapshot_cfg} + if [ -f "$c/${snapshot_submenu_name}"; then + source "$c/${snapshot_submenu_name}" + 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}" + cat <"${snapper_snapshots_cfg}.new" +if [ -z "\$extra_cmdline" ]; then + submenu $hk "Start bootloader from a read-only snapshot" {${snapshot_cfg} + if [ x\$snapshot_found != xtrue ]; then + submenu "Not Found" { true; } + fi + } fi +EOF + + if ${grub_script_check} "${snapper_snapshots_cfg}.new"; then + mv -f "${snapper_snapshots_cfg}.new" "${snapper_snapshots_cfg}" + fi } snapshot_submenu_clean () { - for s_dir in /.snapshots/*; do + for s_dir in ${snapper_snapshot_path}/*; do - snapshot="${s_dir}/snapshot" snapper_cfg="${s_dir}/${snapshot_submenu_name}" if [ -f "$snapper_cfg" ]; then rm -f "$snapper_cfg" + rmdir "$s_dir" 2>/dev/null || true fi done + + if [ -f "${snapper_snapshot_path}/${snapshot_submenu_name}" ]; then + rm -f "${snapper_snapshot_path}/${snapshot_submenu_name}" + fi + } set_grub_setting () { @@ -137,17 +168,32 @@ set_grub_setting () { val=$2 if grep -q "$name" "$grub_setting"; then - sed -i -e "s/.*\($name\)=.*/\1=$val/" "$grub_setting" + sed -i -e "s!.*\($name\)=.*!\1=\"$val\"!" "$grub_setting" else - echo "$name=$val" >> "$grub_setting" + echo "$name=\"$val\"" >> "$grub_setting" fi } -update_grub_cfg () { - - "$grub_mkconfig" -o "$grub_cfg" +enable_grub_settings () { + set_grub_setting SUSE_BTRFS_SNAPSHOT_BOOTING "true" } +disable_grub_settings () { + set_grub_setting SUSE_BTRFS_SNAPSHOT_BOOTING "false" +} + +update_grub () { + "${grub_mkconfig}" -o "${grub_cfg}" +} + +machine=`uname -m` +case "$machine" in +(s390|s390x) + hotkey=1 + ;; +esac +cmdline="$0 $* hotkey='$hotkey'" + # Check the arguments. while test $# -gt 0 do @@ -173,32 +219,20 @@ do 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 - + #enable_grub_settings + #update_grub + snapper_snapshots_cfg_refresh elif [ "x${opt_enable}" = "xfalse" ]; then - + #disable_grub_settings + update_grub 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 - + snapper_snapshots_cfg_refresh fi if [ x${opt_clean} = "xtrue" ]; then - snapshot_submenu_clean - grub_snapshot_cfg_refresh - fi + diff --git a/grub2.changes b/grub2.changes index b7c7818..e1d046b 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Aug 21 06:10:07 UTC 2014 - mchang@suse.com + +- update snapper plugin for rollback support + * refresh grub2-snapper-plugin.sh + ------------------------------------------------------------------- Fri Aug 15 07:55:54 UTC 2014 - mchang@suse.com