debuggers.hg
changeset 20921:d0b431ede24b
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>
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>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Feb 01 14:03:47 2010 +0000 (2010-02-01) |
parents | 5668c36282ea |
children | 4e8ce74fb8bb |
files | tools/pygrub/src/ExtLinuxConf.py tools/pygrub/src/GrubConf.py tools/pygrub/src/pygrub |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/pygrub/src/ExtLinuxConf.py Mon Feb 01 14:03:47 2010 +0000 1.3 @@ -0,0 +1,200 @@ 1.4 +# 1.5 +# ExtLinuxConf.py - Simple syslinux config parsing 1.6 +# 1.7 +# Copyright 2010 Citrix Systems Ltd. 1.8 +# 1.9 +# This software may be freely redistributed under the terms of the GNU 1.10 +# general public license. 1.11 +# 1.12 +# You should have received a copy of the GNU General Public License 1.13 +# along with this program; if not, write to the Free Software 1.14 +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 1.15 +# 1.16 + 1.17 +import sys, re, os 1.18 +import logging 1.19 +import GrubConf 1.20 + 1.21 +class ExtLinuxImage(object): 1.22 + def __init__(self, lines, path): 1.23 + self.reset(lines, path) 1.24 + 1.25 + def __repr__(self): 1.26 + return ("title: %s\n" 1.27 + " root: %s\n" 1.28 + " kernel: %s\n" 1.29 + " args: %s\n" 1.30 + " initrd: %s\n" %(self.title, self.root, self.kernel, 1.31 + self.args, self.initrd)) 1.32 + def reset(self, lines, path): 1.33 + self._initrd = self._kernel = self._readonly = None 1.34 + self._args = "" 1.35 + self.title = "" 1.36 + self.lines = [] 1.37 + self.path = path 1.38 + self.root = "" 1.39 + map(self.set_from_line, lines) 1.40 + 1.41 + def set_from_line(self, line, replace = None): 1.42 + (com, arg) = GrubConf.grub_exact_split(line, 2) 1.43 + com = com.lower() 1.44 + 1.45 + # Special handling for mboot.c32 1.46 + if com.lower() == "append" and self.kernel is not None: 1.47 + (_,kernel) = self.kernel 1.48 + if kernel.endswith("mboot.c32"): 1.49 + kernel = None 1.50 + args = None 1.51 + initrd = None 1.52 + modules = arg.split("---") 1.53 + 1.54 + if len(modules) == 3: # Assume Xen + Kernel + Initrd 1.55 + (_,kernel,initrd) = modules 1.56 + elif len(modules) == 2: # Assume Kernel + Initrd 1.57 + (kernel,initrd) = modules 1.58 + 1.59 + if kernel: 1.60 + setattr(self, "kernel", kernel.strip()) 1.61 + if initrd: 1.62 + setattr(self, "initrd", initrd.strip()) 1.63 + 1.64 + # Bypass regular self.commands handling 1.65 + com = None 1.66 + 1.67 + if com is not None and self.commands.has_key(com): 1.68 + if self.commands[com] is not None: 1.69 + setattr(self, self.commands[com], re.sub('^"(.+)"$', r"\1", arg.strip())) 1.70 + else: 1.71 + logging.info("Ignored image directive %s" %(com,)) 1.72 + elif com is not None: 1.73 + logging.warning("Unknown image directive %s" %(com,)) 1.74 + 1.75 + # now put the line in the list of lines 1.76 + if replace is None: 1.77 + self.lines.append(line) 1.78 + else: 1.79 + self.lines.pop(replace) 1.80 + self.lines.insert(replace, line) 1.81 + 1.82 + def set_kernel(self, val): 1.83 + if val.find(" ") == -1: 1.84 + self._kernel = (None,val) 1.85 + self._args = None 1.86 + return 1.87 + (kernel, args) = val.split(None, 1) 1.88 + self._kernel = (None,kernel) 1.89 + self._args = args 1.90 + def get_kernel(self): 1.91 + return self._kernel 1.92 + def get_args(self): 1.93 + return self._args 1.94 + kernel = property(get_kernel, set_kernel) 1.95 + args = property(get_args) 1.96 + 1.97 + def set_initrd(self, val): 1.98 + self._initrd = (None,val) 1.99 + def get_initrd(self): 1.100 + return self._initrd 1.101 + initrd = property(get_initrd, set_initrd) 1.102 + 1.103 + def set_readonly(self, val): 1.104 + self._readonly = 1 1.105 + def get_readonly(self): 1.106 + return self._readonly 1.107 + readonly = property(get_readonly, set_readonly) 1.108 + 1.109 + # set up command handlers 1.110 + commands = { 1.111 + "label": "title", 1.112 + "kernel": "kernel", 1.113 + "append": "args"} 1.114 + 1.115 +class ExtLinuxConfigFile(object): 1.116 + def __init__(self, fn = None): 1.117 + self.filename = fn 1.118 + self.images = [] 1.119 + self.timeout = -1 1.120 + self._default = 0 1.121 + 1.122 + if fn is not None: 1.123 + self.parse() 1.124 + 1.125 + def parse(self, buf = None): 1.126 + if buf is None: 1.127 + if self.filename is None: 1.128 + raise ValueError, "No config file defined to parse!" 1.129 + 1.130 + f = open(self.filename, 'r') 1.131 + lines = f.readlines() 1.132 + f.close() 1.133 + else: 1.134 + lines = buf.split("\n") 1.135 + 1.136 + path = os.path.dirname(self.filename) 1.137 + img = [] 1.138 + for l in lines: 1.139 + l = l.strip() 1.140 + # skip blank lines 1.141 + if len(l) == 0: 1.142 + continue 1.143 + # skip comments 1.144 + if l.startswith('#'): 1.145 + continue 1.146 + # new image 1.147 + if l.lower().startswith("label"): 1.148 + if len(img) > 0: 1.149 + self.add_image(ExtLinuxImage(img, path)) 1.150 + img = [l] 1.151 + continue 1.152 + 1.153 + if len(img) > 0: 1.154 + img.append(l) 1.155 + continue 1.156 + 1.157 + (com, arg) = GrubConf.grub_exact_split(l, 2) 1.158 + com = com.lower() 1.159 + if self.commands.has_key(com): 1.160 + if self.commands[com] is not None: 1.161 + setattr(self, self.commands[com], arg.strip()) 1.162 + else: 1.163 + logging.info("Ignored directive %s" %(com,)) 1.164 + else: 1.165 + logging.warning("Unknown directive %s" %(com,)) 1.166 + 1.167 + if len(img) > 0: 1.168 + self.add_image(ExtLinuxImage(img, path)) 1.169 + 1.170 + def hasPassword(self): 1.171 + return False 1.172 + 1.173 + def hasPasswordAccess(self): 1.174 + return True 1.175 + 1.176 + def add_image(self, image): 1.177 + self.images.append(image) 1.178 + 1.179 + def _get_default(self): 1.180 + for i in range(len(self.images)): 1.181 + if self.images[i].title == self._default: 1.182 + return i 1.183 + return 0 1.184 + def _set_default(self, val): 1.185 + self._default = val 1.186 + default = property(_get_default, _set_default) 1.187 + 1.188 + commands = { "default": "default", 1.189 + "timeout": "timeout", 1.190 + "serial": None, 1.191 + "prompt": None, 1.192 + "display": None, 1.193 + "f1": None, 1.194 + "f2": None, 1.195 + } 1.196 + 1.197 +if __name__ == "__main__": 1.198 + if sys.argv < 2: 1.199 + raise RuntimeError, "Need a configuration file to read" 1.200 + g = ExtLinuxConfigFile(sys.argv[1]) 1.201 + for i in g.images: 1.202 + print i 1.203 + print g.default
2.1 --- a/tools/pygrub/src/GrubConf.py Mon Feb 01 14:03:06 2010 +0000 2.2 +++ b/tools/pygrub/src/GrubConf.py Mon Feb 01 14:03:47 2010 +0000 2.3 @@ -1,6 +1,7 @@ 2.4 # 2.5 # GrubConf.py - Simple grub.conf parsing 2.6 # 2.7 +# Copyright 2009 Citrix Systems Inc. 2.8 # Copyright 2005-2006 Red Hat, Inc. 2.9 # Jeremy Katz <katzj@redhat.com> 2.10 #
3.1 --- a/tools/pygrub/src/pygrub Mon Feb 01 14:03:06 2010 +0000 3.2 +++ b/tools/pygrub/src/pygrub Mon Feb 01 14:03:47 2010 +0000 3.3 @@ -24,6 +24,7 @@ import getopt 3.4 import fsimage 3.5 import grub.GrubConf 3.6 import grub.LiloConf 3.7 +import grub.ExtLinuxConf 3.8 3.9 PYGRUB_VER = 0.6 3.10 3.11 @@ -383,7 +384,10 @@ class Grub: 3.12 ["/boot/grub/menu.lst", "/boot/grub/grub.conf", 3.13 "/grub/menu.lst", "/grub/grub.conf"]) + \ 3.14 map(lambda x: (x,grub.GrubConf.Grub2ConfigFile), 3.15 - ["/boot/grub/grub.cfg"]) 3.16 + ["/boot/grub/grub.cfg"]) + \ 3.17 + map(lambda x: (x,grub.ExtLinuxConf.ExtLinuxConfigFile), 3.18 + ["/boot/isolinux/isolinux.cfg", 3.19 + "/boot/extlinux.conf"]) 3.20 3.21 if not fs: 3.22 # set the config file and parse it