# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1258963614 0
# Node ID c8caa281a75ab3ff4a246d357ad83e4959b8489e
# Parent 6e32b7a3e80202ed6c4d09a1211e14c786cb3731
pygrub: add basic support for parsing grub2 style grub.cfg file
This represents a very simplistic aproach to parsing these file. It
is basically sufficient to parse the files produced by Debian
Squeeze's version of update-grub. The actual grub.cfg syntax is much
more expresive but not apparently documented apart from a few
examples...
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
tools/pygrub/src/GrubConf.py | 123 +++++++++++++++++++++++++++++++++++++++++--
tools/pygrub/src/pygrub | 4 +
2 files changed, 123 insertions(+), 4 deletions(-)
diff -r 6e32b7a3e802 -r c8caa281a75a tools/pygrub/src/GrubConf.py
--- a/tools/pygrub/src/GrubConf.py Mon Nov 23 08:06:19 2009 +0000
+++ b/tools/pygrub/src/GrubConf.py Mon Nov 23 08:06:54 2009 +0000
@@ -14,6 +14,7 @@
import os, sys
import logging
+import re
def grub_split(s, maxsplit = -1):
eq = s.find('=')
@@ -298,9 +299,125 @@ class GrubConfigFile(_GrubConfigFile):
if self.hasPassword():
self.setPasswordAccess(False)
+class Grub2Image(_GrubImage):
+ def __init__(self, title, lines):
+ _GrubImage.__init__(self, title, lines)
+
+ def set_from_line(self, line, replace = None):
+ (com, arg) = grub_exact_split(line, 2)
+
+ if com == "set":
+ (com,arg) = grub_split(arg,2)
+ com="set:" + com
+
+ if self.commands.has_key(com):
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], arg.strip())
+ else:
+ logging.info("Ignored image directive %s" %(com,))
+ else:
+ logging.warning("Unknown image directive %s" %(com,))
+
+ # now put the line in the list of lines
+ if replace is None:
+ self.lines.append(line)
+ else:
+ self.lines.pop(replace)
+ self.lines.insert(replace, line)
+
+ commands = {'set:root': 'root',
+ 'linux': 'kernel',
+ 'initrd': 'initrd',
+ 'insmod': None,
+ 'search': None}
+
+class Grub2ConfigFile(_GrubConfigFile):
+ def __init__(self, fn = None):
+ _GrubConfigFile.__init__(self, fn)
+
+ def parse(self, buf = None):
+ if buf is None:
+ if self.filename is None:
+ raise ValueError, "No config file defined to parse!"
+
+ f = open(self.filename, 'r')
+ lines = f.readlines()
+ f.close()
+ else:
+ lines = buf.split("\n")
+
+ img = None
+ title = ""
+ for l in lines:
+ l = l.strip()
+ # skip blank lines
+ if len(l) == 0:
+ continue
+ # skip comments
+ if l.startswith('#'):
+ continue
+ # new image
+ title_match = re.match('^menuentry "(.*)" {', l)
+ if title_match:
+ if img is not None:
+ raise RuntimeError, "syntax error 1 %d %s" % (len(img),img)
+ img = []
+ title = title_match.group(1)
+ continue
+
+ if l.startswith("}"):
+ if img is None:
+ raise RuntimeError, "syntax error 2 %d %s" % (len(img),img)
+
+ self.add_image(Grub2Image(title, img))
+ img = None
+ continue
+
+ if img is not None:
+ img.append(l)
+ continue
+
+ (com, arg) = grub_exact_split(l, 2)
+
+ if com == "set":
+ (com,arg) = grub_split(arg,2)
+ com="set:" + com
+
+ if self.commands.has_key(com):
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], arg.strip())
+ else:
+ logging.info("Ignored directive %s" %(com,))
+ else:
+ logging.warning("Unknown directive %s" %(com,))
+
+ if img is not None:
+ raise RuntimeError, "syntax error 3 %d %s" % (len(img),img)
+
+ if self.hasPassword():
+ self.setPasswordAccess(False)
+
+ commands = {'set:default': 'default',
+ 'set:root': 'root',
+ 'set:timeout': 'timeout',
+ 'set:gfxmode': None,
+ 'set:menu_color_normal': None,
+ 'set:menu_color_highlight': None,
+ 'terminal': None,
+ 'insmod': None,
+ 'search': None,
+ 'if': None,
+ 'fi': None,
+ }
+
if __name__ == "__main__":
- if sys.argv < 2:
- raise RuntimeError, "Need a grub.conf to read"
- g = GrubConfigFile(sys.argv[1])
+ if sys.argv < 3:
+ raise RuntimeError, "Need a grub version (\"grub\" or \"grub2\") and a
grub.conf or grub.cfg to read"
+ if sys.argv[1] == "grub":
+ g = GrubConfigFile(sys.argv[2])
+ elif sys.argv[1] == "grub2":
+ g = Grub2ConfigFile(sys.argv[2])
+ else:
+ raise RuntimeError, "Unknown config type %s" % sys.argv[1]
for i in g.images:
print i #, i.title, i.root, i.kernel, i.args, i.initrd
diff -r 6e32b7a3e802 -r c8caa281a75a tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub Mon Nov 23 08:06:19 2009 +0000
+++ b/tools/pygrub/src/pygrub Mon Nov 23 08:06:54 2009 +0000
@@ -381,7 +381,9 @@ class Grub:
else:
cfg_list = map(lambda x: (x,grub.GrubConf.GrubConfigFile),
["/boot/grub/menu.lst", "/boot/grub/grub.conf",
- "/grub/menu.lst", "/grub/grub.conf"])
+ "/grub/menu.lst", "/grub/grub.conf"]) + \
+ map(lambda x: (x,grub.GrubConf.Grub2ConfigFile),
+ ["/boot/grub/grub.cfg"])
if not fs:
# set the config file and parse it
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|