WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 5 of 5] pygrub: add basic support for parsing grub2 s

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 5 of 5] pygrub: add basic support for parsing grub2 style grub.cfg file
From: ian.campbell@xxxxxxxxxx
Date: Sun, 22 Nov 2009 19:15:03 -0000
Delivery-date: Sun, 22 Nov 2009 11:19:35 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1258917298@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1258917298@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.3.1
# HG changeset patch
# User Ian Campbell <ijc@xxxxxxxxxxxxxx>
# Date 1258917181 0
# Node ID 870c7bbe259b5fb9dea78ee009d242e5ff006d9e
# Parent  69d318d58ed3e4266bfb76f514d90b69270aed9a
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>

diff -r 69d318d58ed3 -r 870c7bbe259b tools/pygrub/src/GrubConf.py
--- a/tools/pygrub/src/GrubConf.py      Sun Nov 22 19:13:01 2009 +0000
+++ b/tools/pygrub/src/GrubConf.py      Sun Nov 22 19:13:01 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 @@
         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 69d318d58ed3 -r 870c7bbe259b tools/pygrub/src/pygrub
--- a/tools/pygrub/src/pygrub   Sun Nov 22 19:13:01 2009 +0000
+++ b/tools/pygrub/src/pygrub   Sun Nov 22 19:13:01 2009 +0000
@@ -381,7 +381,9 @@
         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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel