33
33
from clidisplay import CliDisplay
34
34
from cibstatus import CibStatus
35
35
from idmgmt import IdMgmt
36
- from ra import RAInfo , get_properties_list , get_pe_meta
36
+ from ra import get_ra , get_properties_list , get_pe_meta
37
37
38
38
def show_unrecognized_elems (doc ):
39
39
try :
@@ -242,18 +242,18 @@ def process_primitive(prim, clash_dict):
242
242
(ra_class, ra_provider, ra_type, name, value) -> [ resourcename ]
243
243
if parameter "name" should be unique
244
244
'''
245
- ra_class = prim .getAttribute ("class" )
246
- ra_provider = prim .getAttribute ("provider" )
247
- ra_type = prim .getAttribute ("type" )
248
245
ra_id = prim .getAttribute ("id" )
249
- ra = RAInfo (ra_class , ra_type , ra_provider )
250
- if ra == None :
246
+ r_node = reduce_primitive (prim )
247
+ if not r_node :
248
+ return # template not defined yet
249
+ ra = get_ra (r_node )
250
+ if not ra .mk_ra_node (): # no RA found?
251
251
return
252
252
ra_params = ra .params ()
253
- for a in prim .getElementsByTagName ("instance_attributes" ):
253
+ for a in r_node .getElementsByTagName ("instance_attributes" ):
254
254
# params are in instance_attributes just below the parent
255
255
# operations may have some as well, e.g. OCF_CHECK_LEVEL
256
- if a .parentNode != prim :
256
+ if a .parentNode != r_node :
257
257
continue
258
258
for p in a .getElementsByTagName ("nvpair" ):
259
259
name = p .getAttribute ("name" )
@@ -984,11 +984,22 @@ def cli_list2node(self,cli_list,oldnode):
984
984
remove_id_used_attributes (get_topnode (cib_factory .doc ,self .parent_type ))
985
985
return headnode
986
986
987
- def get_ra (node ):
988
- ra_type = node .getAttribute ("type" )
989
- ra_class = node .getAttribute ("class" )
990
- ra_provider = node .getAttribute ("provider" )
991
- return RAInfo (ra_class ,ra_type ,ra_provider )
987
+ def reduce_primitive (node ):
988
+ '''
989
+ A primitive may reference template. If so, put the two
990
+ together.
991
+ Returns:
992
+ - if no template reference, node itself
993
+ - if template reference, but no template found, None
994
+ - return merged primitive node into template node
995
+ '''
996
+ template = node .getAttribute ("template" )
997
+ if not template :
998
+ return node
999
+ template_obj = cib_factory .find_object (template )
1000
+ if not template_obj :
1001
+ return None
1002
+ return merge_nodes_2 (node , template_obj .node )
992
1003
993
1004
class CibPrimitive (CibObject ):
994
1005
'''
@@ -1002,17 +1013,25 @@ class CibPrimitive(CibObject):
1002
1013
def repr_cli_head (self ,node ):
1003
1014
obj_type = vars .cib_cli_map [node .tagName ]
1004
1015
node_id = node .getAttribute ("id" )
1005
- ra_type = node .getAttribute ("type" )
1006
- ra_class = node .getAttribute ("class" )
1007
- ra_provider = node .getAttribute ("provider" )
1008
- s1 = s2 = ''
1009
- if ra_class :
1010
- s1 = "%s:" % ra_class
1011
- if ra_provider :
1012
- s2 = "%s:" % ra_provider
1016
+ if obj_type == "primitive" :
1017
+ template_ref = node .getAttribute ("template" )
1018
+ else :
1019
+ template_ref = None
1020
+ if template_ref :
1021
+ rsc_spec = "@%s" % cli_display .idref (template_ref )
1022
+ else :
1023
+ ra_type = node .getAttribute ("type" )
1024
+ ra_class = node .getAttribute ("class" )
1025
+ ra_provider = node .getAttribute ("provider" )
1026
+ s1 = s2 = ''
1027
+ if ra_class :
1028
+ s1 = "%s:" % ra_class
1029
+ if ra_provider :
1030
+ s2 = "%s:" % ra_provider
1031
+ rsc_spec = '' .join ((s1 ,s2 ,ra_type ))
1013
1032
s = cli_display .keyword (obj_type )
1014
1033
id = cli_display .id (node_id )
1015
- return "%s %s %s" % (s , id , '' . join (( s1 , s2 , ra_type )) )
1034
+ return "%s %s %s" % (s , id , rsc_spec )
1016
1035
def repr_cli_child (self ,c ,format ):
1017
1036
if c .tagName in self .set_names :
1018
1037
return "%s %s" % \
@@ -1080,31 +1099,30 @@ def check_sanity(self):
1080
1099
common_err ("%s: no xml (strange)" % self .obj_id )
1081
1100
return user_prefs .get_check_rc ()
1082
1101
rc3 = sanity_check_meta (self .obj_id ,self .node ,vars .rsc_meta_attributes )
1083
- ra = get_ra (self .node )
1102
+ if self .obj_type == "primitive" :
1103
+ r_node = reduce_primitive (self .node )
1104
+ if not r_node :
1105
+ # perhaps the template will be defined later
1106
+ return rc3
1107
+ else :
1108
+ r_node = self .node
1109
+ ra = get_ra (r_node )
1084
1110
if not ra .mk_ra_node (): # no RA found?
1085
1111
if cib_factory .is_asymm_cluster ():
1086
1112
return rc3
1087
1113
ra .error ("no such resource agent" )
1088
1114
return user_prefs .get_check_rc ()
1115
+ actions = get_rsc_operations (r_node )
1116
+ default_timeout = get_default_timeout ()
1117
+ rc2 = ra .sanity_check_ops (self .obj_id , actions , default_timeout )
1089
1118
params = []
1090
- for c in self . node .childNodes :
1119
+ for c in r_node .childNodes :
1091
1120
if not is_element (c ):
1092
1121
continue
1093
1122
if c .tagName == "instance_attributes" :
1094
1123
params += nvpairs2list (c )
1095
- rc1 = ra .sanity_check_params (self .obj_id , params )
1096
- actions = {}
1097
- for c in self .node .childNodes :
1098
- if not is_element (c ):
1099
- continue
1100
- if c .tagName == "operations" :
1101
- for c2 in c .childNodes :
1102
- if is_element (c2 ) and c2 .tagName == "op" :
1103
- op ,pl = op2list (c2 )
1104
- if op :
1105
- actions [op ] = pl
1106
- default_timeout = get_default_timeout ()
1107
- rc2 = ra .sanity_check_ops (self .obj_id , actions , default_timeout )
1124
+ rc1 = ra .sanity_check_params (self .obj_id , params ,
1125
+ existence_only = (self .obj_type != "primitive" ))
1108
1126
return rc1 | rc2 | rc3
1109
1127
1110
1128
class CibContainer (CibObject ):
@@ -1389,6 +1407,7 @@ def get_default_timeout():
1389
1407
"group" : ( "group" , CibContainer , "resources" ),
1390
1408
"clone" : ( "clone" , CibContainer , "resources" ),
1391
1409
"master" : ( "ms" , CibContainer , "resources" ),
1410
+ "template" : ( "rsc_template" , CibPrimitive , "resources" ),
1392
1411
"rsc_location" : ( "location" , CibLocation , "constraints" ),
1393
1412
"rsc_colocation" : ( "colocation" , CibSimpleConstraint , "constraints" ),
1394
1413
"rsc_order" : ( "order" , CibSimpleConstraint , "constraints" ),
@@ -1755,6 +1774,10 @@ def f_prim_id_list(self):
1755
1774
"List of possible primitives ids (for group completion)."
1756
1775
return [x .obj_id for x in self .cib_objects \
1757
1776
if x .obj_type == "primitive" and not x .parent ]
1777
+ def rsc_template_list (self ):
1778
+ "List of templates."
1779
+ return [x .obj_id for x in self .cib_objects \
1780
+ if x .obj_type == "rsc_template" ]
1758
1781
def f_children_id_list (self ):
1759
1782
"List of possible child ids (for clone/master completion)."
1760
1783
return [x .obj_id for x in self .cib_objects \
@@ -1800,13 +1823,19 @@ def default_timeouts(self,*args):
1800
1823
common_warn ("element %s is not a primitive" % obj_id )
1801
1824
rc = False
1802
1825
continue
1803
- ra = get_ra (obj .node )
1826
+ r_node = reduce_primitive (obj .node )
1827
+ if not r_node :
1828
+ # cannot do anything without template defined
1829
+ common_warn ("template for %s not defined" % obj_id )
1830
+ rc = False
1831
+ continue
1832
+ ra = get_ra (r_node )
1804
1833
if not ra .mk_ra_node (): # no RA found?
1805
1834
if not self .is_asymm_cluster ():
1806
1835
ra .error ("no resource agent found for %s" % obj_id )
1807
1836
continue
1808
1837
obj_modified = False
1809
- for c in obj . node .childNodes :
1838
+ for c in r_node .childNodes :
1810
1839
if not is_element (c ):
1811
1840
continue
1812
1841
if c .tagName == "operations" :
@@ -1818,7 +1847,7 @@ def default_timeouts(self,*args):
1818
1847
continue
1819
1848
if op in implied_actions :
1820
1849
implied_actions .remove (op )
1821
- elif can_migrate (obj . node ) and op in implied_migrate_actions :
1850
+ elif can_migrate (r_node ) and op in implied_migrate_actions :
1822
1851
implied_migrate_actions .remove (op )
1823
1852
elif is_ms (obj .node .parentNode ) and op in implied_ms_actions :
1824
1853
implied_ms_actions .remove (op )
@@ -1829,7 +1858,7 @@ def default_timeouts(self,*args):
1829
1858
c2 .setAttribute ("timeout" ,adv_timeout )
1830
1859
obj_modified = True
1831
1860
l = implied_actions
1832
- if can_migrate (obj . node ):
1861
+ if can_migrate (r_node ):
1833
1862
l += implied_migrate_actions
1834
1863
if is_ms (obj .node .parentNode ):
1835
1864
l += implied_ms_actions
@@ -2123,7 +2152,7 @@ def merge_from_cli(self,obj,cli_list):
2123
2152
if not node :
2124
2153
return
2125
2154
if obj .obj_type in vars .nvset_cli_names :
2126
- rc = merge_nvpairs (obj .node , node )
2155
+ rc = merge_attributes (obj .node , node , "nvpair" )
2127
2156
else :
2128
2157
rc = merge_nodes (obj .node , node )
2129
2158
if rc :
0 commit comments