[Cluster-devel] conga/luci site/luci/Extensions/StorageReport. ...

kupcevic at sourceware.org kupcevic at sourceware.org
Sun Oct 15 22:34:55 UTC 2006


CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	kupcevic at sourceware.org	2006-10-15 22:34:54

Modified files:
	luci/site/luci/Extensions: StorageReport.py Variable.py 
	                           conga_storage_constants.py 
	                           storage_adapters.py 
	luci/storage   : form-chooser form-macros 

Log message:
	luci storage:
	- add "add sources" button to mappers' view
	- add "add sources" form

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/StorageReport.py.diff?cvsroot=cluster&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/Variable.py.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_storage_constants.py.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/storage_adapters.py.diff?cvsroot=cluster&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/form-chooser.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/form-macros.diff?cvsroot=cluster&r1=1.13&r2=1.14

--- conga/luci/site/luci/Extensions/StorageReport.py	2006/10/15 05:44:03	1.16
+++ conga/luci/site/luci/Extensions/StorageReport.py	2006/10/15 22:34:54	1.17
@@ -4,7 +4,7 @@
 from xml.dom import minidom
 
 
-from Variable import parse_variable, Variable
+from Variable import parse_variable, Variable, VariableList
 from ricci_defines import *
 from PropsObject import PropsObject
 from conga_storage_constants import *
@@ -476,11 +476,16 @@
                   'msg'  : 'Are you sure you want to remove ' + pretty_type + ' \\\'' + pretty_name + '\\\'?',
                   'link' : ''}
         actions.append(action)
+    if type == MAPPER_VG_TYPE or type == MAPPER_MDRAID_TYPE or type == MAPPER_ATARAID_TYPE or type == MAPPER_MULTIPATH_TYPE:
+        action = {'name' : 'Add ' + mapper_ret['pretty_sources_name'], 
+                  'msg'  : '',
+                  'link' : './?' + PAGETYPE + '=' + ADD_SOURCES + '&' + PT_MAPPER_ID + '=' + mapper_ret['mapper_id'] + '&' + PT_MAPPER_TYPE + '=' + mapper_ret['mapper_type']}
+        actions.append(action)
     if type == MAPPER_VG_TYPE:
         for nt in mapper_ret['new_targets']:
             if nt['props']['snapshot']['value'] == 'false':
                 if nt['new']:
-                    action = {'name' : 'New Logical Volume',
+                    action = {'name' : 'New ' + mapper_ret['pretty_target_name'], 
                               'msg'  : '',
                               'link' : './?' + PAGETYPE + '=' + VIEW_BD + '&' + PT_MAPPER_ID + '=' + mapper_ret['mapper_id'] + '&' + PT_MAPPER_TYPE + '=' + mapper_ret['mapper_type'] + '&' + PT_PATH + '=' + nt['path']}
                     actions.append(action)
@@ -491,7 +496,7 @@
         link_snapshots(mapper_ret)
     
     # cylinders work properly for VGs only, for now
-    mapper_ret['graphical_view'] = type == MAPPER_VG_TYPE
+    mapper_ret['graphical_view'] = type != MAPPER_PT_TYPE
     if mapper_ret['graphical_view']:
         mapper_ret['mappings-view_css_classnames'] = {'graphical_view' : 'visible',
                                                       'textual_view'   : 'invisible'}
@@ -709,6 +714,17 @@
             return 'BAD: Invalid number of ' + data['pretty_sources_name'] + ' selected'
         props = data['props']
         pass
+    elif object_type == 'add_sources':
+        data = get_mapper_data(self, storage_report, mapper_id)
+        # find sources
+        sources_num = 0
+        for v in request.keys():
+            if v.find('source_bd_') == 0:
+                if request[v] == 'on':
+                    sources_num += 1
+        if sources_num == 0 or sources_num > len(data['new_sources']):
+            return 'BAD: Invalid number of ' + data['pretty_sources_name'] + ' selected'
+        pass
     
     if props != None:
         res = check_props(self, props, request)
@@ -1420,6 +1436,90 @@
     
     
     
+    elif object_type == 'add_sources':
+        mapper_data = get_mapper_data(self, storage_report, mapper_id)
+        mapper_xml = mapper_data['xml'].cloneNode(True)
+        new_sources = []
+        #return mapper_xml.toprettyxml()
+        
+        if action_type == 'Apply':
+            # find sources
+            for v in request.keys():
+                if v.find('source_bd_') == 0:
+                    if request[v] == 'on':
+                        path = v[len('source_bd_'):]
+                        for ns in mapper_data['new_sources']:
+                            if ns['path'] == path:
+                                new_sources.append(ns['xml'].cloneNode(True))
+            #return mapper_xml.toprettyxml()
+            doc = minidom.Document()
+            batch = doc.createElement("batch")
+            module = doc.createElement("module")
+            module.setAttribute("name", "storage")
+            req = doc.createElement("request")
+            req.setAttribute("API_version", "1.0")
+            req.setAttribute("sequence", "11")
+            f_call = doc.createElement("function_call")
+            f_call.setAttribute('name', 'add_mapper_sources')
+            f_call.appendChild(Variable('mapper_type', mapper_type).export_xml(doc))
+            f_call.appendChild(Variable('mapper_id', mapper_id).export_xml(doc))
+            f_call.appendChild(Variable('mapper_state_ind', mapper_xml.getAttribute('state_ind')).export_xml(doc))
+            f_call.appendChild(VariableList('bds', new_sources, [], VARIABLE_TYPE_LIST_XML).export_xml(doc))
+            
+            req.appendChild(f_call)
+            module.appendChild(req)
+            batch.appendChild(module)
+            
+            #return batch.toprettyxml()
+            
+            res = ricci.process_batch(batch, False)
+            if res.getAttribute('status') != '0':
+                invalidate_storage_report(request.SESSION, storagename)
+                err_msg = 'Error adding sources to ' + mapper_type + ' ' + mapper_id + '\n' + res.toprettyxml()
+                return err_msg
+            module_r = None
+            for node in res.childNodes:
+                if node.nodeType == xml.dom.Node.ELEMENT_NODE:
+                    if node.nodeName == 'module':
+                        module_r = node
+            if module_r == None:
+                raise 'missing <module/> in <batch/>'
+            if module_r.getAttribute('status') != '0':
+                raise 'error retrieving storage report'
+            resp_r = None
+            for node in module_r.childNodes:
+                if node.nodeType == xml.dom.Node.ELEMENT_NODE:
+                    if node.nodeName == RESPONSE_TAG:
+                        resp_r = node
+            if resp_r == None:
+                raise 'missing <response/> in <module/>'
+            fr_r = None
+            for node in resp_r.childNodes:
+                if node.nodeType == xml.dom.Node.ELEMENT_NODE:
+                    if node.nodeName == FUNC_RESP_TAG:
+                        fr_r = node
+            if fr_r == None:
+                raise 'missing <function_response/> in <response/>'
+            mapper_var = None
+            for node in fr_r.childNodes:
+                if node.nodeType == xml.dom.Node.ELEMENT_NODE:
+                    if node.nodeName == VARIABLE_TAG:
+                        if node.getAttribute('name') == 'mapper':
+                            mapper_var = node
+            if mapper_var == None:
+                raise 'missing <var name="mapper"/> in <function_response/>'
+            mapper_xml = None
+            for node in mapper_var.childNodes:
+                if node.nodeType == xml.dom.Node.ELEMENT_NODE:
+                    if node.nodeName == 'mapper':
+                        mapper_xml = node.cloneNode(True)
+            mapper_id = mapper_xml.getAttribute('mapper_id')
+            pass
+        pass
+    
+    
+    
+    
     
     
     invalidate_storage_report(request.SESSION, storagename)
@@ -1441,6 +1541,8 @@
             goto_url += '&pagetype=' + VIEW_MAPPER
     elif object_type == 'mapper_template':
         goto_url += '&pagetype=' + VIEW_MAPPER
+    elif object_type == 'add_sources':
+        goto_url += '&pagetype=' + VIEW_MAPPER
     goto_url += '&' + PT_MAPPER_TYPE  + '=' + mapper_type
     goto_url += '&' + PT_MAPPER_ID  + '=' + mapper_id
     redirect_html = '<head>\n'
--- conga/luci/site/luci/Extensions/Variable.py	2006/05/30 20:17:21	1.1
+++ conga/luci/site/luci/Extensions/Variable.py	2006/10/15 22:34:54	1.2
@@ -262,12 +262,13 @@
         elem.setAttribute('type', self.type())
         
         l = self.get_value()
-        for i in range(len(l)):
-            x = l[i]
-            e2 = doc.createElement(VARIABLE_TYPE_LISTENTRY)
-            e2.setAttribute('value', str(x))
-            e2.setAttribute('list_index', str(i))
-            elem.appendChild(e2)
+        for x in l:
+            if self.type() == VARIABLE_TYPE_LIST_XML:
+                elem.appendChild(x.cloneNode(True))
+            else:
+                e2 = doc.createElement(VARIABLE_TYPE_LISTENTRY)
+                e2.setAttribute('value', str(x))
+                elem.appendChild(e2)
         for mod in self.__mods:
             elem.setAttribute(str(mod), str(self.__mods[mod]))
         return elem
--- conga/luci/site/luci/Extensions/conga_storage_constants.py	2006/10/09 17:01:19	1.7
+++ conga/luci/site/luci/Extensions/conga_storage_constants.py	2006/10/15 22:34:54	1.8
@@ -70,7 +70,7 @@
 
 
 CREATE_MAPPER = '101'
-
+ADD_SOURCES   = '102'
 
 
 
--- conga/luci/site/luci/Extensions/storage_adapters.py	2006/10/09 17:01:19	1.5
+++ conga/luci/site/luci/Extensions/storage_adapters.py	2006/10/15 22:34:54	1.6
@@ -180,7 +180,7 @@
   srs_p['cfg_type'] = "nodes"
   srs_p['absolute_url'] = url + '?' + PAGETYPE + '=' + VIEW_MAPPERS + '&' + STONAME + '=' + hostname + '&' + PT_MAPPER_TYPE + '=' + mapper_type
   srs_p['Description'] = pretty_names_desc
-  if (pagetype_req == VIEW_MAPPERS or pagetype_req == VIEW_MAPPER or pagetype_req == CREATE_MAPPER or pagetype_req == VIEW_BD) and mapper_type_req == mapper_type:
+  if (pagetype_req == VIEW_MAPPERS or pagetype_req == VIEW_MAPPER or pagetype_req == ADD_SOURCES or pagetype_req == CREATE_MAPPER or pagetype_req == VIEW_BD) and mapper_type_req == mapper_type:
     srs_p['show_children'] = True
   else:
     srs_p['show_children'] = False
@@ -222,7 +222,7 @@
     sr['absolute_url'] = url + '?' + PAGETYPE + '=' + VIEW_MAPPER + '&' + STONAME + '=' + hostname + '&' + PT_MAPPER_TYPE + '=' + mapper_type + '&' + PT_MAPPER_ID + '=' + sr_id
     sr['Description'] = pretty_name_desc
     
-    if (pagetype_req == VIEW_MAPPER or pagetype_req == VIEW_BD) and mapper_id_req == sr_id:
+    if (pagetype_req == VIEW_MAPPER or pagetype_req == ADD_SOURCES or pagetype_req == VIEW_BD) and mapper_id_req == sr_id:
       sr['currentItem'] = True
     else:
       sr['currentItem'] = False
--- conga/luci/storage/form-chooser	2006/10/09 16:16:11	1.4
+++ conga/luci/storage/form-chooser	2006/10/15 22:34:54	1.5
@@ -70,6 +70,10 @@
       <div metal:use-macro="here/form-macros/macros/create-mapper-form"/>
     </span>
 
+    <span tal:omit-tag="" tal:condition="python: pagetype == '102' and storage_report != None">
+      <div metal:use-macro="here/form-macros/macros/add-sources-form"/>
+    </span>
+
   </metal:choose-form>
 
   </body>
--- conga/luci/storage/form-macros	2006/10/15 05:09:46	1.13
+++ conga/luci/storage/form-macros	2006/10/15 22:34:54	1.14
@@ -777,6 +777,135 @@
 
 
 
+  <div metal:define-macro="add-sources-form" 
+       tal:define="mapper                  python:here.get_mapper_data(storage_report, request['mapper_id']); 
+                   prefix                  python:'add_sources_to_' + mapper['mapper_id'] + '_'; 
+                   properties_span_id      string:; 
+                   add_sources_form_id     python:prefix + 'form_id'; 
+                   add_sources_button_id   python:prefix + 'button_id'; 
+                   form_submit_button_id   add_sources_button_id">
+   <div metal:use-macro="here/form-macros/macros/forms-css"/>
+   <div metal:use-macro="here/form-macros/macros/form-scripts"/>
+   <span tal:omit-tag="" 
+         tal:condition="not: mapper/new_sources">
+    There is no available <span tal:replace="mapper/pretty_sources_name"/> to be added to <span tal:replace="mapper/pretty_type"/> '<span tal:replace="mapper/pretty_name"/>'. 
+     <br/>
+     <br/>
+    <a tal:define="go_to_mapper_url  python:'./?pagetype=52&mapper_type=' + mapper['mapper_type'] + '&mapper_id=' + mapper['mapper_id'] + '&storagename=' + storagename" 
+           tal:attributes="href go_to_mapper_url">
+     Go Back to <span tal:replace="mapper/pretty_type"/>
+    </a>
+   </span>
+   <form tal:condition="mapper/new_sources" 
+         tal:attributes="id      add_sources_form_id; 
+                         method  string:get">
+    <input tal:attributes="type  string:hidden; 
+                           name  string:pagetype; 
+                           value string:commit_changes"/>
+    <input tal:attributes="type  string:hidden; 
+                           name  string:object_type; 
+                           value string:add_sources"/>
+    <input tal:attributes="type  string:hidden; 
+                           name  string:mapper_type; 
+                           value mapper/mapper_type"/>
+    <input tal:attributes="type  string:hidden; 
+                           name  string:mapper_id; 
+                           value mapper/mapper_id"/>
+    <input tal:attributes="type  string:hidden; 
+                           name  string:storagename; 
+                           value storagename"/>
+    <table class="props-form-table">
+     <tr class="props-form-header">
+      <th colspan="2"
+          tal:attributes="style python:here.add_commas('font-size: large', 'color: ' + mapper['color'])">
+       <table>
+        <tr>
+         <td style="min-width: 30px;">
+          <img tal:condition="mapper/icon"
+               tal:attributes="src mapper/icon"
+               height="29px"
+               width="29px"/>
+         </td>
+         <td style="width: 100%;">
+          Adding new <span tal:replace="mapper/pretty_sources_name"/> to <span tal:replace="mapper/pretty_type"/> '<span tal:replace="mapper/pretty_name"/>'
+         </td>
+         <td style="min-width: 30px;">
+           
+         </td>
+        </tr>
+       </table>
+      </th>
+     </tr>
+     <tr class="props-form-body">
+      <td style="height: 100%;">
+       <table class="props-inner-table">
+        <th colspan="2">
+         <span tal:condition="python:len(mapper['new_sources']) == 1">
+          Select <span tal:replace="mapper/pretty_source_name"/> to add
+         </span>
+         <span tal:condition="python:len(mapper['new_sources']) > 1">
+          Select one or more <span tal:replace="mapper/pretty_sources_name"/> to add
+         </span>
+        </th>
+        <span tal:omit-tag=""
+              tal:define="bds mapper/new_sources"
+              tal:repeat="bd bds">
+         <tr>
+          <td>
+           <input tal:attributes="type string:checkbox; 
+                                  name python:'source_bd_' + bd['path']"/>
+          </td>
+          <td tal:define="bytes  bd/props/size/value;
+                          dummy  python:here.bytes_to_value_units(bytes);
+                          size   python:dummy[0];
+                          units  python:dummy[1]">
+           <span tal:replace="bd/path"/> (<span tal:replace="size"/> <span tal:replace="units"/> - <span tal:replace="bd/pretty_type"/>)
+          </td>
+         </tr>
+        </span>
+        <tr>
+         <td colspan="2"
+             style="height: 100%;">
+           
+         </td>
+        </tr>
+       </table>
+      </td>
+      <td>
+        
+      </td>
+     </tr>
+     <tr class="props-form-footer">
+      <td colspan="2">
+       <table style="width: 100%;">
+        <tr>
+         <td align="left">
+           
+         </td>
+         <td align="right">
+          <input tal:define="go_to_mapper_url  python:'./?pagetype=52&mapper_type=' + mapper['mapper_type'] + '&mapper_id=' + mapper['mapper_id'] + '&storagename=' + storagename" 
+                 tal:attributes="type    string:button; 
+                                 name    string:cancel_button; 
+                                 value   string:Cancel; 
+                                 onclick python:'window.location.assign(\'' + go_to_mapper_url + '\')'"
+                 class="form_button"/>
+          <input tal:define="prompt_msg    python:'Do you really want to add selected ' + mapper['pretty_sources_name'] + ' to \\\'' + mapper['pretty_name'] + '\\\'?';
+                             validate_url  context/validate_html/absolute_url" 
+                 tal:attributes="id      add_sources_button_id; 
+                                 type    string:button; 
+                                 name    string:action_type; 
+                                 value   string:Add; 
+                                 onclick python:'return validate_and_submit_form(\'' + validate_url + '\', \'' + add_sources_form_id + '\', \'' + add_sources_button_id + '\', \'' + prompt_msg + '\')'"
+                 class="form_button"/>
+         </td>
+        </tr>
+       </table>
+      </td>
+     </tr>
+    </table>
+   </form>
+  </div>
+
 
 
 
@@ -1755,5 +1884,6 @@
 
 
 
+
   </body>
 </html>




More information about the Cluster-devel mailing list