# HG changeset patch # User Ian Campbell # Date 1258917181 0 # Node ID d641f06a4889748dc7efec62398b5d333ad0df87 # Parent 13311ab2b104f238a88b3842a05d0053eb8569dc pygrub: factor generic Grub functionality into GrubConf base classes and inherit from these classes to implement Grub-legacy functionality. Use a tuple of (parser-object,configuration-file) in pygrub to allow for multiple parsers. Makes way for grub2 support. Signed-off-by: Ian Campbell diff -r 13311ab2b104 -r d641f06a4889 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 @@ -78,7 +78,7 @@ self._part = int(val) part = property(get_part, set_part) -class GrubImage(object): +class _GrubImage(object): def __init__(self, lines): self.reset(lines) @@ -89,30 +89,14 @@ " args: %s\n" " initrd: %s\n" %(self.title, self.root, self.kernel, self.args, self.initrd)) + def _parse(self, lines): + map(self.set_from_line, lines) def reset(self, lines): self._root = self._initrd = self._kernel = self._args = None self.title = "" self.lines = [] - map(self.set_from_line, lines) - - def set_from_line(self, line, replace = None): - (com, arg) = grub_exact_split(line, 2) - - 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) + self._parse(lines) def set_root(self, val): self._root = GrubDiskPart(val) @@ -141,6 +125,28 @@ return self._initrd initrd = property(get_initrd, set_initrd) +class GrubImage(_GrubImage): + def __init__(self, lines): + _GrubImage.__init__(self, lines) + + def set_from_line(self, line, replace = None): + (com, arg) = grub_exact_split(line, 2) + + 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) + # set up command handlers commands = { "title": "title", "root": "root", @@ -149,9 +155,8 @@ "initrd": "initrd", "chainloader": None, "module": None} - -class GrubConfigFile(object): +class _GrubConfigFile(object): def __init__(self, fn = None): self.filename = fn self.images = [] @@ -164,50 +169,7 @@ 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") - - 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.startswith("title"): - if len(img) > 0: - self.add_image(GrubImage(img)) - img = [l] - continue - - if len(img) > 0: - img.append(l) - continue - - (com, arg) = grub_exact_split(l, 2) - 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(GrubImage(img)) - - if self.hasPassword(): - self.setPasswordAccess(False) + raise RuntimeError, "unimplemented parse function" def hasPasswordAccess(self): return self.passwordAccess @@ -285,7 +247,56 @@ commands[c] = None del c +class GrubConfigFile(_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 = [] + 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.startswith("title"): + if len(img) > 0: + self.add_image(GrubImage(img)) + img = [l] + continue + + if len(img) > 0: + img.append(l) + continue + + (com, arg) = grub_exact_split(l, 2) + 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(GrubImage(img)) + + if self.hasPassword(): + self.setPasswordAccess(False) + if __name__ == "__main__": if sys.argv < 2: raise RuntimeError, "Need a grub.conf to read" diff -r 13311ab2b104 -r d641f06a4889 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 @@ -371,17 +371,17 @@ raise RuntimeError, "Unable to access %s" %(fn,) if platform.machine() == 'ia64': - self.cf = grub.LiloConf.LiloConfigFile() - # common distributions - file_list = ("/efi/debian/elilo.conf", "/efi/gentoo/elilo.conf", - "/efi/redflag/elilo.conf", "/efi/redhat/elilo.conf", - "/efi/SuSE/elilo.conf",) - # fallbacks - file_list += ("/efi/boot/elilo.conf", "/elilo.conf",) + cfg_list = map(lambda x: (x,grub.LiloConf.LiloConfigFile), + # common distributions + ["/efi/debian/elilo.conf", "/efi/gentoo/elilo.conf", + "/efi/redflag/elilo.conf", "/efi/redhat/elilo.conf", + "/efi/SuSE/elilo.conf",] + + # fallbacks + ["/efi/boot/elilo.conf", "/elilo.conf",]) else: - self.cf = grub.GrubConf.GrubConfigFile() - file_list = ("/boot/grub/menu.lst", "/boot/grub/grub.conf", - "/grub/menu.lst", "/grub/grub.conf") + cfg_list = map(lambda x: (x,grub.GrubConf.GrubConfigFile), + ["/boot/grub/menu.lst", "/boot/grub/grub.conf", + "/grub/menu.lst", "/grub/grub.conf"]) if not fs: # set the config file and parse it @@ -389,8 +389,10 @@ self.cf.parse() return - for f in file_list: + for f,parser in cfg_list: if fs.file_exists(f): + print >>sys.stderr, "Using %s to parse %s" % (parser,f) + self.cf = parser() self.cf.filename = f break if self.cf.filename is None: