From 51a9dce9de3ea159011928e2db8541f3c7e8383a Mon Sep 17 00:00:00 2001 From: Michael Young Date: Thu, 15 Aug 2019 19:55:30 +0100 Subject: [PATCH] read grubenv and set default from saved_entry or next_entry This patch looks for a grubenv file in the same directory as the grub.cfg file and includes it at front of the grub.cfg file when passed to parse() As the grubenv file consists of variable=value lines padded by hashes these are treated as commands in parse() where it uses the value of saved_entry or next_entry (if set) to set the default entry if a title matches or is a number. --- tools/pygrub/src/GrubConf.py | 11 +++++++++++ tools/pygrub/src/pygrub | 13 ++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py index 594139bac7..22e0948da2 100644 --- a/tools/pygrub/src/GrubConf.py +++ b/tools/pygrub/src/GrubConf.py @@ -383,6 +383,8 @@ class Grub2ConfigFile(_GrubConfigFile): img = None title = "" menu_level=0 + img_count=0 + default_title="" for l in lines: l = l.strip() # skip blank lines @@ -408,6 +410,9 @@ class Grub2ConfigFile(_GrubConfigFile): raise RuntimeError("syntax error: cannot nest menuentry (%d %s)" % (len(img),img)) img = [] title = title_match.group(1) + if title == default_title: + setattr(self, 'default', img_count) + img_count += 1 continue if l.startswith("submenu"): @@ -432,6 +437,10 @@ class Grub2ConfigFile(_GrubConfigFile): (com, arg) = grub_exact_split(l, 2) + if com == "saved_entry" or com == "next_entry": + default_title = arg + continue + if com == "set": (com,arg) = grub2_handle_set(arg) @@ -449,6 +458,8 @@ class Grub2ConfigFile(_GrubConfigFile): else: logging.warning("Unknown directive %s" %(com,)) + if default_title.isdigit(): + setattr(self, 'default', default_title) if img is not None: raise RuntimeError("syntax error: end of file with open menuentry(%d %s)" % (len(img),img)) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index ce7ab0eb8c..267788795b 100755 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -454,8 +454,19 @@ class Grub: if self.__dict__.get('cf', None) is None: raise RuntimeError("couldn't find bootloader config file in the image provided.") f = fs.open_file(self.cf.filename) + fenv = self.cf.filename.replace("grub.cfg","grubenv") + if fenv != self.cf.filename and fs.file_exists(fenv): + # if grubenv file exists next to grub.cfg prepend it + fenvf = fs.open_file(fenv) + if sys.version_info[0] < 3: + fsep = "\n" + else: + fsep = b"\n" + buf = fsep.join((fenvf.read(FS_READ_MAX),f.read(FS_READ_MAX))) + del fenvf # limit read size to avoid pathological cases - buf = f.read(FS_READ_MAX) + else: + buf = f.read(FS_READ_MAX) del f if sys.version_info[0] < 3: self.cf.parse(buf) -- 2.21.0