Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/python/pacemaker/_cts/cibxml.py b/python/pacemaker/_cts/cibxml.py
index 48fe118434..0f394b638f 100644
--- a/python/pacemaker/_cts/cibxml.py
+++ b/python/pacemaker/_cts/cibxml.py
@@ -1,396 +1,396 @@
""" CIB XML generator for Pacemaker's Cluster Test Suite (CTS)
"""
__all__ = [ "Alerts", "Clone", "Expression", "FencingTopology", "Group", "Nodes", "OpDefaults", "Option", "Resource", "Rule" ]
__copyright__ = "Copyright 2008-2023 the Pacemaker project contributors"
__license__ = "GNU General Public License version 2 or later (GPLv2+) WITHOUT ANY WARRANTY"
import sys
def key_val_string(**kwargs):
""" Given keyword arguments as key=value pairs, construct a single string
containing all those pairs separated by spaces. This is suitable for
using in an XML element as a list of its attributes.
Any pairs that have value=None will be skipped.
Note that a dictionary can be passed to this function instead of kwargs
by using a construction like:
key_val_string(**{"a": 1, "b": 2})
"""
retval = ""
for (k, v) in kwargs.items():
if v is None:
continue
retval += ' %s="%s"' % (k, v)
return retval
def element(element_name, **kwargs):
""" Create an XML element string with the given element_name and attributes.
This element does not support having any children, so it will be closed
on the same line. The attributes are processed by key_val_string.
"""
return "<%s %s/>" % (element_name, key_val_string(**kwargs))
def containing_element(element_name, inner, **kwargs):
""" Like element, but surrounds some child text passed by the inner
parameter.
"""
attrs = key_val_string(**kwargs)
return "<%s %s>%s</%s>" % (element_name, attrs, inner, element_name)
class CibBase:
def __init__(self, factory, tag, _id, **kwargs):
self._children = []
self._factory = factory
self._kwargs = kwargs
self._tag = tag
self.name = _id
def __repr__(self):
return "%s-%s" % (self._tag, self.name)
def add_child(self, child):
self._children.append(child)
def __setitem__(self, key, value):
if value:
self._kwargs[key] = value
else:
self._kwargs.pop(key, None)
class XmlBase(CibBase):
def show(self):
text = '''<%s''' % self._tag
if self.name:
text += ''' id="%s"''' % self.name
text += key_val_string(**self._kwargs)
if not self._children:
text += '''/>'''
return text
text += '''>'''
for c in self._children:
text += c.show()
text += '''</%s>''' % self._tag
return text
- def _run(self, operation, xml, section="all", options=""):
+ def _run(self, operation, xml, section, options=""):
if self.name:
label = self.name
else:
label = "<%s>" % self._tag
self._factory.debug("Writing out %s" % label)
fixed = "HOME=/root CIB_file=%s" % self._factory.tmpfile
fixed += " cibadmin --%s --scope %s %s --xml-text '%s'" % (operation, section, options, xml)
(rc, _) = self._factory.rsh(self._factory.target, fixed)
if rc != 0:
self._factory.log("Configure call failed: %s" % fixed)
sys.exit(1)
class InstanceAttributes(XmlBase):
""" Create an <instance_attributes> section with name-value pairs """
def __init__(self, factory, name, attrs):
XmlBase.__init__(self, factory, "instance_attributes", name)
# Create an <nvpair> for each attribute
for (attr, value) in attrs.items():
self.add_child(XmlBase(factory, "nvpair", "%s-%s" % (name, attr),
name=attr, value=value))
class Node(XmlBase):
""" Create a <node> section with node attributes for one node """
def __init__(self, factory, node_name, node_id, node_attrs):
XmlBase.__init__(self, factory, "node", node_id, uname=node_name)
self.add_child(InstanceAttributes(factory, "%s-1" % node_name, node_attrs))
class Nodes(XmlBase):
""" Create a <nodes> section """
def __init__(self, factory):
XmlBase.__init__(self, factory, "nodes", None)
def add_node(self, node_name, node_id, node_attrs):
self.add_child(Node(self._factory, node_name, node_id, node_attrs))
def commit(self):
self._run("modify", self.show(), "configuration", "--allow-create")
class FencingTopology(XmlBase):
def __init__(self, factory):
XmlBase.__init__(self, factory, "fencing-topology", None)
def level(self, index, target, devices, target_attr=None, target_value=None):
# Generate XML ID (sanitizing target-by-attribute levels)
if target:
xml_id = "cts-%s.%d" % (target, index)
self.add_child(XmlBase(self._factory, "fencing-level", xml_id, target=target, index=index, devices=devices))
else:
xml_id = "%s-%s.%d" % (target_attr, target_value, index)
child = XmlBase(self._factory, "fencing-level", xml_id, index=index, devices=devices)
child["target-attribute"]=target_attr
child["target-value"]=target_value
self.add_child(child)
def commit(self):
self._run("create", self.show(), "configuration", "--allow-create")
class Option(XmlBase):
def __init__(self, factory, section="cib-bootstrap-options"):
XmlBase.__init__(self, factory, "cluster_property_set", section)
def __setitem__(self, key, value):
self.add_child(XmlBase(self._factory, "nvpair", "cts-%s" % key, name=key, value=value))
def commit(self):
self._run("modify", self.show(), "crm_config", "--allow-create")
class OpDefaults(XmlBase):
def __init__(self, factory):
XmlBase.__init__(self, factory, "op_defaults", None)
self.meta = XmlBase(self._factory, "meta_attributes", "cts-op_defaults-meta")
self.add_child(self.meta)
def __setitem__(self, key, value):
self.meta.add_child(XmlBase(self._factory, "nvpair", "cts-op_defaults-%s" % key, name=key, value=value))
def commit(self):
self._run("modify", self.show(), "configuration", "--allow-create")
class Alerts(XmlBase):
def __init__(self, factory):
XmlBase.__init__(self, factory, "alerts", None)
self._alert_count = 0
def add_alert(self, path, recipient):
self._alert_count += 1
alert = XmlBase(self._factory, "alert", "alert-%d" % self._alert_count,
path=path)
recipient1 = XmlBase(self._factory, "recipient",
"alert-%d-recipient-1" % self._alert_count,
value=recipient)
alert.add_child(recipient1)
self.add_child(alert)
def commit(self):
self._run("modify", self.show(), "configuration", "--allow-create")
class Expression(XmlBase):
def __init__(self, factory, name, attr, op, value=None):
XmlBase.__init__(self, factory, "expression", name, attribute=attr, operation=op)
if value:
self["value"] = value
class Rule(XmlBase):
def __init__(self, factory, name, score, op="and", expr=None):
XmlBase.__init__(self, factory, "rule", "%s" % name)
self["boolean-op"] = op
self["score"] = score
if expr:
self.add_child(expr)
class Resource(XmlBase):
def __init__(self, factory, name, rtype, standard, provider=None):
XmlBase.__init__(self, factory, "native", name)
self._provider = provider
self._rtype = rtype
self._standard = standard
self._meta = {}
self._op = []
self._param = {}
self._coloc = {}
self._needs = {}
self._scores = {}
if self._standard == "ocf" and not provider:
self._provider = "heartbeat"
elif self._standard == "lsb":
self._provider = None
def __setitem__(self, key, value):
self._add_param(key, value)
def add_op(self, name, interval, **kwargs):
self._op.append(XmlBase(self._factory, "op", "%s-%s" % (name, interval),
name=name, interval=interval, **kwargs))
def _add_param(self, name, value):
self._param[name] = value
def add_meta(self, name, value):
self._meta[name] = value
def prefer(self, node, score="INFINITY", rule=None):
if not rule:
rule = Rule(self._factory, "prefer-%s-r" % node, score,
expr=Expression(self._factory, "prefer-%s-e" % node, "#uname", "eq", node))
self._scores[node] = rule
def after(self, resource, kind="Mandatory", first="start", then="start", **kwargs):
kargs = kwargs.copy()
kargs["kind"] = kind
if then:
kargs["first-action"] = "start"
kargs["then-action"] = then
if first:
kargs["first-action"] = first
self._needs[resource] = kargs
def colocate(self, resource, score="INFINITY", role=None, withrole=None, **kwargs):
kargs = kwargs.copy()
kargs["score"] = score
if role:
kargs["rsc-role"] = role
if withrole:
kargs["with-rsc-role"] = withrole
self._coloc[resource] = kargs
def _constraints(self):
text = "<constraints>"
for (k, v) in self._scores.items():
attrs = {"id": "prefer-%s" % k, "rsc": self.name}
text += containing_element("rsc_location", v.show(), **attrs)
for (k, kargs) in self._needs.items():
attrs = {"id": "%s-after-%s" % (self.name, k), "first": k, "then": self.name}
text += element("rsc_order", **attrs, **kargs)
for (k, kargs) in self._coloc.items():
attrs = {"id": "%s-with-%s" % (self.name, k), "rsc": self.name, "with-rsc": k}
text += element("rsc_colocation", **attrs)
text += "</constraints>"
return text
def show(self):
text = '''<primitive id="%s" class="%s" type="%s"''' % (self.name, self._standard, self._rtype)
if self._provider:
text += ''' provider="%s"''' % self._provider
text += '''>'''
if len(self._meta) > 0:
nvpairs = ""
for (p, v) in self._meta.items():
attrs = {"id": "%s-%s" % (self.name, p), "name": p, "value": v}
nvpairs += element("nvpair", **attrs)
text += containing_element("meta_attributes", nvpairs,
id="%s-meta" % self.name)
if len(self._param) > 0:
nvpairs = ""
for (p, v) in self._param.items():
attrs = {"id": "%s-%s" % (self.name, p), "name": p, "value": v}
nvpairs += element("nvpair", **attrs)
text += containing_element("instance_attributes", nvpairs,
id="%s-params" % self.name)
if len(self._op) > 0:
text += '''<operations>'''
for o in self._op:
key = o.name
o.name = "%s-%s" % (self.name, key)
text += o.show()
o.name = key
text += '''</operations>'''
text += '''</primitive>'''
return text
def commit(self):
self._run("create", self.show(), "resources")
- self._run("modify", self._constraints())
+ self._run("modify", self._constraints(), "constraints")
class Group(Resource):
def __init__(self, factory, name):
Resource.__init__(self, factory, name, None, None)
self.tag = "group"
def __setitem__(self, key, value):
self.add_meta(key, value)
def show(self):
text = '''<%s id="%s">''' % (self.tag, self.name)
if len(self._meta) > 0:
nvpairs = ""
for (p, v) in self._meta.items():
attrs = {"id": "%s-%s" % (self.name, p), "name": p, "value": v}
nvpairs += element("nvpair", **attrs)
text += containing_element("meta_attributes", nvpairs,
id="%s-meta" % self.name)
for c in self._children:
text += c.show()
text += '''</%s>''' % self.tag
return text
class Clone(Group):
def __init__(self, factory, name, child=None):
Group.__init__(self, factory, name)
self.tag = "clone"
if child:
self.add_child(child)
def add_child(self, child):
if not self._children:
self._children.append(child)
else:
self._factory.log("Clones can only have a single child. Ignoring %s" % child.name)

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jun 25, 6:25 AM (12 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1952422
Default Alt Text
(12 KB)

Event Timeline