grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
* Proposition for Add-on
@ 2013-12-02  0:11 Michel Benoit
  2013-12-02  0:28 ` SevenBits
  2013-12-02  3:59 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 2 replies; 3+ messages in thread
From: Michel Benoit @ 2013-12-02  0:11 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 2993 bytes --]

Hi!

I’ve d develop an internal command for grub to help the administrators of 
pool of dual boot machine.

The problem: We have class with near 100 computers in dual boot, under 
windows we have a maintenance period in the night to automatically install 
update. For that, in grub we put Windows has the default menu-entry.

The only time the computers are in linux, is when a student is using it. 
It's not a good time to install update. To install update, security patch, 
or other package, i was forced to pass computer by computer.


To get a period for the maintenance in linux, i wrote a simple module for 
grub that select the default menu-entry depending of the time of the day.

ex. :

    I set the period from 4am to 6am with the default boot to linux.
    So i can put a script in the crontab at 4h05 to install the update.
    (you have to put a shutdown -r command in Windows task scheduler at 4.00 
am. And use a wake on lan for computer that are down)

Is it possible to integrate in in the distribution of grub, if you think it 
could help other user.

-------------------------------------------------------------------------------------------------------------------------------------------------------------

The principal module grub-core/commands/select_by_time.c

The configuration file, two option

        the simple version /etc/grub.d/98_select_by_time

                    In 98_select_by_time, you select the period of time and 
the menuentry for that period, you can use many period of time. It use the 
24 hours time format notation without colon.

        ex:

            # from 4 am to 6 am select item 3 as default
            select_by_time 0400 0600 3
            # and from 11h25 pm to midnight select item 5 as default
            select_by_time 2325 2400 5

       or

        the more complete /etc/grub.d/99_select_by_time, that use the config 
file /boot/grub/select_by_time.cfg
        With this version you don't have to know the position of the 
operating system in grub.cfg (menuitem).

        exemple of select_by_time.cfg

            select_default Windows
            select_by_time 5:00 6:00 ubuntu           # maintenance period
            select_by_time 13:00 15:00 ubuntu       # linux course
            select_by_time 19:00 2308 "Linux 3.2.0-23-generic"    # specific

–--------------------------------------------------------------------------------------

Right now, we are using select_by_time with 98_select_by_time, and we save a 
lot of days of work.
If you think it could be helpful for other administrator, could you put it 
in a future grub distribution (the source code is very simple).
The 99_select_by_time is optional, it's just more easy to use.

Thank's

------------------------------------------------------
Michel Benoit (morph1853)
Technicien Systèmes Ordinés
Dep. Informatique
Université de Sherbooke
michel.benoit@usherbrooke.ca

[-- Attachment #2: 98_select_by_time --]
[-- Type: application/octet-stream, Size: 375 bytes --]

#!/bin/sh
exec awk '$1 ~ /select_by_time/ {print $1,$2,$3,$4;}' $0

# select_by_time start_time stop_time menu choice
#
# exemple between 4h00am to 6h00am select the third menu in grub (menuitem start at 0) 
# select_by_time 400 600 2
# Module to select default entry by time

select_by_time 0400 0600 2    # linux maintenance period 
select_by_time 2000 2200 4


[-- Attachment #3: 99_select_by_time --]
[-- Type: application/octet-stream, Size: 6557 bytes --]

#!/bin/sh
# Module to select default entry by time


# Validation and Transformation of the time format
decript () { 
	# remove : h  AM  PM
        value=` echo $1 | tr -d '[:a-zA-Z]'`
           pm=` echo $1 | tr '[:upper:]' '[:lower:]' | tr -d '[:h0-9]' `	
	
	# data format validation  
	to_validate=` echo $1 | tr  '[:upper:]' '[:lower:]' `
 	case "$to_validate" in				# valide format
			           [0-9][0-5][0-9]) ;; 	#   700
		 	      [0,1][0-9][0-5][0-9]) ;;	#  1700
		 	        [2][0-4][0-5][0-9]) ;;	#  1700
			       [0-9][h:][0-5][0-9]) ;;	#  7:00  7h00
			  [0,1][0-9][h:][0-5][0-9]) ;; 	# 19:00 19h00
			    [2][0-4][h:][0-5][0-9]) ;; 	# 21:00 22h00
		
			    [0-9][0-5][0-9][a,p]m) ;; 	#   700am
		       [0,1][0-9][0-5][0-9][a,p]m) ;;	#  1700pm
		         [2][0-4][0-5][0-9][a,p]m) ;;	#  2300pm
		        [0-9][h:][0-5][0-9][a,p]m) ;;	#  7:00pm  7h00am
	 	   [0,1][0-9][h:][0-5][0-9][a,p]m) ;; 	# 19:00pm 19h00pm
	 	     [2][0-4][h:][0-5][0-9][a,p]m) ;; 	# 21:00pm 22h00pm

		*)  # echo "Invalide format" >&2
			return 1 
			;;
	esac
	if [ "$pm" = "pm" ]
	then
		if [ "$value" -lt "1200" ] ; then  value=`expr $value + 1200 ` ; fi  
	fi 
	if [ "$value" -gt "2400" ] ; then  return 1 ; fi  #echo not in range, only 24h by day
	echo $value  	# echo OK
        return 0
}

# find choice of menuentry in grub.cfg
# by item number
# or by description (ex.: Ubuntu, Debian, Windows, ... )
find_menu_item ()  {
      if [ ! -z "$1" ] ; then
                validate=` echo $1 | sed  's/[^0-9]*//g' `
                if [ "$1" = "$validate" ]  ; then
                        # the choice is a number
                        if [ $1 -gt $last_menu ]  ; then return 1 ; fi
                        choice=$1
                else
                        # the choice in alphanumeric, patch choice beginning by -
                        search=`echo $1 |  sed "s/^-/\\\\\-/"  `
                        choice=`egrep  "^menuentry" $GRUB_PREFIX/$MENU_FILE_CONVERT | nl -v0 -w1 -s\: | egrep -m1 -i "$search" | cut -d\:  -f1 `
                        # text selected not in menuentrys
                        if [ "$choice" = "" ]  ; then return 1 ; fi
                fi
                echo $choice    # first entry corresponding
		return 0
      fi
}

select_by_time ()  { 

	if [ $# != 3 ] ; then 
	  echo "select_by_time  $* : syntaxe error " >&2  
	  echo "    Select_by_time  start_time end_time menu_choice " >&2  
	  return
	fi
	start_time=`decript "$1" `
	if [ $? = 1 ] ; then echo "Select_by_time $* \t: Invalid format $1 " >&2 ; return ; fi 
	stop_time=`decript "$2" `
	if [ $? = 1 ] ; then echo "Select_by_time $* \t: Invalid format $2 " >&2 ; return ; fi 
	menu_item=`find_menu_item "$3" `
	if [ $? = 1 ] ; then echo "Select_by_time $* \t: $3 not available " >&2 ; return ; fi 

	if [ $start_time -ge $stop_time ] ; then echo "Select_by_time $* \t: Stop time is before start time " >&2 ; return ; fi
 
	echo  select_by_time $start_time $stop_time $menu_item
}


select_default ()  { 

	if [ $# != 1 ] ; then 
	  echo "select_default  $* : syntaxe error " >&2  
	  echo "    select_default  menu_choice " >&2  
	  return
	fi
	menu_item=`find_menu_item "$1" `
	if [ $? = 1 ] ; then return ; fi 
	echo  default=$menu_item
}

# extract menuentry from grub.cfg.new, taking care of "previous version" item
convert_grub_cfg ()  {
	if [ -f  $GRUB_PREFIX/$MENU_FILE_CONVERT ] ; then rm -f  $GRUB_PREFIX/$MENU_FILE_CONVERT ; fi 
        menu_count=0
        bracket_count=0
        sed "s/[{}]/\n&\n/" "$GRUB_PREFIX/$MENU_FILE" | egrep "}|{|menuentry|submenu"  | while read line 
        do
                bcount_open=`echo $line |  grep -o '{' | wc -w`
                bcount_close=`echo $line |  grep -o '}' | wc -w`
                bracket_count=` expr $bracket_count + $bcount_open - $bcount_close `
                tmp=`echo $line | egrep -ic "^menuentry"`
                if [ $? = 0 ] ; then
                        if [ $bracket_count = 0 ] ; then
                                sub_count=0
                                echo "$line" >> $GRUB_PREFIX/$MENU_FILE_CONVERT
                        else
                          if [ $bracket_count = 1 ] ; then  # inside a submenu
                                if  [ $sub_count = 0 ] ; then
                                        sub_count=1
                                        echo "$line"  >> $GRUB_PREFIX/$MENU_FILE_CONVERT
                                fi
                          fi
                        fi
                fi
        done
}


# main()

MENU_FILE="grub.cfg.new"
MENU_FILE_CONVERT="select_by_time_menu_grub"
USER_CHOICE="select_by_time.cfg"
if [ ! -e "$GRUB_PREFIX/$MENU_FILE" ] ; then  DEBUG=1 ; fi
if [ $DEBUG ] ; then 
	# set -x	
	GRUB_PREFIX=/boot/grub
	MENU_FILE=grub.cfg
fi
convert_grub_cfg     # extract menuentry from grub.cfg.new, taking care of "previous version" item

last_menu=`egrep  "^menuentry" $GRUB_PREFIX/$MENU_FILE_CONVERT | nl -v0 -w1 -s\: |tail -1 |cut -d\: -f1`
if [ "$last_menu" = "" ] ; then return; fi # file not containing menuentry

if [ -f "$GRUB_PREFIX/$USER_CHOICE" ] ; then
   # traitement
   # read user file

        egrep -i  "select_by_time|select_default" "$GRUB_PREFIX/$USER_CHOICE" | awk -F"#" '{print $1}' | tr '[:upper:]' '[:lower:]'  | while read line
        do
		command=`echo $line | awk -F" " '{print $1}'`
		argument=`echo $line | awk -F" " '{$1=""; print }'`
		eval set -- "$argument"
		if [ "$command" = "select_by_time" ] ; then select_by_time "$@" ; fi
		if [ "$command" = "select_default" ] ; then select_default "$@" ; fi 
	done
fi 

###################################################
# Clean temporary file
###################################################
if [ -f  $GRUB_PREFIX/$MENU_FILE_CONVERT ] ; then rm -f  $GRUB_PREFIX/$MENU_FILE_CONVERT ; fi 


###########################################################################################################
# time selection in /boot/grub/select_by_time.cfg
###########################################################################################################
# select_default must be before select_by_time
# exemple
# select_default Windows
# select_by_time 5:00 6:00 ubuntu	     # maintenance period
# select_by_time 13:00 15:00 ubuntu	     # linux course
# select_by_time 19:00 2308 "Linux 3.2.0-23-generic"   # specific 
# select_by_time  19:00 2302 "recovery mode" 





[-- Attachment #4: select_by_time.c --]
[-- Type: application/octet-stream, Size: 1972 bytes --]

/* select_by_time.c - command to choice menu item depanding of the time of the day.  */
/*
 * idea of: Michel.benoit@USherbrooke.ca (morph1853)
 */

#include <grub/dl.h>
#include <grub/err.h>
#include <grub/datetime.h>
#include <grub/command.h>
#include <grub/env.h>

GRUB_MOD_LICENSE ("GPLv3+");

static grub_err_t
grub_cmd_select_by_time (grub_command_t cmd __attribute__ ((unused)),
               int argc, char **args)
{
  struct grub_datetime datetime;

  if (argc != 3)
    {
	grub_printf (" Select default boot by time of the day \n");
	grub_printf (" usage: select_by_time hhmm HHMM number_of_menuitem \n");
	grub_printf (" between the time hhmm and HHMM use number_of_menuitem as default choice \n");
	
      return 0;
    }

  char *s;
  int  start_time, stop_time,  current_time ;
  if (grub_get_datetime (&datetime))
        return grub_errno;
  current_time= (datetime.hour * 100) + datetime.minute;
 
  /* convert argument, and validate that they contain only number, arg0 -> start_time, arg1 -> stop_time, arg2 -> menu choice */  
  start_time = grub_strtoul (args[0], &s, 10);
  if ( grub_errno != 0 || *s)
	return grub_error (GRUB_ERR_BAD_ARGUMENT, "start time invalid format"); 

  stop_time = grub_strtoul (args[1], &s, 10);
  if ( grub_errno != 0 || *s)
	return grub_error (GRUB_ERR_BAD_ARGUMENT, "stop time invalid format"); 

  grub_strtoul (args[2], &s, 10);
  if ( grub_errno != 0 || *s)
	return grub_error (GRUB_ERR_BAD_ARGUMENT, "menu choice not valid"); 
	
  if ((current_time >= start_time) && (current_time <= stop_time))
	grub_env_set ("default",args[2]);
  return 0;
}

static grub_command_t cmd;

GRUB_MOD_INIT(select_by_time)
{
  cmd =
    grub_register_command ("select_by_time", grub_cmd_select_by_time,
			   N_("hourminute  hourminute menuitem"),
			   N_("Set the default menu item by time."));
}

GRUB_MOD_FINI(select_by_time)
{
  grub_unregister_command (cmd);
}


[-- Attachment #5: select_by_time.cfg --]
[-- Type: application/octet-stream, Size: 590 bytes --]

###########################################################################################################
# select_by_time.cfg: time selection 
###########################################################################################################
# select_default must be before select_by_time
#
# exemple
# select_default Windows
# select_by_time 5:00 6:00 ubuntu            # maintenance period
# select_by_time 13:00 15:00 ubuntu          # linux course
# select_by_time 19:00 2308 "Linux 3.2.0-23-generic"   # specific 
# select_by_time  19:00 2302 "recovery mode" 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Proposition for Add-on
  2013-12-02  0:11 Proposition for Add-on Michel Benoit
@ 2013-12-02  0:28 ` SevenBits
  2013-12-02  3:59 ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 0 replies; 3+ messages in thread
From: SevenBits @ 2013-12-02  0:28 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 3717 bytes --]

The way things like this are usually done on mailing lists like this one
are that you post a patch file containing the changes that you have made to
the entire project, not simply the source file you want included. There are
special commands for this, which you can find on the Internet. You also
typically put the patch in the body of your message without formatting.

One of the head people on the project will then review it and see if it's
worth including. I'm new here myself, but it's important to learn the
proper way to do things.

-- SevenBits

On Sunday, December 1, 2013, Michel Benoit wrote:

> Hi!
>
> I’ve d develop an internal command for grub to help the administrators of
> pool of dual boot machine.
>
> The problem: We have class with near 100 computers in dual boot, under
> windows we have a maintenance period in the night to automatically install
> update. For that, in grub we put Windows has the default menu-entry.
>
> The only time the computers are in linux, is when a student is using it.
> It's not a good time to install update. To install update, security patch,
> or other package, i was forced to pass computer by computer.
>
>
> To get a period for the maintenance in linux, i wrote a simple module for
> grub that select the default menu-entry depending of the time of the day.
>
> ex. :
>
>    I set the period from 4am to 6am with the default boot to linux.
>    So i can put a script in the crontab at 4h05 to install the update.
>    (you have to put a shutdown -r command in Windows task scheduler at
> 4.00 am. And use a wake on lan for computer that are down)
>
> Is it possible to integrate in in the distribution of grub, if you think
> it could help other user.
>
> ------------------------------------------------------------
> ------------------------------------------------------------
> -------------------------------------
>
> The principal module grub-core/commands/select_by_time.c
>
> The configuration file, two option
>
>        the simple version /etc/grub.d/98_select_by_time
>
>                    In 98_select_by_time, you select the period of time and
> the menuentry for that period, you can use many period of time. It use the
> 24 hours time format notation without colon.
>
>        ex:
>
>            # from 4 am to 6 am select item 3 as default
>            select_by_time 0400 0600 3
>            # and from 11h25 pm to midnight select item 5 as default
>            select_by_time 2325 2400 5
>
>       or
>
>        the more complete /etc/grub.d/99_select_by_time, that use the
> config file /boot/grub/select_by_time.cfg
>        With this version you don't have to know the position of the
> operating system in grub.cfg (menuitem).
>
>        exemple of select_by_time.cfg
>
>            select_default Windows
>            select_by_time 5:00 6:00 ubuntu           # maintenance period
>            select_by_time 13:00 15:00 ubuntu       # linux course
>            select_by_time 19:00 2308 "Linux 3.2.0-23-generic"    # specific
>
> –-----------------------------------------------------------
> ---------------------------
>
> Right now, we are using select_by_time with 98_select_by_time, and we save
> a lot of days of work.
> If you think it could be helpful for other administrator, could you put it
> in a future grub distribution (the source code is very simple).
> The 99_select_by_time is optional, it's just more easy to use.
>
> Thank's
>
> ------------------------------------------------------
> Michel Benoit (morph1853)
> Technicien Systèmes Ordinés
> Dep. Informatique
> Université de Sherbooke
> michel.benoit@usherbrooke.ca
>

[-- Attachment #2: Type: text/html, Size: 4080 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Proposition for Add-on
  2013-12-02  0:11 Proposition for Add-on Michel Benoit
  2013-12-02  0:28 ` SevenBits
@ 2013-12-02  3:59 ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 0 replies; 3+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-12-02  3:59 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 3490 bytes --]

On 02.12.2013 01:11, Michel Benoit wrote:
> Hi!
> 
> I’ve d develop an internal command for grub to help the administrators
> of pool of dual boot machine.
> 
> The problem: We have class with near 100 computers in dual boot, under
> windows we have a maintenance period in the night to automatically
> install update. For that, in grub we put Windows has the default
> menu-entry.
> 
> The only time the computers are in linux, is when a student is using it.
> It's not a good time to install update. To install update, security
> patch, or other package, i was forced to pass computer by computer.
> 
No neede to write a module for this. Just do:
insmod datehook
if [ $HOUR -ge 4 -a $HOUR -lt 6 ]; then
  default=linux
else
  default=windows
fi
> 
> To get a period for the maintenance in linux, i wrote a simple module
> for grub that select the default menu-entry depending of the time of the
> day.
> 
> ex. :
> 
>    I set the period from 4am to 6am with the default boot to linux.
>    So i can put a script in the crontab at 4h05 to install the update.
>    (you have to put a shutdown -r command in Windows task scheduler at
> 4.00 am. And use a wake on lan for computer that are down)
> 
> Is it possible to integrate in in the distribution of grub, if you think
> it could help other user.
> 
> -------------------------------------------------------------------------------------------------------------------------------------------------------------
> 
> 
> The principal module grub-core/commands/select_by_time.c
> 
> The configuration file, two option
> 
>        the simple version /etc/grub.d/98_select_by_time
> 
>                    In 98_select_by_time, you select the period of time
> and the menuentry for that period, you can use many period of time. It
> use the 24 hours time format notation without colon.
> 
>        ex:
> 
>            # from 4 am to 6 am select item 3 as default
>            select_by_time 0400 0600 3
>            # and from 11h25 pm to midnight select item 5 as default
>            select_by_time 2325 2400 5
> 
>       or
> 
>        the more complete /etc/grub.d/99_select_by_time, that use the
> config file /boot/grub/select_by_time.cfg
>        With this version you don't have to know the position of the
> operating system in grub.cfg (menuitem).
> 
>        exemple of select_by_time.cfg
> 
>            select_default Windows
>            select_by_time 5:00 6:00 ubuntu           # maintenance period
>            select_by_time 13:00 15:00 ubuntu       # linux course
>            select_by_time 19:00 2308 "Linux 3.2.0-23-generic"    # specific
> 
> –--------------------------------------------------------------------------------------
> 
> 
> Right now, we are using select_by_time with 98_select_by_time, and we
> save a lot of days of work.
> If you think it could be helpful for other administrator, could you put
> it in a future grub distribution (the source code is very simple).
> The 99_select_by_time is optional, it's just more easy to use.
> 
> Thank's
> 
> ------------------------------------------------------
> Michel Benoit (morph1853)
> Technicien Systèmes Ordinés
> Dep. Informatique
> Université de Sherbooke
> michel.benoit@usherbrooke.ca
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 291 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-12-02  3:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-02  0:11 Proposition for Add-on Michel Benoit
2013-12-02  0:28 ` SevenBits
2013-12-02  3:59 ` Vladimir 'φ-coder/phcoder' Serbinenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).