modified: dialog/di_dialog.py modified: interface/ri_oper.py modified: operation/configure_fstab.sh
367 lines
14 KiB
Python
367 lines
14 KiB
Python
#!/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 ri_dep
|
|
import os
|
|
import subprocess
|
|
import signal
|
|
|
|
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
|
|
current_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 script
|
|
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 doesn't exist",u"设备节点不存在"),\
|
|
3:("File system hasn't been implemented",u'文件系统没有实现'),\
|
|
}
|
|
self.english_name = e
|
|
self.chinese_name = c
|
|
self.script = s
|
|
self.score = scr
|
|
self.steps = 1
|
|
self.current_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, \
|
|
preexec_fn=self.sigpipe_handle, \
|
|
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.current_step < self.steps:
|
|
self.current_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 sigpipe_handle(self):
|
|
signal.signal(signal.SIGPIPE,signal.SIG_DFL)
|
|
|
|
def get_arguments(self):
|
|
return []
|
|
def get_stdin(self):
|
|
return ''
|
|
@staticmethod
|
|
def getarch():
|
|
cmd='uname -m'
|
|
result = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True)
|
|
arch = result.stdout.readline().rstrip()
|
|
return arch
|
|
|
|
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] = ('No tool to format partitions', u'没有格式化硬盘分区的工具')
|
|
|
|
def get_stdin(self):
|
|
format=''
|
|
n = 0
|
|
for instance in ri_data.MountPoint.dict.values():
|
|
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"""
|
|
def __init__(self,scr):
|
|
Operation.__init__(self,"Making a RAID", u"正在制作RAID磁盘阵列", "mkraid_wrapper.sh", scr)
|
|
self.return_value[2] = ('this levelY need more devices',u'制作这个级别的raid需要更多的分区.')
|
|
self.return_value[3] = ('the raid name has exist',u'这个raid已经存在.')
|
|
self.return_value[4] = ('this shell not support this RAID level', u'不能做这个级别的raid.')
|
|
self.return_value[5] = ('level0 donot need spare devices', u'raid0不需要备用分区')
|
|
self.return_value[6] = ('incorrect active and spare devices name, maybe it has been used', u'这个分区已经被做过raid了.')
|
|
self.return_value[7] = ('create or assimble raid device lose', u'制作raid不成功')
|
|
|
|
def get_stdin(self):
|
|
args = ''
|
|
n = 0
|
|
for instance in ri_data.Raid.dict.values():
|
|
if instance.from_os == 'no':
|
|
args += '-n /dev/%s -l %s -a %s' %(instance.device, instance.level,','.join([ '/dev/%s' %ac for ac in instance.active_components]))
|
|
if instance.spare_components :
|
|
args += ' -s %s' % ','.join([ '/dev/%s' %sp for sp in instance.spare_components])
|
|
args +='\n'
|
|
n += 1
|
|
self.steps += n
|
|
return args
|
|
|
|
class MakeRaidConfigure(Operation):
|
|
"""class for make raid configure"""
|
|
def __init__(self,scr):
|
|
Operation.__init__(self,"Generate /etc/mdadm.conf",u"生成raid配置文件","mkraidconf.sh",scr)
|
|
|
|
def install(self):
|
|
if ri_data.Raid.dict.values():
|
|
return 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"""
|
|
# dict saved only device and mount point
|
|
dict={}
|
|
def __init__(self,scr):
|
|
Operation.__init__(self,'Mount partition', u'挂载分区', 'mount_partition.sh',scr)
|
|
|
|
def get_stdin(self):
|
|
mount=''
|
|
n = 0
|
|
for dir in set([ m.directory for m in ri_data.MountPoint.dict.values() if m.directory ]):
|
|
for k in ri_data.MountPoint.dict.keys():
|
|
if ri_data.MountPoint.dict[k].directory == dir and ri_data.MountPoint.dict[k].filesystem:
|
|
# during configure fstab, use dict of Mount
|
|
Mount.dict[k]=dir
|
|
mount+='/dev/%s %s %s\n' %(k,dir,ri_data.MountPoint.dict[k].filesystem)
|
|
n+=1
|
|
break
|
|
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]=("Software source directory doesn't exist",u"软件包所在目录不存在")
|
|
self.return_value[3]=("Software package doesn't exist",u"软件包不存在")
|
|
|
|
def get_stdin(self):
|
|
pkgname = set(ri_data.Group.get_install_pkgs() + self.get_dependency_pkg())
|
|
self.steps += len(pkgname)
|
|
return '\n'.join(pkgname)+'\n'
|
|
|
|
def get_arguments(self):
|
|
return ["-s","/Rocky/packages"]
|
|
|
|
def get_dependency_pkg(self):
|
|
ri_dep.dependency_init()
|
|
return ri_dep.dependency_init.dep_dict.keys() + ri_dep.dependency_init.func_dep_list
|
|
|
|
class ConfigureFstab(Mount):
|
|
"""class for configure /etc/fstab"""
|
|
def __init__(self,scr):
|
|
Operation.__init__(self,'Configure /etc/fstab',u'配置/etc/fstab文件','configure_fstab.sh',scr)
|
|
self.return_value[2]=("/etc/fstab doesn't exist",u"/etc/fstab文件不存在")
|
|
|
|
def get_stdin(self):
|
|
fstab=''
|
|
# Note: Mount.dict are mount point. it isn't equal ri_data.MountPoint.dict
|
|
for k in Mount.dict.keys():
|
|
if ri_data.MountPoint.dict[k].filesystem != 'swap':
|
|
fstab += "/dev/%s %s %s\n" %(k,Mount.dict[k],ri_data.MountPoint.dict[k].filesystem)
|
|
|
|
for k in ri_data.MountPoint.dict.keys():
|
|
if ri_data.MountPoint.dict[k].filesystem == 'swap':
|
|
fstab += '/dev/%s swap swap\n' %k
|
|
break
|
|
|
|
# process fstab to sort
|
|
fstab_new = ''
|
|
cmd_t = "echo '%s' | sort -k 2" %fstab
|
|
std_out = os.popen(cmd_t).readlines()
|
|
for l in std_out:
|
|
fstab_new += l
|
|
return fstab_new
|
|
|
|
class GenerateIssue(Operation):
|
|
"""class for generate /etc/issue"""
|
|
def __init__(self,scr):
|
|
Operation.__init__(self,'Generate /etc/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:])]
|
|
fd.close()
|
|
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 address, network, or geteway is incorrect",u"Ip地址、子网掩码、网关不正确")
|
|
self.return_value[3]=("/etc/hosts, /etc/resolv.conf, /etc/sysconfig/network-devices/ifcfg.template, or /etc/sysconfig/network doesn't exist",\
|
|
u"文件/etc/hosts,/etc/resolv.conf,/etc/sysconfig/network-devices/ifcfg.template或/etc/sysconfig/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:
|
|
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 kernel",u"拷贝内核","copy_kernels.sh",scr)
|
|
self.return_value[1]=("kernel directory, modules directory, initrd.gz, or 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 script",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 hasn't been specified",u"没有指定引导程序的类型")
|
|
self.return_value[3]=("Bootloader hasn't been implemented",u"没有实现bootloader")
|
|
self.return_value[127]=("No tool to bootloader. E.g grub",u"没有安装引导程序的工具。如grub等")
|
|
|
|
def get_arguments(self):
|
|
if self.getarch() == "ppc64":
|
|
pass
|
|
elif self.getarch() == "ia64":
|
|
return ["-t elilo"]
|
|
else:
|
|
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 hasn't specified",u"没有指定引导程序的类型")
|
|
self.return_value[3]=("Bootloader hasn't been implemented",u"没有实现bootloader")
|
|
self.return_value[4]=("Bootloader configuration file doesn't exist",u"引导程序配置文件不存在")
|
|
|
|
def get_arguments(self):
|
|
list=[]
|
|
|
|
if self.getarch() == "ppc64":
|
|
pass
|
|
elif self.getarch() == "ia64":
|
|
tp = "elilo"
|
|
else:
|
|
tp = "grub"
|
|
# FIXME if tag file format is error?
|
|
if os.path.isfile("/tag"):
|
|
fd = open("/tag","r")
|
|
string = fd.read()
|
|
list = string.split('-')
|
|
fd.close()
|
|
|
|
bootloader=['-t',tp,'-o',list[0][5:].split('.')[0]+'.'+list[0][5:].split('.')[1],'-k','"linx_serial=%s vga=791 quiet"' %ri_data.SerialNumber.value.strip()]
|
|
|
|
for k in Mount.dict.keys():
|
|
if '/' == Mount.dict[k]:
|
|
bootloader += ['-r',k]
|
|
if '/boot' == Mount.dict[k]:
|
|
bootloader += ['-b',k]
|
|
|
|
return bootloader
|