1# 2#LiloConf.py 3# 4 5from __future__ import print_function, absolute_import 6 7import sys, re, os 8import logging 9from . import GrubConf 10 11class LiloImage(object): 12 def __init__(self, lines, path): 13 self.reset(lines, path) 14 15 def __repr__(self): 16 return ("title: %s\n" 17 " root: %s\n" 18 " kernel: %s\n" 19 " args: %s\n" 20 " initrd: %s\n" %(self.title, self.root, self.kernel, 21 self.args, self.initrd)) 22 def reset(self, lines, path): 23 self._initrd = self._kernel = self._readonly = None 24 self._args = "" 25 self.title = "" 26 self.lines = [] 27 self.path = path 28 self.root = "" 29 for line in lines: 30 self.set_from_line(line) 31 32 def set_from_line(self, line, replace = None): 33 (com, arg) = GrubConf.grub_exact_split(line, 2) 34 35 if com in self.commands: 36 if self.commands[com] is not None: 37 setattr(self, self.commands[com], re.sub('^"(.+)"$', r"\1", arg.strip())) 38 else: 39 logging.info("Ignored image directive %s" %(com,)) 40 else: 41 logging.warning("Unknown image directive %s" %(com,)) 42 43 # now put the line in the list of lines 44 if replace is None: 45 self.lines.append(line) 46 else: 47 self.lines.pop(replace) 48 self.lines.insert(replace, line) 49 50 def set_kernel(self, val): 51 self._kernel = (None, self.path + "/" + val) 52 def get_kernel(self): 53 return self._kernel 54 kernel = property(get_kernel, set_kernel) 55 56 def set_initrd(self, val): 57 self._initrd = (None, self.path + "/" + val) 58 def get_initrd(self): 59 return self._initrd 60 initrd = property(get_initrd, set_initrd) 61 62 def set_args(self, val): 63 self._args = val 64 def get_args(self): 65 args = self._args 66 if self.root: 67 args += " root=" + self.root 68 if self.readonly: 69 args += " ro" 70 return args 71 args = property(get_args, set_args) 72 73 def set_readonly(self, val): 74 self._readonly = 1 75 def get_readonly(self): 76 return self._readonly 77 readonly = property(get_readonly, set_readonly) 78 79 # set up command handlers 80 commands = { "label": "title", 81 "root": "root", 82 "rootnoverify": "root", 83 "image": "kernel", 84 "initrd": "initrd", 85 "append": "args", 86 "read-only": "readonly", 87 "chainloader": None, 88 "module": None} 89 90class LiloConfigFile(object): 91 def __init__(self, fn = None): 92 self.filename = fn 93 self.images = [] 94 self.timeout = -1 95 self._default = 0 96 97 if fn is not None: 98 self.parse() 99 100 def parse(self, buf = None): 101 if buf is None: 102 if self.filename is None: 103 raise ValueError("No config file defined to parse!") 104 105 f = open(self.filename, 'r') 106 lines = f.readlines() 107 f.close() 108 else: 109 lines = buf.split("\n") 110 111 path = os.path.dirname(self.filename) 112 img = [] 113 for l in lines: 114 l = l.strip() 115 # skip blank lines 116 if len(l) == 0: 117 continue 118 # skip comments 119 if l.startswith('#'): 120 continue 121 # new image 122 if l.startswith("image"): 123 if len(img) > 0: 124 self.add_image(LiloImage(img, path)) 125 img = [l] 126 continue 127 128 if len(img) > 0: 129 img.append(l) 130 continue 131 132 (com, arg) = GrubConf.grub_exact_split(l, 2) 133 if com in self.commands: 134 if self.commands[com] is not None: 135 setattr(self, self.commands[com], arg.strip()) 136 else: 137 logging.info("Ignored directive %s" %(com,)) 138 else: 139 logging.warning("Unknown directive %s" %(com,)) 140 141 if len(img) > 0: 142 self.add_image(LiloImage(img, path)) 143 144 def hasPassword(self): 145 return False 146 147 def hasPasswordAccess(self): 148 return True 149 150 def add_image(self, image): 151 self.images.append(image) 152 153 def new_image(self, title, lines): 154 # LiloImage constructor doesn't have title but since path 155 # is being used by get_{kernel|initrd} functions we pass 156 # empty string rather than None (see lines above) 157 return LiloImage(lines, "") 158 159 def _get_default(self): 160 for i in range(len(self.images)): 161 if self.images[i].title == self._default: 162 return i 163 return 0 164 def _set_default(self, val): 165 self._default = val 166 default = property(_get_default, _set_default) 167 168 commands = { "default": "default", 169 "timeout": "timeout", 170 "prompt": None, 171 "relocatable": None, 172 } 173 174if __name__ == "__main__": 175 if len(sys.argv) < 2: 176 raise RuntimeError("Need a lilo.conf to read") 177 g = LiloConfigFile(sys.argv[1]) 178 for i in g.images: 179 print(i) #, i.title, i.root, i.kernel, i.args, i.initrd 180 print(g.default) 181