FastBoot for Grub Legacy Menu us

Go Back
#!/bin/bash

#: Title       : fastboot
#: Date Created: Sun Oct 30 09:42:11 CDT 2011
#: Last Edit   : Sat Mar  3  9:08:11 CDT 2012
#: Author      : James D. McDaniel
#: Version     : 1.40
#: Description : uses kexec to restart kernel
#: Options     : fastboot [#] for grub menu entry to use

TITLE="FastBoot for Grub Legacy Menu using Kexec - Version 1.40"

#
# Written for the openSUSE forums on Saturday March 3, 2012
#

#
# Copy and Paste the text of this script into a text editor and save 
# it as the file fastboot in the folder /usr/local/bin as root.
# in KDE use: kdesu kwrite fastboot & in gnome use: gnomesu gedit fastboot
# This script must be marked executable to be used.  Please run 
# the following Terminal command: sudo chmod +x /usr/local/bin/fastboot
#

#
# This is the standard GPL Statement, leave at the top of the script.
# Just use the command show_gpl after this function for it to be shown.
#
function show_gpl {
  color 7 0 B 
  echo ""
  echo "fastboot is a bash script file written to be used with openSUSE."
  echo "Copyright (C) 2011 by James D. McDaniel, jmcdaniel3@austin.rr.com"
  echo ""
  echo "This program is free software; you can redistribute it and/or modify"
  echo "it under the terms of the GNU General Public License as published by"
  echo "the Free Software Foundation; either version 2 of the License, or"
  echo "(at your option) any later version."
  echo ""
  echo "This program is distributed in the hope that it will be useful,"
  echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
  echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
  echo "GNU General Public License for more details."
  echo ""
  echo "You should have received a copy of the GNU General Public License"
  echo "along with this program; if not, write to the Free Software"
  echo "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"
  echo ""
  color 7 0 N
  return 0 
}

#
# Do you want to see fastboot in color?  ************************************
# The default is true, but can be set to false ********************************
# New Escape Sequences work without a Desktop loaded **************************
#
use_color=true

#
# Color Display Request - color forground background [b/n] ********************
#              Called from more than 10 locations in program
#
# 0:Black  1:Blue  2:Green  3:Cyan  4:Red  5:Magenta  6:Yellow  7:White
#
# Example: color 7 0 B 
#
# where forground is white (7), backgroud is black (0) and text is in bold (B)
#                          $1                      $2                      $3
#
function color {
  if $use_color ; then
    if [[ $3 == [Bb] ]] ; then
      case "$1" in
        "0") echo -ne '\E[1;30m' ;;
        "1") echo -ne '\E[1;34m' ;;
        "2") echo -ne '\E[1;32m' ;;
        "3") echo -ne '\E[1;36m' ;;
        "4") echo -ne '\E[1;31m' ;;
        "5") echo -ne '\E[1;35m' ;;
        "6") echo -ne '\E[1;33m' ;;
        "7") echo -ne '\E[1;37m' ;;
        *) echo -ne '\E[1;37m' ;;
      esac
    else
      case "$1" in
        "0") echo -ne '\E[30m' ;;
        "1") echo -ne '\E[34m' ;;
        "2") echo -ne '\E[32m' ;;
        "3") echo -ne '\E[36m' ;;
        "4") echo -ne '\E[31m' ;;
        "5") echo -ne '\E[35m' ;;
        "6") echo -ne '\E[33m' ;;
        "7") echo -ne '\E[37m' ;;
        *) echo -ne '\E[37m' ;;
      esac
    fi
    case "$2" in
      "0") echo -ne '\E[40m' ;;
      "1") echo -ne '\E[44m' ;;
      "2") echo -ne '\E[42m' ;;
      "3") echo -ne '\E[46m' ;;
      "4") echo -ne '\E[41m' ;;
      "5") echo -ne '\E[45m' ;;
      "6") echo -ne '\E[43m' ;;
      "7") echo -ne '\E[47m' ;;
      *) echo -ne '\E[40m' ;;
    esac
  else
    echo -ne '\E[37;40m' 
  fi
  if [[ $3 == [Nn] ]] ; then
    tput sgr0
  fi
  return 0
}

#
# Produced using figlet *******************************************************
#
function banner {
  color 2 0 B
  cat << "EOFBANNER"
           __           _   _                 _   
          / _| __ _ ___| |_| |__   ___   ___ | |_ 
         | |_ / _` / __| __| '_ \ / _ \ / _ \| __|
         |  _| (_| \__ \ |_| |_) | (_) | (_) | |_ 
         |_|  \__,_|___/\__|_.__/ \___/ \___/ \__|
                             ____  _   _ ____  _____ 
       ___  _ __   ___ _ __ / ___|| | | / ___|| ____|
      / _ \| '_ \ / _ \ '_ \\___ \| | | \___ \|  _|  
     | (_) | |_) |  __/ | | |___) | |_| |___) | |___ 
      \___/| .__/ \___|_| |_|____/ \___/|____/|_____|
           |_|  

EOFBANNER
  color 7 0 B
  return 0
}

#
# fastboot can create a kde desktop icon if you want ***************************
#
fastbootcheck=true
fastbooticon="$HOME/Desktop/fastboot.desktop"

#
# Check/Create fastboot Icon on the kde desktop *******************************
#
function deskicon {

  if $fastbootcheck ; then
    let de=0
    which ps 2>&1 > /dev/null 
    if [ $? -eq 0 ] ; then
      ps nc -C plasma-desktop >/dev/null &&  let de=1
      if [ $de -eq 1 ] ; then
        if [ ! -e $fastbooticon ] ; then
        cat >> "$fastbooticon" << "EOFTEXT"
[Desktop Entry]
Comment[en_US]=
Comment=
Exec=/usr/local/bin/fastboot
GenericName[en_US]=fastboot
GenericName=fastboot
Icon=yast-bootloader
MimeType=
Name[en_US]=fastboot
Name=fastboot
Path=
StartupNotify=true
Terminal=true
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=
X-KDE-SubstituteUID=false
X-KDE-Username=
X-SuSE-translate=true
EOFTEXT
        chmod +x $fastbooticon
        fi
      fi
    fi
  fi
  return 0
}

#
# Set columns & Widths ********************************************************
#
function set_display {
  WIDTH=$(tput cols)
  HEIGHT=$(tput lines)
# Starting Terminal Line Number for menu
  s_line=0
# Starting Terminal Column Number for Menu
  if [ $(($WIDTH)) -le  60  ] ; then
    s_col=0
  else
    s_col=$((($WIDTH - 60) / 2 ))
  fi
  return 0
}

#
# fastboot header display *****************************************************
#
function header {

  dash1="----------------------------------------------------------"
  tput clear
  tput cup $(( s_line )) $(( s_col ))
  color 2 0 B
  echo $dash1  
  color 7 2 B
  tput cup $(( s_line+1 )) $(( s_col ))
  echo " $TITLE "
  color 2 0 B
  tput cup $(( s_line+2 )) $(( s_col ))
  echo $dash1
  color 7 0 B
  echo
  return 0
}

#
# Error display function ******************************************************
#
function input_error {
  header
  color 4 0 B
  message=$1
  len=${#message}
  if [ $len -lt 52 ] ; then
    let len=52-len
    let len=len/2
  else
    len=0
  fi
  tput cup $(( s_line+4 )) $(( s_col+len ))
  echo "Error: $message"
  color 7 0 B
  tput cup $(( s_line+6 )) $(( s_col+13 ))
  echo -n "Press Any Key to Try again ... "
  read something
  color 7 0 N
  exit $2
  return 0
}

#
# Display Actual Kernel Loading command *************************************** 
#
function kernel_command {
  P1=$(echo "$@" | awk '{print $1}')
  P2=$(echo "$@" | awk '{print $2}') ; len2=${#P2} ; P2=${P2:2:len2-2}
  P3=$(echo "$@" | awk '{print $3}') ; len3=${#P3} ; P3=${P3:2:len3-2}
  RC=$(echo "$@" | grep "resume=" )
  if [ "$RC" == "" ] ; then
    let offset2=1
    P5=$(echo "$@" | awk '{for(i=4; i<=NF; i++) {printf("%s ", $i)}}')
  else
    P4=$(echo "$@" | awk '{print $4}') 
    P5=$(echo "$@" | awk '{for(i=5; i<=NF; i++) {printf("%s ", $i)}}')
  fi
  len=${#P1}
  if [ ${#P2} -gt $len ] ; then
    len=${#P2}
  fi
  if [ ${#P3} -gt $len ] ; then
    len=${#P3}
  fi
  if [ ${#P4} -gt $len ] ; then
    len=${#P4}
  fi
  if [ ${#P5} -gt $len ] ; then
    len=${#P5}
  fi
  let len=len+8
  if [ $len -lt $WIDTH ] ; then
    s_col=$((($WIDTH - $len) / 2 ))
  else
    s_col=0
  fi
  return 0
}

#
# fastboot Help Display Function **********************************************
#
function help {
  tput clear
  color 3 0 B 
  cat << EOFHELP

 $TITLE

 fastboot [x [y]] ( Example: fastboot 1 <or> fastboot 1 3 )

 fastboot requires no Startup Options, But if you use them, your choices are:

 fastboot x	 ; Select Kernel to be loaded [1 through max menu entries]
 fastbbot x  y   ; Same as above but adds kernel load option y like a 3
 fastboot -h     ; Shows this help
 fastboot --help ; Shows this help 

EOFHELP

  color 2 0 B
  echo -n " Press <enter> to read the GPL Statement for fastboot "
  read CHOICE
  color 7 0 B
  header
  banner
  show_gpl
  exit 0
  return 0
}

#
# fastboot help request *******************************************************
#
case "$1" in
    -h|--help) help ;;
esac

#
# Check to see if we are root ************************************************
#
if [[ $UID -ne 0 ]]; then
  deskicon
  cont=true
  tput clear
  while $cont ; do
    color 7 0 B 
    id -Gn | grep -q wheel || echo "Root User Permissions are required, Please Enter the ..."
    echo
    sudo $0 $@
    Exit_Code=$?
    if [ $Exit_Code -eq 0 ] ; then
      cont=false
    fi
    if [ $Exit_Code -eq 2 ] ; then
      cont=false
    fi
  done
    header
    banner
    show_gpl
    exit 0
else
  tput clear
fi

#
# Determine if the package kexec-tools is installed ***********************************
#
which /sbin/kexec > /dev/null
Exit_Code=$?
if [ $(( Exit_Code )) -ge 1 ] ; then
  clear
  color 7 4 B
  echo "The kexec-tools Utility Package is not installed!"
  color 7 0 B
  echo
  echo -n "Would you like to install the kexec-tools package(y/N)? "
  read CHOICE
  if [[ $CHOICE == [Yy] ]] ; then
    sudo zypper in kexec-tools
  else
    color 7 4 B
    echo "The kexec-tools Utility Package was not installed!"
    color 7 0 B
    exit 1
  fi
fi

#
# Main Program Starts here ****************************************************
#
unset number
dollar1=$1
set_display

# Use the first parameter or show a menu if none is specified
if [ "$1" != "" ] ; then
  # Make sure the selected number is an integer
  if [[ $1 =~ ^[0-9]+$ ]] ; then
    number=$1
  else
    input_error "The selected parameter $1 is not valid number" 2 
    exit 0
  fi
else

#
# My Replacement Menu starts here *********************************************
#
  size=$(cat /boot/grub/menu.lst | grep -c "title" )
  menu=true
  while $menu ; do
  header
  inc=1
  offset=0
  # Display The Kernel load options
  while [ $inc -le $size ] ; do
    titles[$inc]=$(cat /boot/grub/menu.lst | grep "title"| sed -n $(( inc ))p)
    len=${#titles[$inc]}
    titles[$inc]=${titles[$inc]:6:len-6}
    win=$( echo ${titles[$inc]} | grep -v -i "windows")
    if [ "$win" != "" ] ; then
      tput cup $(( s_line+3+$inc-offset )) $(( s_col ))
      if [ $inc -lt 10 ] ; then
        echo -n "     $inc) "
      else
        echo -n "    $inc) "
      fi
      color 3 0 B
      echo "${titles[$inc]}"
      color 7 0 B
    else
      let offset=offset+1
    fi
    let inc=inc+1
  done

  echo
  echo
  color 7 1 B 
  tput cup $(( s_line+5+$size-offset )) $(( s_col ))
  echo -n "Type the Kernel # to Boot [1-$size] & press <enter> (Q=Quit):" 
  color 7 0 B 
  echo -n " "
  read number

  if [[ $number =~ ^[0-9]+$ ]] ; then
    if [[ $number -le $size ]] && [[ $number -gt 0 ]]; then
      menu=false
    fi
  fi
  if [[ $number == [Qq] ]] ; then
    exit 0
  fi
  done
fi

#
# determine the kernel commands ***********************************************
#
if [ "$2" == "" ] ; then
  options=""
else
  shift
  options="$@"
fi

menu=true
while $menu ; do

  unset kernel
  unset initrd
  unset append
  item=0

# Parse GRUBs menu.lst
  while read key val extra; do
    [[ $key = "title" ]] && ((item++)) # Count the number of title's
    (( item == number )) || continue   # Wait until the right number
    [[ $key = "kernel" ]] && kernel="$val" && append="$extra"
    [[ $key = "initrd" ]] && initrd="$val"
  done < /boot/grub/menu.lst

  [[ $kernel ]] || input_error " No kernel with number $number & Windows can't use Kexec!" 1

# http://stackoverflow.com/questions/2167558/give-the-mount-point-of-a-path
  root="$(df /boot | tail -n 1 | awk '{ print $NF}')"

  set -- "$root$kernel"
  [[ -n "${initrd+set}" ]] && set -- "$@" --initrd="$root$initrd"
  set -- "$@" --append="$append $options"

#
# Show and Confirm Kernel to boot from ****************************************
#
  if [ "$dollar1" == "" ] ; then
    kernel_command "$@"
    header
    tput cup $(( s_line+4 )) $(( s_col ))
    echo "You have selected to boot using Kexec & kernel ..."
    tput cup $(( s_line+6 )) $(( s_col ))
    echo -n "$number) "
    color 3 0 B
    echo "${titles[$number]}"
    color 7 0 B
    tput cup $(( s_line+8 )) $(( s_col ))
    color 6 1 B
    echo "kernel=$P1"
    tput cup $(( s_line+9 )) $(( s_col ))
    echo "$P2"
    tput cup $(( s_line+10 )) $(( s_col ))
    echo "$P3"
    RC=$(echo "$@" | grep "resume=" )
    tput cup $(( s_line+11 )) $(( s_col ))
    if [ "$RC" == "" ] ; then
      echo "options: $P5"
    else
      echo "$P4"
    tput cup $(( s_line+12 )) $(( s_col ))
      echo "options: $P5"
    fi
    tput cup $(( s_line+14-offset2 )) $(( s_col ))
    color 7 1 B
    echo -n "Do you Wish to Continue? (Y/N) or A=Add kernel load option:"
    color 7 0 B
    echo -n " "
    read CHOICE
    echo
    if [[ $CHOICE == [Nn] ]] ; then
      menu=false
      exit 0
    fi
    if [[ $CHOICE == [Qq] ]] ; then
      menu=false
      exit 0
    fi
    if [[ $CHOICE == [Yy] ]] ; then
      menu=false
    fi
    if [[ $CHOICE == [Aa] ]] ; then
      color 7 4 B
      tput cup $(( s_line+16-offset2)) $(( s_col ))
      echo -n "Enter kernel load option to add & press <enter>:"
      color 7 0 B
      echo -n " "
      read options
    fi
  else
    menu=false
  fi
done

kexec "$@"

color 7 4 B
tput cup $(( s_line+17 )) $(( s_col ))
echo "Booting Selected Kernel $number Now in Progress ... "
color 7 0 N

exit 0

# End Of Script
Go Back