ia64/xen-unstable

view tools/pygrub/src/GrubConf.py @ 8323:566395e5a14f

Minor tidy.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Mon Dec 12 16:32:50 2005 +0000 (2005-12-12)
parents f85eb51dc313
children 2e8b1175fd37
line source
1 #
2 # GrubConf.py - Simple grub.conf parsing
3 #
4 # Copyright 2005 Red Hat, Inc.
5 # Jeremy Katz <katzj@redhat.com>
6 #
7 # This software may be freely redistributed under the terms of the GNU
8 # general public license.
9 #
10 # You should have received a copy of the GNU General Public License
11 # along with this program; if not, write to the Free Software
12 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
13 #
15 import os, sys
16 import logging
18 def grub_split(s, maxsplit = -1):
19 """Split a grub option screen separated with either '=' or whitespace."""
20 eq = s.find('=')
21 if eq == -1:
22 return s.split(None, maxsplit)
24 # see which of a space or tab is first
25 sp = s.find(' ')
26 tab = s.find('\t')
27 if (tab != -1 and tab < sp) or (tab != -1 and sp == -1):
28 sp = tab
30 if eq != -1 and eq < sp or (eq != -1 and sp == -1):
31 return s.split('=', maxsplit)
32 else:
33 return s.split(None, maxsplit)
35 def get_path(s):
36 """Returns a tuple of (GrubDiskPart, path) corresponding to string."""
37 if not s.startswith('('):
38 return (None, s)
39 idx = s.find(')')
40 if idx == -1:
41 raise ValueError, "Unable to find matching ')'"
42 d = s[:idx]
43 return (GrubDiskPart(d), s[idx + 1:])
45 class GrubDiskPart(object):
46 def __init__(self, str):
47 if str.find(',') != -1:
48 (self.disk, self.part) = str.split(",", 2)
49 else:
50 self.disk = str
51 self.part = None
53 def __repr__(self):
54 if self.part is not None:
55 return "d%dp%d" %(self.disk, self.part)
56 else:
57 return "d%d" %(self,disk,)
59 def get_disk(self):
60 return self._disk
61 def set_disk(self, val):
62 val = val.replace("(", "").replace(")", "")
63 self._disk = int(val[2:])
64 disk = property(get_disk, set_disk)
66 def get_part(self):
67 return self._part
68 def set_part(self, val):
69 if val is None:
70 self._part = val
71 return
72 val = val.replace("(", "").replace(")", "")
73 self._part = int(val)
74 part = property(get_part, set_part)
76 class GrubImage(object):
77 def __init__(self, lines):
78 self._root = self._initrd = self._kernel = self._args = None
79 for l in lines:
80 (com, arg) = grub_split(l, 1)
82 if self.commands.has_key(com):
83 if self.commands[com] is not None:
84 exec("%s = r\"%s\"" %(self.commands[com], arg.strip()))
85 else:
86 logging.info("Ignored image directive %s" %(com,))
87 else:
88 logging.warning("Unknown image directive %s" %(com,))
90 def __repr__(self):
91 return ("title: %s\n"
92 " root: %s\n"
93 " kernel: %s\n"
94 " args: %s\n"
95 " initrd: %s" %(self.title, self.root, self.kernel,
96 self.args, self.initrd))
98 def set_root(self, val):
99 self._root = GrubDiskPart(val)
100 def get_root(self):
101 return self._root
102 root = property(get_root, set_root)
104 def set_kernel(self, val):
105 if val.find(" ") == -1:
106 self._kernel = get_path(val)
107 self._args = None
108 return
109 (kernel, args) = val.split(None, 1)
110 self._kernel = get_path(kernel)
111 self._args = args
112 def get_kernel(self):
113 return self._kernel
114 def get_args(self):
115 return self._args
116 kernel = property(get_kernel, set_kernel)
117 args = property(get_args)
119 def set_initrd(self, val):
120 self._initrd = get_path(val)
121 def get_initrd(self):
122 return self._initrd
123 initrd = property(get_initrd, set_initrd)
125 # set up command handlers
126 commands = { "title": "self.title",
127 "root": "self.root",
128 "rootnoverify": "self.root",
129 "kernel": "self.kernel",
130 "initrd": "self.initrd",
131 "chainloader": None,
132 "module": None}
135 class GrubConfigFile(object):
136 def __init__(self, fn = None):
137 self.filename = fn
138 self.images = []
139 self.timeout = -1
141 if fn is not None:
142 self.parse()
144 def parse(self, buf = None):
145 if buf is None:
146 if self.filename is None:
147 raise ValueError, "No config file defined to parse!"
149 f = open(self.filename, 'r')
150 lines = f.readlines()
151 f.close()
152 else:
153 lines = buf.split("\n")
155 img = []
156 for l in lines:
157 l = l.strip()
158 # skip blank lines
159 if len(l) == 0:
160 continue
161 # skip comments
162 if l.startswith('#'):
163 continue
164 # new image
165 if l.startswith("title"):
166 if len(img) > 0:
167 self.images.append(GrubImage(img))
168 img = [l]
169 continue
171 if len(img) > 0:
172 img.append(l)
173 continue
175 try:
176 (com, arg) = grub_split(l, 1)
177 except ValueError:
178 com = l
179 arg = ""
181 if self.commands.has_key(com):
182 if self.commands[com] is not None:
183 exec("%s = r\"%s\"" %(self.commands[com], arg.strip()))
184 else:
185 logging.info("Ignored directive %s" %(com,))
186 else:
187 logging.warning("Unknown directive %s" %(com,))
189 if len(img) > 0:
190 self.images.append(GrubImage(img))
192 def _get_default(self):
193 return self._default
194 def _set_default(self, val):
195 if val == "saved":
196 self._default = -1
197 else:
198 self._default = int(val)
200 if self._default < 0:
201 raise ValueError, "default must be positive number"
202 default = property(_get_default, _set_default)
204 def set_splash(self, val):
205 self._splash = get_path(val)
206 def get_splash(self):
207 return self._splash
208 splash = property(get_splash, set_splash)
210 # set up command handlers
211 commands = { "default": "self.default",
212 "timeout": "self.timeout",
213 "fallback": "self.fallback",
214 "hiddenmenu": "self.hiddenmenu",
215 "splashimage": "self.splash",
216 "password": "self.password" }
217 for c in ("bootp", "color", "device", "dhcp", "hide", "ifconfig",
218 "pager", "partnew", "parttype", "rarp", "serial",
219 "setkey", "terminal", "terminfo", "tftpserver", "unhide"):
220 commands[c] = None
221 del c
224 if __name__ == "__main__":
225 if sys.argv < 2:
226 raise RuntimeError, "Need a grub.conf to read"
227 g = GrubConfigFile(sys.argv[1])
228 for i in g.images:
229 print i #, i.title, i.root, i.kernel, i.args, i.initrd