system-config-kickstart源码阅读(四)引导程序grub篇
适兕
|
1#
适兕 发表于 2008-11-05 18:59
system-config-kickstart源码阅读(四)引导程序grub篇
按照此系列文章的
《二》 中的“功能篇”,安从上到下,或是理解为按照首字母顺序来一一解析。 顾名思义,bootloader.py即是linux系统引导程序,现在lilo基本消失了,grbu独占此领域。对于安装程序anaconda来说,解析、处理kickstart生成的文件中,此项绝对重要,一个系统若是安装了却不能引导,那其实等于什么也没有做。 先来看下其类的UML视图: 此文要比我们以前所见到的类要好多,而且还将继承关系体现了出来,这就是OOP,既然GRUB不是全部,那就定义个类似的,其他的任何来了继承就解决了。抽象不能解决问题,尽管它可以提供一些思考的方向。 import gtk import gtk.glade import string import random import crypt #模块就不用解释了,均在上几篇文章解释过的。 ## ## I18N ## import gettext gtk.glade.bindtextdomain("system-config-kickstart") _ = lambda x: gettext.ldgettext("system-config-kickstart", x) import kickstartGui class AbstractBootloader: //高级类定义,具体的grub来继承这个类。 def __init__(self, xml, notebook, ksHandler): self.xml = xml self.notebook = notebook self.ks = ksHandler def applyKickstart(self): pass def enableUpgrade(self, boolean): pass def formToKickstart(self): return 0 def hide(self): pass def show(self, platform): pass def toggled_bootloader(self, args): pass class GrubBootloader(AbstractBootloader): //继承了! def __init__(self, xml, notebook, ksHandler): AbstractBootloader.__init__(self, xml, notebook, ksHandler) self.bootloader_vbox = xml.get_widget("bootloader_vbox") self.bootloader_label = xml.get_widget("bootloader_label") self.install_bootloader_radio = xml.get_widget("install_bootloader_radio") self.upgrade_bootloader_radio = xml.get_widget("upgrade_bootloader_radio") self.no_bootloader_radio = xml.get_widget("no_bootloader_radio") self.mbr_radiobutton = xml.get_widget("mbr_radiobutton") self.firstsector_radiobutton = xml.get_widget("firstsector_radiobutton") self.parameters_label = xml.get_widget("parameters_label") self.parameters_entry = xml.get_widget("parameters_entry") self.linear_checkbutton = xml.get_widget("linear_checkbutton") self.lba32_checkbutton = xml.get_widget("lba32_checkbutton") self.grub_options_label = xml.get_widget("grub_options_label") self.grub_password_checkbutton = xml.get_widget("grub_password_checkbutton") self.grub_password_hbox = xml.get_widget("grub_password_hbox") self.grub_password_entry = xml.get_widget("grub_password_entry") self.grub_password_confirm = xml.get_widget("grub_password_confirm") self.grub_password_encrypt_checkbutton = xml.get_widget("grub_password_encrypt_checkbutton") #获取glade文件的widget,这点有点难度了,因为在glade编辑器中难以做到所写即所得。非熟悉gtk+的人是做不来的,也说明了此处技艺的高超。 self.install_bootloader_radio.connect("toggled", self.toggled_bootloader)//定义触发按钮信号,以及相应的处理函数,下同。 self.grub_password_checkbutton.connect("toggled", self._toggled_grub_password) def _toggled_grub_password(self, args): self.grub_password_hbox.set_sensitive(self.grub_password_checkbutton.get_active()) //可选框是否激活? def applyKickstart(self): //每个功能篇中的都有的方法,局部生效。也就是默认选项。 if self.ks.bootloader.location == "none": //判断是否选择安装引导程序?如果选择了不安装,则激活不安装按钮。 self.no_bootloader_radio.set_active(True) elif self.ks.bootloader.location == "mbr": //否则,默认安装到MBR self.mbr_radiobutton.set_active(True) elif self.ks.bootloader.location == "partition": //否则,默认安装到分区上 self.firstsector_radiobutton.set_active(True) if self.ks.bootloader.password != "": self.grub_password_entry.set_text(self.ks.bootloader.password) self.grub_password_confirm.set_text(self.ks.bootloader.password) self.parameters_entry.set_text(self.ks.bootloader.appendLine)//内核参数。 if self.ks.bootloader.md5pass != "": //是否选择给grub密码加密? self.grub_password_encrypt_checkbutton.set_active(True) else: self.grub_password_encrypt_checkbutton.set_active(False) if self.ks.bootloader.upgrade == True: 升级现有的引导程序? self.upgrade_bootloader_radio.set_active(True) else: self.upgrade_bootloader_radio.set_active(False) def enableUpgrade(self, boolean): self.upgrade_bootloader_radio.set_sensitive(not boolean) def formToKickstart(self): //来自文件的设置 if self.install_bootloader_radio.get_active(): buf = "" if self.mbr_radiobutton.get_active(): self.ks.bootloader.location = "mbr" elif self.firstsector_radiobutton.get_active(): self.ks.bootloader.location = "partition" params = string.strip (self.parameters_entry.get_text()) self.ks.bootloader.appendLine = params //加密很精彩? if self.grub_password_checkbutton.get_active() == True: gp = string.strip (self.grub_password_entry.get_text()) cp = string.strip (self.grub_password_confirm.get_text()) if len(gp) > 0: if gp == cp: if self.grub_password_encrypt_checkbutton.get_active(): salt = "$1$" saltLen = 8 for i in range(saltLen): salt = salt + random.choice (string.letters + string.digits + './')//此处的东西,我得去寻找anaconda的源码来确认解密的过程。。 self.passwd = crypt.crypt (gp, salt) self.ks.bootloader.md5pass = unicode(self.passwd, 'iso-8859-1') else: self.ks.bootloader.password = gp self.ks.bootloader.md5pass = "" else: dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, (_("Grub passwords do not match. Please try again."))) dlg.set_position(gtk.WIN_POS_CENTER) dlg.set_modal(True) dlg.set_icon(kickstartGui.iconPixbuf) dlg.run() dlg.destroy() self.grub_password_entry.set_text("") self.grub_password_confirm.set_text("") self.notebook.set_current_page(2) self.grub_password_entry.grab_focus() return None else: self.ks.bootloader.password = "" self.ks.bootloader.md5pass = "" elif self.upgrade_bootloader_radio.get_active(): self.ks.bootloader.upgrade = True else: self.ks.bootloader.location = "none" self.ks.bootloader.password = "" self.ks.bootloader.md5pass = "" return 0 def hide(self): self.bootloader_vbox.hide() def show(self, platform): 更本就不显示设置项。 self.bootloader_vbox.show() def toggled_bootloader (self, args): //触发信号的调用函数。 status = self.install_bootloader_radio.get_active() self.parameters_label.set_sensitive(status) self.parameters_entry.set_sensitive(status) self.mbr_radiobutton.set_sensitive(status) self.firstsector_radiobutton.set_sensitive(status) self.grub_options_label.set_sensitive(status) self.grub_password_checkbutton.set_sensitive(status) self.grub_password_entry.set_sensitive(status) self.grub_password_confirm.set_sensitive(status) self.grub_password_encrypt_checkbutton.set_sensitive(status) class UnknownBootloader(AbstractBootloader): def __init__(self, xml, notebook, ksHandler): AbstractBootloader.__init__(self, xml, notebook, ksHandler) self.bootloader_label = xml.get_widget("bootloader_label") def hide(self): self.bootloader_label.hide() def show(self, platform): self.bootloader_label.set_text(_("Bootloader options are not applicable to " "the %s platform" % platform)) self.bootloader_label.show() class bootloader: //供kickstartGui类使用的类。 def __init__(self, xml, notebook, ksHandler): self.default = UnknownBootloader(xml, notebook, ksHandler) self.blDict = {"x86, AMD64, or Intel EM64T": GrubBootloader(xml, notebook, ksHandler)} self._setBl(ksHandler.platform) def _setBl(self, platform): try: self.bl = self.blDict[platform] except: self.bl = self.default def applyKickstart(self): self.bl.applyKickstart() def enableUpgrade(self, boolean): self.bl.enableUpgrade(not boolean) def formToKickstart(self): return self.bl.formToKickstart() def platformTypeChanged(self, platform): self.bl.hide() self._setBl(platform) self.bl.show(platform) def updateKS(self, ksHandler) //使bootload生效。: self.ks = ksHandler self.default.ks = ksHandler for bl in self.blDict.values(): bl.ks = ksHandler 此时,我真的迷了!无所适从了,恰如我现在的生活。当去全局考虑,不明白细节;当去探求细节时,忘了全局。 顺序程序设计而已,总是在按照某种规定的方式走的,无论它有多少次if-else,假如不是这样,这个程序就没有任何的意义,一如人生,但人生似乎都把握不住岔路! |