def find_resources_to_unmanage(resource_el): """ Get resources to unmanage to unmanage the specified resource succesfully etree resource_el -- resource element """ # resource hierarchy - specified resource - what to return # a primitive - the primitive - the primitive # # a cloned primitive - the primitive - the primitive # a cloned primitive - the clone - the primitive # The resource will run on all nodes after unclone. However that doesn't # seem to be bad behavior. Moreover, if monitor operations were disabled, # they wouldn't enable on unclone, but the resource would become managed, # which is definitely bad. # # a primitive in a group - the primitive - the primitive # Otherwise all primitives in the group would become unmanaged. # a primitive in a group - the group - all primitives in the group # If only the group was set to unmanaged, setting any primitive in the # group to managed would set all the primitives in the group to managed. # If the group as well as all its primitives were set to unmanaged, any # primitive added to the group would become unmanaged. This new primitive # would become managed if any original group primitive becomes managed. # Therefore changing one primitive influences another one, which we do # not want to happen. # # a primitive in a cloned group - the primitive - the primitive # a primitive in a cloned group - the group - all primitives in the group # See group notes above # a primitive in a cloned group - the clone - all primitives in the group # See clone notes above # # a bundled primitive - the primitive - the primitive # a bundled primitive - the bundle - the bundle and the primitive # We need to unmanage implicit resources create by pacemaker and there is # no other way to do it than unmanage the bundle itself. # Since it is not possible to unbundle a resource, the concers described # at unclone don't apply here. However to prevent future bugs, in case # unbundling becomes possible, we unmanage the primitive as well. # an empty bundle - the bundle - the bundle # There is nothing else to unmanage. if is_bundle(resource_el): in_bundle = get_bundle_inner_resource(resource_el) return ( [resource_el, in_bundle] if in_bundle is not None else [resource_el] ) if is_any_clone(resource_el): resource_el = get_clone_inner_resource(resource_el) if is_group(resource_el): return get_group_inner_resources(resource_el) if is_primitive(resource_el): return [resource_el] return []
def find_primitives(resource_el): """ Get list of primitives contained in a given resource etree resource_el -- resource element """ if is_bundle(resource_el): in_bundle = get_bundle_inner_resource(resource_el) return [in_bundle] if in_bundle is not None else [] if is_any_clone(resource_el): resource_el = get_clone_inner_resource(resource_el) if is_group(resource_el): return get_group_inner_resources(resource_el) if is_primitive(resource_el): return [resource_el] return []
def find_resources_to_unmanage(resource_el): """ Get resources to unmanage to unmanage the specified resource succesfully etree resource_el -- resource element """ # resource hierarchy - specified resource - what to return # a primitive - the primitive - the primitive # # a cloned primitive - the primitive - the primitive # a cloned primitive - the clone - the primitive # The resource will run on all nodes after unclone. However that doesn't # seem to be bad behavior. Moreover, if monitor operations were disabled, # they wouldn't enable on unclone, but the resource would become managed, # which is definitely bad. # # a primitive in a group - the primitive - the primitive # Otherwise all primitives in the group would become unmanaged. # a primitive in a group - the group - all primitives in the group # If only the group was set to unmanaged, setting any primitive in the # group to managed would set all the primitives in the group to managed. # If the group as well as all its primitives were set to unmanaged, any # primitive added to the group would become unmanaged. This new primitive # would become managed if any original group primitive becomes managed. # Therefore changing one primitive influences another one, which we do # not want to happen. # # a primitive in a cloned group - the primitive - the primitive # a primitive in a cloned group - the group - all primitives in the group # See group notes above # a primitive in a cloned group - the clone - all primitives in the group # See clone notes above # # a bundled primitive - the primitive - the primitive # a bundled primitive - the bundle - nothing # bundles currently cannot be set as unmanaged - pcmk does not support that # an empty bundle - the bundle - nothing # bundles currently cannot be set as unmanaged - pcmk does not support that if is_any_clone(resource_el): resource_el = get_clone_inner_resource(resource_el) if is_group(resource_el): return get_group_inner_resources(resource_el) if is_primitive(resource_el): return [resource_el] return []
def _validate_resource_elements( self, bad_or_missing_group_specified, bad_resources_specified, bad_adjacent_specified, ): report_list = [] # Check if the group element is really a group unless it has been # checked before. if not bad_or_missing_group_specified and not group.is_group( self._group_element): bad_or_missing_group_specified = True report_list.append( ReportItem.error( reports.messages.IdBelongsToUnexpectedType( self._group_element.attrib.get("id"), expected_types=[group.TAG], current_type=self._group_element.tag, ))) # Report an error if no resources were specified. If resource ids have # been specified but they are not valid resource ids, then some # resources were specified, even though not valid ones. if not bad_resources_specified and not self._resource_element_list: report_list.append( ReportItem.error( reports.messages.CannotGroupResourceNoResources())) resources_already_in_the_group = set() resources_count = defaultdict(int) for resource in self._resource_element_list: resource_id = resource.attrib.get("id") if not primitive.is_primitive(resource): report_list.append( ReportItem.error( reports.messages.CannotGroupResourceWrongType( resource_id, resource.tag))) continue resources_count[resource_id] = resources_count[resource_id] + 1 parent = resource.getparent() if parent is not None: if group.is_group(parent): # If no adjacent resource has been specified (either valid # or invalid), the resources must not already be in the # group, if the group already exists. if (not bad_or_missing_group_specified and not bad_adjacent_specified and self._adjacent_resource_element is None and (parent.attrib.get("id") == self._group_element.attrib.get("id"))): resources_already_in_the_group.add(resource_id) elif parent.tag != "resources": # If the primitive is not in a 'group' or 'resources' tag, # it is either in a clone, master, bundle or similar tag # and cannot be put into a group. report_list.append( ReportItem.error( reports.messages.CannotGroupResourceWrongType( resource_id, parent.tag))) if resources_already_in_the_group: report_list.append( ReportItem.error( reports.messages.CannotGroupResourceAlreadyInTheGroup( sorted(resources_already_in_the_group), self._group_element.attrib.get("id"), ))) more_than_once_resources = [ resource for resource, count in resources_count.items() if count > 1 ] if more_than_once_resources: report_list.append( ReportItem.error( reports.messages.CannotGroupResourceMoreThanOnce( sorted(more_than_once_resources)))) return report_list
def _validate_resource_elements( self, bad_or_missing_group_specified, bad_resources_specified, bad_adjacent_specified ): report_list = [] # Check if the group element is really a group unless it has been # checked before. if ( not bad_or_missing_group_specified and not group.is_group(self._group_element) ): bad_or_missing_group_specified = True report_list.append( reports.id_belongs_to_unexpected_type( self._group_element.attrib.get("id"), expected_types=[group.TAG], current_type=self._group_element.tag ) ) # Report an error if no resources were specified. If resource ids have # been specified but they are not valid resource ids, then some # resources were specified, even though not valid ones. if not bad_resources_specified and not self._resource_element_list: report_list.append(reports.cannot_group_resource_no_resources()) resources_already_in_the_group = set() resources_count = defaultdict(int) for resource in self._resource_element_list: resource_id = resource.attrib.get("id") if not primitive.is_primitive(resource): report_list.append( reports.cannot_group_resource_wrong_type( resource_id, resource.tag ) ) continue resources_count[resource_id] = resources_count[resource_id] + 1 parent = resource.getparent() if parent is not None: if group.is_group(parent): # If no adjacent resource has been specified (either valid # or invalid), the resources must not already be in the # group, if the group already exists. if ( not bad_or_missing_group_specified and not bad_adjacent_specified and self._adjacent_resource_element is None and ( parent.attrib.get("id") == self._group_element.attrib.get("id") ) ): resources_already_in_the_group.add(resource_id) elif parent.tag != "resources": # If the primitive is not in a 'group' or 'resources' tag, # it is either in a clone, master, bundle or similar tag # and cannot be put into a group. report_list.append( reports.cannot_group_resource_wrong_type( resource_id, parent.tag ) ) if resources_already_in_the_group: report_list.append( reports.cannot_group_resource_already_in_the_group( resources_already_in_the_group, self._group_element.attrib.get("id") ) ) more_than_once_resources = [ resource for resource, count in resources_count.items() if count > 1 ] if more_than_once_resources: report_list.append( reports.cannot_group_resource_more_than_once( more_than_once_resources ) ) return report_list