Esempio n. 1
0
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 []
Esempio n. 2
0
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 []
Esempio n. 3
0
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 []
Esempio n. 4
0
    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
Esempio n. 5
0
    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