There has been some discussion recently on IRC about how to implement dynamic menu generation in grub-script, and I think the discussion is worth moving to the mailing list as whatever option we choose we will be stuck supporting for a long time to come.
Dynamic menu generation basically means that "menuentry" will become a true command that can be executed from loops / conditional statements and that the resulting menu entry can be different depending on different circumstances. For instance, you could detect all GNU/Linux installations on a computer at boot and generate menu entries for every kernel image found, passing the detected UUID for the root= statement in the kernel parameters (see osdetect.cfg from bvk's osdetect bzr branch which does this as well as detecting other OSs). Two main options for the syntax of the menuentry command have been fleshed out so far: 1. In the first, menu entries act very similar to functions, passing variables like the kernel image path via positional parameters ( $1 being the title of the menu entry ). As an example, here is how you could generate a menu for choosing among detected grub2 installations with this syntax: for core in (*)/boot/grub/core.img; do # Extract just the device portion from the path to the core.img regexp -s device '^(\(.-\))' $core menuentry "Load $core" $device $core { device=$2 core=$3 root=$device multiboot $core } done An example menu entry created by this code would be titled "Load (hd0,1)/boot/grub/core.img" and if you pressed 'e' to view the source you would see: +--------------------------------------------------------------------------+ | setparams "Load (hd0,1)/boot/grub/core.img" (hd0,1) (hd0,1)/boot/grub c\ | | ore.img | | | | device=$2 | | core=$3 | | | | root=$device | | multiboot $core | | | | | | | +--------------------------------------------------------------------------+ This is basically implemented right now. 2. The other option would be to pass the source of the menu entry as a regular string, using normal shell syntax to construct this string. An implementation of the same example would be: for core in (*)/boot/grub/core.img; do # Extract just the device portion from the path to the core.img regexp -s device '^(\(.-\))' $core menuentry "Load $core" --source " root=$device multiboot $core " done And the resulting menu entry would show up in grub's menu entry editor as: +--------------------------------------------------------------------------+ | root=(hd0,1) | | multiboot (hd0,1)/boot/grub/core.img | | | | | | | | | | | | | | | | | | | +--------------------------------------------------------------------------+ Points in favor of option one: * With option one syntax can be checked ahead of time. If grub-script-check finds no syntax errors in the grub.cfg then there will be no syntax errors in the generated menu entries. As any string can be generated at runtime and passed via option two, this type of checking is not possible. * Option one follows common pattern of passing variables via positional parameters, familiar to anyone who has used functions in *NIX shells. * Option one requires no additional escaping. With option two we open ourselves to the escaping problems seen with grub-mkconfig, for instance http://lists.gnu.org/archive/html/grub-devel/2010-04/msg00090.html * Option one doesn't treat dynamic menu entry generation as a special case (with no extra parameters after the title, you are back to exactly the same syntax currently used for static entries). Points in favor of option two: * This is subjective, but I find the syntax of option one hard to read, both in the grub.cfg and in the menu entries that it creates when viewed in grub's menu entry editor. * Option one only allows for "templates" of menu entries, where the source is basically always the same, but acts differently depending on positional parameters. I have created a script with grub's lua support which parses a grub legacy menu.lst file by building the source of each menu entry line by line, replacing grub legacy commands with their grub2 equivalents. I don't think that such a script would be possible to create with this grub-script syntax (but would with option two). While I only mentioned the two options that were discussed on IRC, I am sure there are other solutions to be brought to this discussion. -- Jordan Uggla (Jordan_U on irc.freenode.net) _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel