add Qin Bo's operating shell scripts in
rename directory 'python' to 'interface', for I think it is a better name for its included python scripts function.
This commit is contained in:
107
interface/mine/install_xml.py
Normal file
107
interface/mine/install_xml.py
Normal file
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from xml.dom import minidom
|
||||
import Tkinter
|
||||
|
||||
def attr_to_dict(attr):
|
||||
''' convert (widget or grid_location) attributes into a dict '''
|
||||
dict = {}
|
||||
for a in attr.values():
|
||||
if a.name == 'image':
|
||||
dict[a.name] = Tkinter.PhotoImage(file=a.value)
|
||||
elif a.name == 'command':
|
||||
module = sys.modules[__name__]
|
||||
dict[a.name] = getattr(module, a.value)
|
||||
else:
|
||||
dict[a.name] = a.value
|
||||
return dict
|
||||
|
||||
def construct_widget_dict():
|
||||
''' Go through all widget xml nodes on first level, I mean, those widgets defined
|
||||
inside other widget will not be checked. If the widget has a name, it will
|
||||
be recorded in the widget_dict.'''
|
||||
widgets = [e for e in xmldoc.firstChild.childNodes
|
||||
if e.nodeType == e.ELEMENT_NODE and e.nodeName == "widget"]
|
||||
for w in widgets:
|
||||
if "name" in w.attributes.keys():
|
||||
widget_dict[w.attributes["name"].value] = w
|
||||
|
||||
def widget(w_xml, p_win):
|
||||
''' create a widget.
|
||||
w_xml is a xml node describing the widget.
|
||||
p_win is the parent widget.'''
|
||||
func = getattr(Tkinter, w_xml.attributes["type"].value)
|
||||
# convert attributes into dictionary
|
||||
wa_list = [wa for wa in w_xml.childNodes
|
||||
if wa.nodeType == wa.ELEMENT_NODE and wa.nodeName =="widget_attribute"]
|
||||
if wa_list:
|
||||
# only process the first element, and there should be only one element.
|
||||
attr_dict = attr_to_dict(wa_list[0].attributes)
|
||||
w_win = func(p_win, attr_dict)
|
||||
else:
|
||||
w_win = func(p_win)
|
||||
|
||||
gm_list = [m for m in w_xml.childNodes
|
||||
if m.nodeType == m.ELEMENT_NODE and m.nodeName == "grid_management"]
|
||||
gl_list = [l for l in w_xml.childNodes
|
||||
if l.nodeType == l.ELEMENT_NODE and l.nodeName == "grid_location"]
|
||||
w_list = [ w for w in w_xml.childNodes
|
||||
if w.nodeType == w.ELEMENT_NODE and w.nodeName == "widget" ]
|
||||
|
||||
for w in w_list:
|
||||
widget(w, w_win)
|
||||
|
||||
for m in gm_list:
|
||||
for cf in m.childNodes:
|
||||
if cf.nodeType != m.ELEMENT_NODE or cf.nodeName != "configure":
|
||||
continue
|
||||
if "row" in cf.attributes.keys():
|
||||
cf_func = getattr(w_win, "rowconfigure")
|
||||
n = cf.attributes["row"].value
|
||||
elif "column" in cf.attributes.keys():
|
||||
cf_func = getattr(w_win, "columnconfigure")
|
||||
n = cf.attributes["column"].value
|
||||
else:
|
||||
continue
|
||||
cf_func(n, weight=cf.attributes["weight"].value)
|
||||
# only process the first item
|
||||
break
|
||||
|
||||
for l in gl_list:
|
||||
ld = attr_to_dict(l.attributes)
|
||||
w_win.grid(ld)
|
||||
# only process the first item
|
||||
break
|
||||
|
||||
def display():
|
||||
''' Display a series of widgets '''
|
||||
root_window = Tkinter.Tk()
|
||||
|
||||
# first display the main frame
|
||||
widget(widget_dict["main"], root_window)
|
||||
root_window.columnconfigure(0, weight=1)
|
||||
root_window.rowconfigure(0, weight=1)
|
||||
root_window.geometry('800x600+0+0')
|
||||
root_window.mainloop()
|
||||
|
||||
# commands for buttons
|
||||
def quit():
|
||||
print "quit"
|
||||
|
||||
def previous_step():
|
||||
print "previous step"
|
||||
|
||||
def next_step():
|
||||
|
||||
print "next step"
|
||||
|
||||
xmldoc = minidom.parse("../../xml/interface_t.xml")
|
||||
|
||||
widget_dict={}
|
||||
construct_widget_dict()
|
||||
|
||||
sequence_dict={}
|
||||
construct_sequence_dict()
|
||||
|
||||
display()
|
||||
39
interface/ri_cmd.py
Normal file
39
interface/ri_cmd.py
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/python
|
||||
''' handle commands.'''
|
||||
|
||||
import ri_widget
|
||||
|
||||
def quit():
|
||||
''' correspond to quit button '''
|
||||
# maybe a quit in current widget, so call widget.hide()
|
||||
# get current widget, call its quit()
|
||||
q, t = ri_widget.Sequence.current()
|
||||
ri_widget.Widget.dict[t].hide()
|
||||
display.quit()
|
||||
ri_data.to_xml()
|
||||
|
||||
def previous():
|
||||
''' correspond to previous button '''
|
||||
q, t = ri_widget.Sequence.current()
|
||||
wid_name = ri_widget.Sequence.previous()
|
||||
if wid_name is not None:
|
||||
ri_widget.Widget.dict[t].hide()
|
||||
|
||||
ri_widget.Widget.dict[wid_name].show()
|
||||
else:
|
||||
ri_widget.MessageBox.dict["previous"].show()
|
||||
|
||||
def next():
|
||||
''' correspond to next button '''
|
||||
q, t = ri_widget.Sequence.current()
|
||||
wid_name = ri_widget.Sequence.next()
|
||||
if wid_name is not None:
|
||||
ri_widget.Widget.dict[t].hide()
|
||||
|
||||
ri_widget.Widget.dict[wid_name].show()
|
||||
else:
|
||||
ri_widget.MessageBox.dict["next"].show()
|
||||
|
||||
from ri_tk_cmd import *
|
||||
|
||||
|
||||
621
interface/ri_data.py
Normal file
621
interface/ri_data.py
Normal file
@@ -0,0 +1,621 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import re
|
||||
import commands
|
||||
from xml.dom import minidom
|
||||
from xml.dom.ext import PrettyPrint
|
||||
|
||||
# xml file names
|
||||
install_xml = '../xml/install.xml'
|
||||
config_xml = '../xml/config.xml'
|
||||
|
||||
def to_xml_attr(doc, node, cls, name):
|
||||
''' This method is called by to_xml. Its function is to create an attribute, and set its value based on Network data member
|
||||
doc - xml document
|
||||
node - xml node
|
||||
cls - python class/python instance
|
||||
name - attribute name'''
|
||||
attr = doc.createAttribute(name)
|
||||
attr.value = getattr(cls, name)
|
||||
node.setAttributeNode(attr)
|
||||
|
||||
class SerialNumber:
|
||||
''' serial number '''
|
||||
value = ''
|
||||
@staticmethod
|
||||
def init_from_xml(node):
|
||||
''' set value based on xml node '''
|
||||
SerialNumber.value = node.firstChild.data.encode('ascii')
|
||||
|
||||
@staticmethod
|
||||
def to_xml(doc, p_node):
|
||||
''' write SerialNumber into xml
|
||||
doc - xml document instance
|
||||
p_node - xml node (parent node)'''
|
||||
sn = doc.createElement('serial-number')
|
||||
data = doc.createTextNode(SerialNumber.value)
|
||||
sn.appendChild(data)
|
||||
p_node.appendChild(sn)
|
||||
|
||||
class Partition:
|
||||
''' disk partition '''
|
||||
unit=''
|
||||
list=[]
|
||||
def __init__(self, dev, st, sz, id, fr):
|
||||
''' Partition init function '''
|
||||
self.device = dev
|
||||
self.start = st
|
||||
self.size = sz
|
||||
self.id = id
|
||||
self.from_os = fr
|
||||
Partition.list.append(self)
|
||||
|
||||
@staticmethod
|
||||
def init_from_os():
|
||||
''' create a Partition instance from hardware info'''
|
||||
# cmd = 'sfdisk -d'
|
||||
# has problem on raid detection
|
||||
cmd = 'cat /home/zhi/work/new_install/python/mine/sfdisk.txt'
|
||||
st, o = commands.getstatusoutput(cmd)
|
||||
if st:
|
||||
return
|
||||
p0 = re.compile(r'unit:\s*(\w+)')
|
||||
p = re.compile(r'''
|
||||
\s*(\w+)\s*: # device
|
||||
\s*start=\s*(\d+)\s*, # start
|
||||
\s*size=\s*(\d+)\s*, # size
|
||||
\s*Id=\s*(\d+) # id
|
||||
''', re.VERBOSE)
|
||||
for s in o.splitlines():
|
||||
res0 = p0.search(s)
|
||||
if res0:
|
||||
Partition.unit = res0.groups()[0]
|
||||
res = p.search(s)
|
||||
if res:
|
||||
dev, start, size, id = res.groups()
|
||||
Partition(dev.split('/')[-1], start, size, id, True)
|
||||
|
||||
@staticmethod
|
||||
def init_from_xml(node):
|
||||
''' create Partition instances from xml node '''
|
||||
Partition.unit = node.attributes['unit'].value.encode('ascii')
|
||||
for p in node.childNodes:
|
||||
if p.nodeType == node.ELEMENT_NODE and p.nodeName == 'partition':
|
||||
Partition(p.attributes['device'].value.encode('ascii'),\
|
||||
p.attributes['start'].value.encode('ascii'), \
|
||||
p.attributes['size'].value.encode('ascii'), \
|
||||
p.attributes['id'].value.encode('ascii'), \
|
||||
p.attributes['from_os'].value.encode('ascii'))
|
||||
|
||||
@staticmethod
|
||||
def to_xml(doc, p_node):
|
||||
''' write all Partition instance into xml
|
||||
doc - xml document instance
|
||||
p_node - xml node (parent node)'''
|
||||
pts = doc.createElement("partitions")
|
||||
unit_attr = doc.createAttribute('unit')
|
||||
unit_attr.value = Partition.unit
|
||||
pts.setAttributeNode(unit_attr)
|
||||
for p in Partition.list:
|
||||
pt = doc.createElement('partition')
|
||||
dev_attr = doc.createAttribute('device')
|
||||
start_attr = doc.createAttribute('start')
|
||||
size_attr = doc.createAttribute('size')
|
||||
id_attr = doc.createAttribute('id')
|
||||
from_attr = doc.createAttribute('from_os')
|
||||
dev_attr.value = p.device
|
||||
start_attr.value = p.start
|
||||
size_attr.value = p.size
|
||||
id_attr.value = p.id
|
||||
from_attr.value = p.from_os
|
||||
pt.setAttributeNode(dev_attr)
|
||||
pt.setAttributeNode(start_attr)
|
||||
pt.setAttributeNode(size_attr)
|
||||
pt.setAttributeNode(id_attr)
|
||||
pt.setAttributeNode(from_attr)
|
||||
pts.appendChild(pt)
|
||||
p_node.appendChild(pts)
|
||||
|
||||
@staticmethod
|
||||
def get_size(dev):
|
||||
for p in Partition.list:
|
||||
if p.device == dev:
|
||||
return p.size
|
||||
|
||||
class Raid:
|
||||
''' raid information '''
|
||||
list = []
|
||||
def __init__(self, dev, from_os, level, sz, a_devs, s_devs=[]):
|
||||
''' Raid init function '''
|
||||
self.device = dev
|
||||
self.from_os = from_os
|
||||
self.level = level
|
||||
self.size = sz
|
||||
self.active_components = a_devs
|
||||
self.spare_components = s_devs
|
||||
Raid.list.append(self)
|
||||
|
||||
@staticmethod
|
||||
def init_from_os():
|
||||
#cmd = 'cat /proc/mdstat'
|
||||
cmd = 'cat /home/zhi/work/new_install/python/mine/raid.txt'
|
||||
st, o = commands.getstatusoutput(cmd)
|
||||
if st:
|
||||
return
|
||||
dev_p = re.compile(r'''
|
||||
^(md\d+)\s*: # md device
|
||||
\s*active\s* # "active"
|
||||
(\w+)\s* # raid type
|
||||
''', re.VERBOSE)
|
||||
|
||||
size_p = re.compile(r'''
|
||||
^\s*(\d+) # block number
|
||||
\s*blocks''', re.VERBOSE)
|
||||
|
||||
|
||||
for s in o.splitlines():
|
||||
dev_res = dev_p.split(s)
|
||||
if len(dev_res)>1: # matched
|
||||
# dev_res[0] is ''
|
||||
raid_dev = dev_res[1]
|
||||
raid_level = dev_res[2]
|
||||
act_cmpts =[]
|
||||
spr_cmpts =[]
|
||||
for ss in dev_res[3].split():
|
||||
if re.search(r'\(S\)', ss):
|
||||
spr_cmpts.append(ss[:ss.index('[')])
|
||||
else:
|
||||
act_cmpts.append(ss[:ss.index('[')])
|
||||
continue
|
||||
|
||||
if size_p.match(s).groups():
|
||||
raid_size = size_p.match(s).groups()[0]
|
||||
# if already detect a raid dev
|
||||
if raid_dev:
|
||||
Raid(raid_dev, True, raid_level, raid_size, act_cmpts, spr_cmpts)
|
||||
# clear raid dev
|
||||
raid_dev=''
|
||||
|
||||
|
||||
@staticmethod
|
||||
def add_component(node, l):
|
||||
''' add component devices (in xml node) to list
|
||||
node - xml node
|
||||
l - list
|
||||
'''
|
||||
for sub in node.childNodes:
|
||||
if sub.nodeType == sub.ELEMENT_NODE and sub.nodeName == 'component':
|
||||
l.append(sub.firstChild.data.encode('ascii'))
|
||||
|
||||
@staticmethod
|
||||
def init_from_xml(node):
|
||||
''' create Raid instances from xml node '''
|
||||
for e in node.childNodes:
|
||||
if e.nodeType == e.ELEMENT_NODE and e.nodeName == 'raid':
|
||||
raid_dev = e.attributes['device'].value
|
||||
raid_from = e.attributes['from_os'].value
|
||||
raid_level = e.attributes['level'].value
|
||||
raid_size = e.attributes['size'].value
|
||||
act_cmpts = []
|
||||
spr_cmpts = []
|
||||
for sub_e in e.childNodes:
|
||||
if sub_e.nodeType == sub_e.ELEMENT_NODE:
|
||||
if sub_e.nodeName == 'active':
|
||||
Raid.add_component(sub_e, act_cmpts)
|
||||
elif sub_e.nodeName == 'spare':
|
||||
Raid.add_component(sub_e, spr_cmpts)
|
||||
|
||||
Raid(raid_dev, raid_from, raid_level, raid_size, act_cmpts, spr_cmpts)
|
||||
|
||||
@staticmethod
|
||||
def to_xml(doc, p_node):
|
||||
''' write all raid instance into xml
|
||||
doc - xml document instance
|
||||
p_node - xml node (parent node) '''
|
||||
raids = doc.createElement('raids')
|
||||
for r in Raid.list:
|
||||
rd = doc.createElement('raid')
|
||||
|
||||
rd_dev_attr = doc.createAttribute('device')
|
||||
rd_dev_attr.value = r.device
|
||||
rd.setAttributeNode(rd_dev_attr)
|
||||
|
||||
rd_from_attr = doc.createAttribute('from_os')
|
||||
rd_from_attr.value = r.from_os
|
||||
rd.setAttributeNode(rd_from_attr)
|
||||
|
||||
rd_level_attr = doc.createAttribute('level')
|
||||
rd_level_attr.value = r.level
|
||||
rd.setAttributeNode(rd_level_attr)
|
||||
|
||||
rd_size_attr = doc.createAttribute('size')
|
||||
rd_size_attr.value = r.size
|
||||
rd.setAttributeNode(rd_size_attr)
|
||||
|
||||
rd_act_elem = doc.createElement('active')
|
||||
for act_c in r.active_components:
|
||||
act_c_e = doc.createElement('component')
|
||||
act_c_tn = doc.createTextNode(act_c)
|
||||
act_c_e.appendChild(act_c_tn)
|
||||
rd_act_elem.appendChild(act_c_e)
|
||||
rd.appendChild(rd_act_elem)
|
||||
|
||||
rd_spr_elem = doc.createElement('spare')
|
||||
for spr_c in r.spare_components:
|
||||
spr_c_e = doc.createElement('component')
|
||||
spr_c_tn = doc.createTextNode(spr_c)
|
||||
spr_c_e.appendChild(spr_c_tn)
|
||||
rd_spr_elem.appendChild(spr_c_e)
|
||||
rd.appendChild(rd_spr_elem)
|
||||
|
||||
raids.appendChild(rd)
|
||||
|
||||
p_node.appendChild(raids)
|
||||
|
||||
@staticmethod
|
||||
def get_size(dev):
|
||||
for r in Raid.list:
|
||||
if r.device == dev:
|
||||
return r.size
|
||||
|
||||
@staticmethod
|
||||
def get_next_device():
|
||||
''' get next available raid device name '''
|
||||
num_p = re.compile(r'md(\d+)')
|
||||
numbers = [ int(num_p.match(r.device).groups()[0]) for r in Raid.list ]
|
||||
max = 0
|
||||
for n in numbers:
|
||||
if n > max: max = n
|
||||
return 'md%d' %(max+1)
|
||||
|
||||
class MountPoint:
|
||||
''' mount-points '''
|
||||
list=[]
|
||||
def __init__(self, dev, dir='', fs='', fm='no', sz='0'):
|
||||
self.device = dev
|
||||
self.directory = dir
|
||||
self.filesystem = fs
|
||||
self.format = fm
|
||||
self.size = sz
|
||||
MountPoint.list.append(self)
|
||||
|
||||
@staticmethod
|
||||
def change(dev, dir, fs, fm):
|
||||
for mp in MountPoint.list:
|
||||
if mp.device == dev:
|
||||
mp.directory = dir
|
||||
mp.filesystem = fs
|
||||
mp.format = fm
|
||||
|
||||
def device(self):
|
||||
return self.device
|
||||
|
||||
@staticmethod
|
||||
def init_from_internal():
|
||||
''' init MountPoint from internal class Partition and class Raid '''
|
||||
devs = [ m.device for m in MountPoint.list ]
|
||||
for p in Partition.list:
|
||||
if p.id != 'fd' and p.device not in devs:
|
||||
MountPoint(p.device, sz=p.size)
|
||||
|
||||
for r in Raid.list:
|
||||
if r.device not in devs:
|
||||
MountPoint(r.device, sz=r.size)
|
||||
|
||||
# now process whether a partition or raid was removed
|
||||
s1 = set([ m.device for m in MountPoint.list ])
|
||||
s2 = set([ p.device for p in Partition.list ] + [ r.device for r in Raid.list])
|
||||
for dev in s1-s2:
|
||||
for i in range(len(MountPoint.list)):
|
||||
if dev == MountPoint.list[i].device:
|
||||
del MountPoint.list[i]
|
||||
break
|
||||
# sort
|
||||
MountPoint.list.sort(key=MountPoint.device)
|
||||
|
||||
@staticmethod
|
||||
def init_from_xml(node):
|
||||
''' create MountPoint instances from xml node '''
|
||||
for m in node.childNodes:
|
||||
if m.nodeType == node.ELEMENT_NODE and m.nodeName == 'mount-point':
|
||||
MountPoint(m.attributes['device'].value.encode('ascii'), \
|
||||
m.attributes['directory'].value.encode('ascii'), \
|
||||
m.attributes['file-system'].value.encode('ascii'), \
|
||||
m.attributes['format'].value.encode('ascii') )
|
||||
|
||||
@staticmethod
|
||||
def to_xml(doc, p_node):
|
||||
''' write all MountPoint instance into xml
|
||||
doc - xml document instance
|
||||
p_node - xml node (parent node)'''
|
||||
mps = doc.createElement('mount-points')
|
||||
for m in MountPoint.list:
|
||||
mp = doc.createElement('mount-point')
|
||||
dev_attr = doc.createAttribute('device')
|
||||
dir_attr = doc.createAttribute('directory')
|
||||
fs_attr = doc.createAttribute('file-system')
|
||||
fm_attr = doc.createAttribute('format')
|
||||
dev_attr.value = m.device
|
||||
dir_attr.value = m.directory
|
||||
fs_attr.value = m.filesystem
|
||||
fm_attr.value = m.format
|
||||
mp.setAttributeNode(dev_attr)
|
||||
mp.setAttributeNode(dir_attr)
|
||||
mp.setAttributeNode(fs_attr)
|
||||
mp.setAttributeNode(fm_attr)
|
||||
mps.appendChild(mp)
|
||||
p_node.appendChild(mps)
|
||||
|
||||
class Network:
|
||||
''' network '''
|
||||
hostname =''
|
||||
configuration =''
|
||||
domain = ''
|
||||
ip = ''
|
||||
mask = ''
|
||||
gateway = ''
|
||||
primary_dns = ''
|
||||
secondary_dns = ''
|
||||
|
||||
@staticmethod
|
||||
def init_from_xml(node):
|
||||
''' init Network from xml node '''
|
||||
for k in node.attributes.keys():
|
||||
setattr(Network, k, node.attributes[k].value.encode('ascii'))
|
||||
|
||||
@staticmethod
|
||||
def to_xml(doc, p_node):
|
||||
''' write Network into xml
|
||||
doc - xml document instance
|
||||
p_node - xml node (parent node)'''
|
||||
ntwk = doc.createElement('network')
|
||||
for nm in ('hostname', 'configuration', 'ip', 'mask', 'gateway', 'primary_dns', 'secondary_dns', 'domain'):
|
||||
to_xml_attr(doc, ntwk, Network, nm)
|
||||
p_node.appendChild(ntwk)
|
||||
|
||||
class Group:
|
||||
''' software package group '''
|
||||
dict = {}
|
||||
def __init__(self, n, i):
|
||||
self.name = n
|
||||
self.install = i
|
||||
self.description = ''
|
||||
self.mandatory = []
|
||||
self.selection = 'manual'
|
||||
self.optional = []
|
||||
Group.dict[n] = self
|
||||
|
||||
@staticmethod
|
||||
def handle_release_node(r_node):
|
||||
''' This method is called by init_from_config_xml
|
||||
r_node - release node '''
|
||||
for i in r_node.childNodes:
|
||||
if i.nodeType == i.ELEMENT_NODE and i.nodeName == 'including':
|
||||
Group(i.attributes['group'].value, \
|
||||
i.attributes['install'].value == 'mandatory' and 'mandatory' or 'no')
|
||||
|
||||
@staticmethod
|
||||
def handle_group_node(g_node):
|
||||
''' This method is called by init_from_config_xml
|
||||
g_node - group node '''
|
||||
g = Group.dict[g_node.attributes['name'].value]
|
||||
for n in g_node.childNodes:
|
||||
if n.nodeType == n.ELEMENT_NODE:
|
||||
if n.nodeName == 'description':
|
||||
g.description = n.firstChild.data
|
||||
elif n.nodeName == 'including':
|
||||
if n.attributes['install'].value == 'mandatory':
|
||||
g.mandatory.append(n.attributes['package'].value.encode('ascii'))
|
||||
else:
|
||||
g.optional.append([n.attributes['package'].value.encode('ascii'), 'no'])
|
||||
|
||||
@staticmethod
|
||||
def init_from_config_xml(node):
|
||||
''' init Group instances from config xml
|
||||
node - root node of config xml'''
|
||||
rls_list = [r for r in node.childNodes
|
||||
if r.nodeType == r.ELEMENT_NODE and r.nodeName == 'release']
|
||||
grp_list = [g for g in node.childNodes
|
||||
if g.nodeType == g.ELEMENT_NODE and g.nodeName == 'group']
|
||||
Group.handle_release_node(rls_list[0])
|
||||
for g in grp_list:
|
||||
Group.handle_group_node(g)
|
||||
|
||||
@staticmethod
|
||||
def init_from_install_xml(node):
|
||||
''' init Group instances from install xml
|
||||
node - install xml 'groups' node'''
|
||||
for grp in node.childNodes:
|
||||
if grp.nodeType == grp.ELEMENT_NODE and grp.nodeName == 'group':
|
||||
g = Group(grp.attributes['name'].value, grp.attributes['install'].value)
|
||||
for grp_chld in grp.childNodes:
|
||||
if grp_chld.nodeType == grp_chld.ELEMENT_NODE:
|
||||
if grp_chld.nodeName == 'description':
|
||||
g.description = grp_chld.firstChild.data
|
||||
elif grp_chld.nodeName == 'mandatory':
|
||||
g.mandatory.extend([pkg.attributes['name'].value for pkg in grp_chld.childNodes
|
||||
if pkg.nodeType == pkg.ELEMENT_NODE and pkg.nodeName == 'package'])
|
||||
elif grp_chld.nodeName == 'optional':
|
||||
g.optional.extend([[pkg.attributes['name'].value, pkg.attributes['install'].value] for pkg in grp_chld.childNodes
|
||||
if pkg.nodeType == pkg.ELEMENT_NODE and pkg.nodeName == 'package'])
|
||||
g.selection = grp_chld.attributes['selection'].value
|
||||
init_from_xml = init_from_install_xml
|
||||
@staticmethod
|
||||
def to_xml(doc, p_node):
|
||||
''' write Group instances into xml
|
||||
doc - xml document instance
|
||||
p_node - xml node (parent node)'''
|
||||
grps = doc.createElement('groups')
|
||||
for g in Group.dict.values():
|
||||
grp = doc.createElement('group')
|
||||
name_attr = doc.createAttribute('name')
|
||||
name_attr.value = g.name
|
||||
grp.setAttributeNode(name_attr)
|
||||
|
||||
inst_attr = doc.createAttribute('install')
|
||||
inst_attr.value = g.install
|
||||
grp.setAttributeNode(inst_attr)
|
||||
|
||||
if g.description:
|
||||
dscp = doc.createElement('description')
|
||||
dscp_data = doc.createTextNode(g.description)
|
||||
dscp.appendChild(dscp_data)
|
||||
grp.appendChild(dscp)
|
||||
|
||||
if g.mandatory:
|
||||
mndt = doc.createElement('mandatory')
|
||||
for m in g.mandatory:
|
||||
pkg = doc.createElement('package')
|
||||
pname_attr = doc.createAttribute('name')
|
||||
pname_attr.value = m
|
||||
pkg.setAttributeNode(pname_attr)
|
||||
|
||||
mndt.appendChild(pkg)
|
||||
grp.appendChild(mndt)
|
||||
|
||||
if g.optional:
|
||||
optl = doc.createElement('optional')
|
||||
sel_attr = doc.createAttribute('selection')
|
||||
sel_attr.value = g.selection
|
||||
optl.setAttributeNode(sel_attr)
|
||||
for o in g.optional:
|
||||
pkg = doc.createElement('package')
|
||||
pname_attr = doc.createAttribute('name')
|
||||
pname_attr.value = o[0]
|
||||
pkg.setAttributeNode(pname_attr)
|
||||
pinst_attr = doc.createAttribute('install')
|
||||
pinst_attr.value = o[1]
|
||||
pkg.setAttributeNode(pinst_attr)
|
||||
optl.appendChild(pkg)
|
||||
grp.appendChild(optl)
|
||||
grps.appendChild(grp)
|
||||
p_node.appendChild(grps)
|
||||
|
||||
class Service:
|
||||
''' service '''
|
||||
list = []
|
||||
def __init__(self, nm, nb, sc, st, p):
|
||||
''' init method
|
||||
nm - name
|
||||
nb - number
|
||||
sc - script
|
||||
st - start (yes/no/disable)
|
||||
p - pkg, that includes this service
|
||||
'''
|
||||
self.name = nm
|
||||
self.number = nb
|
||||
self.script = sc
|
||||
self.start = st
|
||||
self.package = p
|
||||
Service.list.append(self)
|
||||
|
||||
@staticmethod
|
||||
def init_from_config_xml(root):
|
||||
''' init Service instances from config xml
|
||||
root - root node of config xml '''
|
||||
for p in root.childNodes:
|
||||
if p.nodeType == p.ELEMENT_NODE and p.nodeName == 'package':
|
||||
for s in p.childNodes:
|
||||
if s.nodeType == s.ELEMENT_NODE and s.nodeName == 'service':
|
||||
Service(s.attributes['name'].value, \
|
||||
s.attributes['number'].value, \
|
||||
s.attributes['script'].value, \
|
||||
'disable', \
|
||||
p.attributes['name'].value )
|
||||
|
||||
@staticmethod
|
||||
def change_state():
|
||||
''' Based on package information in Group class, change 'start' data member
|
||||
from 'disable' to 'no', or from 'yes'/'no' to 'disable' '''
|
||||
l = []
|
||||
for g in Group.dict.values():
|
||||
if g.install == 'mandatory' or g.install == 'yes':
|
||||
l.extend(g.mandatory)
|
||||
if g.selection == 'all':
|
||||
l.extend([ n for n, i in g.optional])
|
||||
elif g.selection == 'manual':
|
||||
l.extend([ n for n, i in g.optional if i == 'yes'])
|
||||
else: # selection is 'none'
|
||||
pass
|
||||
|
||||
for s in Service.list:
|
||||
if s.package in l:
|
||||
if s.start == 'disable':
|
||||
s.start = 'no'
|
||||
else:
|
||||
s.start = 'disable'
|
||||
|
||||
@staticmethod
|
||||
def init_from_install_xml(node):
|
||||
''' init Service instances from install xml
|
||||
node - install xml 'services' node'''
|
||||
for srv in node.childNodes:
|
||||
if srv.nodeType == srv.ELEMENT_NODE and srv.nodeName == 'service':
|
||||
Service(srv.attributes['name'].value, \
|
||||
srv.attributes['number'].value, \
|
||||
srv.attributes['script'].value, \
|
||||
srv.attributes['start'].value, \
|
||||
srv.attributes['package'].value)
|
||||
|
||||
init_from_xml = init_from_install_xml
|
||||
@staticmethod
|
||||
def to_xml(doc, p_node):
|
||||
''' write Service instances into xml
|
||||
doc - xml document instance
|
||||
p_node - xml node (parent node)'''
|
||||
srvs = doc.createElement('services')
|
||||
for s in Service.list:
|
||||
srv = doc.createElement('service')
|
||||
for n in ('name', 'number', 'script', 'start', 'package'):
|
||||
to_xml_attr(doc, srv, s, n)
|
||||
srvs.appendChild(srv)
|
||||
p_node.appendChild(srvs)
|
||||
|
||||
def init():
|
||||
''' initialize '''
|
||||
Partition.init_from_os()
|
||||
Raid.init_from_os()
|
||||
MountPoint.init_from_internal()
|
||||
xmldoc_cfg = minidom.parse(config_xml)
|
||||
root_cfg = xmldoc_cfg.firstChild
|
||||
Group.init_from_config_xml(root_cfg)
|
||||
Service.init_from_config_xml(root_cfg)
|
||||
|
||||
def init_from_xml():
|
||||
''' init all classes in this module based input file (install xml) '''
|
||||
xmldoc = minidom.parse(install_xml)
|
||||
root = xmldoc.firstChild
|
||||
for n in root.childNodes:
|
||||
if n.nodeType == n.ELEMENT_NODE:
|
||||
if n.nodeName == 'serial-number':
|
||||
SerialNumber.init_from_xml(n)
|
||||
elif n.nodeName == 'partitions':
|
||||
Partition.init_from_xml(n)
|
||||
elif n.nodeName == 'raids':
|
||||
Raid.init_from_xml(n)
|
||||
elif n.nodeName == 'mount-points':
|
||||
MountPoint.init_from_xml(n)
|
||||
elif n.nodeName == 'network':
|
||||
Network.init_from_xml(n)
|
||||
elif n.nodeName == 'groups':
|
||||
Group.init_from_xml(n)
|
||||
elif n.nodeName == 'services':
|
||||
Service.init_from_xml(n)
|
||||
|
||||
def to_xml():
|
||||
''' write internal data into xml file '''
|
||||
f = file(install_xml, 'w')
|
||||
xmldoc = minidom.Document()
|
||||
root = xmldoc.createElement('install')
|
||||
xmldoc.appendChild(root)
|
||||
|
||||
SerialNumber.to_xml(xmldoc, root)
|
||||
Partition.to_xml(xmldoc, root)
|
||||
Raid.to_xml(xmldoc, root)
|
||||
MountPoint.to_xml(xmldoc, root)
|
||||
Network.to_xml(xmldoc, root)
|
||||
Group.to_xml(xmldoc, root)
|
||||
Service.to_xml(xmldoc, root)
|
||||
|
||||
PrettyPrint(xmldoc, f)
|
||||
f.close()
|
||||
85
interface/ri_dep.py
Normal file
85
interface/ri_dep.py
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import ri_data
|
||||
|
||||
from xml.dom import minidom
|
||||
import os.path
|
||||
|
||||
dep_xml = os.path.join(os.path.dirname(__file__), '../xml/dependency.xml')
|
||||
|
||||
class Depending:
|
||||
''' Class recording depending relation '''
|
||||
dict={}
|
||||
def __init__(self, n):
|
||||
self.name = n
|
||||
self.depending = set()
|
||||
# flag for resolve recursive
|
||||
self.resolved = False
|
||||
Depending.dict[n] = self
|
||||
|
||||
def resolve_recursive(self):
|
||||
if self.resolved: return
|
||||
for d in self.depending:
|
||||
Depending.dict[d].resolve_recursive()
|
||||
tmp=set(self.depending)
|
||||
for d in self.depending:
|
||||
tmp.update(Depending.dict[d].depending)
|
||||
self.depending = tmp
|
||||
self.resolved = True
|
||||
|
||||
class Depended:
|
||||
''' Class recording depended by relation '''
|
||||
dict={}
|
||||
def __init__(self, n):
|
||||
self.name = n
|
||||
self.depended_by = set()
|
||||
Depended.dict[n] = self
|
||||
|
||||
def construct_depending():
|
||||
xml_doc = minidom.parse(dep_xml)
|
||||
xml_root = xml_doc.firstChild
|
||||
xml_dict = {}
|
||||
for n in xml_root.childNodes:
|
||||
if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'package':
|
||||
xml_dict[n.attributes['name'].value] = n
|
||||
Depending(n.attributes['name'].value)
|
||||
|
||||
for d in Depending.dict.values():
|
||||
n = xml_dict[d.name]
|
||||
for r in n.getElementsByTagName('runtime'):
|
||||
for dep in r.getElementsByTagName('depending'):
|
||||
d.depending.add(dep.attributes['package'].value)
|
||||
|
||||
def resolve_recursive_depending():
|
||||
for d in Depending.dict.values():
|
||||
d.resolve_recursive()
|
||||
|
||||
def construct_depended():
|
||||
for d in Depending.dict.values():
|
||||
for dep in d.depending:
|
||||
if not Depended.dict.has_key(dep):
|
||||
Depended(dep)
|
||||
Depended.dict[dep].depended_by.add(d.name)
|
||||
|
||||
def get_extra_depending():
|
||||
l = []
|
||||
for g in ri_data.Group.dict.values():
|
||||
if g.install != 'no':
|
||||
l.extend([ p for p in g.mandatory ])
|
||||
if g.selection == 'manual':
|
||||
l.extend([ p[0] for p in g.optional if p[1] == 'yes' ])
|
||||
else:
|
||||
l.extend([ p[0] for p in g.optional ])
|
||||
|
||||
set1 = set(l)
|
||||
set2 = set(set1)
|
||||
|
||||
for d in set1:
|
||||
set2.update(Depending.dict[d].depending)
|
||||
|
||||
res = {}
|
||||
for d in set2.difference(set1):
|
||||
res[d] = Depended.dict[d].depended_by.intersection(set1)
|
||||
|
||||
return res
|
||||
|
||||
42
interface/ri_seq.py
Normal file
42
interface/ri_seq.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
class Sequence:
|
||||
''' implement sequence in interface xml'''
|
||||
dict={}
|
||||
|
||||
def __init__(self, xml_node):
|
||||
self.steps = [ s.attributes["name"].value for s in xml_node.childNodes
|
||||
if s.nodeType == s.ELEMENT_NODE and s.nodeName == "widget" ]
|
||||
self.current_step = 0
|
||||
|
||||
def set_current_step(self, st):
|
||||
''' set current step based on input step name'''
|
||||
self.current_step = self.steps.index(st)
|
||||
|
||||
@staticmethod
|
||||
def set_current_sequence(name):
|
||||
Sequence.current_sequence = Sequence.dict[name]
|
||||
|
||||
@staticmethod
|
||||
def current():
|
||||
return (Sequence.current_sequence, Sequence.current_sequence.steps[Sequence.current_sequence.current_step])
|
||||
|
||||
@staticmethod
|
||||
def previous():
|
||||
if Sequence.current_sequence.current_step:
|
||||
Sequence.current_sequence.current_step -= 1
|
||||
return Sequence.current_sequence.steps[Sequence.current_sequence.current_step]
|
||||
|
||||
@staticmethod
|
||||
def next():
|
||||
if Sequence.current_sequence.current_step < len(Sequence.current_sequence.steps)-1:
|
||||
Sequence.current_sequence.current_step += 1
|
||||
return Sequence.current_sequence.steps[Sequence.current_sequence.current_step]
|
||||
|
||||
def construct(xml_root):
|
||||
''' construct Sequence's static members'''
|
||||
for s in xml_root.childNodes:
|
||||
if s.nodeType == s.ELEMENT_NODE and s.nodeName == "sequence":
|
||||
Sequence.dict[s.attributes["name"].value] = Sequence(s)
|
||||
|
||||
|
||||
349
interface/ri_tk.py
Normal file
349
interface/ri_tk.py
Normal file
@@ -0,0 +1,349 @@
|
||||
#!/usr/bin/python
|
||||
''' handle display related work upon Tkinter '''
|
||||
|
||||
import Tkinter
|
||||
import tkMessageBox
|
||||
import sys
|
||||
import ri_cmd
|
||||
import ri_widget
|
||||
|
||||
var_dict={}
|
||||
# language should be all lower case letters
|
||||
language='english'
|
||||
|
||||
def init(base_w):
|
||||
''' base_w - base widget instance '''
|
||||
global root_window
|
||||
root_window = Tkinter.Tk()
|
||||
|
||||
# grid management for root_window
|
||||
root_window.columnconfigure(0, weight=1)
|
||||
root_window.rowconfigure(0, weight=1)
|
||||
|
||||
root_window.geometry("%sx%s+0+0" %(root_window.winfo_screenwidth(),root_window.winfo_screenheight()))
|
||||
root_window.title(translate_text('Linx'))
|
||||
|
||||
# bind WM_DELETE_WINDOW
|
||||
root_window.protocol("WM_DELETE_WINDOW", root_window.quit)
|
||||
global base_widget
|
||||
base_widget = create_widget_sub(base_w, root_window)
|
||||
|
||||
def quit():
|
||||
''' exit root window '''
|
||||
root_window.quit()
|
||||
|
||||
def set_step_info(s):
|
||||
''' set some information in base widget '''
|
||||
# set step name which will be shown on base widget column 1 row 0
|
||||
title = translate_text(s)
|
||||
var_dict['main.step_name'].set(title)
|
||||
|
||||
def create_widget(w):
|
||||
''' w - widget instance '''
|
||||
|
||||
create_widget_sub(w, base_widget)
|
||||
|
||||
# set step name
|
||||
if 'name' in dir(w):
|
||||
set_step_info(w.name)
|
||||
|
||||
import os.path
|
||||
|
||||
class MyImage:
|
||||
''' MyImage - a dummy class to hold Image variable '''
|
||||
count = 0
|
||||
|
||||
def translate_text(txt):
|
||||
''' multi-language support, translate t if needed '''
|
||||
key = txt.lower()
|
||||
if key in ri_widget.Text.dict.keys() and (txt[0] == '#' or language != 'english'):
|
||||
return getattr(ri_widget.Text.dict[key], language)
|
||||
else:
|
||||
return txt
|
||||
|
||||
def modify_attributes(attr_dict):
|
||||
''' modify values in attr_dict to suit Tk usage '''
|
||||
for a in attr_dict.keys():
|
||||
if a == 'image':
|
||||
# I think there is a bug in Tkinter on Image processing
|
||||
# I have to bypass it in the following way:
|
||||
image_var = 'a' + str(MyImage.count)
|
||||
drt = os.path.join(os.path.dirname(__file__), '../data')
|
||||
setattr(MyImage, image_var, Tkinter.PhotoImage(file=os.path.join(drt, attr_dict[a])))
|
||||
MyImage.count += 1
|
||||
attr_dict[a] = getattr(MyImage, image_var)
|
||||
elif a == 'command':
|
||||
attr_dict[a] = getattr(sys.modules["ri_cmd"], attr_dict[a])
|
||||
elif a == "textvariable" or a == "listvariable" or a == 'variable':
|
||||
attr_dict[a] = var_dict[attr_dict[a]]
|
||||
elif a == "text":
|
||||
attr_dict[a] = translate_text(attr_dict[a])
|
||||
|
||||
def create_widget_sub(w, p_win):
|
||||
'''
|
||||
w - widget instance
|
||||
p_win - Tk parent window '''
|
||||
|
||||
# name type and value
|
||||
for v_n, v_t, v_v in w.variables:
|
||||
if not v_n in var_dict.keys():
|
||||
# if not yet in dict, create it
|
||||
var_dict[v_n] = getattr(Tkinter, v_t)(value=v_v)
|
||||
|
||||
# change attr, if needed to suit tk
|
||||
tk_attr = dict(w.attr)
|
||||
modify_attributes(tk_attr)
|
||||
|
||||
tk_func = getattr(Tkinter, w.tp)
|
||||
w_win = tk_func(p_win, tk_attr)
|
||||
|
||||
# display sub widgets
|
||||
for sub_w in w.widgets:
|
||||
create_widget_sub(sub_w, w_win)
|
||||
|
||||
# process action init
|
||||
if 'action' in dir(w) and 'init' in w.action.dict:
|
||||
getattr(sys.modules['ri_cmd'], w.action.dict['init'])()
|
||||
|
||||
# handle scroll bar for sub_widgets
|
||||
if 'action' in dir(w):
|
||||
# ing for scrolling, ed for scrolled
|
||||
for ing, ed in w.action.scrolls:
|
||||
ing_win = w.dict[ing].tk_widget
|
||||
ed_win = w.dict[ed].tk_widget
|
||||
if ing_win['orient'] == 'vertical':
|
||||
ed_cmd_name = 'yscrollcommand'
|
||||
ing_cmd = getattr(ed_win, 'yview')
|
||||
else:
|
||||
ed_cmd_name = 'xscrollcommand'
|
||||
ing_cmd = getattr(ed_win, 'xview')
|
||||
|
||||
ing_win.configure(command=ing_cmd)
|
||||
ed_win[ed_cmd_name]=ing_win.set
|
||||
|
||||
# grid management
|
||||
if 'grid_management' in dir(w):
|
||||
for cf in w.grid_management.cf_list:
|
||||
cf_func = getattr(w_win, cf[0])
|
||||
cf_func( cf[1], weight=cf[2])
|
||||
|
||||
# grid location
|
||||
if 'grid_location' in dir(w):
|
||||
w_win.grid(w.grid_location.dict)
|
||||
|
||||
# handle bindings
|
||||
for bd in w.bindings:
|
||||
w_win.bind(bd[0], getattr(ri_cmd, bd[1]))
|
||||
|
||||
# save tk widget instance into w (widget instance)
|
||||
setattr(w, 'tk_widget', w_win)
|
||||
|
||||
return w_win
|
||||
|
||||
# When creating widget, I have to create each sub widget.
|
||||
# while destroying a widget, only destroy one. Tk functions will
|
||||
# destroy all descendant.
|
||||
# so init is a little different from quit.
|
||||
def process_action_quit(w):
|
||||
''' process action quit '''
|
||||
if 'action' in dir(w) and 'quit' in w.action.dict:
|
||||
getattr(sys.modules['ri_cmd'], w.action.dict['quit'])()
|
||||
|
||||
if 'widgets' in dir(w):
|
||||
for sub_w in w.widgets:
|
||||
process_action_quit(sub_w)
|
||||
|
||||
def destroy_widget(w):
|
||||
''' w - Widget instance '''
|
||||
process_action_quit(w)
|
||||
w.tk_widget.destroy()
|
||||
|
||||
def create_message_box(w):
|
||||
''' display MessageBox
|
||||
w - MessageBox instance'''
|
||||
disp = getattr(tkMessageBox, w.tp)
|
||||
disp(translate_text(w.title), translate_text(w.message))
|
||||
|
||||
def create_top_window(w):
|
||||
''' display TopWindow
|
||||
w - TopWindow instance '''
|
||||
tk_attr = dict(w.attr)
|
||||
modify_attributes(tk_attr)
|
||||
|
||||
w_win = Tkinter.Toplevel(root_window, tk_attr)
|
||||
|
||||
for sub_w in w.widgets:
|
||||
create_widget_sub(sub_w, w_win)
|
||||
|
||||
if 'grid_management' in dir(w):
|
||||
for cf in w.grid_management.cf_list:
|
||||
cf_func = getattr(w_win, cf[0])
|
||||
cf_func(cf[1], weight=cf[2])
|
||||
|
||||
# save tk widget instance into w (TopWindow instance)
|
||||
setattr(w, 'tk_widget', w_win)
|
||||
|
||||
# 'bind' it to root window
|
||||
w_win.transient(root_window)
|
||||
# grab all events into it
|
||||
while True:
|
||||
try:
|
||||
w_win.grab_set()
|
||||
except Tkinter.TclError:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
w_win.wait_window()
|
||||
|
||||
return w_win
|
||||
|
||||
def destroy_top_window(w):
|
||||
''' w - Toplevel instance '''
|
||||
w.tk_widget.destroy()
|
||||
|
||||
class SoftwarePackageWindow():
|
||||
''' Toplevel window for a group of software packages
|
||||
class member
|
||||
---------------------------
|
||||
dict - class static member
|
||||
---------------------------
|
||||
|
||||
instance member
|
||||
---------------------------
|
||||
group - data layer group instance
|
||||
win - Tk widget
|
||||
selection - StringVar variable for 'select_all'
|
||||
opt_vars - a list to hold variables containing status for optional packages
|
||||
opt_chks - a list to hold Checkbuttons for optional packages
|
||||
'''
|
||||
dict = {}
|
||||
def __init__(self, g):
|
||||
self.group = g
|
||||
self.opt_vars = []
|
||||
self.opt_chks = []
|
||||
SoftwarePackageWindow.dict[g.name] = self
|
||||
|
||||
def select_all(self):
|
||||
''' callback function for check button select_all '''
|
||||
if self.selection.get() == 'all':
|
||||
for ck in self.opt_chks:
|
||||
ck.configure(state='disable')
|
||||
else:
|
||||
for ck in self.opt_chks:
|
||||
ck.configure(state='normal')
|
||||
|
||||
|
||||
def ok(self):
|
||||
''' callback function for button OK '''
|
||||
self.group.selection = self.selection.get()
|
||||
for i in range(len(self.group.optional)):
|
||||
# install field, yes or no
|
||||
self.group.optional[i][1] = self.opt_vars[i].get()
|
||||
# clear variables and check buttons
|
||||
self.opt_vars = []
|
||||
self.opt_chks = []
|
||||
self.win.destroy()
|
||||
|
||||
def cancel(self):
|
||||
''' callback function for button cancel '''
|
||||
# clear variables and check buttons
|
||||
self.opt_vars = []
|
||||
self.opt_chks = []
|
||||
self.win.destroy()
|
||||
|
||||
def show(self):
|
||||
win = Tkinter.Toplevel(root_window)
|
||||
self.win = win
|
||||
win.geometry("%sx%s+%s+%s" %(int(root_window.winfo_screenwidth()*0.8),\
|
||||
int(root_window.winfo_screenheight()*0.8),\
|
||||
int(root_window.winfo_screenwidth()*0.1),\
|
||||
int(root_window.winfo_screenheight()*0.1)))
|
||||
win.columnconfigure(0, weight=1)
|
||||
win.rowconfigure(1, weight=1)
|
||||
win.rowconfigure(4, weight=1)
|
||||
|
||||
text_mdt = translate_text('Mandatory')
|
||||
Tkinter.Label(win, text=text_mdt).grid(column=0, row=0)
|
||||
cnv1 = Tkinter.Canvas(win)
|
||||
hs1 = Tkinter.Scrollbar(win, orient='horizontal')
|
||||
hs1.configure(command=cnv1.xview)
|
||||
vs1 = Tkinter.Scrollbar(win, orient='vertical')
|
||||
vs1.configure(command=cnv1.yview)
|
||||
cnv1.grid(column=0, row=1, sticky='NWES')
|
||||
vs1.grid(column=1, row=1, sticky='NSW')
|
||||
hs1.grid(column=0, row=2, sticky='NWE')
|
||||
cnv1.configure(yscrollcommand=vs1.set, xscrollcommand=hs1.set)
|
||||
fr1 = Tkinter.Frame(cnv1)
|
||||
cnv1.create_window((0,0), window=fr1, anchor='nw')
|
||||
#column set to 5
|
||||
fr1.columnconfigure(0, weight=1)
|
||||
fr1.columnconfigure(1, weight=1)
|
||||
fr1.columnconfigure(2, weight=1)
|
||||
fr1.columnconfigure(3, weight=1)
|
||||
fr1.columnconfigure(4, weight=1)
|
||||
|
||||
for i in range(len(self.group.mandatory)):
|
||||
Tkinter.Label(fr1, text=self.group.mandatory[i]).grid(column=i%5, row=i/5, sticky='NWES')
|
||||
|
||||
text_opt = translate_text('Optional')
|
||||
Tkinter.Label(win, text=text_opt).grid(column=0, row=3)
|
||||
self.selection = Tkinter.StringVar(value=self.group.selection)
|
||||
text_sal = translate_text('Select all')
|
||||
chk_sa = Tkinter.Checkbutton(win, text=text_sal, command=self.select_all, variable=self.selection, onvalue='all', offvalue='manual')
|
||||
chk_sa.grid(column=1, row=3)
|
||||
if self.group.selection == 'all':
|
||||
chk_sa.select()
|
||||
else:
|
||||
chk_sa.deselect()
|
||||
|
||||
cnv2 = Tkinter.Canvas(win)
|
||||
hs2 = Tkinter.Scrollbar(win, orient='horizontal')
|
||||
hs2.configure(command=cnv2.xview)
|
||||
vs2 = Tkinter.Scrollbar(win, orient='vertical')
|
||||
vs2.configure(command=cnv2.yview)
|
||||
cnv2.grid(column=0, row=4, sticky='NWES')
|
||||
vs2.grid(column=1, row=4, sticky='NSW')
|
||||
hs2.grid(column=0, row=5, sticky='NWE')
|
||||
cnv2.configure(yscrollcommand=vs2.set, xscrollcommand=hs2.set)
|
||||
fr2 = Tkinter.Frame(cnv2)
|
||||
cnv2.create_window((0,0), window=fr2, anchor='nw')
|
||||
#column set to 5
|
||||
fr2.columnconfigure(0, weight=1)
|
||||
fr2.columnconfigure(1, weight=1)
|
||||
fr2.columnconfigure(2, weight=1)
|
||||
fr2.columnconfigure(3, weight=1)
|
||||
fr2.columnconfigure(4, weight=1)
|
||||
|
||||
for i in range(len(self.group.optional)):
|
||||
name, y_n = self.group.optional[i]
|
||||
v = Tkinter.StringVar(value='no')
|
||||
self.opt_vars.append(v)
|
||||
chk = Tkinter.Checkbutton(fr2, text=name, onvalue='yes', offvalue='no', variable=self.opt_vars[i])
|
||||
self.opt_chks.append(chk)
|
||||
chk.grid(column=i%5, row=i/5, sticky='NWS')
|
||||
if y_n == 'yes':
|
||||
chk.select()
|
||||
else:
|
||||
chk.deselect()
|
||||
|
||||
if self.group.selection == 'all':
|
||||
chk.configure(state='disable')
|
||||
|
||||
Tkinter.Button(win, text='OK', command=self.ok).grid(column=0, row=6, pady=2)
|
||||
Tkinter.Button(win, text='Cancel', command=self.cancel).grid(column=1, row=6, pady=2)
|
||||
|
||||
win.after_idle(lambda : cnv1.configure(scrollregion=(0,0, fr1.winfo_width(), fr1.winfo_height())))
|
||||
win.after_idle(lambda : cnv2.configure(scrollregion=(0,0, fr2.winfo_width(), fr2.winfo_height())))
|
||||
|
||||
win.transient(root_window)
|
||||
# grab all events into it
|
||||
while True:
|
||||
try:
|
||||
win.grab_set()
|
||||
except Tkinter.TclError:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
win.wait_window()
|
||||
358
interface/ri_tk_cmd.py
Normal file
358
interface/ri_tk_cmd.py
Normal file
@@ -0,0 +1,358 @@
|
||||
#!/usr/bin/python
|
||||
''' handle gui commands '''
|
||||
import ri_tk as display
|
||||
import ri_widget
|
||||
import ri_data
|
||||
import ri_dep
|
||||
|
||||
import re
|
||||
import copy
|
||||
import sys
|
||||
|
||||
def serial_no_init():
|
||||
display.var_dict['serial_no.number'].set(value=ri_data.SerialNumber.value)
|
||||
|
||||
def serial_no_quit():
|
||||
ri_data.SerialNumber.value = display.var_dict['serial_no.number'].get()
|
||||
|
||||
def mount_list_init():
|
||||
''' initialize mount list '''
|
||||
ri_data.MountPoint.init_from_internal()
|
||||
l = []
|
||||
for m in ri_data.MountPoint.list:
|
||||
# get size from Partition info
|
||||
sz = ri_data.Partition.get_size(m.device)
|
||||
if not sz:
|
||||
sz = ri_data.Raid.get_size(m.device)
|
||||
s = m.device.ljust(10) + m.directory.ljust(10) + m.filesystem.ljust(10) + m.format.ljust(4) + sz.ljust(6)
|
||||
l.append(s)
|
||||
display.var_dict['mount.list'].set(value=tuple([str(i) for i in l]))
|
||||
|
||||
def mount_list_modify(*args):
|
||||
''' modify an item in mount list '''
|
||||
tw = ri_widget.TopWindow.dict['mount_list_modify']
|
||||
tw.show()
|
||||
|
||||
def mp_top_init():
|
||||
''' mount dir top window initialize '''
|
||||
ml_win = ri_widget.Widget.dict['mount.list'].tk_widget
|
||||
idxs = ml_win.curselection()
|
||||
if len(idxs) == 1:
|
||||
idx = int(idxs[0])
|
||||
mp = ri_data.MountPoint.list[idx]
|
||||
dev = mp.device
|
||||
dir = mp.directory
|
||||
fs = mp.filesystem
|
||||
fm = mp.format
|
||||
sz = mp.size
|
||||
display.var_dict['mp_top_dev'].set(value=dev)
|
||||
display.var_dict['mp_top_size'].set(value=sz)
|
||||
display.var_dict['mp_top_dir'].set(value=dir)
|
||||
if fm == 'yes':
|
||||
ri_widget.Widget.dict['mp_top_format'].tk_widget.select()
|
||||
else:
|
||||
ri_widget.Widget.dict['mp_top_not_format'].tk_widget.select()
|
||||
|
||||
fs_values = eval(display.var_dict['mp_top_fs'].get())
|
||||
for i in range(len(fs_values)):
|
||||
if fs == fs_values[i]:
|
||||
ri_widget.Widget.dict['mp_top_fs'].tk_widget.selection_set(i)
|
||||
|
||||
def mp_top_ok():
|
||||
''' mount dir top window OK '''
|
||||
l = []
|
||||
for itm in eval(display.var_dict['mount.list'].get()):
|
||||
dev = itm.split()[0]
|
||||
dev2 = display.var_dict['mp_top_dev'].get()
|
||||
if dev == dev2:
|
||||
sz = display.var_dict['mp_top_size'].get()
|
||||
dir = display.var_dict['mp_top_dir'].get()
|
||||
fm = display.var_dict['mp_top_format'].get()
|
||||
idxs2 = ri_widget.Widget.dict['mp_top_fs'].tk_widget.curselection()
|
||||
if len(idxs2):
|
||||
idx2 = int(idxs2[0])
|
||||
fs = eval(display.var_dict['mp_top_fs'].get())[idx2]
|
||||
else:
|
||||
fs = ''
|
||||
|
||||
s2 = dev.ljust(10) + dir.ljust(10) + fs.ljust(10) + fm.ljust(4) + sz.ljust(6)
|
||||
l.append(s2)
|
||||
# make change in internal data structure
|
||||
ri_data.MountPoint.change(dev2, dir, fs, fm)
|
||||
else:
|
||||
l.append(itm)
|
||||
|
||||
display.var_dict['mount.list'].set(value=tuple(l))
|
||||
ri_widget.TopWindow.dict['mount_list_modify'].hide()
|
||||
|
||||
def mp_top_cancel():
|
||||
''' mount dir top window cancel '''
|
||||
ri_widget.TopWindow.dict['mount_list_modify'].hide()
|
||||
pass
|
||||
|
||||
def network_init():
|
||||
''' network initialize '''
|
||||
display.var_dict['network_host_name']. set(value=ri_data.Network.hostname)
|
||||
ri_widget.Widget.dict['network_config_%s' %(ri_data.Network.configuration and ri_data.Network.configuration or 'static')].tk_widget.invoke()
|
||||
display.var_dict['network_domain_name']. set(value=ri_data.Network.domain)
|
||||
display.var_dict['network_ip']. set(value=ri_data.Network.ip)
|
||||
display.var_dict['network_subnet_mask']. set(value=ri_data.Network.mask)
|
||||
display.var_dict['network_gateway']. set(value=ri_data.Network.gateway)
|
||||
display.var_dict['network_primary_dns']. set(value=ri_data.Network.primary_dns)
|
||||
display.var_dict['network_secondary_dns'].set(value=ri_data.Network.secondary_dns)
|
||||
|
||||
def network_quit():
|
||||
''' network quit '''
|
||||
ri_data.Network.hostname = display.var_dict['network_host_name'].get()
|
||||
ri_data.Network.configuration = display.var_dict['network_config_method'].get()
|
||||
ri_data.Network.domain = display.var_dict['network_domain_name'].get()
|
||||
ri_data.Network.ip = display.var_dict['network_ip'].get()
|
||||
ri_data.Network.mask = display.var_dict['network_subnet_mask'].get()
|
||||
ri_data.Network.gateway = display.var_dict['network_gateway'].get()
|
||||
ri_data.Network.primary_dns = display.var_dict['network_primary_dns'].get()
|
||||
ri_data.Network.secondary_dns = display.var_dict['network_secondary_dns'].get()
|
||||
|
||||
def ncm_dynamic():
|
||||
''' when radio button ncm dynamic is checked, several data entry will be set 'disable' '''
|
||||
|
||||
for n in ('network_domain_name','network_ip','network_subnet_mask','network_gateway','network_primary_dns','network_secondary_dns'):
|
||||
ri_widget.Widget.dict[n].tk_widget.configure(state='disable')
|
||||
|
||||
def ncm_static():
|
||||
''' when radio button ncm static is checked, several data entry will be set 'normal' '''
|
||||
for n in ('network_domain_name','network_ip','network_subnet_mask','network_gateway','network_primary_dns','network_secondary_dns'):
|
||||
ri_widget.Widget.dict[n].tk_widget.configure(state='normal')
|
||||
|
||||
class GroupButton(object):
|
||||
''' A function class called whenever the group button is clicked '''
|
||||
dict={}
|
||||
def __init__(self, g):
|
||||
self.name = g.name
|
||||
GroupButton.dict[g.name] = self
|
||||
display.SoftwarePackageWindow(g)
|
||||
|
||||
def __call__(self):
|
||||
print self.name
|
||||
display.SoftwarePackageWindow.dict[self.name].show()
|
||||
|
||||
class GroupCheck(GroupButton):
|
||||
''' A function class called whenever the group check button is checked '''
|
||||
def __init__(self, g, v):
|
||||
self.variable = v
|
||||
GroupButton.__init__(self, g)
|
||||
|
||||
def __call__(self):
|
||||
v = display.var_dict[self.variable]
|
||||
if v.get() == 'yes':
|
||||
display.SoftwarePackageWindow.dict[self.name].show()
|
||||
|
||||
def software_group_mandatory_construct(w):
|
||||
''' construct widgets based actual data
|
||||
w - Widget instance '''
|
||||
mdt = [ m for m in ri_data.Group.dict.values() if m.install == 'mandatory' ]
|
||||
wit = w.widgets.pop()
|
||||
for i in mdt:
|
||||
wi = copy.deepcopy(wit)
|
||||
wi.attr['text'] = i.name
|
||||
vn = "software_group_%s" %(i.name)
|
||||
idx = mdt.index(i)
|
||||
wi.grid_location.dict['column'] = idx % int(w.grid_management.columns)
|
||||
wi.grid_location.dict['row'] = idx / int(w.grid_management.columns)
|
||||
gc = GroupButton(i)
|
||||
setattr(sys.modules['ri_cmd'], vn, gc)
|
||||
wi.attr['command'] = vn
|
||||
w.add_sub_widget(wi)
|
||||
|
||||
def software_group_optional_construct(w):
|
||||
''' construct widgets based actual data
|
||||
w - Widget instance '''
|
||||
opt = [ o for o in ri_data.Group.dict.values() if o.install != 'mandatory' ]
|
||||
wit = w.widgets.pop()
|
||||
for i in opt:
|
||||
wi = copy.deepcopy(wit)
|
||||
wi.attr['text'] = i.name
|
||||
vn = "software_group_%s" %(i.name)
|
||||
idx = opt.index(i)
|
||||
wi.grid_location.dict['column'] = idx % int(w.grid_management.columns)
|
||||
wi.grid_location.dict['row'] = idx / int(w.grid_management.columns)
|
||||
gc = GroupCheck(i, vn)
|
||||
setattr(sys.modules['ri_cmd'], vn, gc)
|
||||
wi.attr['command'] = vn
|
||||
wi.attr['variable'] = vn
|
||||
wi.variables = [(vn, 'StringVar', i.install),]
|
||||
w.add_sub_widget(wi)
|
||||
|
||||
def software_group_optional_quit():
|
||||
''' software group window quit, record optional group state '''
|
||||
opt = [ o for o in ri_data.Group.dict.values() if o.install != 'mandatory' ]
|
||||
for i in opt:
|
||||
print i.name
|
||||
vn = "software_group_%s" %(i.name)
|
||||
i.install = display.var_dict[vn].get()
|
||||
print i.name, i.install
|
||||
|
||||
def dependency_list_init():
|
||||
''' init function for list in dependency step '''
|
||||
ri_dep.construct_depending()
|
||||
ri_dep.resolve_recursive_depending()
|
||||
ri_dep.construct_depended()
|
||||
dep_dict = ri_dep.get_extra_depending()
|
||||
l = [ k.ljust(20) + ': ' + ' '.join(dep_dict[k]) for k in dep_dict.keys()]
|
||||
display.var_dict['dependency.list'].set(value=tuple(l))
|
||||
|
||||
def service_construct(w):
|
||||
''' construct service widget based on actual data
|
||||
w - Widget instance '''
|
||||
|
||||
# first refresh service state
|
||||
wit = w.widgets.pop()
|
||||
for i in ri_data.Service.list:
|
||||
wi = copy.deepcopy(wit)
|
||||
vn = "service_%s" %(i.name)
|
||||
# process widget name
|
||||
wi.name = vn
|
||||
ri_widget.Widget.dict[vn] = wi
|
||||
wi.attr['text'] = i.name
|
||||
wi.attr['variable'] = vn
|
||||
wi.variables = [(vn, 'StringVar', '')]
|
||||
idx = ri_data.Service.list.index(i)
|
||||
wi.grid_location.dict['column'] = idx % int(w.grid_management.columns)
|
||||
wi.grid_location.dict['row'] = idx / int(w.grid_management.columns)
|
||||
w.add_sub_widget(wi)
|
||||
|
||||
def service_init():
|
||||
''' initialize service checkboxes, based on package selection '''
|
||||
# first refresh service state
|
||||
ri_data.Service.change_state()
|
||||
for i in ri_data.Service.list:
|
||||
vn = "service_%s" %(i.name)
|
||||
win = ri_widget.Widget.dict[vn].tk_widget
|
||||
if i.start == 'disable':
|
||||
win.configure(state = 'disable')
|
||||
display.var_dict[vn].set(value=i.start=='yes' and 'yes' or 'no')
|
||||
|
||||
def service_quit():
|
||||
''' record service state '''
|
||||
for i in ri_data.Service.list:
|
||||
if i.start != 'disable':
|
||||
vn = "service_%s" %(i.name)
|
||||
i.start = display.var_dict[vn].get()
|
||||
|
||||
def raid_raw_init():
|
||||
''' initialize raid raw devices (parttion with id 'fd' '''
|
||||
global raid_raw_initialized
|
||||
if not raid_raw_initialized:
|
||||
raid_raw_initialized = True
|
||||
# get all component devices already in raid
|
||||
dev_in_raid = set()
|
||||
for r in ri_data.Raid.list:
|
||||
dev_in_raid.update(r.active_components)
|
||||
dev_in_raid.update(r.spare_components)
|
||||
|
||||
raw_devs = [ p.device for p in ri_data.Partition.list
|
||||
if p.id == 'fd' and p.device not in dev_in_raid ]
|
||||
display.var_dict['raid_raw_devs'].set(value=tuple(raw_devs))
|
||||
|
||||
def list_to_list(list_from, var_from, var_to):
|
||||
''' move item from list a to list b '''
|
||||
win_from = ri_widget.Widget.dict[list_from].tk_widget
|
||||
idxs = win_from.curselection()
|
||||
if len(idxs) == 1:
|
||||
idx = int(idxs[0])
|
||||
l_fr = list(eval(display.var_dict[var_from].get()))
|
||||
itm = l_fr[idx]
|
||||
del l_fr[idx]
|
||||
display.var_dict[var_from].set(value=tuple(l_fr))
|
||||
l_to = list(eval(display.var_dict[var_to].get()))
|
||||
l_to.append(itm)
|
||||
display.var_dict[var_to].set(value=tuple(l_to))
|
||||
|
||||
def raid_raw_to_active():
|
||||
''' move device from raw to active '''
|
||||
list_to_list('raid_raw.list', 'raid_raw_devs', 'raid_active_devs')
|
||||
|
||||
def raid_active_to_raw():
|
||||
''' move device from active to raw '''
|
||||
list_to_list('raid_active.list', 'raid_active_devs', 'raid_raw_devs')
|
||||
|
||||
def raid_raw_to_spare():
|
||||
''' move device from raw to spare '''
|
||||
list_to_list('raid_raw.list', 'raid_raw_devs', 'raid_spare_devs')
|
||||
|
||||
def raid_spare_to_raw():
|
||||
''' move device from spare to raw '''
|
||||
list_to_list('raid_spare.list', 'raid_spare_devs', 'raid_raw_devs')
|
||||
|
||||
def raid_device_init():
|
||||
''' initialize raid device list '''
|
||||
raid_devs = [ r.device for r in ri_data.Raid.list ]
|
||||
display.var_dict['raid_devs'].set(value=tuple(raid_devs))
|
||||
|
||||
def raid_calc_size(level, devs):
|
||||
''' calculate raid device size
|
||||
level - raid level (0/1/5)
|
||||
devs - raid component devices
|
||||
'''
|
||||
# all devs shall have same size.
|
||||
for p in ri_data.Partition.list:
|
||||
if p.device == devs[0]:
|
||||
sz = p.size
|
||||
break
|
||||
if level == '0':
|
||||
return len(devs)*sz
|
||||
elif level == '1':
|
||||
return sz
|
||||
elif level == '5':
|
||||
return sz*(len(devs)-1)
|
||||
|
||||
def raid_device_add():
|
||||
''' add a new raid device '''
|
||||
active = eval(display.var_dict['raid_active_devs'].get())
|
||||
spare = eval(display.var_dict['raid_spare_devs'].get())
|
||||
level = display.var_dict['raid_level'].get()
|
||||
|
||||
if not active or not level:
|
||||
ri_widget.MessageBox.dict["raid_add_warning"].show()
|
||||
return
|
||||
|
||||
dev = ri_data.Raid.get_next_device()
|
||||
ri_data.Raid(dev, False, level, raid_calc_size(level, active), active, spare)
|
||||
raid_device_init()
|
||||
display.var_dict['raid_active_devs'].set(value='')
|
||||
display.var_dict['raid_spare_devs'].set(value='')
|
||||
ri_widget.Widget.dict['raid_level_0'].tk_widget.deselect()
|
||||
ri_widget.Widget.dict['raid_level_1'].tk_widget.deselect()
|
||||
ri_widget.Widget.dict['raid_level_5'].tk_widget.deselect()
|
||||
|
||||
def raid_device_delete():
|
||||
''' delete a raid device, put its component devices into active/spare device list '''
|
||||
win_dev = ri_widget.Widget.dict['raid_dev.list'].tk_widget
|
||||
idxs = win_dev.curselection()
|
||||
if len(idxs) == 1:
|
||||
idx = int(idxs[0])
|
||||
r = ri_data.Raid.list[idx]
|
||||
if r.from_os:
|
||||
ri_widget.MessageBox.dict["raid_delete_warning"].show()
|
||||
return
|
||||
active = list(eval(display.var_dict['raid_active_devs'].get()))
|
||||
active.extend(r.active_components)
|
||||
spare = list(eval(display.var_dict['raid_spare_devs'].get()))
|
||||
spare.extend(r.spare_components)
|
||||
# do not touch level
|
||||
display.var_dict['raid_active_devs'].set(value=tuple(active))
|
||||
display.var_dict['raid_spare_devs'].set(value=tuple(spare))
|
||||
del ri_data.Raid.list[idx]
|
||||
raid_device_init()
|
||||
|
||||
def raid_device_list_detail(*args):
|
||||
''' show details of a raid device '''
|
||||
win = ri_widget.Widget.dict['raid_dev.list'].tk_widget
|
||||
idxs = win.curselection()
|
||||
if len(idxs) == 1:
|
||||
idx = int(idxs[0])
|
||||
r = ri_data.Raid.list[idx]
|
||||
display.var_dict['raid_detail_active'].set(value='active: %s' %(str(r.active_components)))
|
||||
display.var_dict['raid_detail_spare'].set(value='spare: %s' %(str(r.spare_components)))
|
||||
display.var_dict['raid_detail_level'].set(value='level: %s' %(str(r.level)))
|
||||
|
||||
raid_raw_initialized = False
|
||||
201
interface/ri_widget.py
Normal file
201
interface/ri_widget.py
Normal file
@@ -0,0 +1,201 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import ri_tk as display
|
||||
import sys
|
||||
import ri_cmd
|
||||
|
||||
class GridManagement:
|
||||
''' implement grid management '''
|
||||
def __init__(self, xml_node):
|
||||
self.rows = xml_node.attributes['rows'].value
|
||||
self.columns = xml_node.attributes['columns'].value
|
||||
self.cf_list=[]
|
||||
for cf in xml_node.childNodes:
|
||||
if cf.nodeType != cf.ELEMENT_NODE or cf.nodeName != "configure":
|
||||
continue
|
||||
if "row" in cf.attributes.keys():
|
||||
cf_func = "rowconfigure"
|
||||
n = cf.attributes["row"].value
|
||||
elif "column" in cf.attributes.keys():
|
||||
cf_func = "columnconfigure"
|
||||
n = cf.attributes["column"].value
|
||||
else:
|
||||
continue
|
||||
self.cf_list.append((cf_func, n, cf.attributes["weight"].value))
|
||||
|
||||
class GridLocation:
|
||||
''' implement grid_location in interface xml '''
|
||||
def __init__(self, xml_node):
|
||||
self.dict={}
|
||||
for a in xml_node.attributes.values():
|
||||
self.dict[a.name] = a.value
|
||||
|
||||
class Action:
|
||||
''' implement action in interface xml '''
|
||||
def __init__(self, xml_node):
|
||||
self.dict={}
|
||||
for a in xml_node.attributes.values():
|
||||
self.dict[a.name] = a.value
|
||||
self.scrolls = []
|
||||
for node in xml_node.childNodes:
|
||||
if node.nodeName == 'scroll':
|
||||
self.scrolls.append((node.attributes['scrolling'].value, node.attributes['scrolled'].value))
|
||||
|
||||
class Widget:
|
||||
''' implement widget in interface xml '''
|
||||
current_widget=""
|
||||
dict={}
|
||||
|
||||
def __init__(self, xml_node):
|
||||
if 'name' in xml_node.attributes.keys():
|
||||
self.name = xml_node.attributes["name"].value
|
||||
Widget.dict[self.name] = self
|
||||
|
||||
self.tp = xml_node.attributes["type"].value
|
||||
self.attr = {}
|
||||
self.widgets=[]
|
||||
self.variables=[]
|
||||
self.bindings = []
|
||||
for node in xml_node.childNodes:
|
||||
if node.nodeType == node.ELEMENT_NODE:
|
||||
if node.nodeName == "grid_management":
|
||||
self.grid_management = GridManagement(node)
|
||||
elif node.nodeName == "grid_location":
|
||||
self.grid_location = GridLocation(node)
|
||||
elif node.nodeName == "widget_attribute":
|
||||
for a in node.attributes.values():
|
||||
self.attr[a.name] = a.value
|
||||
elif node.nodeName == "widget":
|
||||
self.widgets.append(Widget(node))
|
||||
elif node.nodeName == "variable":
|
||||
self.variables.append((node.attributes["name"].value, \
|
||||
node.attributes["type"].value, \
|
||||
"value" in node.attributes.keys() and node.attributes["value"].value or "" ))
|
||||
elif node.nodeName == "action":
|
||||
self.action = Action(node)
|
||||
elif node.nodeName == 'binding':
|
||||
seq = node.attributes["sequence"].value
|
||||
self.bindings.append((seq, \
|
||||
node.attributes["function"].value))
|
||||
|
||||
if 'construct' in xml_node.attributes.keys():
|
||||
getattr(ri_cmd, xml_node.attributes["construct"].value)(self)
|
||||
|
||||
|
||||
def add_sub_widget(self, w):
|
||||
self.widgets.append(w)
|
||||
|
||||
def show(self):
|
||||
Widget.current_widget = self
|
||||
display.create_widget(self)
|
||||
|
||||
def hide(self):
|
||||
display.destroy_widget(self)
|
||||
|
||||
class MessageBox:
|
||||
''' implement dialog in interface.xml '''
|
||||
dict={}
|
||||
|
||||
def __init__(self, xml_node):
|
||||
self.name = xml_node.attributes["name"].value
|
||||
self.tp = xml_node.attributes["type"].value
|
||||
self.title = xml_node.attributes["title"].value
|
||||
self.message = xml_node.attributes["message"].value
|
||||
|
||||
MessageBox.dict[self.name] = self
|
||||
|
||||
def show(self):
|
||||
''' display dialog'''
|
||||
display.create_message_box(self)
|
||||
|
||||
class TopWindow:
|
||||
''' implement top_window in interface.xml - top_window corresponds to Toplevel in Tkinter '''
|
||||
dict={}
|
||||
def __init__(self, xml_node):
|
||||
self.name = xml_node.attributes["name"].value
|
||||
TopWindow.dict[self.name] = self
|
||||
self.attr = {}
|
||||
self.widgets = []
|
||||
for node in xml_node.childNodes:
|
||||
if node.nodeType == node.ELEMENT_NODE:
|
||||
if node.nodeName == 'grid_management':
|
||||
self.grid_management = GridManagement(node)
|
||||
elif node.nodeName == "widget_attribute":
|
||||
for a in node.attributes.values():
|
||||
self.attr[a.name] = a.value
|
||||
elif node.nodeName == "widget":
|
||||
self.widgets.append(Widget(node))
|
||||
|
||||
def show(self):
|
||||
display.create_top_window(self)
|
||||
|
||||
def hide(self):
|
||||
display.destroy_top_window(self)
|
||||
|
||||
class Sequence:
|
||||
''' implement sequence in interface xml'''
|
||||
dict={}
|
||||
|
||||
def __init__(self, xml_node):
|
||||
self.steps = [ s.attributes["name"].value for s in xml_node.childNodes
|
||||
if s.nodeType == s.ELEMENT_NODE and s.nodeName == "widget" ]
|
||||
self.current_step = 0
|
||||
Sequence.dict[xml_node.attributes["name"].value] = self
|
||||
|
||||
def set_current_step(self, st):
|
||||
''' set current step based on input step name'''
|
||||
self.current_step = self.steps.index(st)
|
||||
|
||||
@staticmethod
|
||||
def set_current_sequence(name):
|
||||
Sequence.current_sequence = Sequence.dict[name]
|
||||
|
||||
@staticmethod
|
||||
def current():
|
||||
return (Sequence.current_sequence, Sequence.current_sequence.steps[Sequence.current_sequence.current_step])
|
||||
|
||||
@staticmethod
|
||||
def previous():
|
||||
if Sequence.current_sequence.current_step:
|
||||
Sequence.current_sequence.current_step -= 1
|
||||
return Sequence.current_sequence.steps[Sequence.current_sequence.current_step]
|
||||
|
||||
@staticmethod
|
||||
def next():
|
||||
if Sequence.current_sequence.current_step < len(Sequence.current_sequence.steps)-1:
|
||||
Sequence.current_sequence.current_step += 1
|
||||
return Sequence.current_sequence.steps[Sequence.current_sequence.current_step]
|
||||
|
||||
class Text:
|
||||
''' implement text in interface.xml '''
|
||||
dict={}
|
||||
|
||||
def __init__(self, xml_node):
|
||||
for n in xml_node.childNodes:
|
||||
if n.nodeType == n.ELEMENT_NODE:
|
||||
if n.nodeName == 'English': self.english = n.firstChild.data
|
||||
elif n.nodeName == 'Chinese': self.chinese = n.firstChild.data
|
||||
|
||||
if 'key' in xml_node.attributes.keys():
|
||||
self.key = xml_node.attributes['key'].value
|
||||
else:
|
||||
self.key = self.english
|
||||
Text.dict[self.key.lower()] = self
|
||||
|
||||
def construct(xml_root):
|
||||
''' construct Widget's static members'''
|
||||
for n in xml_root.childNodes:
|
||||
if n.nodeType == n.ELEMENT_NODE:
|
||||
if n.nodeName == "widget": Widget(n)
|
||||
elif n.nodeName == "message_box": MessageBox(n)
|
||||
elif n.nodeName == "top_window": TopWindow(n)
|
||||
elif n.nodeName == "sequence": Sequence(n)
|
||||
elif n.nodeName == "text": Text(n)
|
||||
|
||||
def init_display(bw):
|
||||
''' base widget name'''
|
||||
display.init(Widget.dict[bw])
|
||||
|
||||
def mainloop():
|
||||
'''run message main loop '''
|
||||
display.root_window.mainloop()
|
||||
62
interface/test.py
Normal file
62
interface/test.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import ri_widget
|
||||
import ri_tk
|
||||
import ri_data
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
from xml.dom import minidom
|
||||
import os.path
|
||||
|
||||
def print_usages():
|
||||
print 'Usages: %s [-b|--begin step_name] [-l|--language language] [interface_xml_file] [install_xml_file]' %sys.argv[0]
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "b:l:", ["begin=","language="])
|
||||
except getopt.GetoptError:
|
||||
print_usages()
|
||||
sys.exit(1)
|
||||
|
||||
begin_step=None
|
||||
for opt, arg in opts:
|
||||
if opt in ('-b', '--begin'):
|
||||
begin_step = arg
|
||||
elif opt in ('-l', '--language'):
|
||||
ri_tk.language = arg.lower()
|
||||
|
||||
if len(args) == 0:
|
||||
itf_xml = "../xml/interface.xml"
|
||||
ins_xml = "../xml/install.xml"
|
||||
elif len(args) == 1:
|
||||
itf_xml = args[0]
|
||||
ins_xml = "../xml/install.xml"
|
||||
else:
|
||||
itf_xml = args[0]
|
||||
ins_xml = args[1]
|
||||
|
||||
xmldoc = minidom.parse(itf_xml)
|
||||
ri_data.install_xml = ins_xml
|
||||
|
||||
if os.path.isfile(ins_xml):
|
||||
ri_data.init_from_xml()
|
||||
else:
|
||||
ri_data.init()
|
||||
|
||||
ri_widget.construct(xmldoc.firstChild)
|
||||
|
||||
base_widget_name = xmldoc.firstChild.attributes["base_widget"].value
|
||||
ri_widget.init_display(base_widget_name)
|
||||
|
||||
main_sequence_name = xmldoc.firstChild.attributes["sequence"].value
|
||||
ri_widget.Sequence.set_current_sequence(main_sequence_name)
|
||||
main_sequence = ri_widget.Sequence.dict[main_sequence_name]
|
||||
|
||||
if begin_step is None:
|
||||
begin_step = main_sequence.steps[0]
|
||||
else:
|
||||
main_sequence.set_current_step(begin_step)
|
||||
|
||||
ri_widget.Widget.dict[begin_step].show()
|
||||
|
||||
ri_widget.mainloop()
|
||||
48
interface/test_data.py
Normal file
48
interface/test_data.py
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from ri_data import *
|
||||
from xml.dom import minidom
|
||||
from xml.dom.ext import PrettyPrint
|
||||
|
||||
xmldoc = minidom.parse('./i.xml')
|
||||
root = xmldoc.firstChild
|
||||
|
||||
for e in root.childNodes:
|
||||
if e.nodeType == e.ELEMENT_NODE:
|
||||
if e.nodeName == 'serial-number':
|
||||
SerialNumber.init_from_xml(e)
|
||||
elif e.nodeName == 'partitions':
|
||||
Partition.init_from_xml(e)
|
||||
elif e.nodeName == 'raids':
|
||||
Raid.init_from_xml(e)
|
||||
elif e.nodeName == 'mount-points':
|
||||
MountPoint.init_from_xml(e)
|
||||
elif e.nodeName == 'network':
|
||||
Network.init_from_xml(e)
|
||||
elif e.nodeName == 'groups':
|
||||
Group.init_from_install_xml(e)
|
||||
# elif e.nodeName == 'services':
|
||||
# Service.init_from_install_xml(e)
|
||||
|
||||
xmldoc2 = minidom.Document()
|
||||
root2 = xmldoc2.createElement('install')
|
||||
xmldoc2.appendChild(root2)
|
||||
|
||||
SerialNumber.to_xml(xmldoc2, root2)
|
||||
Partition.to_xml(xmldoc2, root2)
|
||||
Raid.to_xml(xmldoc2, root2)
|
||||
# test MountPoint.init_from_internal
|
||||
MountPoint.list=[]
|
||||
MountPoint.init_from_internal()
|
||||
MountPoint.to_xml(xmldoc2, root2)
|
||||
Network.to_xml(xmldoc2, root2)
|
||||
Group.to_xml(xmldoc2, root2)
|
||||
#Group.to_xml(xmldoc2, root2)
|
||||
xmldoc_cfg = minidom.parse('./config.xml')
|
||||
root_cfg = xmldoc_cfg.firstChild
|
||||
#Group.init_from_config_xml(root_cfg)
|
||||
#Group.to_xml(xmldoc2, root2)
|
||||
Service.init_from_config_xml(root_cfg)
|
||||
Service.to_xml(xmldoc2, root2)
|
||||
PrettyPrint(xmldoc2)
|
||||
|
||||
Reference in New Issue
Block a user