aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pygrub
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-02-01 14:03:47 +0000
committerKeir Fraser <keir.fraser@citrix.com>2010-02-01 14:03:47 +0000
commitc11179ee21c5b934f401039985ad6573b72f92e7 (patch)
tree4705397c7c62ff2b16d785c3c55a1ad654d54e99 /tools/pygrub
parent62e1b8798b3dbc07e466bc6318131a2b3443b95b (diff)
downloadxen-c11179ee21c5b934f401039985ad6573b72f92e7.tar.gz
xen-c11179ee21c5b934f401039985ad6573b72f92e7.tar.bz2
xen-c11179ee21c5b934f401039985ad6573b72f92e7.zip
pygrub: support parsing of syslinux configuration files
Allows booting from ISOs which use isolinux as well as guests using extlinux. Also add copyright header to GrubConf.py, I think the grub2 support added last year qualifies as a substantial change. Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools/pygrub')
-rw-r--r--tools/pygrub/src/ExtLinuxConf.py200
-rw-r--r--tools/pygrub/src/GrubConf.py1
-rw-r--r--tools/pygrub/src/pygrub6
3 files changed, 206 insertions, 1 deletions
diff --git a/tools/pygrub/src/ExtLinuxConf.py b/tools/pygrub/src/ExtLinuxConf.py
new file mode 100644
index 0000000000..99f0990a90
--- /dev/null
+++ b/tools/pygrub/src/ExtLinuxConf.py
@@ -0,0 +1,200 @@
+#
+# ExtLinuxConf.py - Simple syslinux config parsing
+#
+# Copyright 2010 Citrix Systems Ltd.
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+import sys, re, os
+import logging
+import GrubConf
+
+class ExtLinuxImage(object):
+ def __init__(self, lines, path):
+ self.reset(lines, path)
+
+ def __repr__(self):
+ return ("title: %s\n"
+ " root: %s\n"
+ " kernel: %s\n"
+ " args: %s\n"
+ " initrd: %s\n" %(self.title, self.root, self.kernel,
+ self.args, self.initrd))
+ def reset(self, lines, path):
+ self._initrd = self._kernel = self._readonly = None
+ self._args = ""
+ self.title = ""
+ self.lines = []
+ self.path = path
+ self.root = ""
+ map(self.set_from_line, lines)
+
+ def set_from_line(self, line, replace = None):
+ (com, arg) = GrubConf.grub_exact_split(line, 2)
+ com = com.lower()
+
+ # Special handling for mboot.c32
+ if com.lower() == "append" and self.kernel is not None:
+ (_,kernel) = self.kernel
+ if kernel.endswith("mboot.c32"):
+ kernel = None
+ args = None
+ initrd = None
+ modules = arg.split("---")
+
+ if len(modules) == 3: # Assume Xen + Kernel + Initrd
+ (_,kernel,initrd) = modules
+ elif len(modules) == 2: # Assume Kernel + Initrd
+ (kernel,initrd) = modules
+
+ if kernel:
+ setattr(self, "kernel", kernel.strip())
+ if initrd:
+ setattr(self, "initrd", initrd.strip())
+
+ # Bypass regular self.commands handling
+ com = None
+
+ if com is not None and self.commands.has_key(com):
+ if self.commands[com] is not None:
+ setattr(self, self.commands[com], re.sub('^"(.+)"$', r"\1", arg.strip()))
+ else:
+ logging.info("Ignored image directive %s" %(com,))
+ elif com is not None:
+ 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)
+
+ def set_kernel(self, val):
+ if val.find(" ") == -1:
+ self._kernel = (None,val)
+ self._args = None
+ return
+ (kernel, args) = val.split(None, 1)
+ self._kernel = (None,kernel)
+ self._args = args
+ def get_kernel(self):
+ return self._kernel
+ def get_args(self):
+ return self._args
+ kernel = property(get_kernel, set_kernel)
+ args = property(get_args)
+
+ def set_initrd(self, val):
+ self._initrd = (None,val)
+ def get_initrd(self):
+ return self._initrd
+ initrd = property(get_initrd, set_initrd)
+
+ def set_readonly(self, val):
+ self._readonly = 1
+ def get_readonly(self):
+ return self._readonly
+ readonly = property(get_readonly, set_readonly)
+
+ # set up command handlers
+ commands = {
+ "label": "title",
+ "kernel": "kernel",
+ "append": "args"}
+
+class ExtLinuxConfigFile(object):
+ def __init__(self, fn = None):
+ self.filename = fn
+ self.images = []
+ self.timeout = -1
+ self._default = 0
+
+ if fn is not None:
+ self.parse()
+
+ 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")
+
+ path = os.path.dirname(self.filename)
+ img = []
+ for l in lines:
+ l = l.strip()
+ # skip blank lines
+ if len(l) == 0:
+ continue
+ # skip comments
+ if l.startswith('#'):
+ continue
+ # new image
+ if l.lower().startswith("label"):
+ if len(img) > 0:
+ self.add_image(ExtLinuxImage(img, path))
+ img = [l]
+ continue
+
+ if len(img) > 0:
+ img.append(l)
+ continue
+
+ (com, arg) = GrubConf.grub_exact_split(l, 2)
+ com = com.lower()
+ 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 len(img) > 0:
+ self.add_image(ExtLinuxImage(img, path))
+
+ def hasPassword(self):
+ return False
+
+ def hasPasswordAccess(self):
+ return True
+
+ def add_image(self, image):
+ self.images.append(image)
+
+ def _get_default(self):
+ for i in range(len(self.images)):
+ if self.images[i].title == self._default:
+ return i
+ return 0
+ def _set_default(self, val):
+ self._default = val
+ default = property(_get_default, _set_default)
+
+ commands = { "default": "default",
+ "timeout": "timeout",
+ "serial": None,
+ "prompt": None,
+ "display": None,
+ "f1": None,
+ "f2": None,
+ }
+
+if __name__ == "__main__":
+ if sys.argv < 2:
+ raise RuntimeError, "Need a configuration file to read"
+ g = ExtLinuxConfigFile(sys.argv[1])
+ for i in g.images:
+ print i
+ print g.default
diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py
index 58a448ca20..60b7f50e66 100644
--- a/tools/pygrub/src/GrubConf.py
+++ b/tools/pygrub/src/GrubConf.py
@@ -1,6 +1,7 @@
#
# GrubConf.py - Simple grub.conf parsing
#
+# Copyright 2009 Citrix Systems Inc.
# Copyright 2005-2006 Red Hat, Inc.
# Jeremy Katz <katzj@redhat.com>
#
diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
index c2870853c2..1b1ed986c3 100644
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -24,6 +24,7 @@ import getopt
import fsimage
import grub.GrubConf
import grub.LiloConf
+import grub.ExtLinuxConf
PYGRUB_VER = 0.6
@@ -383,7 +384,10 @@ class Grub:
["/boot/grub/menu.lst", "/boot/grub/grub.conf",
"/grub/menu.lst", "/grub/grub.conf"]) + \
map(lambda x: (x,grub.GrubConf.Grub2ConfigFile),
- ["/boot/grub/grub.cfg"])
+ ["/boot/grub/grub.cfg"]) + \
+ map(lambda x: (x,grub.ExtLinuxConf.ExtLinuxConfigFile),
+ ["/boot/isolinux/isolinux.cfg",
+ "/boot/extlinux.conf"])
if not fs:
# set the config file and parse it