按照此系列文章的
《二》中的“功能篇”,安从上到下,或是理解为按照首字母顺序来一一解析。
顾名思义,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,假如不是这样,这个程序就没有任何的意义,一如人生,但人生似乎都把握不住岔路!