[luci] luci: Add expand/collapse buttons for each inline resource
by Ryan McCabe
commit a0ccdcf9fc6a681560877467c0021fa6426981db
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Tue May 5 08:45:13 2015 -0400
luci: Add expand/collapse buttons for each inline resource
Add expand and collapse buttons for all resources inside
service groups.
Resolves: rhbz#919223
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
luci/public/js/service.js | 4 +++-
luci/templates/resource_list.html | 9 +++++++--
2 files changed, 10 insertions(+), 3 deletions(-)
---
diff --git a/luci/public/js/service.js b/luci/public/js/service.js
index 185e1c5..dbd6f1e 100644
--- a/luci/public/js/service.js
+++ b/luci/public/js/service.js
@@ -140,7 +140,9 @@ function insert_resource(res_id, container_id, form, parent_id) {
var table_id_str = 'table_' + cur_id_str;
var res_anchor_name = 'anchor_' + cur_id_str;
- var svc_tables = $('<a name="' + res_anchor_name + '" id="' + res_anchor_name + '"/><table class="detailstable" id="' + table_id_str + '"><thead class="svc_padding"><tr class="svc_padding"><th class="svc_padding" width="5"/><th class="svc_padding" width="98%"/><th class="svc_padding" colspan="3"/></tr></thead><tbody><tr class="svc_res_table"><td></td><td align="right" class="svc_padding" colspan="4"><a href="#" onclick="$(\'#' + table_id_str + '\').remove();return false;">Remove</a></td></tr><tr><td class="svc_padding"></td><td colspan="4" class="svc_content" id="' + td_id_str + '"></td></tr></tbody></table>');
+ var expander_div = '<div><input type="button" value="Expand" class="button small silver expander" onclick="$(\'#' + table_id_str + ' table.formtable > tbody > tr > td\').not(\'.nocollapse\').show()"><input type="button" value="Collapse" class="button small silver expander" onclick="$(\'#' + table_id_str + ' table.formtable > tbody > tr > td\').not(\'.nocollapse\').hide()"></div>';
+
+ var svc_tables = $('<a name="' + res_anchor_name + '" id="' + res_anchor_name + '"/><table class="detailstable" id="' + table_id_str + '"><thead class="svc_padding"><tr class="svc_padding"><th class="svc_padding" width="5"/><th class="svc_padding" width="98%"/><th class="svc_padding" colspan="3"/></tr></thead><tbody><tr class="svc_res_table"><td align="left" colspan="2">' + expander_div + '</td><td align="right" colspan="2"><a href="#" onclick="$(\'#' + table_id_str + '\').remove();return false;">Remove</a></td></tr><tr><td class="svc_padding"></td><td colspan="4" class="svc_content" id="' + td_id_str + '"></td></tr></tbody></table>');
var containing_div = $('<div class="reslevel"></div>');
$(containing_div).attr('id', cur_id_str);
diff --git a/luci/templates/resource_list.html b/luci/templates/resource_list.html
index 965dae8..ae489e8 100644
--- a/luci/templates/resource_list.html
+++ b/luci/templates/resource_list.html
@@ -2164,8 +2164,13 @@ ${bindmount_resource(None,None,None,0)}
</thead>
<tbody>
<tr class="svc_res_table">
- <td></td>
- <td align="right" colspan="4">
+ <td align="left" colspan="2">
+ <div py:if="defined('svc')">
+ <input type="button" value="Expand" class="button small silver expander" py:attrs="{'onclick': '$(\'#%s table.formtable > tbody > tr > td\').not(\'.nocollapse\').show()' % cur_id_str}"/>
+ <input type="button" value="Collapse" class="button small silver expander" py:attrs="{'onclick': '$(\'#%s table.formtable > tbody > tr > td\').not(\'.nocollapse\').hide()' % cur_id_str}"/>
+ </div>
+ </td>
+ <td align="right" colspan="2">
<a href="#"
py:attrs="{'onclick': '$(\'#table_%s\').remove();return false;' % cur_id_str}">Remove</a>
</td>
9 years
[luci] luci: Update fence_virt / fence_xvm labels
by Ryan McCabe
commit adf3f53a8119b7a90090954f840bac46736e169a
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Tue May 5 08:44:18 2015 -0400
luci: Update fence_virt / fence_xvm labels
fence_virt is no longer tech preview, so remove the label. Also
add support for fence_virt's "timeout" attribute, which was missing.
Resolves: rhbz#1204910
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
luci/templates/fence_devices.html | 11 +++++++++--
luci/validation/validate_fence.py | 1 +
2 files changed, 10 insertions(+), 2 deletions(-)
---
diff --git a/luci/templates/fence_devices.html b/luci/templates/fence_devices.html
index 3417e64..ffbe295 100644
--- a/luci/templates/fence_devices.html
+++ b/luci/templates/fence_devices.html
@@ -1215,6 +1215,13 @@
py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('channel_address')} or {}"/>
</td>
</tr>
+ <tr>
+ <td>Timeout (optional)</td>
+ <td>
+ <input name="timeout" type="text" class="text"
+ py:attrs="cur_fencedev and {'value': cur_fencedev.getAttribute('timeout')}"/>
+ </td>
+ </tr>
</table>
<py:if test="cur_fencedev">
@@ -5170,8 +5177,8 @@ ${fence_unknown(None,0)}
<option name="fence_eps" value="fence_eps">ePowerSwitch</option>
<py:choose test="cluster_version">
<py:when test="3">
- <option name="fence_virt" value="fence_virt">Fence virt (Tech Preview)</option>
- <option name="fence_xvm" value="fence_xvm">Fence virt (Multicast Mode)</option>
+ <option name="fence_virt" value="fence_virt">Fence virt (Serial/VMChannel Mode)</option>
+ <option name="fence_xvm" value="fence_xvm">Fence virt (fence_xvm/Multicast Mode)</option>
<option name="fence_sanlock" value="fence_sanlock">Sanlock (Tech Preview)</option>
</py:when>
</py:choose>
diff --git a/luci/validation/validate_fence.py b/luci/validation/validate_fence.py
index 9f43848..462d5bc 100644
--- a/luci/validation/validate_fence.py
+++ b/luci/validation/validate_fence.py
@@ -301,6 +301,7 @@ def val_virt_fd(fencedev, fence_name, **kw):
('serial_device', True),
('serial_params', False),
('channel_address', False),
+ ('timeout', False),
)
errors = config_fence_attr(params, fencedev, fence_name, **kw)
9 years
[luci] luci: Warn when config can't be set or activated
by Ryan McCabe
commit 72df9021d81816f65d57e0dbdcaba2e4f199e7ac
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Tue May 5 08:42:47 2015 -0400
luci: Warn when config can't be set or activated
Instead of attempting to determine when it is safe to activate a
new cluster configuration on a node, leave it to cman. Instead, warn
the user if any errors occur while attempting to set or activate
the configuration.
Resolves: rhbz#1136456
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
luci/controllers/cluster.py | 99 ++++++++++++++++++-----
luci/lib/ricci_helpers.py | 53 +++++++-----
luci/validation/validate_create_cluster_form.py | 6 +-
3 files changed, 115 insertions(+), 43 deletions(-)
---
diff --git a/luci/controllers/cluster.py b/luci/controllers/cluster.py
index 0792b47..c8afce5 100644
--- a/luci/controllers/cluster.py
+++ b/luci/controllers/cluster.py
@@ -229,7 +229,10 @@ class IndividualClusterController(BaseController):
if found_method is True:
log.info('User "%s" removed method "%s" from node "%s" in cluster "%s"'
% (self.username, methodname, cur_nodename, self.name))
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
else:
log.error('User "%s" failed to remove method "%s" from node "%s" in cluster "%s"'
% (self.username, methodname, cur_nodename, self.name))
@@ -246,7 +249,10 @@ class IndividualClusterController(BaseController):
if found_instance is True:
log.info('User "%s" removed fence instance "%s" from method "%s" from node "%s" in cluster "%s"'
% (self.username, fenceinst, methodname, cur_nodename, self.name))
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
else:
log.error('User "%s" failed to remove fence instance "%s" from method "%s" from node "%s" in cluster "%s"'
% (self.username, fenceinst, methodname, cur_nodename, self.name))
@@ -259,7 +265,10 @@ class IndividualClusterController(BaseController):
mposition = fence_elem.findMethod(methodname)
if mposition is not None and mposition > 0:
fence_elem.moveMethodUp(mposition)
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
log.info('User "%s" moved up fence method "%s" for node "%s" in cluster "%s"'
% (self.username, methodname, cur_nodename, self.name))
@@ -272,7 +281,10 @@ class IndividualClusterController(BaseController):
mposition = fence_elem.findMethod(methodname)
if mposition is not None and mposition < len(levels) - 1:
fence_elem.moveMethodDown(mposition)
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
log.info('User "%s" moved down fence method "%s" for node "%s" in cluster "%s"'
% (self.username, methodname, cur_nodename, self.name))
@@ -313,7 +325,10 @@ class IndividualClusterController(BaseController):
flash(_('Updating fence settings for node "%s"' % cur_nodename))
log.info('User "%s" added a fence instance to fence method "%s" for node "%s" in cluster "%s"'
% (self.username, methodname, cur_nodename, self.name))
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
else:
msgs = retobj
if msgs and len(msgs) > 0:
@@ -362,7 +377,10 @@ class IndividualClusterController(BaseController):
node.getFenceNode().children[int(method_num)].children[int(fence_instance_id)] = retobj
log.info('User "%s" edited "%s" fence instance of fence method "%s" for node "%s" in cluster "%s"'
% (self.username, kw.get('fencedev'), method_num, cur_nodename, self.name))
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
elif command == "AddFenceMethod":
node = self.model.retrieveNodeByName(cur_nodename)
@@ -372,7 +390,10 @@ class IndividualClusterController(BaseController):
node.getFenceNode().addChild(method)
log.info('User "%s" added fence method "%s" to node "%s" in cluster "%s"'
% (self.username, methodname, cur_nodename, self.name))
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
redirect('%s%s' % (tmpl_context.cluster_url, cur_nodename))
@@ -481,8 +502,10 @@ class IndividualClusterController(BaseController):
if msgs and len(msgs) > 0:
flash2.warning(', '.join(msgs))
flash2.info(_('Updating properties of node: %s') % cur_list[0])
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
flash2.flush()
- rh.update_cluster_conf(self.model)
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
@@ -573,7 +596,10 @@ class IndividualClusterController(BaseController):
flash(_("Deleting resources %s") % ', '.join(cur_list),
status='info')
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
redirect(tmpl_context.cluster_url)
elif command in ("Create", "Edit"):
if command == 'Create':
@@ -604,7 +630,10 @@ class IndividualClusterController(BaseController):
log.info('User "%s" %s global resource "%s" in cluster "%s"'
% (self.username, cur_action, res_name, self.name))
flash(_('%s global resource "%s"') % (cur_action, res_name))
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
redirect(redir_fmt
% (tmpl_context.cluster_url, quote_plus(res_name)))
else:
@@ -691,7 +720,10 @@ class IndividualClusterController(BaseController):
for i in cur_list:
self.model.deleteService(i)
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
redirect(tmpl_context.cluster_url)
if command == 'Start':
try:
@@ -779,7 +811,10 @@ class IndividualClusterController(BaseController):
log.info('User "%s" %s cluster service "%s" in cluster "%s"'
% (self.username, cur_action, svc_name, self.name))
flash(_('%s cluster service "%s"') % (cur_action, svc_name))
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
@@ -861,7 +896,10 @@ class IndividualClusterController(BaseController):
flash(_('Deleting failover domains %s') % ', '.join(cur_list))
for i in cur_list:
self.model.deleteFailoverDomain(i)
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
redirect(tmpl_context.cluster_url)
@@ -878,7 +916,10 @@ class IndividualClusterController(BaseController):
log.info('User "%s" updated the settings of failover domain "%s" in cluster "%s"'
% (self.username, cur_list[0], self.name))
flash(_('Updating settings for failover domain "%s"') % cur_list[0])
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
@@ -891,7 +932,10 @@ class IndividualClusterController(BaseController):
log.info('User "%s" updated the properties of failover domain "%s" in cluster "%s"'
% (self.username, cur_list[0], self.name))
flash(_('Updating properties for failover domain "%s"') % cur_list[0])
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
else:
msgs = vret[1].get('errors')
if msgs and len(msgs) > 0:
@@ -904,7 +948,10 @@ class IndividualClusterController(BaseController):
log.info('User "%s" created failover domain "%s" in cluster "%s"'
% (self.username, kw.get('fdom_name'), self.name))
flash(_('Creating failover domain "%s"') % kw.get('fdom_name'))
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
redirect('%s?name=%s'
% (tmpl_context.cluster_url, quote_plus(kw.get('fdom_name').strip())))
else:
@@ -982,7 +1029,10 @@ class IndividualClusterController(BaseController):
if command == 'Create':
fret = validateNewFenceDevice(self.model, **kw)
if fret[0] is True:
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
flash(_('Created fence device "%s"') % cur_list[0])
log.info('User "%s" created fence device "%s" in cluster "%s"'
% (self.username, ', '.join(cur_list), self.name))
@@ -1006,11 +1056,17 @@ class IndividualClusterController(BaseController):
continue
updated |= self.model.deleteFenceDevice(cur_fencedev)
if updated:
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
elif command == 'Update':
fret = validateFenceDevice(self.model, **kw)
if fret[0] is True:
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
flash(_('Edited fence device "%s"') % cur_list[0])
log.info('User "%s" updated fence device "%s" in cluster "%s"'
% (self.username, ', '.join(cur_list), self.name))
@@ -1066,7 +1122,10 @@ class IndividualClusterController(BaseController):
msgs = vret[1].get('flash')
if msgs and len(msgs) > 0:
flash(', '.join(msgs), status="info")
- rh.update_cluster_conf(self.model)
+ msgs = rh.update_cluster_conf(self.model)
+ if msgs and len(msgs) > 0:
+ flash2.warning(', '.join(msgs))
+ flash2.flush()
if vret[1].get('start_qdisk'):
log.info('Starting qdiskd for cluster "%s"' % self.name)
rh.cluster_node_start(self.name, [])
diff --git a/luci/lib/ricci_helpers.py b/luci/lib/ricci_helpers.py
index f74b5bb..f90cff2 100644
--- a/luci/lib/ricci_helpers.py
+++ b/luci/lib/ricci_helpers.py
@@ -114,7 +114,7 @@ def update_cluster_conf(cluster_model, node_list=[]):
cluster_name = cluster_model.getClusterName()
cluster_obj = get_cluster_db_obj(cluster_name)
if not cluster_obj:
- return False
+ return [_('Unable to find DB object for cluster %s') % cluster_name]
conf_str = cluster_model.exportModelAsString()
if cluster_model.getClusterVersion() < 3:
@@ -124,12 +124,14 @@ def update_cluster_conf(cluster_model, node_list=[]):
rc = get_agent_for_cluster(cluster_name)
ret = rq.setClusterConfSync(get_agent_for_cluster(cluster_name), conf_str)
if ret != True:
- log.info('Config update for %s failed at node %s' \
- % (cluster_name, rc.hostname()))
- return False
+ err_str = _('Config update for %s failed at node %s') \
+ % (cluster_name, rc.hostname())
+ log.info('%s' % err_str)
+ return [ err_str ]
except Exception, e:
- log.exception('Config update for %s failed' % cluster_name)
- return False
+ err_str = _('Config update for %s failed') % cluster_name
+ log.exception('%s' % err_str)
+ return [ err_str ]
else:
# For >= cluster3, RHEL6 set the conf on each node, then activate
# the new version.
@@ -137,11 +139,12 @@ def update_cluster_conf(cluster_model, node_list=[]):
try:
ret = send_batch_parallel(host_triples, 10, True)
except Exception, e:
- log.exception('error updating cluster config for "%s"' \
+ err_str = _('error updating cluster config for "%s"' \
% cluster_name)
- return False
+ log.exception('%s' % err_str)
+ return [ err_str ]
- sync_err = False
+ err_strs = []
for i in ret.keys():
try:
batch_status = ret[i].get('batch_result')
@@ -157,17 +160,16 @@ def update_cluster_conf(cluster_model, node_list=[]):
DBSession.add(task_obj)
else:
if ret[i].get('error'):
- log.error('Error retrieving batch number from %s: %s' %
+ err_str = _('Error retrieving batch number from %s: %s' %
(i, ret[i].get('err_msg')))
- sync_err = True
+ err_strs.append(err_str)
+ log.error('%s' % err_str)
except Exception, e:
- log.exception('Unable to retrieve the batch number from %s' % i)
- sync_err = True
+ err_str = _('Unable to retrieve the batch number from %s' % i)
+ err_strs.append(err_str)
+ log.exception('%s' % err_str)
continue
- if not sync_err:
- return False
-
# Activate the new config we just set
new_version = cluster_model.getClusterConfigVersion()
host_triples = prepare_host_triples(cluster_obj, node_list, rq.setClusterVersion, new_version)
@@ -175,8 +177,10 @@ def update_cluster_conf(cluster_model, node_list=[]):
try:
ret = send_batch_parallel(host_triples, 10, True)
except Exception, e:
- log.exception('Error activating new config for "%s"' % cluster_name)
- return False
+ err_str = _('Error sending activation command for new config for "%s"' % cluster_name)
+ err_strs.append(err_str)
+ log.exception('%s' % err_str)
+ return [ err_strs ]
for i in ret.keys():
try:
@@ -193,13 +197,20 @@ def update_cluster_conf(cluster_model, node_list=[]):
DBSession.add(task_obj)
else:
if ret[i].get('error'):
- log.error('Error retrieving batch number from %s: %s' %
+ err_str = _('Error retrieving batch number from %s: %s' %
(i, ret[i].get('err_msg')))
+ err_strs.append(err_str)
+ log.error('%s' % err_str)
except Exception, e:
- log.exception('Unable to retrieve the batch number from %s' % i)
+ err_str = _('Unable to retrieve the batch number from %s while attempting to activate the new cluster configuration' % i)
+ err_strs.append(err_str)
+ log.exception('%s' % err_str)
continue
- return True
+ if err_strs:
+ return err_strs
+
+ return None
def cluster_start(cluster_name):
cluster_obj = get_cluster_db_obj(cluster_name)
diff --git a/luci/validation/validate_create_cluster_form.py b/luci/validation/validate_create_cluster_form.py
index 76d0342..c7405e5 100644
--- a/luci/validation/validate_create_cluster_form.py
+++ b/luci/validation/validate_create_cluster_form.py
@@ -315,8 +315,10 @@ def validate_node_add_form(model, db_obj, **kw):
if len(errors) == 0:
model.getClusterPtr().incrementConfigVersion()
model.lockConfigVersion()
- if update_cluster_conf(model) is not True:
- errors.append(_('Unable to update the cluster configuration on existing nodes'))
+ msgs = update_cluster_conf(model)
+ if msgs and len(msgs) > 0:
+ errors = msgs
+ errors.append(_('Unable to update the cluster configuration on all existing nodes'))
if len(errors) > 0:
flash(_('The following errors occurred while creating cluster "%s": %s')
9 years
[luci] luci: Preserve expert mode resource attributes
by Ryan McCabe
commit cdd9f5954a1f0cdb8a81ee96b73692bb010b4773
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Tue May 5 08:41:29 2015 -0400
luci: Preserve expert mode resource attributes
Preserve expert mode resource attributes when editing inline
resources contained in service groups while not in expert mode.
Resolves: rhbz#1112297
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
luci/templates/resource_list.html | 22 ++++++++++++++++++++++
luci/validation/validate_resource.py | 21 +++++++++++++--------
2 files changed, 35 insertions(+), 8 deletions(-)
---
diff --git a/luci/templates/resource_list.html b/luci/templates/resource_list.html
index 5c69dbe..965dae8 100644
--- a/luci/templates/resource_list.html
+++ b/luci/templates/resource_list.html
@@ -127,6 +127,9 @@
</tr>
${res_footer(res)}
</table>
+ <py:if test="res and not expertMode and defined('svc')">
+ <input type="hidden" name="prefer_interface" value="${res.getAttribute('prefer_interface')}" />
+ </py:if>
</div>
<div py:def="fs_resource(res, form_id, parent_id, isref)" name="FS" id="fs_resource" class="row rescfg"
@@ -249,6 +252,9 @@
</tr>
${res_footer(res)}
</table>
+ <py:if test="res and not expertMode and defined('svc')">
+ <input py:if="res.getBinaryAttribute('use_findmnt') is True" type="hidden" name="use_findmnt" value="1" />
+ </py:if>
</div>
<div py:def="clusterfs_resource(res, form_id, parent_id, isref)" name="CLUSTERFS" id="clusterfs_resource" class="row rescfg"
@@ -358,6 +364,9 @@
</tr>
${res_footer(res)}
</table>
+ <py:if test="res and not expertMode and defined('svc')">
+ <input py:if="res.getBinaryAttribute('use_findmnt') is True" type="hidden" name="use_findmnt" value="1" />
+ </py:if>
</div>
<div py:def="netfs_resource(res, form_id, parent_id, isref)" name="NETFS" id="netfs_resource" class="row rescfg"
@@ -452,6 +461,9 @@
</tr>
${res_footer(res)}
</table>
+ <py:if test="res and not expertMode and defined('svc')">
+ <input py:if="res.getBinaryAttribute('use_findmnt') is True" type="hidden" name="use_findmnt" value="1" />
+ </py:if>
</div>
<div py:def="bindmount_resource(res, form_id, parent_id, isref)" name="BIND-MOUNT" id="bindmount_resource" class="row rescfg"
@@ -527,6 +539,9 @@
</tr>
${res_footer(res)}
</table>
+ <py:if test="res and not expertMode and defined('svc')">
+ <input type="hidden" name="path" value="${res.getAttribute('path')}" />
+ </py:if>
</div>
<div py:def="nfsserver_resource(res, form_id, parent_id, isref)" name="NFSSERVER" id="nfsserver_resource" class="row rescfg"
@@ -574,6 +589,10 @@
</tr>
${res_footer(res)}
</table>
+ <py:if test="res and not expertMode and defined('svc')">
+ <input type="hidden" name="path" value="${res.getAttribute('path')}" />
+ <input type="hidden" name="nfspath" value="${res.getAttribute('nfspath')}" />
+ </py:if>
</div>
<div py:def="nfsclient_resource(res, form_id, parent_id, isref)" name="NFSCLIENT" id="nfsclient_resource" class="row rescfg"
@@ -626,6 +645,9 @@
</tr>
${res_footer(res)}
</table>
+ <py:if test="res and not expertMode and defined('svc')">
+ <input type="hidden" name="path" value="${res.getAttribute('path')}" />
+ </py:if>
</div>
<div py:def="samba_resource(res, form_id, parent_id, isref)" name="SAMBA" id="samba_resource" class="row rescfg"
diff --git a/luci/validation/validate_resource.py b/luci/validation/validate_resource.py
index ac37f28..9611180 100644
--- a/luci/validation/validate_resource.py
+++ b/luci/validation/validate_resource.py
@@ -129,7 +129,7 @@ def addIp(res, rname, model, **kw):
if not res.getBinaryAttribute('disable_rdisc'):
res.removeAttribute('disable_rdisc')
- if kw.get('expert_mode'):
+ if kw.get('expert_mode') or kw.get('svc_edit'):
prefer_interface = kw.get('prefer_interface')
if prefer_interface and not prefer_interface.isspace():
res.addAttribute('prefer_interface', prefer_interface)
@@ -152,7 +152,7 @@ def addFs(res, rname, model, **kw):
('options', '', False, None)
]
- if kw.get('expert_mode'):
+ if kw.get('expert_mode') or kw.get('svc_edit'):
params.append(('use_findmnt', '', False, None))
if not kw.get('use_findmnt'):
kw['use_findmnt'] = '0'
@@ -188,7 +188,7 @@ def addClusterfs(res, rname, model, **kw):
('options', '', False, None)
]
- if kw.get('expert_mode'):
+ if kw.get('expert_mode') or kw.get('svc_edit'):
params.append(('use_findmnt', '', False, None))
if not kw.get('use_findmnt'):
kw['use_findmnt'] = '0'
@@ -223,7 +223,7 @@ def addNetfs(res, rname, model, **kw):
('fstype', '', False, None)
]
- if kw.get('expert_mode'):
+ if kw.get('expert_mode') or kw.get('svc_edit'):
params.append(('use_findmnt', '', False, None))
if not kw.get('use_findmnt'):
kw['use_findmnt'] = '0'
@@ -278,7 +278,7 @@ def addNFSClient(res, rname, model, **kw):
)
errors = config_resource(params, res, rname, **kw)
- if kw.get('expert_mode'):
+ if kw.get('expert_mode') or kw.get('svc_edit'):
# The inherited path can be overriden while in expert mode
path_override = kw.get('path')
if path_override and not path_override.isspace():
@@ -294,7 +294,7 @@ def addNFSClient(res, rname, model, **kw):
def addNFSExport(res, rname, model, **kw):
# Only the name is used
- if kw.get('expert_mode'):
+ if kw.get('expert_mode') or kw.get('svc_edit'):
# The inherited path can be overriden while in expert mode
path_override = kw.get('path')
if path_override and not path_override.isspace():
@@ -309,7 +309,7 @@ def addNFSServer(res, rname, model, **kw):
)
errors = config_resource(params, res, rname, **kw)
- if kw.get('expert_mode'):
+ if kw.get('expert_mode') or kw.get('svc_edit'):
# The inherited path can be overriden while in expert mode
path_override = kw.get('path')
if path_override and not path_override.isspace():
@@ -657,6 +657,7 @@ def create_resource(res_type, model, **kw):
def validate_clusvc_form(model, **kw):
errors = list()
+ expert_mode = False
new_service = Service()
old_name = kw.get('old_name')
@@ -750,6 +751,7 @@ def validate_clusvc_form(model, **kw):
new_service.delExclusive()
if kw.get('expert_mode'):
+ expert_mode = True
new_service.setNFSLock(kw.get('nfslock') is not None)
new_service.setNFSClientCache(kw.get('nfs_client_cache') is not None)
@@ -829,7 +831,10 @@ def validate_clusvc_form(model, **kw):
if not form_parent in form_hash:
form_hash[form_parent] = {'form': None, 'kids': []}
form_hash[form_parent]['kids'].append(form_id)
- dummy_form = {}
+ dummy_form = {'svc_edit': 'true'}
+
+ if expert_mode:
+ dummy_form['expert_mode'] = True
for i in ielems:
try:
9 years