diff --git a/design.txt b/design.txt
index 5e3a77c..0fcd272 100644
--- a/design.txt
+++ b/design.txt
@@ -86,6 +86,9 @@ row 4 | quit previous next |
Besides these, 2 things I also think about: multi-language support(at least English & Chinese) and inheritance among windows/frames. Can Chinese font be displayed in Curses mode? I'm not sure for now. And, at least supporting English is not a bad choice, I think. As I mentioned in section 3.1.1, most windows are similar, they are 5 rows X 3 columns, and only one row are different. So if I brought in a somehow inheritance way into xml format, it would save a lot of code lines and errors.
To the first problem, I will design a data type "Message" in XML who has "key", "English text", and "Chinese text". All messages, such as a text on a button, will be references to "Message" variables, via key(for long message) or just English text(for short text). To the second problem, I first think about to introduce XML elements/attributes "derived_from" and "exception", which are similar to what I have done in building system implementation. But finally, I give up, for it is a little complex. Now it is enough to define a base widget for GUI row 0, 1, 3, and 4. While other widgets just define the content in row 2.
+ group install: mandatory, yes, no
+ service start: disable, yes, no
+
3.2 Data layer
I have inspected those data files generated by current install program. After trying to merge them into one unified data, in xml format, I found it is unbelievable simple!
diff --git a/python/mine/ri_cmd.py b/python/mine/ri_cmd.py
index c96faa6..00c425a 100644
--- a/python/mine/ri_cmd.py
+++ b/python/mine/ri_cmd.py
@@ -4,6 +4,8 @@
import ri_tk as display
import ri_seq
import ri_widget
+import ri_data
+
import re
def quit():
@@ -33,27 +35,17 @@ def next():
ri_widget.MessageBox.dict["next"].show()
def serial_no_init():
- display.var_dict['serial_no.number'].set(value='123')
+ display.var_dict['serial_no.number'].set(value=ri_data.SerialNumber.value)
def serial_no_quit():
- v = display.var_dict['serial_no.number'].get()
+ ri_data.SerialNumber.value = display.var_dict['serial_no.number'].get()
+
def mount_list_init():
''' initialize mount list '''
- f = file('/proc/partitions', 'r')
- pattern = re.compile(r'''
-\s*\d+ # major dev number
-\s*\d+ # minor dev number
-\s*\d+ # blocks
-\s*(\w+\d) # name
-\s*$''', re.VERBOSE)
- s = []
- while True:
- l = f.readline()
- if not l:
- break
- res = pattern.search(l)
- if res:
- s.append(res.groups()[0])
-
- display.var_dict['mount.list'].set(value='\n'.join(s))
+ l = []
+ for m in ri_data.MountPoint.list:
+# s = m.device.center(10) + m.directory.center(20) + m.filesystem.center(10)
+ s = m.device.ljust(10) + m.directory.ljust(20) + m.filesystem.ljust(10)
+ l.append(s)
+ display.var_dict['mount.list'].set(value=tuple([str(i) for i in l]))
diff --git a/python/mine/ri_data.py b/python/mine/ri_data.py
index 8ad4b59..c9222da 100644
--- a/python/mine/ri_data.py
+++ b/python/mine/ri_data.py
@@ -3,6 +3,16 @@
import re
import commands
+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 = ''
@@ -237,16 +247,6 @@ class Network:
for k in node.attributes.keys():
setattr(Network, k, node.attributes[k].value.encode('ascii'))
- @staticmethod
- def to_xml_attr(doc, node, 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
- name - attribute name'''
- attr = doc.createAttribute(name)
- attr.value = getattr(Network, name)
- node.setAttributeNode(attr)
-
@staticmethod
def to_xml(doc, p_node):
''' write Network into xml
@@ -254,7 +254,7 @@ 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'):
- Network.to_xml_attr(doc, ntwk, nm)
+ to_xml_attr(doc, ntwk, Network, nm)
p_node.appendChild(ntwk)
class Group:
@@ -276,7 +276,7 @@ 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 'yes' or 'no')
+ i.attributes['install'].value == 'mandatory' and 'mandatory' or 'no')
@staticmethod
def handle_group_node(g_node):
@@ -291,20 +291,38 @@ g_node - group node '''
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'))
+ g.optional.append(n.attributes['package'].value.encode('ascii'), 'no')
@staticmethod
def init_from_config_xml(node):
- ''' init Group instance from config xml
+ ''' 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']
- handle_release_node(rls_list[0])
+ Group.handle_release_node(rls_list[0])
for g in grp_list:
- handle_group_node(g)
+ 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'])
+ init_from_xml = init_from_install_xml
@staticmethod
def to_xml(doc, p_node):
''' write Group instances into xml
@@ -332,7 +350,7 @@ p_node - xml node (parent node)'''
for m in g.mandatory:
pkg = doc.createElement('package')
pname_attr = doc.createAttribute('name')
- pname_attr = m
+ pname_attr.value = m
pkg.setAttributeNode(pname_attr)
mndt.appendChild(pkg)
@@ -343,12 +361,137 @@ p_node - xml node (parent node)'''
for o in g.optional:
pkg = doc.createElement('package')
pname_attr = doc.createAttribute('name')
- pname_attr = o
+ pname_attr.value = o[0]
pkg.setAttributeNode(pname_attr)
pinst_attr = doc.createAttribute('install')
- pinst_attr = 'no'
+ pinst_attr.value = o[1]
pkg.setAttributeNode(pinst_attr)
optl.appendChild(pkg)
grp.appendChild(optl)
- grps.append(grp)
+ 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.pkg 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)
+
+# xml file names
+install_xml = '../../xml/install.xml'
+config_xml = './config.xml'
+
+from xml.dom import minidom
+
+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()
diff --git a/python/mine/test.py b/python/mine/test.py
index 712e5fd..136ac8b 100644
--- a/python/mine/test.py
+++ b/python/mine/test.py
@@ -3,13 +3,14 @@
import ri_widget
import ri_tk
import ri_seq
-from xml.dom import minidom
+import ri_data
import sys
import getopt
+from xml.dom import minidom
def print_usages():
- print 'Usages: %s [-b|--begin] xml_file_name' %sys.argv[0]
+ print 'Usages: %s [-b|--begin step_name] [interface_xml_file] [install_xml_file]' %sys.argv[0]
try:
opts, args = getopt.getopt(sys.argv[1:], "b:", ["begin=",])
@@ -22,10 +23,19 @@ for opt, arg in opts:
if opt in ('-b', '--begin'):
begin_step = arg
-if len(args):
- xmldoc = minidom.parse(args[0])
+if len(args) == 0:
+ itf_xml = "../../xml/interface_t.xml"
+ ins_xml = "../../xml/install.xml"
+elif len(args) == 1:
+ itf_xml = args[0]
+ ins_xml = "../../xml/install.xml"
else:
- xmldoc = minidom.parse("../../xml/interface_t.xml")
+ itf_xml = args[0]
+ ins_xml = args[1]
+
+xmldoc = minidom.parse(itf_xml)
+ri_data.install_xml = ins_xml
+ri_data.init_from_xml()
ri_widget.construct(xmldoc.firstChild)
ri_seq.construct(xmldoc.firstChild)
diff --git a/python/mine/test_data.py b/python/mine/test_data.py
index 6f4e405..5f3681f 100644
--- a/python/mine/test_data.py
+++ b/python/mine/test_data.py
@@ -19,6 +19,10 @@ for e in root.childNodes:
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')
@@ -32,7 +36,13 @@ 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)
diff --git a/xml/install.xml b/xml/install.xml
index 9c78e68..ff5658c 100644
--- a/xml/install.xml
+++ b/xml/install.xml
@@ -40,7 +40,7 @@
-
+
diff --git a/xml/install_ng.xml b/xml/install_ng.xml
index b06db93..c7a2d74 100644
--- a/xml/install_ng.xml
+++ b/xml/install_ng.xml
@@ -99,7 +99,11 @@
-
+
+ mandatory
+ yes
+ no
+
@@ -157,10 +161,16 @@
+
-
+
+ disable
+ yes
+ no
+
+