aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pygrub
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-11-23 08:06:54 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-11-23 08:06:54 +0000
commit57bc0df07cfae0c6ab0c4e1ca41469eb5fa3a460 (patch)
tree53d51da3ed4c59ca3afc169551b8235b54170abd /tools/pygrub
parentccc76c47dec5d7ea50cdeb153b4d60b4d7cbbc29 (diff)
downloadxen-57bc0df07cfae0c6ab0c4e1ca41469eb5fa3a460.tar.gz
xen-57bc0df07cfae0c6ab0c4e1ca41469eb5fa3a460.tar.bz2
xen-57bc0df07cfae0c6ab0c4e1ca41469eb5fa3a460.zip
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@citrix.com>
Diffstat (limited to 'tools/pygrub')
-rw-r--r--tools/pygrub/src/GrubConf.py123
-rw-r--r--tools/pygrub/src/pygrub4
2 files changed, 123 insertions, 4 deletions
diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py
index a36951ed2d..074f3a2155 100644
--- a/tools/pygrub/src/GrubConf.py
+++ b/tools/pygrub/src/GrubConf.py
@@ -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 --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
index b4b2e1023a..d77fee77d1 100644
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -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