[luci] Allow using the same multicast address for primary and alternate rings, but don't allow the ports to
by Ryan McCabe
commit 00c4cb1d2be8cd8683cbef32349db1598149d59c
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Wed May 23 10:52:03 2012 -0400
Allow using the same multicast address for primary and alternate rings, but
don't allow the ports to overlap if the multicast addresses are known to be
the same.
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
luci/validation/validate_cluster_prop.py | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
---
diff --git a/luci/validation/validate_cluster_prop.py b/luci/validation/validate_cluster_prop.py
index c822bcc..dd84092 100644
--- a/luci/validation/validate_cluster_prop.py
+++ b/luci/validation/validate_cluster_prop.py
@@ -632,12 +632,13 @@ def validate_rrp_config(model, **kw):
if not altmcast_ptr:
altmcast_ptr = model.addAltmcastPtr()
+ mcast_addr_same = False
altmcast_addr = kw.get('altmcast_addr')
if altmcast_addr and not altmcast_addr.isspace():
try:
altmcast_ptr.setAddr(altmcast_addr)
if model.getMcastAddr() == altmcast_addr:
- errors.append(_('The alternate multicast address %s is the same as the primary cluster multicast address') % altmcast_addr)
+ mcast_addr_same = True
except:
errors.append(_('Invalid alternate ring multicast address: %s') % altmcast_addr)
else:
@@ -654,8 +655,8 @@ def validate_rrp_config(model, **kw):
cp = Cman()
cman_port = int(cp.getPort())
altmcast_port = int(altmcast_port)
- if abs(cman_port - altmcast_port) < 2:
- errors.append(_('Alternate multicast ports (%d %d) and CMAN ports (%d %d) overlap') % (altmcast_port, altmcast_port - 1, cman_port, cman_port - 1))
+ if mcast_addr_same and abs(cman_port - altmcast_port) < 2:
+ errors.append(_('Alternate multicast ports (%d %d) and CMAN ports (%d %d) must not overlap when using the same multicast address') % (altmcast_port, altmcast_port - 1, cman_port, cman_port - 1))
except:
errors.append(_('Invalid alternate ring CMAN port: %s') % altmcast_port)
else:
12 years, 1 month
[luci] Fix handling of power_wait for fence_intelmodular
by Ryan McCabe
commit dd9a17c628d7257071a20a0424dbca09a7ea2b0d
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Wed May 23 10:51:05 2012 -0400
Fix handling of power_wait for fence_intelmodular
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
luci/validation/validate_fence.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
---
diff --git a/luci/validation/validate_fence.py b/luci/validation/validate_fence.py
index 87ab6df..e95c69b 100644
--- a/luci/validation/validate_fence.py
+++ b/luci/validation/validate_fence.py
@@ -558,6 +558,7 @@ def val_intelmodular_fd(fencedev, fence_name, **kw):
('snmp_priv_prot', False),
('snmp_priv_passwd', False),
('snmp_priv_passwd_script', False),
+ ('power_wait', False),
)
errors = config_fence_attr(params, fencedev, fence_name, **kw)
@@ -919,7 +920,6 @@ def val_apc_snmp_fi(fenceinst, parent_name, **kw):
def val_intelmodular_fi(fenceinst, parent_name, **kw):
params = (
('port', True),
- ('power_wait', False),
)
errors = config_fence_attr(params, fenceinst, parent_name, **kw)
12 years, 1 month
[luci] Clean up validation of the RRP configuration form.
by Ryan McCabe
commit e83a40e8692049c3d450b851f33a4b0d709f2c91
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Fri May 11 15:40:56 2012 -0400
Clean up validation of the RRP configuration form.
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
luci/lib/ClusterConf/Altmulticast.py | 2 +-
luci/lib/ClusterConf/ModelBuilder.py | 30 ++++++++++++++++++++++
luci/templates/configure.html | 7 ++---
luci/validation/validate_cluster_prop.py | 41 +++++++++++++++++++++++++++---
4 files changed, 71 insertions(+), 9 deletions(-)
---
diff --git a/luci/lib/ClusterConf/Altmulticast.py b/luci/lib/ClusterConf/Altmulticast.py
index bac0612..e295b17 100644
--- a/luci/lib/ClusterConf/Altmulticast.py
+++ b/luci/lib/ClusterConf/Altmulticast.py
@@ -21,7 +21,7 @@ class Altmulticast(TagObject):
return self.addAttribute('addr', val)
def delAddr(self):
- return self.attr_hash.get('addr')
+ return self.removeAttribute('addr')
def getPort(self):
return self.getAttribute('port')
diff --git a/luci/lib/ClusterConf/ModelBuilder.py b/luci/lib/ClusterConf/ModelBuilder.py
index 23ba30d..817551c 100644
--- a/luci/lib/ClusterConf/ModelBuilder.py
+++ b/luci/lib/ClusterConf/ModelBuilder.py
@@ -759,6 +759,36 @@ class ModelBuilder:
an.delPort()
if altmcast_ttl and an.getTTL() == altmcast_ttl:
an.delTTL()
+
+ def getAltmcastConfig(self):
+ alt_mcast_addrs = set()
+ alt_mcast_ports = set()
+ alt_mcast_ttl = set()
+
+ if self.altmcast_ptr:
+ return self.altmcast_ptr
+
+ for node in self.getNodes():
+ an = node.getAltname()
+ if an:
+ cur_amc_mcast = an.getMcast()
+ if cur_amc_mcast:
+ alt_mcast_addrs.add(cur_amc_mcast)
+ cur_amc_port = an.getPort()
+ if cur_amc_port:
+ alt_mcast_ports.add(cur_amc_port)
+ cur_amc_ttl = an.getTTL()
+ if cur_amc_ttl:
+ alt_mcast_ttl.add(cur_amc_ttl)
+
+ am = Altmulticast.Altmulticast()
+ if len(alt_mcast_addrs) == 1:
+ am.setAddr(alt_mcast_addrs.pop())
+ if len(alt_mcast_ports) == 1:
+ am.setPort(alt_mcast_ports.pop())
+ if len(alt_mcast_ttl) == 1:
+ am.setTTL(alt_mcast_ttl.pop())
+ return am
def setQuorumd(self, qd):
cp = self.getClusterPtr()
diff --git a/luci/templates/configure.html b/luci/templates/configure.html
index d6a83d3..e23d942 100644
--- a/luci/templates/configure.html
+++ b/luci/templates/configure.html
@@ -197,24 +197,23 @@
<td>Alternate Ring Multicast Address</td>
<td>
<input name="altmcast_addr" type="text" class="text"
- py:attrs="cluster_data and {'disabled': not cluster_data.get_cluster_multicast() and 'disabled' or None, 'value': cluster_data.getAltmcastPtr() and cluster_data.getAltmcastPtr().getAddr() } or {}"/>
+ py:attrs="cluster_data and {'disabled': not cluster_data.get_cluster_multicast() and 'disabled' or None, 'value': cluster_data.getAltmcastConfig().getAddr() } or {}"/>
</td>
</tr>
<tr>
<td>Alternate Ring CMAN Port</td>
<td>
<input name="altmcast_port" type="text" class="text"
- py:attrs="cluster_data and {'disabled': not cluster_data.get_cluster_multicast() and 'disabled' or None, 'value': cluster_data.getAltmcastPtr() and cluster_data.getAltmcastPtr().getPort() } or {}"/>
+ py:attrs="cluster_data and {'disabled': not cluster_data.get_cluster_multicast() and 'disabled' or None, 'value': cluster_data.getAltmcastConfig().getPort() } or {}"/>
</td>
</tr>
<tr>
<td>Alternate Ring Multicast Packet TTL</td>
<td>
<input name="altmcast_ttl" type="text" class="text"
- py:attrs="cluster_data and {'disabled': not cluster_data.get_cluster_multicast() and 'disabled' or None, 'value': cluster_data.getAltmcastPtr() and cluster_data.getAltmcastPtr().getTTL() } or {}"/>
+ py:attrs="cluster_data and {'disabled': not cluster_data.get_cluster_multicast() and 'disabled' or None, 'value': cluster_data.getAltmcastConfig().getTTL() } or {}"/>
</td>
</tr>
-
</table>
<h4>Redundant Ring Cluster Node Configuration</h4>
<table py:if="cluster_data">
diff --git a/luci/validation/validate_cluster_prop.py b/luci/validation/validate_cluster_prop.py
index dead3bb..c822bcc 100644
--- a/luci/validation/validate_cluster_prop.py
+++ b/luci/validation/validate_cluster_prop.py
@@ -15,6 +15,7 @@ from luci.lib.ClusterConf.Method import Method
from luci.lib.ClusterConf.Logging import Logging
from luci.lib.ClusterConf.LoggingDaemon import LoggingDaemon
from luci.lib.ClusterConf.Altname import Altname
+from luci.lib.ClusterConf.Cman import Cman
from luci.lib.db_helpers import create_cluster_obj, get_node_by_name, get_cluster_db_obj, create_user_db_obj
from luci.lib.ricci_communicator import RicciCommunicator
@@ -635,6 +636,8 @@ def validate_rrp_config(model, **kw):
if altmcast_addr and not altmcast_addr.isspace():
try:
altmcast_ptr.setAddr(altmcast_addr)
+ if model.getMcastAddr() == altmcast_addr:
+ errors.append(_('The alternate multicast address %s is the same as the primary cluster multicast address') % altmcast_addr)
except:
errors.append(_('Invalid alternate ring multicast address: %s') % altmcast_addr)
else:
@@ -644,6 +647,15 @@ def validate_rrp_config(model, **kw):
if altmcast_port and not altmcast_port.isspace():
try:
altmcast_ptr.setPort(altmcast_port)
+
+ cman_port = None
+ cp = model.getCMANPtr()
+ if not cp:
+ cp = Cman()
+ cman_port = int(cp.getPort())
+ altmcast_port = int(altmcast_port)
+ if abs(cman_port - altmcast_port) < 2:
+ errors.append(_('Alternate multicast ports (%d %d) and CMAN ports (%d %d) overlap') % (altmcast_port, altmcast_port - 1, cman_port, cman_port - 1))
except:
errors.append(_('Invalid alternate ring CMAN port: %s') % altmcast_port)
else:
@@ -658,22 +670,43 @@ def validate_rrp_config(model, **kw):
else:
altmcast_ptr.delTTL()
+ if not altmcast_ptr.getAddr():
+ if altmcast_ptr.getPort() or altmcast_ptr.getTTL():
+ errors.append(_('Alternate multicast address must be given if alternate multicast port or alternate multicast TTL is given'))
+
+ altnames = set()
for i in model.getNodes():
- cur_node_conf = kw.get('altmcast_%s' % i.getName())
- if cur_node_conf:
+ cur_nodename = i.getName()
+ cur_node_conf = kw.get('altmcast_%s' % cur_nodename)
+ if cur_node_conf and not cur_node_conf.isspace():
# Since we only want the addr attribute, create a new object
# to replace an existing altname that may contain old-style config
try:
cur_an = Altname()
- cur_an.setName(cur_node_conf)
+ cur_an.setName(cur_node_conf.strip())
i.setAltname(cur_an)
+ altnames.add(cur_nodename)
except Exception, e:
errors.append(_('Error setting alternate address for %s: %s')
% (i.getName(), str(e)))
+ else:
+ i.delAltname()
+
+ if len(altnames) > 0:
+ if not altmcast_ptr.getAddr():
+ errors.append(_('If alternate node names are given, the alternate cluster multicast address must be given'))
+ for i in set(model.getNodeNames()) - altnames:
+ errors.append(_('No alternate node name was given for node %s') % i)
+ else:
+ if altmcast_ptr.getAddr():
+ errors.append(_('If an alternate cluster multicast address is given, alternate node names must be given'))
+
+ if len(errors) > 0:
+ return (False, {'errors': errors})
# Clean up any old-style config that may still be around
model.updateRRPConfig()
- return (len(errors) < 1, {'errors': errors})
+ return (len(errors) < 1, {'errors': errors, 'flash': [_('These changes will take effect only after the cluster is completely stopped, then restarted')]})
def validate_log_config(model, **kw):
new_conf = False
12 years, 1 month
[luci] Allow new IF MIB and Intel Modular fencing agents to be configured for clusters running RHEL6.
by Ryan McCabe
commit 6166adff2b390faf7be78697899116eb3f94f0d6
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Wed May 9 16:13:18 2012 -0400
Allow new IF MIB and Intel Modular fencing agents to be configured for
clusters running RHEL6.
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
luci/templates/fence_devices.html | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
---
diff --git a/luci/templates/fence_devices.html b/luci/templates/fence_devices.html
index 8b2ece3..2046c0d 100644
--- a/luci/templates/fence_devices.html
+++ b/luci/templates/fence_devices.html
@@ -3104,9 +3104,10 @@ ${fence_unknown(None,0)}
<py:if test="cluster_version == 3 and cluster_os != 'RHEL'">
<option name="fence_cpint" value="fence_cpint">IBM S/390 cpint</option>
<option name="fence_zvm" value="fence_zvm">IBM S/390 z/VM</option>
+ </py:if>
+ <py:if test="cluster_version == 3">
<option name="fence_ifmib" value="fence_ifmib">IF MIB</option>
<option name="fence_intelmodular" value="fence_intelmodular">Intel Modular</option>
- <option name="fence_virsh" value="fence_virsh">virsh fence agent</option>
</py:if>
<option name="fence_rhevm" value="fence_rhevm">RHEV-M fencing</option>
@@ -3124,6 +3125,7 @@ ${fence_unknown(None,0)}
<py:if test="cluster_version == 3 and cluster_os != 'RHEL'">
<option name="fence_alom" value="fence_alom">Sun ALOM</option>
<option name="fence_ldom" value="fence_ldom">Sun LDOM</option>
+ <option name="fence_virsh" value="fence_virsh">virsh fence agent</option>
</py:if>
<option py:if="cluster_version == 2" name="fence_vixel" value="fence_vixel">Vixel SAN Switch</option>
12 years, 1 month
[luci] Clean up some error cases around adding very long user names and user names with spaces.
by Ryan McCabe
commit 8342d6f0f8c3b43d0a5be9bad9d2f4486f805c9a
Author: Ryan McCabe <rmccabe(a)redhat.com>
Date: Fri May 4 13:33:24 2012 -0400
Clean up some error cases around adding very long user names and
user names with spaces.
Signed-off-by: Ryan McCabe <rmccabe(a)redhat.com>
luci/controllers/root.py | 2 ++
luci/lib/db_helpers.py | 24 +++++++++++++++++++-----
2 files changed, 21 insertions(+), 5 deletions(-)
---
diff --git a/luci/controllers/root.py b/luci/controllers/root.py
index 9bcc973..21b5f6f 100644
--- a/luci/controllers/root.py
+++ b/luci/controllers/root.py
@@ -90,6 +90,8 @@ class RootController(BaseController):
return dict(page='admin')
if command == 'create':
+ if name:
+ name = name.strip()
ret = vcp.validate_add_user(name, **args)
if ret[0] is False:
if ret[1].has_key('errors'):
diff --git a/luci/lib/db_helpers.py b/luci/lib/db_helpers.py
index 115e9e4..6f79aa8 100644
--- a/luci/lib/db_helpers.py
+++ b/luci/lib/db_helpers.py
@@ -569,20 +569,34 @@ def get_user_names():
return ret
def create_user_db_obj(username):
- db_obj = User(user_name=unicode(username),
- email_address=unicode(username))
+ if not username or username.isspace():
+ return _("Users with blank usernames cannot be created")
+ username = username.strip()
+
try:
+ orig_user = username
+ db_obj = User(user_name=unicode(username),
+ email_address=unicode(username))
DBSession.add(db_obj)
DBSession.flush()
+ DBSession.refresh(db_obj)
+
+ if db_obj.user_name != orig_user:
+ try:
+ DBSession.delete(db_obj)
+ DBSession.flush()
+ except Exception, ein:
+ log.exception("Cleaning up failed add of long username")
+ return _('Username "%s" is too long and would be truncated by the database') % orig_user
return None
except IntegrityError, ie:
DBSession.rollback()
- log.exception('Error adding user %s' % username)
- return _("User %s already exists") % username
+ log.exception('Error adding user "%s"' % username)
+ return _('User "%s" already exists') % username
except Exception, e:
DBSession.rollback()
log.exception('Error adding user %s' % username)
- return _("Unable to create user %s") % username
+ return _('Unable to create user "%s"') % username
def get_user_roles(username):
db_user = User.by_user_name(username)
12 years, 1 month