📄 pygrub
字号:
y += 1 lines.append(ret) continue # if we got boot, then we want to boot the entered image img = grub.GrubConf.GrubImage(lines) self.cf.add_image(img) self.selected_image = len(self.cf.images) - 1 self.isdone = True break # else, we cancelled and should just go back break def read_config(self, fn, fs = None): """Read the given file to parse the config. If fs = None, then we're being given a raw config file rather than a disk image.""" if not os.access(fn, os.R_OK): 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",) else: self.cf = grub.GrubConf.GrubConfigFile() file_list = ("/boot/grub/menu.lst", "/boot/grub/grub.conf", "/grub/menu.lst", "/grub/grub.conf") if not fs: # set the config file and parse it self.cf.filename = fn self.cf.parse() return for f in file_list: if fs.file_exists(f): self.cf.filename = f break if self.cf.filename is None: raise RuntimeError, "couldn't find bootloader config file in the image provided." f = fs.open_file(self.cf.filename) buf = f.read() del f self.cf.parse(buf) def run(self): timeout = int(self.cf.timeout) self.selected_image = self.cf.default self.isdone = False while not self.isdone: self.run_main(timeout) timeout = -1 return self.selected_image def run_main(self, timeout = -1): def draw(): # set up the screen self.draw_main_windows() self.text_win.addstr(0, 0, "Use the U and D keys to select which entry is highlighted.") self.text_win.addstr(1, 0, "Press enter to boot the selected OS. 'e' to edit the") self.text_win.addstr(2, 0, "commands before booting, 'a' to modify the kernel arguments ") self.text_win.addstr(3, 0, "before booting, or 'c' for a command line.") self.text_win.addch(0, 8, curses.ACS_UARROW) self.text_win.addch(0, 14, curses.ACS_DARROW) (y, x) = self.text_win.getmaxyx() self.text_win.move(y - 1, x - 1) self.text_win.refresh() # now loop until we hit the timeout or get a go from the user mytime = 0 self.start_image = 0 while (timeout == -1 or mytime < int(timeout)): draw() if timeout != -1 and mytime != -1: self.screen.addstr(20, 5, "Will boot selected entry in %2d seconds" %(int(timeout) - mytime)) else: self.screen.addstr(20, 5, " " * 80) self.fill_entry_list() c = self.screen.getch() if c == -1: # Timed out waiting for a keypress if mytime != -1: mytime += 1 if mytime >= int(timeout): self.isdone = True break else: # received a keypress: stop the timer mytime = -1 self.screen.timeout(-1) # handle keypresses if c == ord('c'): self.command_line_mode() break elif c == ord('a'): # find the kernel line, edit it and then boot img = self.cf.images[self.selected_image] for line in img.lines: if line.startswith("kernel"): l = self.edit_line(line) if l is not None: img.set_from_line(l, replace = True) self.isdone = True break break elif c == ord('e'): img = self.cf.images[self.selected_image] self.edit_entry(img) break elif c in (curses.KEY_ENTER, ord('\n'), ord('\r')): self.isdone = True break elif c == curses.KEY_UP: self.selected_image -= 1 elif c == curses.KEY_DOWN: self.selected_image += 1# elif c in (ord('q'), 27): # 27 == esc# self.selected_image = -1# self.isdone = True# break # bound at the top and bottom if self.selected_image < 0: self.selected_image = 0 elif self.selected_image >= len(self.cf.images): self.selected_image = len(self.cf.images) - 1 def get_entry_idx(cf, entry): # first, see if the given entry is numeric try: idx = string.atoi(entry) return idx except ValueError: pass # it's not, now check the labels for a match for i in range(len(cf.images)): if entry == cf.images[i].title: return i return Nonedef run_grub(file, entry, fs): global g global sel def run_main(scr, *args): global sel global g sel = g.run() g = Grub(file, fs) if interactive: curses.wrapper(run_main) else: sel = g.cf.default # set the entry to boot as requested if entry is not None: idx = get_entry_idx(g.cf, entry) if idx is not None and idx > 0 and idx < len(g.cf.images): sel = idx if sel == -1: print "No kernel image selected!" sys.exit(1) img = g.cf.images[sel] grubcfg = { "kernel": None, "ramdisk": None, "args": None } grubcfg["kernel"] = img.kernel[1] if img.initrd: grubcfg["ramdisk"] = img.initrd[1] if img.args: grubcfg["args"] = img.args return grubcfg# If nothing has been specified, look for a Solaris domU. If found, perform the# necessary tweaks.def sniff_solaris(fs, cfg): if not fs.file_exists("/platform/i86xpv/kernel/unix"): return cfg # darned python longmode = (sys.maxint != 2147483647L) if not longmode: longmode = os.uname()[4] == "x86_64" if not longmode: if (os.access("/usr/bin/isainfo", os.R_OK) and os.popen("/usr/bin/isainfo -b").read() == "64\n"): longmode = True if not cfg["kernel"]: cfg["kernel"] = "/platform/i86xpv/kernel/unix" cfg["ramdisk"] = "/platform/i86pc/boot_archive" if longmode: cfg["kernel"] = "/platform/i86xpv/kernel/amd64/unix" cfg["ramdisk"] = "/platform/i86pc/amd64/boot_archive" # Unpleasant. Typically we'll have 'root=foo -k' or 'root=foo /kernel -k', # and we need to maintain Xen properties (root= and ip=) and the kernel # before any user args. xenargs = "" userargs = "" if not cfg["args"]: cfg["args"] = cfg["kernel"] else: for arg in cfg["args"].split(): if re.match("^root=", arg) or re.match("^ip=", arg): xenargs += arg + " " elif arg != cfg["kernel"]: userargs += arg + " " cfg["args"] = xenargs + " " + cfg["kernel"] + " " + userargs return cfg if __name__ == "__main__": sel = None def usage(): print >> sys.stderr, "Usage: %s [-q|--quiet] [-i|--interactive] [--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=] <image>" %(sys.argv[0],) try: opts, args = getopt.gnu_getopt(sys.argv[1:], 'qih::', ["quiet", "interactive", "help", "output=", "entry=", "kernel=", "ramdisk=", "args=", "isconfig"]) except getopt.GetoptError: usage() sys.exit(1) if len(args) < 1: usage() sys.exit(1) file = args[0] output = None entry = None interactive = True isconfig = False # what was passed in incfg = { "kernel": None, "ramdisk": None, "args": None } # what grub or sniffing chose chosencfg = { "kernel": None, "ramdisk": None, "args": None } # what to boot bootcfg = { "kernel": None, "ramdisk": None, "args": None } for o, a in opts: if o in ("-q", "--quiet"): interactive = False elif o in ("-i", "--interactive"): interactive = True elif o in ("-h", "--help"): usage() sys.exit() elif o in ("--output",): output = a elif o in ("--kernel",): incfg["kernel"] = a elif o in ("--ramdisk",): incfg["ramdisk"] = a elif o in ("--args",): incfg["args"] = a elif o in ("--entry",): entry = a # specifying the entry to boot implies non-interactive interactive = False elif o in ("--isconfig",): isconfig = True if output is None or output == "-": fd = sys.stdout.fileno() else: fd = os.open(output, os.O_WRONLY) # debug if isconfig: chosencfg = run_grub(file, entry) print " kernel: %s" % chosencfg["kernel"] if img.initrd: print " initrd: %s" % chosencfg["ramdisk"] print " args: %s" % chosencfg["args"] sys.exit(0) # if boot filesystem is set then pass to fsimage.open bootfsargs = '"%s"' % incfg["args"] bootfsgroup = re.findall('zfs-bootfs=(.*?)[\s\,\"]', bootfsargs) if bootfsgroup: fs = fsimage.open(file, get_fs_offset(file), bootfsgroup[0]) else: fs = fsimage.open(file, get_fs_offset(file)) chosencfg = sniff_solaris(fs, incfg) if not chosencfg["kernel"]: chosencfg = run_grub(file, entry, fs) data = fs.open_file(chosencfg["kernel"]).read() (tfd, bootcfg["kernel"]) = tempfile.mkstemp(prefix="boot_kernel.", dir="/var/run/xend/boot") os.write(tfd, data) os.close(tfd) if chosencfg["ramdisk"]: data = fs.open_file(chosencfg["ramdisk"],).read() (tfd, bootcfg["ramdisk"]) = tempfile.mkstemp(prefix="boot_ramdisk.", dir="/var/run/xend/boot") os.write(tfd, data) os.close(tfd) else: initrd = None sxp = "linux (kernel %s)" % bootcfg["kernel"] if bootcfg["ramdisk"]: sxp += "(ramdisk %s)" % bootcfg["ramdisk"] if chosencfg["args"]: zfsinfo = fsimage.getbootstring(fs) if zfsinfo is None: sxp += "(args \"%s\")" % chosencfg["args"] else: e = re.compile("zfs-bootfs=[\w\-\.\:@/]+" ) (chosencfg["args"],count) = e.subn(zfsinfo, chosencfg["args"]) if count == 0: chosencfg["args"] += " -B %s" % zfsinfo sxp += "(args \"%s\")" % (chosencfg["args"]) sys.stdout.flush() os.write(fd, sxp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -