diff --git a/interface/ri_inst_cli.py b/interface/ri_inst_cli.py new file mode 100644 index 0000000..8efca03 --- /dev/null +++ b/interface/ri_inst_cli.py @@ -0,0 +1,46 @@ +#!/usr/bin/python +# DESCRIPTION: display module for install (cli) +# +# SCRIPT NAME: ri_inst_cli.py +# +# MENTOR: Li Zhi +# +# AUTHOR: Ling Fen +# +# EMAIL: fling@linx-info.com +# +# DATE: 2010-09-20 +# +# HISTORY: +# REVISOR DATE MODIFICATION +# Ling Fen 2010-09-04 create +# + +from ri_oper import language, Rate +def set_task(task_name): + print task_name + +def set_sub_task(sub_task): + print sub_task + +def set_task_scale(): + print '%', Rate.value + +def set_task_over(): + string = raw_input("Rocky system install success,plase reboot now![Y?]") + if string.lower() == "y": + return True + return False + +def root_destroy(): + pass + +def error(oper, ret): + if language == 'chinese': + print "%s:\n Error number: %d\n %s"%(oper.chinese_name, ret, oper.return_value[ret][1]) + else: + print "%s:\n Error number: %d\n %s"%(oper.english_name, ret, oper.return_value[ret][0]) + + +def start(func): + func() diff --git a/interface/ri_inst_tk.py b/interface/ri_inst_tk.py new file mode 100644 index 0000000..130e978 --- /dev/null +++ b/interface/ri_inst_tk.py @@ -0,0 +1,99 @@ +#!/usr/bin/python +#coding: utf-8 +# DESCRIPTION: display module for install (tk) +# +# SCRIPT NAME: ri_inst_tk.py +# +# MENTOR: Li Zhi +# +# AUTHOR: Ling Fen +# +# EMAIL: fling@linx-info.com +# +# DATE: 2010-09-20 +# +# HISTORY: +# REVISOR DATE MODIFICATION +# Ling Fen 2010-09-04 create +# + +from Tkinter import * +import tkMessageBox +import os +from ri_oper import language, Rate + +def set_task(task_name): + lab_operation.configure(text=task_name) + lab_operation.update() + +def set_sub_task(sub_task): + txt_suboperation.insert(END,sub_task) + txt_suboperation.see(END) + +def set_task_scale(): + scl_progress.set(Rate.value) + scl_progress.update() + +def set_task_over(): + ret = tkMessageBox.askokcancel(title="Install",message="%s"%(language=='chinese' and "凝思磐石系统安装完成,请重新启动系统"or "Rocky system install completed,plase reboot")) + return ret + +def root_destroy(): + root.destroy() + +def error(oper, ret): + if language == 'chinese': + tkMessageBox.showerror('Error',u"%s:\n 错误值: %d\n %s"%(oper.chinese_name, ret, oper.return_value[ret][1])) + else: + tkMessageBox.showerror('Error',"%s:\n Error number: %d\n %s"%(oper.english_name, ret, oper.return_value[ret][0])) + +def start(func): + root.protocol('WM_TAKE_FOCUS', func) + root.mainloop() + +#root widget +root = Tk() +root.geometry("%sx%s+0+0" %(root.winfo_screenwidth(),root.winfo_screenheight())) +root.title('Linx') + +# root subwidget +stringvar_bar=StringVar() + +#label +lab_task=Label(root,text='%s:'%(language=="chinese" and u"任务" or "Task")) +lab_progress_bar=Label(root,text='%s:'%(language=="chinese" and u"进度" \ + or 'Progress bar')) +lab_operation=Label(root,text="") +lab_linx=Label(root,text="Linx") + +txt_suboperation=Text(root,width=70,height=10) + +#operation lable and taskname +lab_task.grid (row=1, column=0, sticky='SEW') +lab_operation.grid (row=1, column=1, columnspan=2,sticky="S") +txt_suboperation.grid(row=2, column=1,columnspan=2) +lab_progress_bar.grid(row=3, column=0, sticky='NEW') +lab_linx.grid (row=4, column=1, sticky='E') + +#logo +photo_bm = PhotoImage(file="%s/../data/linxlogo.gif"\ + %os.path.split(os.path.realpath(__file__))[0]) +logo_label=Label(root,image=photo_bm) +logo_label.grid(row=0,column=0,padx=50,pady=50,sticky='NW') + +#progress bar +scl_progress=Scale(root,orient=HORIZONTAL,resolution=0.01,digits=4,from_=0,to=100,variable=stringvar_bar,label='%') +scl_progress.grid(row=3,column=1,columnspan=2,sticky='NEW') + +#root +root.rowconfigure(0,weight=1) +root.rowconfigure(1,weight=1) +root.rowconfigure(2,weight=1) +root.rowconfigure(3,weight=1) +root.rowconfigure(4,weight=1) +root.columnconfigure(0,weight=1) +root.columnconfigure(1,weight=1) +root.columnconfigure(2,weight=1) +root.columnconfigure(3,weight=1) + + diff --git a/interface/ri_install.py b/interface/ri_install.py new file mode 100644 index 0000000..7812a6c --- /dev/null +++ b/interface/ri_install.py @@ -0,0 +1,72 @@ +#!/usr/bin/python +# coding: utf-8 +# +# DESCRIPTION: install for OS +# +# SCRIPT NAME: ri_install.py +# +# Input: +# [-d|--display display-mode ] install display (tk or cli) +# [-l|--language language] insatll display language (chinese or english) +# +# MENTOR: Li Zhi +# +# AUTHOR: Ling Fen +# +# EMAIL: fling@linx-info.com +# +# DATE: 2010-09-20 +import sys +import getopt +import ri_oper +import os +def install_over(ret): + if ri_oper.Rate.value == 100 and ret == 0: + if display.set_task_over(): + print "reboot ..." + os.system("reboot") + else: + display.root_destroy() + +def main(): + global has_run + if has_run: return + has_run = True + for instance in oper_list: + ret = instance.install() + if ret: + display.error(instance, ret) + break + else: + ri_oper.display_sub_operation((ri_oper.language=='chinese' \ + and instance.chinese_name or instance.english_name)+\ + (ri_oper.language=='chinese' and u' 成功' or ' success')) + install_over(ret) + +has_run = False + +oper_list = [ri_oper.MakeRaid(5),ri_oper.Format(5),ri_oper.Mount(5),ri_oper.InstallPkg(40),ri_oper.MakeRaidConfigure(5),ri_oper.ConfigureFstab(5),ri_oper.GenerateIssue(5),ri_oper.ConfigureNetwork(5),ri_oper.MakeServiceAutoBoot(5),ri_oper.CopyKernel(5),ri_oper.ConfigureBootloader(5),ri_oper.BootLoader(5),ri_oper.ExecFinishInstall(5)] + +def print_usages(): + print 'Usages: %s [-l|--language language] [-d|--display display-mode]' %sys.argv[0] + +try: + opts, args = getopt.getopt(sys.argv[1:], "l:d:", ["language=", "display="]) +except getopt.GetoptError: + print_usages() + sys.exit(1) + +ri_oper.language='english' +disp = 'ri_inst_cli' +for opt,arg in opts: + if opt in ("-l","--language"): + ri_oper.language=arg.lower() + elif opt in ("-d", "--display"): + disp = 'ri_inst_%s' %arg.lower() +exec 'import %s as display' %disp + +ri_oper.display_operation = display.set_task +ri_oper.display_sub_operation = display.set_sub_task +ri_oper.display_scale = display.set_task_scale + +display.start(main) diff --git a/interface/ri_oper.py b/interface/ri_oper.py new file mode 100644 index 0000000..ae202a8 --- /dev/null +++ b/interface/ri_oper.py @@ -0,0 +1,312 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# DESCRIPTION: operation install method +# +# SCRIPT NAME: ri_oper.py +# +# MENTOR: Li zhi +# +# AUTHOR: Ling Fen +# +# EMAIL: fling@linx-info.com +# +# DATE: 2010-09-20 +# +# HISTORY: +# REVISOR DATE MODIFICATION +# Ling Fen 2010-09-04 create + +import ri_data +import os +import subprocess + +if os.path.isfile("../xml/install.xml"): + ri_data.init_from_xml() + +display_operation = None +display_sub_operation = None +display_scale = None +language = 'english' + +class Rate: + ''' class for installing progress, value is from 0 to 100''' + value = 0 + @staticmethod + def increase(n, max=100): + if Rate.value+n <= max: + Rate.value += n + @staticmethod + def set(n): + Rate.value = n + +class Operation: + ''' This is a common base class for all install operations. + The instances of its derived class should have the following + data members: + chinese_name - operation name + english_name - operation name + script - shell script name + return_value - shell script return value + score - an abstract value, for example score is 5, + steps - the subprocess of the number of runs + step - the subprocess run one time +total is 100, if this operations is completed, 5% work is done. + + and the following methods: + get_arguments - prepare arguments for scipt + get_stdin - prepare stdin for script + install - install progress ''' + + def __init__(self,e,c,s,scr): + ''' Operation(base class) init method + return_value is a dict, key is return code, value is a tuple, first + element is English, second element is Chinese.''' + self.return_value = {0:('success', u'成功'), \ + 1:('argument error',u'参数错误'), \ + 2:('deivce node do not exist',u'设备节点不存在'),\ + 3:('filesystem no implement',u'文件系统没有实现'),\ + } + self.english_name = e + self.chinese_name = c + self.script = s + self.score = scr + self.steps = 1 + self.step = 0 + + def install(self): + if display_operation: + display_operation(language == 'chinese' and self.chinese_name or self.english_name) + + max = Rate.value+self.score <100 and Rate.value+self.score or 100 + process = subprocess.Popen("./%s " %self.script + ' '.join(self.get_arguments()),\ + stdin=subprocess.PIPE,stdout=subprocess.PIPE, shell=True, \ + cwd="%s/../operation"%os.path.split(os.path.realpath(__file__))[0]) + process.stdin.write(self.get_stdin()) + process.stdin.close() + while True: + line = process.stdout.readline() + if not line: + break + if line[0] == '@' and self.step < self.steps: + self.step += 1 + if display_sub_operation: + display_sub_operation(line[1:]) + Rate.increase(float(self.score)/self.steps, max) + if display_scale: display_scale() + ret = process.wait() + Rate.set(max) + if display_scale: display_scale() + return ret + + def get_arguments(self): + return [] + def get_stdin(self): + return '' + +class Format(Operation): + ''' class for format partition ''' + def __init__(self, scr): + Operation.__init__(self, 'format partition', u'格式化分区', 'format_partition.sh', scr) + self.return_value[127] = ('format partition utils not found', u'没有格式化硬盘功能') + + def get_stdin(self): + format='' + n = 0 + for instance in ri_data.MountPoint.list: + if instance.format == "yes" and instance.filesystem != '': + format+="/dev/%s %s\n"%(instance.device,instance.filesystem) + n += 1 + self.steps += n + return format + +class MakeRaid(Operation): + """class for make raid""" + flag=False + def __init__(self,scr): + Operation.__init__(self,"make RAID",u"正在制作RAID磁盘阵列","mkraid_wrapper.sh",scr) + def get_stdin(self): + args = '' + n = 0 + for instance in ri_data.Raid.list: + if instance.from_os == 'no': + MakeRaid.flag=True + args += '-n /dev/%s -l %s -s %s -a %s\n' %(instance.device, instance.level, \ + ','.join([ '/dev/%s' %sp for sp in instance.spare_components]), \ + ','.join([ '/dev/%s' %ac for ac in instance.active_components])) + n += 1 + self.steps += n + return args + +class MakeRaidConfigure(Operation): + """class for make raid configure""" + def __init__(self,scr): + Operation.__init__(self,"make raid configure file",u"配置raid配置文件","mkraidconf.sh",scr) + def install(self): + if MakeRaid.flag: + Operation.install(self) + else: + max = Rate.value+self.score <100 and Rate.value+self.score or 100 + Rate.set(max) + return 0 + + def get_arguments(self): + return ["/etc/mdadm.conf"] + +class Mount(Operation): + """class for mount partition""" + def __init__(self,scr): + Operation.__init__(self,'mount partition',u'挂载分区','mount_partition.sh',scr) + self.return_value[1]=("device node doesn't exist",u"设备结点不存在") + self.return_value[32]=("mount failure",u"挂载失败") + + def get_stdin(self): + mount='' + n = 0 + for instance in ri_data.MountPoint.list: + if instance.directory != '' and instance.filesystem !='': + mount+="/dev/%s %s %s\n"%(instance.device,instance.directory,instance.filesystem) + n += 1 + self.steps += n + return mount + +class InstallPkg(Operation): + """class for install packages""" + def __init__(self,scr): + Operation.__init__(self,'install packages',u'安装软件包','install_pkg.sh',scr) + self.return_value[2]=("source directory pkg_source_dir doesn't exist",u"软件包所在目录不存在") + self.return_value[3]=("package in source doesn't exist",u"软件包不存在") + + def get_stdin(self): + pkgname=[] + for i in ri_data.Group.dict.values(): + if i.install=='no': + continue + else: + pkgname+=i.mandatory + if i.selection=='all': + pkgname += [ j[0] for j in i.optional ] + else: + pkgname += [ j[0] for j in i.optional if j[1] == 'yes' ] + + self.steps += len(pkgname) + return '\n'.join(pkgname) + + def get_arguments(self): + return ["-s","/Rocky/packages"] + +class ConfigureFstab(Mount): + """class for configure /etc/fstab""" + def __init__(self,scr): + Operation.__init__(self,'configure fstab',u'配置/etc/fstab文件','configure_fstab.sh',scr) + self.return_value[1]=("fstab doesn't exist",u"/etc/fstab文件不存在") + +class GenerateIssue(Operation): + """class for generate /etc/issue""" + def __init__(self,scr): + Operation.__init__(self,'generate issue',u'生成/etc/issue文件','generate_issue.sh',scr) + + def get_arguments(self): + args=[] + # FIXME if tag file format is error? + if os.path.isfile("/tag") : + fd=open("/tag","r") + string = fd.read() + list = string.split('\n')[0].split('-') + args = ['-v']+[list[0][5:]]+["-a"]+[list[1]]+["-r"]+[list[2]]+['-d']+['-'.join(list[3:])] + return args + +class ConfigureNetwork(Operation): + """class for configure network""" + def __init__(self,scr): + Operation.__init__(self,'configure network',u'配置网络','configure_network.sh',scr) + self.return_value[2]=("ip or netmask or geteway address incorrect",u"ip或子网掩码或网关不正确") + self.return_value[3]=("hosts/resolv.conf/ifcfg-eth0/network doesn't exist",u"文件hosts、resolv.conf、ifcfg-eht0、network 不存在") + + def get_arguments(self): + network='' + data=ri_data.Network + if data.configuration == "static": + network+="-t static " + if data.hostname is not '': + network+="-h %s "%data.hostname + if data.domain is not '': + network+="-d %s "%data.domain + if data.ip is not '': + network+="-i %s "%data.ip + if data.mask is not '': + network+="-n %s "%data.mask + if data.gateway is not '': + network+="-g %s "%data.gateway + if data.primary_dns is not '': + network+="-p %s "%data.primary_dns + if data.secondary_dns is not '': + network+="-s %s "%data.secondary_dns + else: + network+="-t dynamic " + if data.hostname is not '': + network+="-h %s "%data.hostname + return [network] + + +class MakeServiceAutoBoot(Operation): + """class for make service autoboot""" + def __init__(self,scr): + Operation.__init__(self,"make service autoboot",u"启动服务器","mk_serv_autoboot.sh",scr) + self.return_value[2]=("boot script doesn't exist",u"引导脚本不存在") + + def get_stdin(self): + serv='' + n = 0 + for i in ri_data.Service.list: + if i.start == "yes": + serv+='%s %s %s %s\n'%(i.package,i.script,i.name,i.number) + n += 1 + self.steps += n + return serv + +class CopyKernel(Operation): + """class for copy kernel""" + def __init__(self,scr): + Operation.__init__(self,"copy kernle",u"拷贝内核","copy_kernels.sh",scr) + self.return_value[1]=("kernel directory/modules directory/initrd.gz/makeinitrd doesn't exist",u"内核目录、模块目录、initrd.gz、makeinitrd 不存在") + +class ExecFinishInstall(Operation): + """class for exec finish install""" + def __init__(self,scr): + Operation.__init__(self,"exec finish install",u"安装完成执行的脚本","exec_finish_install.sh",scr) + def get_stdin(self): + return "99finish_install.sh\n" + +class BootLoader(Operation): + """class for bootloader""" + def __init__(self,scr): + Operation.__init__(self,"install bootloader",u"安装引导程序","install_bootloader.sh",scr) + self.return_value[2]=("bootloader type doesn't specify",u"没有指定引导程序的类型") + self.return_value[3]=("bootloader no implement",u"没有执行bootloader") + self.return_value[127]=("bootloader utils not found",u"没发现bootloader的utils") + + def get_arguments(self): + # only grub? + return ["-t grub"] + +class ConfigureBootloader(Operation): + """class for configure bootloader file""" + def __init__(self,scr): + Operation.__init__(self,"configure bootloader",u"配置bootloader","configure_bootloader_cnf.sh",scr) + self.return_value[2]=("bootloader type doesn't specify",u"没有指定引导程序的类型") + self.return_value[3]=("bootloader configure file doesn't exist",u"引导程序配置文件不存在") + self.return_value[4]=("bootloader configuration file doesn't exist",u"引导程序配置文件不存在") + + def get_arguments(self): + bootloader=[] + # FIXME if tag file format is error? + if os.path.isfile("/tag"): + fd = open("/tag","r") + string = fd.read() + list = string.split('-') + for instance in ri_data.MountPoint.list: + if instance.directory == '/': + # only grub? + bootloader=['-t','grub','-r',instance.device,'-k',ri_data.SerialNumber.value,'-o',list[0][5:].split('.')[0]+'.'+list[0][5:].split('.')[1]] + break + return bootloader diff --git a/operation/mkraid_wrapper.sh b/operation/mkraid_wrapper.sh new file mode 100755 index 0000000..3c55faa --- /dev/null +++ b/operation/mkraid_wrapper.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# DESCRIPTION: better deal with arguments for mkraid.sh (arguments---> stdin) +# +# SCRIPT NAME: mkraid_wrapper.sh +# +# MENTOR: Li Zhi +# +# AUTHOR: Ling Fen +# +# EMAIL: fling@linx-info.com +# +# DATE: 2010-09-20 +# +# HISTORY: +# REVISOR DATE MODIFICATION +# Ling Fen 2010-09-18 create +# + +# This file is a wrapper to mkraid.sh. + +while read line +do + $(dirname $0)/mkraid.sh "$line" + ret=$? + if [ $ret -ne 0 ];then + exit $ret + fi +done