[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