diff --git a/.gitignore b/.gitignore
index 111c603..103ac1c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,22 +1,21 @@
-SOURCES/backports-3.17.2.gem
+SOURCES/backports-3.23.0.gem
 SOURCES/dacite-1.6.0.tar.gz
-SOURCES/daemons-1.3.1.gem
-SOURCES/ethon-0.12.0.gem
+SOURCES/daemons-1.4.1.gem
+SOURCES/ethon-0.15.0.gem
 SOURCES/eventmachine-1.2.7.gem
-SOURCES/ffi-1.13.1.gem
+SOURCES/ffi-1.15.5.gem
 SOURCES/mustermann-1.1.1.gem
 SOURCES/open4-1.3.4-1.gem
-SOURCES/pcs-0.11.1.tar.gz
-SOURCES/pcs-web-ui-0.1.12.tar.gz
-SOURCES/pcs-web-ui-node-modules-0.1.12.tar.xz
+SOURCES/pcs-0.11.3.tar.gz
+SOURCES/pcs-web-ui-0.1.14.tar.gz
+SOURCES/pcs-web-ui-node-modules-0.1.14.tar.xz
 SOURCES/pyagentx-0.4.pcs.2.tar.gz
-SOURCES/rack-2.2.3.gem
-SOURCES/rack-protection-2.0.8.1.gem
+SOURCES/rack-2.2.3.1.gem
+SOURCES/rack-protection-2.2.0.gem
 SOURCES/rack-test-1.1.0.gem
-SOURCES/rexml-3.2.5.gem
-SOURCES/ruby2_keywords-0.0.2.gem
-SOURCES/sinatra-2.0.8.1.gem
-SOURCES/thin-1.7.2.gem
+SOURCES/ruby2_keywords-0.0.5.gem
+SOURCES/sinatra-2.2.0.gem
+SOURCES/thin-1.8.1.gem
 SOURCES/tilt-2.0.10.gem
 SOURCES/tornado-6.1.0.tar.gz
 SOURCES/webrick-1.7.0.gem
diff --git a/.pcs.metadata b/.pcs.metadata
index fc491e3..1000040 100644
--- a/.pcs.metadata
+++ b/.pcs.metadata
@@ -1,22 +1,21 @@
-28b63a742124da6c9575a1c5e7d7331ef93600b2 SOURCES/backports-3.17.2.gem
+0e11246385a9e0a4bc122b74fb74fe536a234f81 SOURCES/backports-3.23.0.gem
 31546c37fbdc6270d5097687619e9c0db6f1c05c SOURCES/dacite-1.6.0.tar.gz
-e28c1e78d1a6e34e80f4933b494f1e0501939dd3 SOURCES/daemons-1.3.1.gem
-921ef1be44583a7644ee7f20fe5f26f21d018a04 SOURCES/ethon-0.12.0.gem
+4795a8962cc1608bfec0d91fa4d438c7cfe90c62 SOURCES/daemons-1.4.1.gem
+29697a34b8cd9df4a77c650e2a38d0a36cdeee8b SOURCES/ethon-0.15.0.gem
 7a5b2896e210fac9759c786ee4510f265f75b481 SOURCES/eventmachine-1.2.7.gem
-cfa25e7a3760c3ec16723cb8263d9b7a52d0eadf SOURCES/ffi-1.13.1.gem
+97632b7975067266c0b39596de0a4c86d9330658 SOURCES/ffi-1.15.5.gem
 50a4e37904485810cb05e27d75c9783e5a8f3402 SOURCES/mustermann-1.1.1.gem
 41a7fe9f8e3e02da5ae76c821b89c5b376a97746 SOURCES/open4-1.3.4-1.gem
-47d8d30bf502ff2a6a81c6cebc262fc272b48011 SOURCES/pcs-0.11.1.tar.gz
-a29bfd22130ac978c5d4a6a82108ce37ad2a5db9 SOURCES/pcs-web-ui-0.1.12.tar.gz
-c9723466d7bfb353899307a5700177f47e7e6cff SOURCES/pcs-web-ui-node-modules-0.1.12.tar.xz
+c16c4623928ba85b0b94b8cbdec6396be85d3672 SOURCES/pcs-0.11.3.tar.gz
+4f518dcca24972f19d3e377931595602106f049d SOURCES/pcs-web-ui-0.1.14.tar.gz
+b3e77ed1e3bb07b8e0ed34ae80fc88b9be0f49a4 SOURCES/pcs-web-ui-node-modules-0.1.14.tar.xz
 3176b2f2b332c2b6bf79fe882e83feecf3d3f011 SOURCES/pyagentx-0.4.pcs.2.tar.gz
-345b7169d4d2d62176a225510399963bad62b68f SOURCES/rack-2.2.3.gem
-1f046e23baca8beece3b38c60382f44aa2b2cb41 SOURCES/rack-protection-2.0.8.1.gem
+be609467c819d263c138c417548431b81f8da216 SOURCES/rack-2.2.3.1.gem
+21cfac2453436c6856da31e741bbfa59da4973e1 SOURCES/rack-protection-2.2.0.gem
 b80bc5ca38a885e747271675ba91dd3d02136bf1 SOURCES/rack-test-1.1.0.gem
-e7f48fa5fb2d92e6cb21d6b1638fe41a5a7c4287 SOURCES/rexml-3.2.5.gem
-0be571aacb5d6a212a30af3f322a7000d8af1ef9 SOURCES/ruby2_keywords-0.0.2.gem
-04cca7a5d9d641fe076e4e24dc5b6ff31922f4c3 SOURCES/sinatra-2.0.8.1.gem
-41395e86322ffd31f3a7aef1f697bda3e1e2d6b9 SOURCES/thin-1.7.2.gem
+d017b9e4d1978e0b3ccc3e2a31493809e4693cd3 SOURCES/ruby2_keywords-0.0.5.gem
+5f0d7e63f9d8683f39ad23afe7e00b99602b87cc SOURCES/sinatra-2.2.0.gem
+1ac6292a98e17247b7bb847a35ff868605256f7b SOURCES/thin-1.8.1.gem
 d265c822a6b228392d899e9eb5114613d65e6967 SOURCES/tilt-2.0.10.gem
 c23c617c7a0205e465bebad5b8cdf289ae8402a2 SOURCES/tornado-6.1.0.tar.gz
 10ba51035928541b7713415f1f2e3a41114972fc SOURCES/webrick-1.7.0.gem
diff --git a/SOURCES/Make-ocf-linbit-drbd-agent-pass-OCF-validation.patch b/SOURCES/Make-ocf-linbit-drbd-agent-pass-OCF-validation.patch
deleted file mode 100644
index 15a7ab4..0000000
--- a/SOURCES/Make-ocf-linbit-drbd-agent-pass-OCF-validation.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From e58f7897d561cff2f9c257933acdb36d57cc130c Mon Sep 17 00:00:00 2001
-From: Tomas Jelinek <tojeline@redhat.com>
-Date: Tue, 4 Jan 2022 12:56:56 +0100
-Subject: [PATCH 2/4] Make ocf:linbit:drbd agent pass OCF validation
-
----
- data/ocf-1.0.rng | 18 ++++++++----------
- 1 file changed, 8 insertions(+), 10 deletions(-)
-
-diff --git a/data/ocf-1.0.rng b/data/ocf-1.0.rng
-index 36ba4611..1e14a83b 100644
---- a/data/ocf-1.0.rng
-+++ b/data/ocf-1.0.rng
-@@ -169,16 +169,14 @@ RNGs. Thank you.
-       <optional>
-         <element name="content">
-           <choice>
--            <attribute name="type">
--              <choice>
--                <value>boolean</value>
--                <value>string</value>
--                <value>integer</value>
--                <value>second</value><!-- used by fence agents -->
--                <value>int</value><!-- used by fence agents intead of integer -->
--                <value>time</value><!-- used by pacemaker metadata -->
--              </choice>
--            </attribute>
-+            <!--
-+              OCF 1.0 allows values: boolean, integer, string. Agents, however,
-+              quite often use other values: int (fence agents), numeric
-+              (ocf:linbit:drbd), second (fence agents), time (pacemaker
-+              metadata). Since pcs doesn't actually care about the type, we
-+              allow any type to keep compatibility with existing agents.
-+            -->
-+            <attribute name="type" />
-             <group>
-               <!--
-                 used by fence agents and processed by pcs even though it is not
--- 
-2.31.1
-
diff --git a/SOURCES/bz1811072-01-revert-of-disallowing-to-clone-a-group-with-a-stonit.patch b/SOURCES/bz1811072-01-revert-of-disallowing-to-clone-a-group-with-a-stonit.patch
deleted file mode 100644
index 6a5ba20..0000000
--- a/SOURCES/bz1811072-01-revert-of-disallowing-to-clone-a-group-with-a-stonit.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From e1573865543a3d59930b315a40ecd9b7a807e1c1 Mon Sep 17 00:00:00 2001
-From: Ondrej Mular <omular@redhat.com>
-Date: Mon, 13 Dec 2021 12:48:26 +0100
-Subject: [PATCH 3/3] revert of disallowing to clone a group with a stonith
- inside
-
-Originally, this was not fixed properly (it was possible to add a stonith
-into a cloned group), therefore to stay consistent, this change is being
-reverted. It will be fixed in the future by not allowing stonith to be
-placed into a group.
----
- pcs/resource.py                                  | 16 ++--------------
- .../tier1/cib_resource/test_clone_unclone.py     |  8 ++------
- 2 files changed, 4 insertions(+), 20 deletions(-)
-
-diff --git a/pcs/resource.py b/pcs/resource.py
-index 928477b2..c7cf4c7e 100644
---- a/pcs/resource.py
-+++ b/pcs/resource.py
-@@ -1697,7 +1697,7 @@ def resource_clone_create(
-     ):
-         element.parentNode.parentNode.removeChild(element.parentNode)
- 
--    def _reject_stonith_clone_report(force_flags, stonith_ids, group_id=None):
-+    if element.getAttribute("class") == "stonith":
-         process_library_reports(
-             [
-                 reports.ReportItem(
-@@ -1706,24 +1706,12 @@ def resource_clone_create(
-                         is_forced=reports.codes.FORCE in force_flags,
-                     ),
-                     message=reports.messages.CloningStonithResourcesHasNoEffect(
--                        stonith_ids, group_id=group_id
-+                        [name]
-                     ),
-                 )
-             ]
-         )
- 
--    if element.getAttribute("class") == "stonith":
--        _reject_stonith_clone_report(force_flags, [name])
--
--    if element.tagName == "group":
--        stonith_ids = [
--            resource.getAttribute("id")
--            for resource in element.getElementsByTagName("primitive")
--            if resource.getAttribute("class") == "stonith"
--        ]
--        if stonith_ids:
--            _reject_stonith_clone_report(force_flags, stonith_ids, name)
--
-     parts = parse_clone_args(argv, promotable=promotable)
-     if not update_existing:
-         clone_id = parts["clone_id"]
-diff --git a/pcs_test/tier1/cib_resource/test_clone_unclone.py b/pcs_test/tier1/cib_resource/test_clone_unclone.py
-index 7b0e89f9..4cc4cb3e 100644
---- a/pcs_test/tier1/cib_resource/test_clone_unclone.py
-+++ b/pcs_test/tier1/cib_resource/test_clone_unclone.py
-@@ -354,12 +354,9 @@ class Clone(
- 
-     def test_clone_group_with_stonith(self):
-         self.set_cib_file(FIXTURE_GROUP_WITH_STONITH)
--        self.assert_pcs_fail(
-+        self.assert_effect(
-             "resource clone Group".split(),
--            fixture_clone_stonith_msg(group=True),
--        )
--        self.assert_resources_xml_in_cib(
--            fixture_resources_xml(FIXTURE_GROUP_WITH_STONITH)
-+            fixture_resources_xml(FIXTURE_CLONED_GROUP_WITH_STONITH),
-         )
- 
-     def test_clone_group_with_stonith_forced(self):
-@@ -367,7 +364,6 @@ class Clone(
-         self.assert_effect(
-             "resource clone Group --force".split(),
-             fixture_resources_xml(FIXTURE_CLONED_GROUP_WITH_STONITH),
--            output=fixture_clone_stonith_msg(forced=True, group=True),
-         )
- 
-     def test_promotable_clone(self):
--- 
-2.31.1
-
diff --git a/SOURCES/bz1990787-01-Multiple-fixes-in-pcs-resource-move-command.patch b/SOURCES/bz1990787-01-Multiple-fixes-in-pcs-resource-move-command.patch
deleted file mode 100644
index b304d91..0000000
--- a/SOURCES/bz1990787-01-Multiple-fixes-in-pcs-resource-move-command.patch
+++ /dev/null
@@ -1,1056 +0,0 @@
-From 4effb249590c6da5eeb13d9106f36e210e6fe5c2 Mon Sep 17 00:00:00 2001
-From: Ondrej Mular <omular@redhat.com>
-Date: Mon, 10 Jan 2022 16:04:54 +0100
-Subject: [PATCH 3/4] Multiple fixes in `pcs resource move` command
-
----
- pcs/common/reports/codes.py                   |   1 +
- pcs/common/reports/messages.py                |  21 ++
- pcs/lib/cib/node.py                           |  14 +-
- pcs/lib/commands/resource.py                  | 105 ++++++-
- pcs/lib/node.py                               |   7 +-
- pcs/resource.py                               |   7 +
- .../tier0/common/reports/test_messages.py     |  12 +
- .../resource/test_resource_move_autoclean.py  | 280 +++++++++++++++++-
- .../resource/test_resource_move_ban.py        |  45 ++-
- .../tools/command_env/config_runner_pcmk.py   |   2 +
- pcs_test/tools/command_env/mock_runner.py     |   2 +-
- pcs_test/tools/fixture_cib.py                 |   1 +
- 12 files changed, 463 insertions(+), 34 deletions(-)
-
-diff --git a/pcs/common/reports/codes.py b/pcs/common/reports/codes.py
-index 8ed83d84..8887fd6d 100644
---- a/pcs/common/reports/codes.py
-+++ b/pcs/common/reports/codes.py
-@@ -421,6 +421,7 @@ RESOURCE_UNMOVE_UNBAN_PCMK_EXPIRED_NOT_SUPPORTED = M(
- )
- RESOURCE_MOVE_CONSTRAINT_CREATED = M("RESOURCE_MOVE_CONSTRAINT_CREATED")
- RESOURCE_MOVE_CONSTRAINT_REMOVED = M("RESOURCE_MOVE_CONSTRAINT_REMOVED")
-+RESOURCE_MOVE_NOT_AFFECTING_RESOURCE = M("RESOURCE_MOVE_NOT_AFFECTING_RESOURCE")
- RESOURCE_MOVE_AFFECTS_OTRHER_RESOURCES = M(
-     "RESOURCE_MOVE_AFFECTS_OTRHER_RESOURCES"
- )
-diff --git a/pcs/common/reports/messages.py b/pcs/common/reports/messages.py
-index 16171fd0..37c79ba1 100644
---- a/pcs/common/reports/messages.py
-+++ b/pcs/common/reports/messages.py
-@@ -6140,6 +6140,27 @@ class ResourceMoveConstraintRemoved(ReportItemMessage):
-         )
- 
- 
-+@dataclass(frozen=True)
-+class ResourceMoveNotAffectingResource(ReportItemMessage):
-+    """
-+    Creating a location constraint to move a resource has no effect on the
-+    resource.
-+
-+    resource_id -- id of the resource to be moved
-+    """
-+
-+    resource_id: str
-+    _code = codes.RESOURCE_MOVE_NOT_AFFECTING_RESOURCE
-+
-+    @property
-+    def message(self) -> str:
-+        return (
-+            f"Unable to move resource '{self.resource_id}' using a location "
-+            "constraint. Current location of the resource may be affected by "
-+            "some other constraint."
-+        )
-+
-+
- @dataclass(frozen=True)
- class ResourceMoveAffectsOtherResources(ReportItemMessage):
-     """
-diff --git a/pcs/lib/cib/node.py b/pcs/lib/cib/node.py
-index 20a41ca0..df2ffbaa 100644
---- a/pcs/lib/cib/node.py
-+++ b/pcs/lib/cib/node.py
-@@ -1,12 +1,17 @@
- from collections import namedtuple
-+from typing import Set
- from lxml import etree
-+from lxml.etree import _Element
- 
- from pcs.common import reports
- from pcs.common.reports.item import ReportItem
- from pcs.lib.cib.nvpair import update_nvset
- from pcs.lib.cib.tools import get_nodes
- from pcs.lib.errors import LibraryError
--from pcs.lib.xml_tools import append_when_useful
-+from pcs.lib.xml_tools import (
-+    append_when_useful,
-+    get_root,
-+)
- 
- 
- class PacemakerNode(namedtuple("PacemakerNode", "name addr")):
-@@ -58,6 +63,13 @@ def update_node_instance_attrs(
-     append_when_useful(cib_nodes, node_el)
- 
- 
-+def get_node_names(cib: _Element) -> Set[str]:
-+    return {
-+        str(node.attrib["uname"])
-+        for node in get_nodes(get_root(cib)).iterfind("./node")
-+    }
-+
-+
- def _ensure_node_exists(tree, node_name, state_nodes=None):
-     """
-     Make sure node with specified name exists
-diff --git a/pcs/lib/commands/resource.py b/pcs/lib/commands/resource.py
-index d0e8f4db..82ce73e0 100644
---- a/pcs/lib/commands/resource.py
-+++ b/pcs/lib/commands/resource.py
-@@ -50,12 +50,16 @@ from pcs.lib.cib.tools import (
- from pcs.lib.env import LibraryEnvironment, WaitType
- from pcs.lib.errors import LibraryError
- from pcs.lib.external import CommandRunner
--from pcs.lib.node import get_existing_nodes_names_addrs
-+from pcs.lib.node import (
-+    get_existing_nodes_names_addrs,
-+    get_pacemaker_node_names,
-+)
- from pcs.lib.pacemaker import simulate as simulate_tools
- from pcs.lib.pacemaker.live import (
-     diff_cibs_xml,
-     get_cib,
-     get_cib_xml,
-+    get_cluster_status_dom,
-     has_resource_unmove_unban_expired_support,
-     push_cib_diff_xml,
-     resource_ban,
-@@ -1589,6 +1593,16 @@ def move(
-     )
- 
- 
-+def _nodes_exist_reports(
-+    cib: _Element, node_names: Iterable[str]
-+) -> ReportItemList:
-+    existing_node_names = get_pacemaker_node_names(cib)
-+    return [
-+        reports.ReportItem.error(reports.messages.NodeNotFound(node_name))
-+        for node_name in (set(node_names) - existing_node_names)
-+    ]
-+
-+
- def move_autoclean(
-     env: LibraryEnvironment,
-     resource_id: str,
-@@ -1626,6 +1640,9 @@ def move_autoclean(
-     if resource_el is not None:
-         report_list.extend(resource.common.validate_move(resource_el, master))
- 
-+    if node:
-+        report_list.extend(_nodes_exist_reports(cib, [node]))
-+
-     if env.report_processor.report_list(report_list).has_errors:
-         raise LibraryError()
- 
-@@ -1659,8 +1676,32 @@ def move_autoclean(
-     add_constraint_cib_diff = diff_cibs_xml(
-         env.cmd_runner(), env.report_processor, cib_xml, rsc_moved_cib_xml
-     )
-+    with get_tmp_cib(
-+        env.report_processor, rsc_moved_cib_xml
-+    ) as rsc_moved_constraint_cleared_cib_file:
-+        stdout, stderr, retval = resource_unmove_unban(
-+            env.cmd_runner(
-+                dict(CIB_file=rsc_moved_constraint_cleared_cib_file.name)
-+            ),
-+            resource_id,
-+            node,
-+            master,
-+        )
-+        if retval != 0:
-+            raise LibraryError(
-+                ReportItem.error(
-+                    reports.messages.ResourceUnmoveUnbanPcmkError(
-+                        resource_id, stdout, stderr
-+                    )
-+                )
-+            )
-+        rsc_moved_constraint_cleared_cib_file.seek(0)
-+        constraint_removed_cib = rsc_moved_constraint_cleared_cib_file.read()
-     remove_constraint_cib_diff = diff_cibs_xml(
--        env.cmd_runner(), env.report_processor, rsc_moved_cib_xml, cib_xml
-+        env.cmd_runner(),
-+        env.report_processor,
-+        rsc_moved_cib_xml,
-+        constraint_removed_cib,
-     )
- 
-     if not (add_constraint_cib_diff and remove_constraint_cib_diff):
-@@ -1689,13 +1730,15 @@ def move_autoclean(
-                     )
-                 )
-             )
--    _ensure_resource_is_not_moved(
-+    _ensure_resource_moved_and_not_moved_back(
-         env.cmd_runner,
-         env.report_processor,
-         etree_to_str(after_move_simulated_cib),
-         remove_constraint_cib_diff,
-         resource_id,
-         strict,
-+        resource_state_before,
-+        node,
-     )
-     push_cib_diff_xml(env.cmd_runner(), add_constraint_cib_diff)
-     env.report_processor.report(
-@@ -1704,13 +1747,15 @@ def move_autoclean(
-         )
-     )
-     env.wait_for_idle(wait_timeout)
--    _ensure_resource_is_not_moved(
-+    _ensure_resource_moved_and_not_moved_back(
-         env.cmd_runner,
-         env.report_processor,
-         get_cib_xml(env.cmd_runner()),
-         remove_constraint_cib_diff,
-         resource_id,
-         strict,
-+        resource_state_before,
-+        node,
-     )
-     push_cib_diff_xml(env.cmd_runner(), remove_constraint_cib_diff)
-     env.report_processor.report(
-@@ -1730,16 +1775,35 @@ def move_autoclean(
-         raise LibraryError()
- 
- 
--def _ensure_resource_is_not_moved(
-+def _ensure_resource_moved_and_not_moved_back(
-     runner_factory: Callable[[Optional[Mapping[str, str]]], CommandRunner],
-     report_processor: reports.ReportProcessor,
-     cib_xml: str,
-     remove_constraint_cib_diff: str,
-     resource_id: str,
-     strict: bool,
-+    resource_state_before: Dict[str, List[str]],
-+    node: Optional[str],
- ) -> None:
-     # pylint: disable=too-many-locals
-     with get_tmp_cib(report_processor, cib_xml) as rsc_unmove_cib_file:
-+        if not _was_resource_moved(
-+            node,
-+            resource_state_before,
-+            get_resource_state(
-+                get_cluster_status_dom(
-+                    runner_factory(dict(CIB_file=rsc_unmove_cib_file.name))
-+                ),
-+                resource_id,
-+            ),
-+        ):
-+            raise LibraryError(
-+                reports.ReportItem.error(
-+                    reports.messages.ResourceMoveNotAffectingResource(
-+                        resource_id
-+                    )
-+                )
-+            )
-         push_cib_diff_xml(
-             runner_factory(dict(CIB_file=rsc_unmove_cib_file.name)),
-             remove_constraint_cib_diff,
-@@ -1809,20 +1873,31 @@ def _resource_running_on_nodes(
-     return frozenset()
- 
- 
-+def _was_resource_moved(
-+    node: Optional[str],
-+    resource_state_before: Dict[str, List[str]],
-+    resource_state_after: Dict[str, List[str]],
-+) -> bool:
-+    running_on_nodes = _resource_running_on_nodes(resource_state_after)
-+    return not bool(
-+        resource_state_before
-+        and (  # running resource moved
-+            not running_on_nodes
-+            or (node and node not in running_on_nodes)
-+            or (resource_state_before == resource_state_after)
-+        )
-+    )
-+
-+
- def _move_wait_report(
-     resource_id: str,
-     node: Optional[str],
-     resource_state_before: Dict[str, List[str]],
-     resource_state_after: Dict[str, List[str]],
- ) -> ReportItem:
--    allowed_nodes = frozenset([node] if node else [])
--    running_on_nodes = _resource_running_on_nodes(resource_state_after)
--
-     severity = reports.item.ReportItemSeverity.info()
--    if resource_state_before and (  # running resource moved
--        not running_on_nodes
--        or (allowed_nodes and allowed_nodes.isdisjoint(running_on_nodes))
--        or (resource_state_before == resource_state_after)
-+    if not _was_resource_moved(
-+        node, resource_state_before, resource_state_after
-     ):
-         severity = reports.item.ReportItemSeverity.error()
-     if not resource_state_after:
-@@ -1873,14 +1948,18 @@ class _MoveBanTemplate:
-         lifetime=None,
-         wait: WaitType = False,
-     ):
-+        # pylint: disable=too-many-locals
-         # validate
-         wait_timeout = env.ensure_wait_satisfiable(wait)  # raises on error
- 
-+        cib = env.get_cib()
-         resource_el, report_list = resource.common.find_one_resource(
--            get_resources(env.get_cib()), resource_id
-+            get_resources(cib), resource_id
-         )
-         if resource_el is not None:
-             report_list.extend(self._validate(resource_el, master))
-+        if node:
-+            report_list.extend(_nodes_exist_reports(cib, [node]))
-         if env.report_processor.report_list(report_list).has_errors:
-             raise LibraryError()
- 
-diff --git a/pcs/lib/node.py b/pcs/lib/node.py
-index ff08f747..3a7f236e 100644
---- a/pcs/lib/node.py
-+++ b/pcs/lib/node.py
-@@ -3,6 +3,7 @@ from typing import (
-     List,
-     Optional,
-     Tuple,
-+    Set,
- )
- 
- from lxml.etree import _Element
-@@ -11,7 +12,7 @@ from pcs.common import reports
- from pcs.common.reports import ReportItemList
- from pcs.common.reports import ReportItemSeverity
- from pcs.common.reports.item import ReportItem
--from pcs.lib.cib.node import PacemakerNode
-+from pcs.lib.cib.node import PacemakerNode, get_node_names
- from pcs.lib.cib.resource import remote_node, guest_node
- from pcs.lib.corosync.config_facade import ConfigFacade as CorosyncConfigFacade
- from pcs.lib.corosync.node import CorosyncNode
-@@ -28,6 +29,10 @@ def get_existing_nodes_names(
-     )
- 
- 
-+def get_pacemaker_node_names(cib: _Element) -> Set[str]:
-+    return get_node_names(cib) | set(get_existing_nodes_names(None, cib)[0])
-+
-+
- def get_existing_nodes_names_addrs(
-     corosync_conf=None, cib=None, error_on_missing_name=False
- ):
-diff --git a/pcs/resource.py b/pcs/resource.py
-index c7cf4c7e..f4f2c093 100644
---- a/pcs/resource.py
-+++ b/pcs/resource.py
-@@ -24,6 +24,7 @@ from pcs.settings import (
-     pacemaker_wait_timeout_status as PACEMAKER_WAIT_TIMEOUT_STATUS,
- )
- from pcs.cli.common.errors import (
-+    SEE_MAN_CHANGES,
-     raise_command_replaced,
-     CmdLineInputError,
- )
-@@ -868,6 +869,12 @@ def resource_move(lib: Any, argv: List[str], modifiers: InputModifiers):
-     node = None
-     if argv:
-         node = argv.pop(0)
-+        if node.startswith("lifetime="):
-+            deprecation_warning(
-+                "Option 'lifetime' has been removed. {}".format(
-+                    SEE_MAN_CHANGES.format("0.11")
-+                )
-+            )
-     if argv:
-         raise CmdLineInputError()
- 
-diff --git a/pcs_test/tier0/common/reports/test_messages.py b/pcs_test/tier0/common/reports/test_messages.py
-index a6f92395..a56ef382 100644
---- a/pcs_test/tier0/common/reports/test_messages.py
-+++ b/pcs_test/tier0/common/reports/test_messages.py
-@@ -4515,6 +4515,18 @@ class ResourceMoveConstraintRemoved(NameBuildTest):
-         )
- 
- 
-+class ResourceMoveNotAffectingResource(NameBuildTest):
-+    def test_success(self):
-+        self.assert_message_from_report(
-+            (
-+                "Unable to move resource 'R1' using a location constraint. "
-+                "Current location of the resource may be affected by some "
-+                "other constraint."
-+            ),
-+            reports.ResourceMoveNotAffectingResource("R1"),
-+        )
-+
-+
- class ResourceMoveAffectsOtherResources(NameBuildTest):
-     def test_multiple(self):
-         self.assert_message_from_report(
-diff --git a/pcs_test/tier0/lib/commands/resource/test_resource_move_autoclean.py b/pcs_test/tier0/lib/commands/resource/test_resource_move_autoclean.py
-index 32d758de..1bd4ee82 100644
---- a/pcs_test/tier0/lib/commands/resource/test_resource_move_autoclean.py
-+++ b/pcs_test/tier0/lib/commands/resource/test_resource_move_autoclean.py
-@@ -20,6 +20,25 @@ from pcs_test.tools.command_env import get_env_tools
- from pcs_test.tools.misc import get_test_resource as rc
- 
- 
-+def _node_fixture(name, node_id):
-+    return f'<node id="{node_id}" uname="{name}"/>'
-+
-+
-+def _node_list_fixture(nodes):
-+    return "\n".join(
-+        _node_fixture(node_name, node_id)
-+        for node_id, node_name in enumerate(nodes)
-+    )
-+
-+
-+def _nodes_section_fixture(content):
-+    return f"""
-+    <nodes>
-+    {content}
-+    </nodes>
-+    """
-+
-+
- def _rsc_primitive_fixture(res_id):
-     return f'<primitive id="{res_id}"/>'
- 
-@@ -145,11 +164,17 @@ class MoveAutocleanSuccess(MoveAutocleanCommonSetup):
-             resources=_resources_tag(
-                 _resource_primitive + _resource_promotable_clone
-             ),
-+            nodes=_nodes_section_fixture(
-+                _node_list_fixture([self.orig_node, self.new_node])
-+            ),
-         )
-         self.orig_cib = etree_to_str(
-             xml_fromstring(self.config.calls.get(config_load_cib_name).stdout)
-         )
-         self.cib_with_constraint = '<updated_cib with_constraint="True"/>'
-+        self.cib_without_constraint = (
-+            '<cib with_constraint="False" updated="True"/>'
-+        )
-         self.cib_simulate_constraint = (
-             '<cib simulate="True" with_constraint="True"/>'
-         )
-@@ -160,6 +185,9 @@ class MoveAutocleanSuccess(MoveAutocleanCommonSetup):
-         self.cib_diff_add_constraint_updated_tmp_file_name = (
-             "cib_diff_add_constraint_updated"
-         )
-+        self.cib_constraint_removed_by_unmove_file_name = (
-+            "cib_constraint_removed_by_unmove"
-+        )
-         self.cib_diff_remove_constraint_orig_tmp_file_name = (
-             "cib_diff_remove_constraint_orig"
-         )
-@@ -220,13 +248,18 @@ class MoveAutocleanSuccess(MoveAutocleanCommonSetup):
-                 self.cib_diff_add_constraint_updated_tmp_file_name,
-                 orig_content=self.cib_with_constraint,
-             ),
-+            TmpFileCall(
-+                self.cib_constraint_removed_by_unmove_file_name,
-+                orig_content=self.cib_with_constraint,
-+                new_content=self.cib_without_constraint,
-+            ),
-             TmpFileCall(
-                 self.cib_diff_remove_constraint_orig_tmp_file_name,
-                 orig_content=self.cib_with_constraint,
-             ),
-             TmpFileCall(
-                 self.cib_diff_remove_constraint_updated_tmp_file_name,
--                orig_content=self.orig_cib,
-+                orig_content=self.cib_without_constraint,
-             ),
-             TmpFileCall(
-                 self.simulated_cib_add_constraint_tmp_file_name,
-@@ -296,6 +329,12 @@ class MoveAutocleanSuccess(MoveAutocleanCommonSetup):
-             stdout=self.cib_diff_add_constraint,
-             name="runner.cib.diff.add_constraint",
-         )
-+        self.config.runner.pcmk.resource_clear(
-+            resource=resource_id,
-+            master=is_promotable,
-+            node=self.new_node if with_node else None,
-+            env=dict(CIB_file=self.cib_constraint_removed_by_unmove_file_name),
-+        )
-         self.config.runner.cib.diff(
-             self.cib_diff_remove_constraint_orig_tmp_file_name,
-             self.cib_diff_remove_constraint_updated_tmp_file_name,
-@@ -308,6 +347,13 @@ class MoveAutocleanSuccess(MoveAutocleanCommonSetup):
-             cib_xml=self.cib_with_constraint,
-             name="pcmk.simulate.rsc.move",
-         )
-+        self.config.runner.pcmk.load_state(
-+            resources=status_after,
-+            name="runner.pcmk.load_state.mid_simulation",
-+            env=dict(
-+                CIB_file=self.cib_apply_diff_remove_constraint_from_simulated_cib_tmp_file_name
-+            ),
-+        )
-         self.config.runner.cib.push_diff(
-             cib_diff=self.cib_diff_remove_constraint,
-             name="pcmk.push_cib_diff.simulation.remove_constraint",
-@@ -335,6 +381,13 @@ class MoveAutocleanSuccess(MoveAutocleanCommonSetup):
-             self.cib_with_constraint,
-             name="load_cib_after_move",
-         )
-+        self.config.runner.pcmk.load_state(
-+            resources=status_after,
-+            name="runner.pcmk.load_state.after_push",
-+            env=dict(
-+                CIB_file=self.cib_apply_diff_remove_constraint_after_push_tmp_file_name
-+            ),
-+        )
-         self.config.runner.cib.push_diff(
-             cib_diff=self.cib_diff_remove_constraint,
-             name="pcmk.push_cib_diff.simulation.remove_constraint_after_move",
-@@ -380,6 +433,11 @@ class MoveAutocleanSuccess(MoveAutocleanCommonSetup):
-                 file_path=self.cib_diff_add_constraint_updated_tmp_file_name,
-                 content=self.cib_with_constraint,
-             ),
-+            fixture.debug(
-+                reports.codes.TMP_FILE_WRITE,
-+                file_path=self.cib_constraint_removed_by_unmove_file_name,
-+                content=self.cib_with_constraint,
-+            ),
-             fixture.debug(
-                 reports.codes.TMP_FILE_WRITE,
-                 file_path=self.cib_diff_remove_constraint_orig_tmp_file_name,
-@@ -388,7 +446,7 @@ class MoveAutocleanSuccess(MoveAutocleanCommonSetup):
-             fixture.debug(
-                 reports.codes.TMP_FILE_WRITE,
-                 file_path=self.cib_diff_remove_constraint_updated_tmp_file_name,
--                content=self.orig_cib,
-+                content=self.cib_without_constraint,
-             ),
-             fixture.debug(
-                 reports.codes.TMP_FILE_WRITE,
-@@ -758,9 +816,7 @@ class MoveAutocleanValidations(MoveAutocleanCommonSetup):
-             resources=_state_resource_fixture(resource_id, "Stopped"),
-         )
-         self.env_assist.assert_raise_library_error(
--            lambda: move_autoclean(
--                self.env_assist.get_env(), resource_id, node="node"
--            ),
-+            lambda: move_autoclean(self.env_assist.get_env(), resource_id),
-             [
-                 fixture.error(
-                     reports.codes.CANNOT_MOVE_RESOURCE_NOT_RUNNING,
-@@ -770,11 +826,33 @@ class MoveAutocleanValidations(MoveAutocleanCommonSetup):
-             expected_in_processor=False,
-         )
- 
-+    def test_node_not_found(self):
-+        resource_id = "A"
-+        node = "non_existing_node"
-+        self.config.runner.cib.load(
-+            resources=_resources_tag(_rsc_primitive_fixture(resource_id)),
-+        )
-+        self.env_assist.assert_raise_library_error(
-+            lambda: move_autoclean(
-+                self.env_assist.get_env(), resource_id, node
-+            ),
-+        )
-+        self.env_assist.assert_reports(
-+            [
-+                fixture.error(
-+                    reports.codes.NODE_NOT_FOUND,
-+                    node=node,
-+                    searched_types=[],
-+                )
-+            ],
-+        )
-+
-     def test_constraint_already_exist(self):
-         resource_id = "A"
-         config_load_cib_name = "load_cib"
-         node = "node1"
-         cib_with_constraint = '<cib with_constraint="True"/>'
-+        cib_without_constraint = '<cib with_constraint="False" updated="True"/>'
-         cib_rsc_move_tmp_file_name = "cib_rsc_move_tmp_file"
-         cib_diff_add_constraint_orig_tmp_file_name = (
-             "cib_diff_add_constraint_orig"
-@@ -788,6 +866,9 @@ class MoveAutocleanValidations(MoveAutocleanCommonSetup):
-         cib_diff_remove_constraint_updated_tmp_file_name = (
-             "cib_diff_remove_constraint_updated"
-         )
-+        cib_constraint_removed_by_unmove_file_name = (
-+            "cib_constraint_removed_by_unmove"
-+        )
-         self.config.runner.cib.load(
-             resources=_resources_tag(_rsc_primitive_fixture(resource_id)),
-             constraints=f"""
-@@ -795,6 +876,7 @@ class MoveAutocleanValidations(MoveAutocleanCommonSetup):
-                   <rsc_location id="prefer-{resource_id}" rsc="{resource_id}" role="Started" node="{node}" score="INFINITY"/>
-               </constraints>
-             """,
-+            nodes=_nodes_section_fixture(_node_list_fixture([node])),
-             name=config_load_cib_name,
-         )
-         orig_cib = etree_to_str(
-@@ -815,13 +897,18 @@ class MoveAutocleanValidations(MoveAutocleanCommonSetup):
-                     cib_diff_add_constraint_updated_tmp_file_name,
-                     orig_content=cib_with_constraint,
-                 ),
-+                TmpFileCall(
-+                    cib_constraint_removed_by_unmove_file_name,
-+                    orig_content=cib_with_constraint,
-+                    new_content=cib_without_constraint,
-+                ),
-                 TmpFileCall(
-                     cib_diff_remove_constraint_orig_tmp_file_name,
-                     orig_content=cib_with_constraint,
-                 ),
-                 TmpFileCall(
-                     cib_diff_remove_constraint_updated_tmp_file_name,
--                    orig_content=orig_cib,
-+                    orig_content=cib_without_constraint,
-                 ),
-             ]
-         )
-@@ -839,6 +926,11 @@ class MoveAutocleanValidations(MoveAutocleanCommonSetup):
-             stdout="",
-             name="runner.cib.diff.add_constraint",
-         )
-+        self.config.runner.pcmk.resource_clear(
-+            resource=resource_id,
-+            node=node,
-+            env=dict(CIB_file=cib_constraint_removed_by_unmove_file_name),
-+        )
-         self.config.runner.cib.diff(
-             cib_diff_remove_constraint_orig_tmp_file_name,
-             cib_diff_remove_constraint_updated_tmp_file_name,
-@@ -863,6 +955,11 @@ class MoveAutocleanValidations(MoveAutocleanCommonSetup):
-                     file_path=cib_diff_add_constraint_updated_tmp_file_name,
-                     content=cib_with_constraint,
-                 ),
-+                fixture.debug(
-+                    reports.codes.TMP_FILE_WRITE,
-+                    file_path=cib_constraint_removed_by_unmove_file_name,
-+                    content=cib_with_constraint,
-+                ),
-                 fixture.debug(
-                     reports.codes.TMP_FILE_WRITE,
-                     file_path=cib_diff_remove_constraint_orig_tmp_file_name,
-@@ -871,7 +968,7 @@ class MoveAutocleanValidations(MoveAutocleanCommonSetup):
-                 fixture.debug(
-                     reports.codes.TMP_FILE_WRITE,
-                     file_path=cib_diff_remove_constraint_updated_tmp_file_name,
--                    content=orig_cib,
-+                    content=cib_without_constraint,
-                 ),
-                 fixture.info(
-                     reports.codes.NO_ACTION_NECESSARY,
-@@ -896,6 +993,9 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-         self.cib_diff_add_constraint = "diff_add_constraint"
-         self.cib_diff_remove_constraint = "diff_remove_constraint"
-         self.cib_with_constraint = '<cib with_constraint="True"/>'
-+        self.cib_without_constraint = (
-+            '<cib with_constraint="False" updated="True"/>'
-+        )
-         self.cib_rsc_move_tmp_file_name = "cib_rsc_move_tmp_file"
-         self.cib_diff_add_constraint_orig_tmp_file_name = (
-             "cib_diff_add_constraint_orig"
-@@ -903,6 +1003,9 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-         self.cib_diff_add_constraint_updated_tmp_file_name = (
-             "cib_diff_add_constraint_updated"
-         )
-+        self.cib_constraint_removed_by_unmove_file_name = (
-+            "cib_constraint_removed_by_unmove"
-+        )
-         self.cib_diff_remove_constraint_orig_tmp_file_name = (
-             "cib_diff_remove_constraint_orig"
-         )
-@@ -951,6 +1054,9 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
- 
-         self.config.runner.cib.load(
-             resources=_resources_tag(_rsc_primitive_fixture(self.resource_id)),
-+            nodes=_nodes_section_fixture(
-+                _node_list_fixture(["node1", "node2"])
-+            ),
-             name=self.config_load_cib_name,
-         )
-         self.orig_cib = etree_to_str(
-@@ -979,13 +1085,18 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-                 self.cib_diff_add_constraint_updated_tmp_file_name,
-                 orig_content=self.cib_with_constraint,
-             ),
-+            TmpFileCall(
-+                self.cib_constraint_removed_by_unmove_file_name,
-+                orig_content=self.cib_with_constraint,
-+                new_content=self.cib_without_constraint,
-+            ),
-             TmpFileCall(
-                 self.cib_diff_remove_constraint_orig_tmp_file_name,
-                 orig_content=self.cib_with_constraint,
-             ),
-             TmpFileCall(
-                 self.cib_diff_remove_constraint_updated_tmp_file_name,
--                orig_content=self.orig_cib,
-+                orig_content=self.cib_without_constraint,
-             ),
-             TmpFileCall(
-                 self.simulated_cib_add_constraint_tmp_file_name,
-@@ -1067,6 +1178,11 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-             stdout=self.cib_diff_add_constraint,
-             name="runner.cib.diff.add_constraint",
-         )
-+        self.config.runner.pcmk.resource_clear(
-+            resource=self.resource_id,
-+            node=node,
-+            env=dict(CIB_file=self.cib_constraint_removed_by_unmove_file_name),
-+        )
-         self.config.runner.cib.diff(
-             self.cib_diff_remove_constraint_orig_tmp_file_name,
-             self.cib_diff_remove_constraint_updated_tmp_file_name,
-@@ -1081,6 +1197,15 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-         )
-         if stage <= 1:
-             return
-+        self.config.runner.pcmk.load_state(
-+            resources=_state_resource_fixture(
-+                self.resource_id, "Started", node if node else "node2"
-+            ),
-+            name="runner.pcmk.load_state.mid_simulation",
-+            env=dict(
-+                CIB_file=self.cib_apply_diff_remove_constraint_from_simulated_cib_tmp_file_name
-+            ),
-+        )
-         self.config.runner.cib.push_diff(
-             cib_diff=self.cib_diff_remove_constraint,
-             name="pcmk.push_cib_diff.simulation.remove_constraint",
-@@ -1110,6 +1235,17 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-             self.cib_with_constraint,
-             name="load_cib_after_move",
-         )
-+        if stage <= 3:
-+            return
-+        self.config.runner.pcmk.load_state(
-+            resources=_state_resource_fixture(
-+                self.resource_id, "Started", node if node else "node2"
-+            ),
-+            name="runner.pcmk.load_state.after_push",
-+            env=dict(
-+                CIB_file=self.cib_apply_diff_remove_constraint_after_push_tmp_file_name
-+            ),
-+        )
-         self.config.runner.cib.push_diff(
-             cib_diff=self.cib_diff_remove_constraint,
-             name="pcmk.push_cib_diff.simulation.remove_constraint_after_move",
-@@ -1126,7 +1262,7 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-             ),
-             name="pcmk.simulate.rsc.unmove.after_push",
-         )
--        if stage <= 3:
-+        if stage <= 4:
-             return
-         self.config.runner.cib.push_diff(
-             cib_diff=self.cib_diff_remove_constraint,
-@@ -1153,6 +1289,11 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-                 file_path=self.cib_diff_add_constraint_updated_tmp_file_name,
-                 content=self.cib_with_constraint,
-             ),
-+            fixture.debug(
-+                reports.codes.TMP_FILE_WRITE,
-+                file_path=self.cib_constraint_removed_by_unmove_file_name,
-+                content=self.cib_with_constraint,
-+            ),
-             fixture.debug(
-                 reports.codes.TMP_FILE_WRITE,
-                 file_path=self.cib_diff_remove_constraint_orig_tmp_file_name,
-@@ -1161,7 +1302,7 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-             fixture.debug(
-                 reports.codes.TMP_FILE_WRITE,
-                 file_path=self.cib_diff_remove_constraint_updated_tmp_file_name,
--                content=self.orig_cib,
-+                content=self.cib_without_constraint,
-             ),
-             fixture.debug(
-                 reports.codes.TMP_FILE_WRITE,
-@@ -1199,7 +1340,7 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-                 reports.codes.WAIT_FOR_IDLE_STARTED,
-                 timeout=0,
-             ),
--        ][: {None: None, 3: -2, 2: 7, 1: 5}[stage]]
-+        ][: {None: None, 4: -2, 3: 10, 2: 8, 1: 6}[stage]]
- 
-     def test_move_affects_other_resources_strict(self):
-         self.tmp_file_mock_obj.set_calls(
-@@ -1304,7 +1445,8 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-                 ),
-             )
-         )
--        self.set_up_testing_env(stage=3)
-+        setup_stage = 4
-+        self.set_up_testing_env(stage=setup_stage)
-         self.env_assist.assert_raise_library_error(
-             lambda: move_autoclean(self.env_assist.get_env(), self.resource_id),
-             [
-@@ -1316,7 +1458,7 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-             ],
-             expected_in_processor=False,
-         )
--        self.env_assist.assert_reports(self.get_reports(stage=3))
-+        self.env_assist.assert_reports(self.get_reports(stage=setup_stage))
- 
-     def test_unmove_after_push_affects_other_resources_strict(self):
-         self.tmp_file_mock_obj.set_calls(
-@@ -1330,7 +1472,8 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-                 ),
-             )
-         )
--        self.set_up_testing_env(stage=3)
-+        setup_stage = 4
-+        self.set_up_testing_env(stage=setup_stage)
-         self.env_assist.assert_raise_library_error(
-             lambda: move_autoclean(
-                 self.env_assist.get_env(),
-@@ -1346,7 +1489,7 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-             ],
-             expected_in_processor=False,
-         )
--        self.env_assist.assert_reports(self.get_reports(stage=3))
-+        self.env_assist.assert_reports(self.get_reports(stage=setup_stage))
- 
-     def test_resource_not_runnig_after_move(self):
-         self.tmp_file_mock_obj.set_calls(
-@@ -1381,8 +1524,113 @@ class MoveAutocleanFailures(MoveAutocleanCommonSetup):
-             ]
-         )
- 
-+    def test_simulation_resource_not_moved(self):
-+        node = "node2"
-+        different_node = f"different-{node}"
-+        setup_stage = 1
-+        self.tmp_file_mock_obj.set_calls(
-+            self.get_tmp_files_mocks(
-+                _simulation_transition_fixture(
-+                    _simulation_synapses_fixture(self.resource_id)
-+                ),
-+            )
-+            + [
-+                TmpFileCall(
-+                    self.cib_apply_diff_remove_constraint_from_simulated_cib_tmp_file_name,
-+                    orig_content=self.cib_simulate_constraint,
-+                ),
-+            ]
-+        )
-+        self.set_up_testing_env(node=node, stage=setup_stage)
-+        self.config.runner.pcmk.load_state(
-+            resources=_state_resource_fixture(
-+                self.resource_id, "Started", different_node
-+            ),
-+            name="runner.pcmk.load_state.final",
-+            env=dict(
-+                CIB_file=self.cib_apply_diff_remove_constraint_from_simulated_cib_tmp_file_name
-+            ),
-+        )
-+        self.env_assist.assert_raise_library_error(
-+            lambda: move_autoclean(
-+                self.env_assist.get_env(),
-+                self.resource_id,
-+                node=node,
-+            ),
-+            [
-+                fixture.error(
-+                    reports.codes.RESOURCE_MOVE_NOT_AFFECTING_RESOURCE,
-+                    resource_id=self.resource_id,
-+                )
-+            ],
-+            expected_in_processor=False,
-+        )
-+        self.env_assist.assert_reports(
-+            self.get_reports(stage=setup_stage)
-+            + [
-+                fixture.debug(
-+                    reports.codes.TMP_FILE_WRITE,
-+                    file_path=self.cib_apply_diff_remove_constraint_from_simulated_cib_tmp_file_name,
-+                    content=self.cib_simulate_constraint,
-+                ),
-+            ]
-+        )
-+
-+    def test_after_push_resource_not_moved(self):
-+        node = "node2"
-+        different_node = f"different-{node}"
-+        setup_stage = 3
-+        self.tmp_file_mock_obj.set_calls(
-+            self.get_tmp_files_mocks(
-+                _simulation_transition_fixture(
-+                    _simulation_synapses_fixture(self.resource_id)
-+                ),
-+                _simulation_transition_fixture(),
-+            )
-+            + [
-+                TmpFileCall(
-+                    self.cib_apply_diff_remove_constraint_after_push_tmp_file_name,
-+                    orig_content=self.cib_with_constraint,
-+                ),
-+            ]
-+        )
-+        self.set_up_testing_env(node=node, stage=setup_stage)
-+        self.config.runner.pcmk.load_state(
-+            resources=_state_resource_fixture(
-+                self.resource_id, "Started", different_node
-+            ),
-+            name="runner.pcmk.load_state.final",
-+            env=dict(
-+                CIB_file=self.cib_apply_diff_remove_constraint_after_push_tmp_file_name,
-+            ),
-+        )
-+        self.env_assist.assert_raise_library_error(
-+            lambda: move_autoclean(
-+                self.env_assist.get_env(),
-+                self.resource_id,
-+                node=node,
-+            ),
-+            [
-+                fixture.error(
-+                    reports.codes.RESOURCE_MOVE_NOT_AFFECTING_RESOURCE,
-+                    resource_id=self.resource_id,
-+                )
-+            ],
-+            expected_in_processor=False,
-+        )
-+        self.env_assist.assert_reports(
-+            self.get_reports(stage=setup_stage)
-+            + [
-+                fixture.debug(
-+                    reports.codes.TMP_FILE_WRITE,
-+                    file_path=self.cib_apply_diff_remove_constraint_after_push_tmp_file_name,
-+                    content=self.cib_with_constraint,
-+                ),
-+            ]
-+        )
-+
-     def test_resource_running_on_a_different_node(self):
--        node = "node1"
-+        node = "node2"
-         different_node = f"different-{node}"
-         self.tmp_file_mock_obj.set_calls(
-             self.get_tmp_files_mocks(
-diff --git a/pcs_test/tier0/lib/commands/resource/test_resource_move_ban.py b/pcs_test/tier0/lib/commands/resource/test_resource_move_ban.py
-index 5d57fa06..28dd1cd1 100644
---- a/pcs_test/tier0/lib/commands/resource/test_resource_move_ban.py
-+++ b/pcs_test/tier0/lib/commands/resource/test_resource_move_ban.py
-@@ -10,6 +10,29 @@ from pcs.common.reports import ReportItemSeverity as severities
- from pcs.common.reports import codes as report_codes
- from pcs.lib.commands import resource
- 
-+
-+def _node_fixture(name, node_id):
-+    return f'<node id="{node_id}" uname="{name}"/>'
-+
-+
-+def _node_list_fixture(nodes):
-+    return "\n".join(
-+        _node_fixture(node_name, node_id)
-+        for node_id, node_name in enumerate(nodes)
-+    )
-+
-+
-+def _nodes_section_fixture(content):
-+    return f"""
-+    <nodes>
-+    {content}
-+    </nodes>
-+    """
-+
-+
-+nodes_section = _nodes_section_fixture(
-+    _node_list_fixture(["node", "node1", "node2"])
-+)
- resources_primitive = """
-     <resources>
-         <primitive id="A" />
-@@ -128,8 +151,24 @@ class MoveBanBaseMixin(MoveBanClearBaseMixin):
-             expected_in_processor=False,
-         )
- 
-+    def test_node_not_found(self):
-+        self.config.runner.cib.load(resources=resources_primitive)
-+        node = "node"
-+        self.env_assist.assert_raise_library_error(
-+            lambda: self.lib_action(self.env_assist.get_env(), "A", node)
-+        )
-+        self.env_assist.assert_reports(
-+            [
-+                fixture.error(
-+                    report_codes.NODE_NOT_FOUND, node=node, searched_types=[]
-+                )
-+            ]
-+        )
-+
-     def test_all_options(self):
--        self.config.runner.cib.load(resources=resources_promotable)
-+        self.config.runner.cib.load(
-+            resources=resources_promotable, nodes=nodes_section
-+        )
-         self.config_pcmk_action(
-             resource="A-clone",
-             master=True,
-@@ -274,7 +313,9 @@ class MoveBanWaitMixin:
-     def setUp(self):
-         self.timeout = 10
-         self.env_assist, self.config = get_env_tools(self)
--        self.config.runner.cib.load(resources=resources_primitive)
-+        self.config.runner.cib.load(
-+            resources=resources_primitive, nodes=nodes_section
-+        )
- 
-     @mock.patch.object(
-         settings,
-diff --git a/pcs_test/tools/command_env/config_runner_pcmk.py b/pcs_test/tools/command_env/config_runner_pcmk.py
-index 6df3dff3..7a88cf96 100644
---- a/pcs_test/tools/command_env/config_runner_pcmk.py
-+++ b/pcs_test/tools/command_env/config_runner_pcmk.py
-@@ -695,6 +695,7 @@ class PcmkShortcuts:
-         stdout="",
-         stderr="",
-         returncode=0,
-+        env=None,
-     ):
-         """
-         Create a call for crm_resource --clear
-@@ -711,6 +712,7 @@ class PcmkShortcuts:
-         string stdout -- crm_resource's stdout
-         string stderr -- crm_resource's stderr
-         int returncode -- crm_resource's returncode
-+        dict env -- CommandRunner environment variables
-         """
-         # arguments are used via locals()
-         # pylint: disable=unused-argument
-diff --git a/pcs_test/tools/command_env/mock_runner.py b/pcs_test/tools/command_env/mock_runner.py
-index f7871fc2..8520ce02 100644
---- a/pcs_test/tools/command_env/mock_runner.py
-+++ b/pcs_test/tools/command_env/mock_runner.py
-@@ -143,6 +143,6 @@ class Runner:
-             env.update(env_extend)
-         if env != call.env:
-             raise self.__call_queue.error_with_context(
--                f"ENV doesn't match. Expected: {call.env}; Real: {env}"
-+                f"Command #{i}: ENV doesn't match. Expected: {call.env}; Real: {env}"
-             )
-         return call.stdout, call.stderr, call.returncode
-diff --git a/pcs_test/tools/fixture_cib.py b/pcs_test/tools/fixture_cib.py
-index 602491c8..bf02bacc 100644
---- a/pcs_test/tools/fixture_cib.py
-+++ b/pcs_test/tools/fixture_cib.py
-@@ -310,6 +310,7 @@ MODIFIER_GENERATORS = {
-     "replace": replace_all,
-     "append": append_all,
-     "resources": lambda xml: replace_all({"./configuration/resources": xml}),
-+    "nodes": lambda xml: replace_all({"./configuration/nodes": xml}),
-     "constraints": lambda xml: replace_all(
-         {"./configuration/constraints": xml}
-     ),
--- 
-2.31.1
-
diff --git a/SOURCES/bz2019836-01-fix-rsc-update-cmd-when-unable-to-get-agent-metadata.patch b/SOURCES/bz2019836-01-fix-rsc-update-cmd-when-unable-to-get-agent-metadata.patch
deleted file mode 100644
index 9611c1a..0000000
--- a/SOURCES/bz2019836-01-fix-rsc-update-cmd-when-unable-to-get-agent-metadata.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 69bfb22dbd68023069f6dae11e418f6ad455474f Mon Sep 17 00:00:00 2001
-From: Ondrej Mular <omular@redhat.com>
-Date: Tue, 7 Dec 2021 11:14:37 +0100
-Subject: [PATCH 2/3] fix rsc update cmd when unable to get agent metadata
-
-`resource update` command failed with a traceback when updating a
-resource with a non-existing resource agent
----
- pcs/resource.py                        | 14 ++++++++------
- pcs_test/tier1/legacy/test_resource.py | 21 +++++++++++++++++++++
- 2 files changed, 29 insertions(+), 6 deletions(-)
-
-diff --git a/pcs/resource.py b/pcs/resource.py
-index b2a5e355..928477b2 100644
---- a/pcs/resource.py
-+++ b/pcs/resource.py
-@@ -1075,13 +1075,15 @@ def resource_update(lib, args, modifiers, deal_with_guest_change=True):
-         if report_list:
-             process_library_reports(report_list)
-     except lib_ra.ResourceAgentError as e:
--        severity = (
--            reports.ReportItemSeverity.WARNING
--            if modifiers.get("--force")
--            else reports.ReportItemSeverity.ERROR
--        )
-         process_library_reports(
--            [lib_ra.resource_agent_error_to_report_item(e, severity)]
-+            [
-+                lib_ra.resource_agent_error_to_report_item(
-+                    e,
-+                    reports.get_severity(
-+                        reports.codes.FORCE, modifiers.get("--force")
-+                    ),
-+                )
-+            ]
-         )
-     except LibraryError as e:
-         process_library_reports(e.args)
-diff --git a/pcs_test/tier1/legacy/test_resource.py b/pcs_test/tier1/legacy/test_resource.py
-index 417ca131..0f8415b4 100644
---- a/pcs_test/tier1/legacy/test_resource.py
-+++ b/pcs_test/tier1/legacy/test_resource.py
-@@ -4882,6 +4882,27 @@ class UpdateInstanceAttrs(
-             ),
-         )
- 
-+    def test_nonexisting_agent(self):
-+        agent = "ocf:pacemaker:nonexistent"
-+        message = (
-+            f"Agent '{agent}' is not installed or does "
-+            "not provide valid metadata: Metadata query for "
-+            f"{agent} failed: Input/output error"
-+        )
-+        self.assert_pcs_success(
-+            f"resource create --force D0 {agent}".split(),
-+            f"Warning: {message}\n",
-+        )
-+
-+        self.assert_pcs_fail(
-+            "resource update D0 test=testA".split(),
-+            f"Error: {message}, use --force to override\n",
-+        )
-+        self.assert_pcs_success(
-+            "resource update --force D0 test=testA".split(),
-+            f"Warning: {message}\n",
-+        )
-+
-     def test_update_existing(self):
-         xml = """
-             <resources>
--- 
-2.31.1
-
diff --git a/SOURCES/bz2026725-01-booth-sync-check-whether-etc-booth-exists.patch b/SOURCES/bz2026725-01-booth-sync-check-whether-etc-booth-exists.patch
new file mode 100644
index 0000000..1a8dc60
--- /dev/null
+++ b/SOURCES/bz2026725-01-booth-sync-check-whether-etc-booth-exists.patch
@@ -0,0 +1,46 @@
+From f863c38497eb716141c9e585ddb418191e9fc2a4 Mon Sep 17 00:00:00 2001
+From: Tomas Jelinek <tojeline@redhat.com>
+Date: Fri, 15 Jul 2022 15:55:57 +0200
+Subject: [PATCH 3/3] booth sync: check whether /etc/booth exists
+
+---
+ pcsd/pcsd_file.rb | 6 +-----
+ pcsd/remote.rb    | 4 ++++
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/pcsd/pcsd_file.rb b/pcsd/pcsd_file.rb
+index d82b55d2..394db59a 100644
+--- a/pcsd/pcsd_file.rb
++++ b/pcsd/pcsd_file.rb
+@@ -112,12 +112,8 @@ module PcsdFile
+       end
+     end
+ 
+-    def dir()
+-      return BOOTH_CONFIG_DIR
+-    end
+-
+     def full_file_name()
+-      @full_file_name ||= File.join(self.dir, @file[:name])
++      @full_file_name ||= File.join(BOOTH_CONFIG_DIR, @file[:name])
+     end
+   end
+ 
+diff --git a/pcsd/remote.rb b/pcsd/remote.rb
+index 854674eb..144d25f3 100644
+--- a/pcsd/remote.rb
++++ b/pcsd/remote.rb
+@@ -2090,6 +2090,10 @@ def booth_set_config(params, request, auth_user)
+     check_permissions(auth_user, Permissions::WRITE)
+     data = check_request_data_for_json(params, auth_user)
+ 
++    if not File.directory?(BOOTH_CONFIG_DIR)
++      raise "Configuration directory for booth '/etc/booth' is missing. Is booth installed?"
++    end
++
+     PcsdExchangeFormat::validate_item_map_is_Hash('files', data)
+     PcsdExchangeFormat::validate_item_is_Hash('file', :config, data[:config])
+     if data[:authfile]
+-- 
+2.35.3
+
diff --git a/SOURCES/bz2032473-01-fix-enabling-corosync-qdevice.patch b/SOURCES/bz2032473-01-fix-enabling-corosync-qdevice.patch
deleted file mode 100644
index 71a2290..0000000
--- a/SOURCES/bz2032473-01-fix-enabling-corosync-qdevice.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 798d054db1a20b7cd2f2aed2b35b9e51835dec55 Mon Sep 17 00:00:00 2001
-From: Tomas Jelinek <tojeline@redhat.com>
-Date: Mon, 6 Dec 2021 16:06:31 +0100
-Subject: [PATCH 1/3] fix enabling corosync-qdevice
-
----
- pcsd/remote.rb | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/pcsd/remote.rb b/pcsd/remote.rb
-index b569e249..e1923d6f 100644
---- a/pcsd/remote.rb
-+++ b/pcsd/remote.rb
-@@ -2002,7 +2002,7 @@ def qdevice_client_enable(param, request, auth_user)
-   unless allowed_for_local_cluster(auth_user, Permissions::WRITE)
-     return 403, 'Permission denied'
-   end
--  if not ServiceChecker.new('corosync', enabled: true).is_enabled?('corosync')
-+  if not ServiceChecker.new(['corosync'], enabled: true).is_enabled?('corosync')
-     return pcsd_success('corosync is not enabled, skipping')
-   elsif enable_service('corosync-qdevice')
-     return pcsd_success('corosync-qdevice enabled')
--- 
-2.31.1
-
diff --git a/SOURCES/bz2033248-01-skip-checking-of-scsi-devices-to-be-removed.patch b/SOURCES/bz2033248-01-skip-checking-of-scsi-devices-to-be-removed.patch
deleted file mode 100644
index 277e1a8..0000000
--- a/SOURCES/bz2033248-01-skip-checking-of-scsi-devices-to-be-removed.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 1f91f67a18885937794e775bbbcde973ffe59468 Mon Sep 17 00:00:00 2001
-From: Miroslav Lisik <mlisik@redhat.com>
-Date: Thu, 16 Dec 2021 14:12:58 +0100
-Subject: [PATCH 1/4] skip checking of scsi devices to be removed before
- unfencing to be added devices
-
----
- pcs/lib/commands/scsi.py                 |  3 ++-
- pcs_test/tier0/lib/commands/test_scsi.py | 21 +++++++++++++++++----
- 2 files changed, 19 insertions(+), 5 deletions(-)
-
-diff --git a/pcs/lib/commands/scsi.py b/pcs/lib/commands/scsi.py
-index ff20a563..ab732805 100644
---- a/pcs/lib/commands/scsi.py
-+++ b/pcs/lib/commands/scsi.py
-@@ -31,7 +31,8 @@ def unfence_node(
-         return
-     fence_scsi_bin = os.path.join(settings.fence_agent_binaries, "fence_scsi")
-     fenced_devices = []
--    for device in original_devices:
-+    # do not check devices being removed
-+    for device in sorted(set(original_devices) & set(updated_devices)):
-         stdout, stderr, return_code = env.cmd_runner().run(
-             [
-                 fence_scsi_bin,
-diff --git a/pcs_test/tier0/lib/commands/test_scsi.py b/pcs_test/tier0/lib/commands/test_scsi.py
-index 8ef9836a..bc2357a9 100644
---- a/pcs_test/tier0/lib/commands/test_scsi.py
-+++ b/pcs_test/tier0/lib/commands/test_scsi.py
-@@ -13,10 +13,13 @@ class TestUnfenceNode(TestCase):
-         self.old_devices = ["device1", "device3"]
-         self.new_devices = ["device3", "device0", "device2"]
-         self.added_devices = set(self.new_devices) - set(self.old_devices)
-+        self.check_devices = sorted(
-+            set(self.old_devices) & set(self.new_devices)
-+        )
-         self.node = "node1"
- 
-     def test_success_devices_to_unfence(self):
--        for old_dev in self.old_devices:
-+        for old_dev in self.check_devices:
-             self.config.runner.scsi.get_status(
-                 self.node, old_dev, name=f"runner.scsi.is_fenced.{old_dev}"
-             )
-@@ -38,9 +41,19 @@ class TestUnfenceNode(TestCase):
-         )
-         self.env_assist.assert_reports([])
- 
-+    def test_success_replace_unavailable_device(self):
-+        self.config.runner.scsi.unfence_node(self.node, {"device2"})
-+        scsi.unfence_node(
-+            self.env_assist.get_env(),
-+            self.node,
-+            {"device1"},
-+            {"device2"},
-+        )
-+        self.env_assist.assert_reports([])
-+
-     def test_unfencing_failure(self):
-         err_msg = "stderr"
--        for old_dev in self.old_devices:
-+        for old_dev in self.check_devices:
-             self.config.runner.scsi.get_status(
-                 self.node, old_dev, name=f"runner.scsi.is_fenced.{old_dev}"
-             )
-@@ -98,7 +111,7 @@ class TestUnfenceNode(TestCase):
- 
-     def test_unfencing_skipped_devices_are_fenced(self):
-         stdout_off = "Status: OFF"
--        for old_dev in self.old_devices:
-+        for old_dev in self.check_devices:
-             self.config.runner.scsi.get_status(
-                 self.node,
-                 old_dev,
-@@ -116,7 +129,7 @@ class TestUnfenceNode(TestCase):
-             [
-                 fixture.info(
-                     report_codes.STONITH_UNFENCING_SKIPPED_DEVICES_FENCED,
--                    devices=sorted(self.old_devices),
-+                    devices=sorted(self.check_devices),
-                 )
-             ]
-         )
--- 
-2.31.1
-
diff --git a/SOURCES/bz2040420-01-fix-creating-empty-cib.patch b/SOURCES/bz2040420-01-fix-creating-empty-cib.patch
deleted file mode 100644
index 0039b3d..0000000
--- a/SOURCES/bz2040420-01-fix-creating-empty-cib.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 94d411afc37de231c8a3101c30e1e6ba66ecd223 Mon Sep 17 00:00:00 2001
-From: Tomas Jelinek <tojeline@redhat.com>
-Date: Thu, 13 Jan 2022 17:32:38 +0100
-Subject: [PATCH 4/4] fix creating empty cib
-
----
- pcs/utils.py                | 21 +++++++++++----------
- pcs_test/tier1/test_misc.py | 25 ++++++++++++++++++++++++-
- 2 files changed, 35 insertions(+), 11 deletions(-)
-
-diff --git a/pcs/utils.py b/pcs/utils.py
-index 2f5949a7..b5b8af05 100644
---- a/pcs/utils.py
-+++ b/pcs/utils.py
-@@ -2135,16 +2135,17 @@ def write_empty_cib(cibfile):
-     """
-     Commandline options: no options
-     """
--    empty_xml = """<?xml version="1.0" encoding="UTF-8"?>
--<cib admin_epoch="0" epoch="1" num_updates="1" validate-with="pacemaker-1.2">
--  <configuration>
--    <crm_config/>
--    <nodes/>
--    <resources/>
--    <constraints/>
--  </configuration>
--  <status/>
--</cib>"""
-+    empty_xml = """
-+        <cib admin_epoch="0" epoch="1" num_updates="1" validate-with="pacemaker-3.1">
-+          <configuration>
-+            <crm_config/>
-+            <nodes/>
-+            <resources/>
-+            <constraints/>
-+          </configuration>
-+          <status/>
-+        </cib>
-+    """
-     with open(cibfile, "w") as f:
-         f.write(empty_xml)
- 
-diff --git a/pcs_test/tier1/test_misc.py b/pcs_test/tier1/test_misc.py
-index 13312a69..abd02c61 100644
---- a/pcs_test/tier1/test_misc.py
-+++ b/pcs_test/tier1/test_misc.py
-@@ -1,8 +1,10 @@
-+import os
- from unittest import TestCase
- 
- from pcs_test.tools.assertions import AssertPcsMixin
- from pcs_test.tools.misc import (
-     get_test_resource as rc,
-+    get_tmp_dir,
-     get_tmp_file,
-     outdent,
-     write_file_to_tmpfile,
-@@ -19,7 +21,7 @@ class ParseArgvDashDash(TestCase, AssertPcsMixin):
-     cmd = "constraint colocation add R1 with R2".split()
- 
-     def setUp(self):
--        self.temp_cib = get_tmp_file("tier1_misc")
-+        self.temp_cib = get_tmp_file("tier1_misc_dashdash")
-         write_file_to_tmpfile(rc("cib-empty.xml"), self.temp_cib)
-         self.pcs_runner = PcsRunner(self.temp_cib.name)
-         self.allowed_roles = format_list(const.PCMK_ROLES)
-@@ -89,3 +91,24 @@ class ParseArgvDashDash(TestCase, AssertPcsMixin):
-                 """
-             ),
-         )
-+
-+
-+class EmptyCibIsPcmk2Compatible(TestCase, AssertPcsMixin):
-+    # This test verifies that a default empty CIB created by pcs when -f points
-+    # to an empty file conforms to minimal schema version supported by
-+    # pacemaker 2.0. If pcs prints a message that CIB schema has been upgraded,
-+    # then the test fails and shows there is a bug. Bundle with promoted-max
-+    # requires CIB compliant with schema 3.1, which was introduced in pacemaker
-+    # 2.0.0.
-+    def setUp(self):
-+        self.cib_dir = get_tmp_dir("tier1_misc_empty_cib")
-+        self.pcs_runner = PcsRunner(os.path.join(self.cib_dir.name, "cib.xml"))
-+
-+    def tearDown(self):
-+        self.cib_dir.cleanup()
-+
-+    def test_success(self):
-+        self.assert_pcs_success(
-+            "resource bundle create b container docker image=my.img promoted-max=1".split(),
-+            "",
-+        )
--- 
-2.31.1
-
diff --git a/SOURCES/bz2044409-01-fix-backend-parameter-all-in-cluster-destroy.patch b/SOURCES/bz2044409-01-fix-backend-parameter-all-in-cluster-destroy.patch
deleted file mode 100644
index 1131d7f..0000000
--- a/SOURCES/bz2044409-01-fix-backend-parameter-all-in-cluster-destroy.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From fa75f40361bc39cbd645b8014713e4c0ad0cda18 Mon Sep 17 00:00:00 2001
-From: Ivan Devat <idevat@redhat.com>
-Date: Mon, 24 Jan 2022 14:08:54 +0100
-Subject: [PATCH 2/2] fix backend parameter "all" in cluster destroy
-
----
- src/app/backend/calls/destroyCluster.ts | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/app/backend/calls/destroyCluster.ts b/src/app/backend/calls/destroyCluster.ts
-index b6e83a41..cf41ea42 100644
---- a/src/app/backend/calls/destroyCluster.ts
-+++ b/src/app/backend/calls/destroyCluster.ts
-@@ -4,5 +4,5 @@ const { url } = endpoints.destroyCluster;
- 
- export const destroyCluster = (clusterName: string): CallResult =>
-   http.post(url({ clusterName }), {
--    params: [["--all", "1"]],
-+    params: [["all", "1"]],
-   });
--- 
-2.31.1
-
diff --git a/SOURCES/bz20486401-01-Fix-snmp-client.patch b/SOURCES/bz20486401-01-Fix-snmp-client.patch
deleted file mode 100644
index 63a05d5..0000000
--- a/SOURCES/bz20486401-01-Fix-snmp-client.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 7902bb8fe7f97fbbc93e7001a6c4e8a445dcb44e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Valentin=20Vidi=C4=87?= <vvidic@valentin-vidic.from.hr>
-Date: Wed, 15 Dec 2021 20:32:26 +0100
-Subject: [PATCH 1/2] Fix snmp client
-
-Required constant is missing causing the command to fail on startup and breaking the pcs_snmp_agent service.
----
- pcsd/pcsd-cli-main.rb | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/pcsd/pcsd-cli-main.rb b/pcsd/pcsd-cli-main.rb
-index 29b9006d..be72d543 100644
---- a/pcsd/pcsd-cli-main.rb
-+++ b/pcsd/pcsd-cli-main.rb
-@@ -10,6 +10,7 @@ require 'remote.rb'
- 
- 
- PCS = get_pcs_path()
-+PCS_INTERNAL = get_pcs_internal_path()
- $logger_device = StringIO.new
- $logger = Logger.new($logger_device)
- early_log($logger)
--- 
-2.34.1
-
diff --git a/SOURCES/bz2058243-01-code-formatting.patch b/SOURCES/bz2058243-01-code-formatting.patch
new file mode 100644
index 0000000..7868ae8
--- /dev/null
+++ b/SOURCES/bz2058243-01-code-formatting.patch
@@ -0,0 +1,2491 @@
+From 8859f3450df675579d24e4bd3d5e12aeefbaef54 Mon Sep 17 00:00:00 2001
+From: Tomas Jelinek <tojeline@redhat.com>
+Date: Thu, 14 Jul 2022 16:22:39 +0200
+Subject: [PATCH 1/3] code formatting
+
+---
+ pcs_test/tier0/lib/commands/test_booth.py | 1684 +++++++++------------
+ 1 file changed, 723 insertions(+), 961 deletions(-)
+
+diff --git a/pcs_test/tier0/lib/commands/test_booth.py b/pcs_test/tier0/lib/commands/test_booth.py
+index 6dc0cf3e..2b20a199 100644
+--- a/pcs_test/tier0/lib/commands/test_booth.py
++++ b/pcs_test/tier0/lib/commands/test_booth.py
+@@ -211,22 +211,23 @@ class ConfigSetup(TestCase, FixtureMixin):
+             )
+         )
+         self.env_assist.assert_reports(
+-            [fixture.error(reports.codes.BOOTH_EVEN_PEERS_NUM, number=4)]
++            [
++                fixture.error(reports.codes.BOOTH_EVEN_PEERS_NUM, number=4),
++            ]
+         )
+ 
+     def fixture_config_success(self, instance_name="booth"):
+-        (
+-            self.config.raw_file.write(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(instance_name),
+-                RANDOM_KEY,
+-                name="raw_file.write.key",
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                self.fixture_cfg_content(self.fixture_key_path(instance_name)),
+-                name="raw_file.write.cfg",
+-            )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(instance_name),
++            RANDOM_KEY,
++            name="raw_file.write.key",
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            self.fixture_cfg_content(self.fixture_key_path(instance_name)),
++            name="raw_file.write.cfg",
+         )
+ 
+     def test_success_default_instance(self):
+@@ -248,19 +249,18 @@ class ConfigSetup(TestCase, FixtureMixin):
+         )
+ 
+     def test_files_exist_config(self):
+-        (
+-            self.config.raw_file.write(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(),
+-                RANDOM_KEY,
+-                name="raw_file.write.key",
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(),
+-                already_exists=True,
+-                name="raw_file.write.cfg",
+-            )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(),
++            RANDOM_KEY,
++            name="raw_file.write.key",
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(),
++            already_exists=True,
++            name="raw_file.write.cfg",
+         )
+ 
+         self.env_assist.assert_raise_library_error(
+@@ -283,14 +283,12 @@ class ConfigSetup(TestCase, FixtureMixin):
+         )
+ 
+     def test_files_exist_key(self):
+-        (
+-            self.config.raw_file.write(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(),
+-                RANDOM_KEY,
+-                already_exists=True,
+-                name="raw_file.write.key",
+-            )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(),
++            RANDOM_KEY,
++            already_exists=True,
++            name="raw_file.write.key",
+         )
+ 
+         self.env_assist.assert_raise_library_error(
+@@ -313,20 +311,19 @@ class ConfigSetup(TestCase, FixtureMixin):
+         )
+ 
+     def test_files_exist_forced(self):
+-        (
+-            self.config.raw_file.write(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(),
+-                RANDOM_KEY,
+-                can_overwrite=True,
+-                name="raw_file.write.key",
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(),
+-                can_overwrite=True,
+-                name="raw_file.write.cfg",
+-            )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(),
++            RANDOM_KEY,
++            can_overwrite=True,
++            name="raw_file.write.key",
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(),
++            can_overwrite=True,
++            name="raw_file.write.cfg",
+         )
+ 
+         commands.config_setup(
+@@ -337,7 +334,6 @@ class ConfigSetup(TestCase, FixtureMixin):
+         )
+ 
+     def _assert_write_config_error(self, error, booth_dir_exists):
+-
+         self.config.raw_file.write(
+             file_type_codes.BOOTH_KEY,
+             self.fixture_key_path(),
+@@ -444,11 +440,7 @@ class ConfigSetup(TestCase, FixtureMixin):
+         )
+         env = self.env_assist.get_env()
+ 
+-        commands.config_setup(
+-            env,
+-            self.sites,
+-            self.arbitrators,
+-        )
++        commands.config_setup(env, self.sites, self.arbitrators)
+ 
+         self.assertEqual(
+             env.get_booth_env(name="").export(),
+@@ -491,38 +483,34 @@ class ConfigDestroy(TestCase, FixtureMixin):
+         self.env_assist, self.config = get_env_tools(self)
+ 
+     def fixture_config_booth_not_used(self, instance_name="booth"):
+-        (
+-            self.config.runner.cib.load()
+-            .services.is_running(
+-                "booth", instance=instance_name, return_value=False
+-            )
+-            .services.is_enabled(
+-                "booth", instance=instance_name, return_value=False
+-            )
++        self.config.runner.cib.load()
++        self.config.services.is_running(
++            "booth", instance=instance_name, return_value=False
++        )
++        self.config.services.is_enabled(
++            "booth", instance=instance_name, return_value=False
+         )
+ 
+     def fixture_config_success(self, instance_name="booth"):
+         self.fixture_config_booth_not_used(instance_name)
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                content=self.fixture_cfg_content(
+-                    self.fixture_key_path(instance_name)
+-                ),
+-            )
+-            .raw_file.remove(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(instance_name),
+-                fail_if_file_not_found=False,
+-                name="raw_file.remove.key",
+-            )
+-            .raw_file.remove(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                fail_if_file_not_found=True,
+-                name="raw_file.remove.cfg",
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            content=self.fixture_cfg_content(
++                self.fixture_key_path(instance_name)
++            ),
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(instance_name),
++            fail_if_file_not_found=False,
++            name="raw_file.remove.key",
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            fail_if_file_not_found=True,
++            name="raw_file.remove.cfg",
+         )
+ 
+     def test_invalid_instance(self):
+@@ -540,9 +528,7 @@ class ConfigDestroy(TestCase, FixtureMixin):
+ 
+     def test_success_default_instance(self):
+         self.fixture_config_success()
+-        commands.config_destroy(
+-            self.env_assist.get_env(),
+-        )
++        commands.config_destroy(self.env_assist.get_env())
+ 
+     def test_success_custom_instance(self):
+         instance_name = "my_booth"
+@@ -553,23 +539,20 @@ class ConfigDestroy(TestCase, FixtureMixin):
+ 
+     def test_success_no_booth_key(self):
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=bytes(),
+-            ).raw_file.remove(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                fail_if_file_not_found=True,
+-                name="raw_file.remove.cfg",
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=bytes(),
+         )
+-
+-        commands.config_destroy(
+-            self.env_assist.get_env(),
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            fail_if_file_not_found=True,
++            name="raw_file.remove.cfg",
+         )
+ 
++        commands.config_destroy(self.env_assist.get_env())
++
+     def test_not_live_booth(self):
+         self.config.env.set_booth(
+             {
+@@ -603,9 +586,7 @@ class ConfigDestroy(TestCase, FixtureMixin):
+             [
+                 fixture.error(
+                     reports.codes.LIVE_ENVIRONMENT_REQUIRED,
+-                    forbidden_options=[
+-                        file_type_codes.CIB,
+-                    ],
++                    forbidden_options=[file_type_codes.CIB],
+                 ),
+             ],
+             expected_in_processor=False,
+@@ -640,20 +621,16 @@ class ConfigDestroy(TestCase, FixtureMixin):
+     def test_booth_config_in_use(self):
+         instance_name = "booth"
+ 
+-        (
+-            self.config.runner.cib.load(resources=self.fixture_cib_resources())
+-            .services.is_running(
+-                "booth", instance=instance_name, return_value=True
+-            )
+-            .services.is_enabled(
+-                "booth", instance=instance_name, return_value=True
+-            )
++        self.config.runner.cib.load(resources=self.fixture_cib_resources())
++        self.config.services.is_running(
++            "booth", instance=instance_name, return_value=True
++        )
++        self.config.services.is_enabled(
++            "booth", instance=instance_name, return_value=True
+         )
+ 
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_destroy(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: commands.config_destroy(self.env_assist.get_env()),
+         )
+ 
+         self.env_assist.assert_reports(
+@@ -682,18 +659,14 @@ class ConfigDestroy(TestCase, FixtureMixin):
+     def test_cannot_read_config(self):
+         error = "an error"
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                exception_msg=error,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            exception_msg=error,
+         )
+ 
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_destroy(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: commands.config_destroy(self.env_assist.get_env()),
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -711,17 +684,16 @@ class ConfigDestroy(TestCase, FixtureMixin):
+     def test_cannot_read_config_forced(self):
+         error = "an error"
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                exception_msg=error,
+-            ).raw_file.remove(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                fail_if_file_not_found=True,
+-                name="raw_file.remove.cfg",
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            exception_msg=error,
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            fail_if_file_not_found=True,
++            name="raw_file.remove.cfg",
+         )
+ 
+         commands.config_destroy(
+@@ -742,18 +714,14 @@ class ConfigDestroy(TestCase, FixtureMixin):
+ 
+     def test_config_parse_error(self):
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content="invalid config".encode("utf-8"),
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content="invalid config".encode("utf-8"),
+         )
+ 
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_destroy(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: commands.config_destroy(self.env_assist.get_env()),
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -768,17 +736,16 @@ class ConfigDestroy(TestCase, FixtureMixin):
+ 
+     def test_config_parse_error_forced(self):
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content="invalid config".encode("utf-8"),
+-            ).raw_file.remove(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                fail_if_file_not_found=True,
+-                name="raw_file.remove.cfg",
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content="invalid config".encode("utf-8"),
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            fail_if_file_not_found=True,
++            name="raw_file.remove.cfg",
+         )
+ 
+         commands.config_destroy(
+@@ -797,52 +764,45 @@ class ConfigDestroy(TestCase, FixtureMixin):
+ 
+     def test_key_already_deleted(self):
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            )
+-            .raw_file.remove(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(),
+-                fail_if_file_not_found=False,
+-                file_not_found_exception=True,
+-                name="raw_file.remove.key",
+-            )
+-            .raw_file.remove(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                fail_if_file_not_found=True,
+-                name="raw_file.remove.cfg",
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
+         )
+-
+-        commands.config_destroy(
+-            self.env_assist.get_env(),
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(),
++            fail_if_file_not_found=False,
++            file_not_found_exception=True,
++            name="raw_file.remove.key",
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            fail_if_file_not_found=True,
++            name="raw_file.remove.cfg",
+         )
+ 
++        commands.config_destroy(self.env_assist.get_env())
++
+     def test_cannot_delete_key(self):
+         error = "an error"
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            ).raw_file.remove(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(),
+-                fail_if_file_not_found=False,
+-                exception_msg=error,
+-                name="raw_file.remove.key",
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(),
++            fail_if_file_not_found=False,
++            exception_msg=error,
++            name="raw_file.remove.key",
+         )
+ 
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_destroy(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: commands.config_destroy(self.env_assist.get_env()),
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -860,25 +820,23 @@ class ConfigDestroy(TestCase, FixtureMixin):
+     def test_cannot_delete_key_forced(self):
+         error = "an error"
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            )
+-            .raw_file.remove(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(),
+-                fail_if_file_not_found=False,
+-                exception_msg=error,
+-                name="raw_file.remove.key",
+-            )
+-            .raw_file.remove(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                fail_if_file_not_found=True,
+-                name="raw_file.remove.cfg",
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(),
++            fail_if_file_not_found=False,
++            exception_msg=error,
++            name="raw_file.remove.key",
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            fail_if_file_not_found=True,
++            name="raw_file.remove.cfg",
+         )
+ 
+         commands.config_destroy(
+@@ -900,31 +858,27 @@ class ConfigDestroy(TestCase, FixtureMixin):
+     def test_cannot_delete_config_forced(self):
+         error = "an error"
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            )
+-            .raw_file.remove(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(),
+-                fail_if_file_not_found=False,
+-                name="raw_file.remove.key",
+-            )
+-            .raw_file.remove(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                fail_if_file_not_found=True,
+-                exception_msg=error,
+-                name="raw_file.remove.cfg",
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(),
++            fail_if_file_not_found=False,
++            name="raw_file.remove.key",
++        )
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            fail_if_file_not_found=True,
++            exception_msg=error,
++            name="raw_file.remove.cfg",
+         )
+ 
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_destroy(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: commands.config_destroy(self.env_assist.get_env()),
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -941,22 +895,19 @@ class ConfigDestroy(TestCase, FixtureMixin):
+     def test_keyfile_outside_of_booth_dir(self):
+         key_path = "/tmp/pcs_test/booth.key"
+         self.fixture_config_booth_not_used()
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=f"authfile = {key_path}".encode("utf-8"),
+-            ).raw_file.remove(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                fail_if_file_not_found=True,
+-                name="raw_file.remove.cfg",
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=f"authfile = {key_path}".encode("utf-8"),
+         )
+-
+-        commands.config_destroy(
+-            self.env_assist.get_env(),
++        self.config.raw_file.remove(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            fail_if_file_not_found=True,
++            name="raw_file.remove.cfg",
+         )
++
++        commands.config_destroy(self.env_assist.get_env())
+         self.env_assist.assert_reports(
+             [
+                 fixture.warn(
+@@ -987,29 +938,23 @@ class ConfigText(TestCase, FixtureMixin):
+ 
+     def test_success_default_instance(self):
+         config_content = "my config content".encode("utf-8")
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=config_content,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=config_content,
+         )
+         self.assertEqual(
+-            commands.config_text(
+-                self.env_assist.get_env(),
+-            ),
++            commands.config_text(self.env_assist.get_env()),
+             config_content,
+         )
+ 
+     def test_success_custom_instance(self):
+         instance_name = "my_booth"
+         config_content = "my config content".encode("utf-8")
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                content=config_content,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            content=config_content,
+         )
+         self.assertEqual(
+             commands.config_text(
+@@ -1029,9 +974,7 @@ class ConfigText(TestCase, FixtureMixin):
+             }
+         )
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_text(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: commands.config_text(self.env_assist.get_env()),
+             [
+                 fixture.error(
+                     reports.codes.LIVE_ENVIRONMENT_REQUIRED,
+@@ -1046,17 +989,13 @@ class ConfigText(TestCase, FixtureMixin):
+ 
+     def test_cannot_read_config(self):
+         error = "an error"
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                exception_msg=error,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            exception_msg=error,
+         )
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_text(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: commands.config_text(self.env_assist.get_env()),
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -1073,12 +1012,10 @@ class ConfigText(TestCase, FixtureMixin):
+     def test_remote_success(self):
+         instance_name = "my_booth"
+         config_content = "my config content"
+-        (
+-            self.config.http.booth.get_config(
+-                instance_name,
+-                config_data=config_content,
+-                node_labels=["node1"],
+-            )
++        self.config.http.booth.get_config(
++            instance_name,
++            config_data=config_content,
++            node_labels=["node1"],
+         )
+         self.assertEqual(
+             commands.config_text(
+@@ -1095,22 +1032,19 @@ class ConfigText(TestCase, FixtureMixin):
+         server_error = (
+             "some error like 'config does not exist' or 'instance name invalid'"
+         )
+-        (
+-            self.config.http.booth.get_config(
+-                instance_name,
+-                communication_list=[
+-                    dict(
+-                        label=node_name,
+-                        response_code=400,
+-                        output=server_error,
+-                    )
+-                ],
+-            )
++        self.config.http.booth.get_config(
++            instance_name,
++            communication_list=[
++                dict(
++                    label=node_name,
++                    response_code=400,
++                    output=server_error,
++                )
++            ],
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_text(
+-                self.env_assist.get_env(),
+-                node_name=node_name,
++                self.env_assist.get_env(), node_name=node_name
+             ),
+         )
+         self.env_assist.assert_reports(
+@@ -1127,21 +1061,18 @@ class ConfigText(TestCase, FixtureMixin):
+     def test_remote_bad_response(self):
+         instance_name = "booth"
+         node_name = "node1"
+-        (
+-            self.config.http.booth.get_config(
+-                instance_name,
+-                communication_list=[
+-                    dict(
+-                        label=node_name,
+-                        output="not a json",
+-                    )
+-                ],
+-            )
++        self.config.http.booth.get_config(
++            instance_name,
++            communication_list=[
++                dict(
++                    label=node_name,
++                    output="not a json",
++                )
++            ],
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_text(
+-                self.env_assist.get_env(),
+-                node_name=node_name,
++                self.env_assist.get_env(), node_name=node_name
+             ),
+         )
+         self.env_assist.assert_reports(
+@@ -1157,23 +1088,20 @@ class ConfigText(TestCase, FixtureMixin):
+         instance_name = "booth"
+         node_name = "node1"
+         error = "an error"
+-        (
+-            self.config.http.booth.get_config(
+-                instance_name,
+-                communication_list=[
+-                    dict(
+-                        label=node_name,
+-                        was_connected=False,
+-                        errno=1,
+-                        error_msg=error,
+-                    )
+-                ],
+-            )
++        self.config.http.booth.get_config(
++            instance_name,
++            communication_list=[
++                dict(
++                    label=node_name,
++                    was_connected=False,
++                    errno=1,
++                    error_msg=error,
++                )
++            ],
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_text(
+-                self.env_assist.get_env(),
+-                node_name=node_name,
++                self.env_assist.get_env(), node_name=node_name
+             ),
+         )
+         self.env_assist.assert_reports(
+@@ -1208,22 +1136,21 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+         )
+ 
+     def fixture_config_success(self, instance_name="booth"):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                content=self.fixture_cfg_content(
+-                    self.fixture_key_path(instance_name)
+-                ),
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                self.fixture_cfg_content(
+-                    self.fixture_key_path(instance_name),
+-                    ticket_list=[["ticketA", []]],
+-                ),
+-                can_overwrite=True,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            content=self.fixture_cfg_content(
++                self.fixture_key_path(instance_name)
++            ),
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            self.fixture_cfg_content(
++                self.fixture_key_path(instance_name),
++                ticket_list=[["ticketA", []]],
++            ),
++            can_overwrite=True,
+         )
+ 
+     def test_success_default_instance(self):
+@@ -1268,21 +1195,20 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+         )
+ 
+     def test_success_ticket_options(self):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(
+-                    ticket_list=[
+-                        ["ticketA", [("retries", "10"), ("timeout", "20")]]
+-                    ]
+-                ),
+-                can_overwrite=True,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(
++                ticket_list=[
++                    ["ticketA", [("retries", "10"), ("timeout", "20")]]
++                ]
++            ),
++            can_overwrite=True,
+         )
+         commands.config_ticket_add(
+             self.env_assist.get_env(),
+@@ -1291,12 +1217,10 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+         )
+ 
+     def test_ticket_already_exists(self):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(ticket_list=[["ticketA", []]]),
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(ticket_list=[["ticketA", []]]),
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_add(
+@@ -1316,12 +1240,10 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+         )
+ 
+     def test_validator_errors(self):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_add(
+@@ -1356,19 +1278,16 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+         )
+ 
+     def test_invalid_ticket_options_forced(self):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(
+-                    ticket_list=[["ticketA", [("a", "A")]]]
+-                ),
+-                can_overwrite=True,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(ticket_list=[["ticketA", [("a", "A")]]]),
++            can_overwrite=True,
+         )
+         commands.config_ticket_add(
+             self.env_assist.get_env(),
+@@ -1399,12 +1318,10 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+         )
+ 
+     def test_config_parse_error(self):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content="invalid config".encode("utf-8"),
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content="invalid config".encode("utf-8"),
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_add(
+@@ -1425,12 +1342,10 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+ 
+     def test_cannot_read_config(self):
+         error = "an error"
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                exception_msg=error,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            exception_msg=error,
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_add(
+@@ -1480,18 +1395,17 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+ 
+     def test_cannot_write_config(self):
+         error = "an error"
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(ticket_list=[["ticketA", []]]),
+-                can_overwrite=True,
+-                exception_msg=error,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(ticket_list=[["ticketA", []]]),
++            can_overwrite=True,
++            exception_msg=error,
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_add(
+@@ -1532,46 +1446,40 @@ class ConfigTicketRemove(TestCase, FixtureMixin):
+         )
+ 
+     def fixture_config_success(self, instance_name="booth"):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                self.fixture_cfg_content(
+-                    self.fixture_key_path(instance_name),
+-                    ticket_list=[
+-                        ["ticketA", []],
+-                        ["ticketB", []],
+-                        ["ticketC", []],
+-                    ],
+-                ),
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                self.fixture_cfg_content(
+-                    self.fixture_key_path(instance_name),
+-                    ticket_list=[
+-                        ["ticketA", []],
+-                        ["ticketC", []],
+-                    ],
+-                ),
+-                can_overwrite=True,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            self.fixture_cfg_content(
++                self.fixture_key_path(instance_name),
++                ticket_list=[
++                    ["ticketA", []],
++                    ["ticketB", []],
++                    ["ticketC", []],
++                ],
++            ),
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            self.fixture_cfg_content(
++                self.fixture_key_path(instance_name),
++                ticket_list=[
++                    ["ticketA", []],
++                    ["ticketC", []],
++                ],
++            ),
++            can_overwrite=True,
+         )
+ 
+     def test_success_default_instance(self):
+         self.fixture_config_success()
+-        commands.config_ticket_remove(
+-            self.env_assist.get_env(),
+-            "ticketB",
+-        )
++        commands.config_ticket_remove(self.env_assist.get_env(), "ticketB")
+ 
+     def test_success_custom_instance(self):
+         instance_name = "my_booth"
+         self.fixture_config_success(instance_name=instance_name)
+         commands.config_ticket_remove(
+-            self.env_assist.get_env(),
+-            "ticketB",
+-            instance_name=instance_name,
++            self.env_assist.get_env(), "ticketB", instance_name=instance_name
+         )
+ 
+     def test_success_not_live(self):
+@@ -1602,51 +1510,44 @@ class ConfigTicketRemove(TestCase, FixtureMixin):
+         )
+ 
+     def test_success_ticket_options(self):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(
+-                    ticket_list=[
+-                        ["ticketA", [("a1", "A1"), ("a2", "A2")]],
+-                        ["ticketB", [("b1", "B1"), ("b2", "B2")]],
+-                        ["ticketC", [("c1", "C1"), ("c2", "C2")]],
+-                    ]
+-                ),
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(
+-                    ticket_list=[
+-                        ["ticketA", [("a1", "A1"), ("a2", "A2")]],
+-                        ["ticketC", [("c1", "C1"), ("c2", "C2")]],
+-                    ]
+-                ),
+-                can_overwrite=True,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(
++                ticket_list=[
++                    ["ticketA", [("a1", "A1"), ("a2", "A2")]],
++                    ["ticketB", [("b1", "B1"), ("b2", "B2")]],
++                    ["ticketC", [("c1", "C1"), ("c2", "C2")]],
++                ]
++            ),
+         )
+-        commands.config_ticket_remove(
+-            self.env_assist.get_env(),
+-            "ticketB",
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(
++                ticket_list=[
++                    ["ticketA", [("a1", "A1"), ("a2", "A2")]],
++                    ["ticketC", [("c1", "C1"), ("c2", "C2")]],
++                ]
++            ),
++            can_overwrite=True,
+         )
++        commands.config_ticket_remove(self.env_assist.get_env(), "ticketB")
+ 
+     def test_ticket_does_not_exist(self):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(
+-                    ticket_list=[
+-                        ["ticketA", []],
+-                        ["ticketC", []],
+-                    ]
+-                ),
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(
++                ticket_list=[
++                    ["ticketA", []],
++                    ["ticketC", []],
++                ]
++            ),
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_remove(
+-                self.env_assist.get_env(),
+-                "ticketB",
++                self.env_assist.get_env(), "ticketB"
+             )
+         )
+         self.env_assist.assert_reports(
+@@ -1659,17 +1560,14 @@ class ConfigTicketRemove(TestCase, FixtureMixin):
+         )
+ 
+     def test_config_parse_error(self):
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content="invalid config".encode("utf-8"),
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content="invalid config".encode("utf-8"),
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_remove(
+-                self.env_assist.get_env(),
+-                "ticketB",
++                self.env_assist.get_env(), "ticketB"
+             )
+         )
+         self.env_assist.assert_reports(
+@@ -1684,17 +1582,14 @@ class ConfigTicketRemove(TestCase, FixtureMixin):
+ 
+     def test_cannot_read_config(self):
+         error = "an error"
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                exception_msg=error,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            exception_msg=error,
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_remove(
+-                self.env_assist.get_env(),
+-                "ticketB",
++                self.env_assist.get_env(), "ticketB"
+             )
+         )
+         self.env_assist.assert_reports(
+@@ -1719,8 +1614,7 @@ class ConfigTicketRemove(TestCase, FixtureMixin):
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_remove(
+-                self.env_assist.get_env(),
+-                "ticketB",
++                self.env_assist.get_env(), "ticketB"
+             )
+         )
+         self.env_assist.assert_reports(
+@@ -1737,27 +1631,25 @@ class ConfigTicketRemove(TestCase, FixtureMixin):
+ 
+     def test_cannot_write_config(self):
+         error = "an error"
+-        (
+-            self.config.raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(
+-                    ticket_list=[
+-                        ["ticketB", []],
+-                    ]
+-                ),
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                self.fixture_cfg_content(),
+-                can_overwrite=True,
+-                exception_msg=error,
+-            )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(
++                ticket_list=[
++                    ["ticketB", []],
++                ]
++            ),
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            self.fixture_cfg_content(),
++            can_overwrite=True,
++            exception_msg=error,
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_ticket_remove(
+-                self.env_assist.get_env(),
+-                "ticketB",
++                self.env_assist.get_env(), "ticketB"
+             )
+         )
+         self.env_assist.assert_reports(
+@@ -1792,40 +1684,35 @@ class CreateInCluster(TestCase, FixtureMixin):
+         )
+ 
+     def fixture_config_success(self, instance_name="booth"):
+-        (
+-            self.config.runner.cib.load()
+-            .raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                content=self.fixture_cfg_content(
+-                    self.fixture_key_path(instance_name)
+-                ),
+-            )
+-            .runner.pcmk.load_agent(
+-                agent_name="ocf:heartbeat:IPaddr2",
+-                name="runner.pcmk.load_agent.ipaddr2",
+-            )
+-            .runner.pcmk.load_agent(
+-                agent_name="ocf:pacemaker:booth-site",
+-                name="runner.pcmk.load_agent.booth-site",
+-            )
+-            .env.push_cib(resources=self.fixture_cib_booth_group(instance_name))
++        self.config.runner.cib.load()
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            content=self.fixture_cfg_content(
++                self.fixture_key_path(instance_name)
++            ),
++        )
++        self.config.runner.pcmk.load_agent(
++            agent_name="ocf:heartbeat:IPaddr2",
++            name="runner.pcmk.load_agent.ipaddr2",
++        )
++        self.config.runner.pcmk.load_agent(
++            agent_name="ocf:pacemaker:booth-site",
++            name="runner.pcmk.load_agent.booth-site",
++        )
++        self.config.env.push_cib(
++            resources=self.fixture_cib_booth_group(instance_name)
+         )
+ 
+     def test_success_default_instance(self):
+         self.fixture_config_success()
+-        commands.create_in_cluster(
+-            self.env_assist.get_env(),
+-            self.site_ip,
+-        )
++        commands.create_in_cluster(self.env_assist.get_env(), self.site_ip)
+ 
+     def test_success_custom_instance(self):
+         instance_name = "my_booth"
+         self.fixture_config_success(instance_name=instance_name)
+         commands.create_in_cluster(
+-            self.env_assist.get_env(),
+-            self.site_ip,
+-            instance_name=instance_name,
++            self.env_assist.get_env(), self.site_ip, instance_name=instance_name
+         )
+ 
+     def test_success_not_live_cib(self):
+@@ -1833,29 +1720,24 @@ class CreateInCluster(TestCase, FixtureMixin):
+         env = dict(CIB_file=tmp_file)
+         with open(rc("cib-empty.xml")) as cib_file:
+             self.config.env.set_cib_data(cib_file.read(), cib_tempfile=tmp_file)
+-        (
+-            self.config.runner.cib.load(env=env)
+-            .raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            )
+-            .runner.pcmk.load_agent(
+-                agent_name="ocf:heartbeat:IPaddr2",
+-                name="runner.pcmk.load_agent.ipaddr2",
+-                env=env,
+-            )
+-            .runner.pcmk.load_agent(
+-                agent_name="ocf:pacemaker:booth-site",
+-                name="runner.pcmk.load_agent.booth-site",
+-                env=env,
+-            )
+-            .env.push_cib(resources=self.fixture_cib_booth_group())
++        self.config.runner.cib.load(env=env)
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
+         )
+-        commands.create_in_cluster(
+-            self.env_assist.get_env(),
+-            self.site_ip,
++        self.config.runner.pcmk.load_agent(
++            agent_name="ocf:heartbeat:IPaddr2",
++            name="runner.pcmk.load_agent.ipaddr2",
++            env=env,
+         )
++        self.config.runner.pcmk.load_agent(
++            agent_name="ocf:pacemaker:booth-site",
++            name="runner.pcmk.load_agent.booth-site",
++            env=env,
++        )
++        self.config.env.push_cib(resources=self.fixture_cib_booth_group())
++        commands.create_in_cluster(self.env_assist.get_env(), self.site_ip)
+ 
+     def test_not_live_booth(self):
+         self.config.env.set_booth(
+@@ -1867,8 +1749,7 @@ class CreateInCluster(TestCase, FixtureMixin):
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.create_in_cluster(
+-                self.env_assist.get_env(),
+-                self.site_ip,
++                self.env_assist.get_env(), self.site_ip
+             ),
+             [
+                 fixture.error(
+@@ -1883,19 +1764,15 @@ class CreateInCluster(TestCase, FixtureMixin):
+         )
+ 
+     def test_booth_resource_already_created(self):
+-        (
+-            self.config.runner.cib.load(
+-                resources=self.fixture_cib_booth_group()
+-            ).raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            )
++        self.config.runner.cib.load(resources=self.fixture_cib_booth_group())
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.create_in_cluster(
+-                self.env_assist.get_env(),
+-                self.site_ip,
++                self.env_assist.get_env(), self.site_ip
+             )
+         )
+         self.env_assist.assert_reports(
+@@ -1904,17 +1781,14 @@ class CreateInCluster(TestCase, FixtureMixin):
+ 
+     def test_booth_config_does_not_exist(self):
+         error = "an error"
+-        (
+-            self.config.runner.cib.load().raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                exception_msg=error,
+-            )
++        self.config.runner.cib.load().raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            exception_msg=error,
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.create_in_cluster(
+-                self.env_assist.get_env(),
+-                self.site_ip,
++                self.env_assist.get_env(), self.site_ip
+             )
+         )
+         self.env_assist.assert_reports(
+@@ -1959,28 +1833,25 @@ class CreateInCluster(TestCase, FixtureMixin):
+         )
+ 
+     def test_booth_agent_missing(self):
+-        (
+-            self.config.runner.cib.load()
+-            .raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            )
+-            .runner.pcmk.load_agent(
+-                agent_name="ocf:heartbeat:IPaddr2",
+-                name="runner.pcmk.load_agent.ipaddr2",
+-            )
+-            .runner.pcmk.load_agent(
+-                agent_name="ocf:pacemaker:booth-site",
+-                agent_is_missing=True,
+-                name="runner.pcmk.load_agent.booth-site",
+-                stderr=REASON,
+-            )
++        self.config.runner.cib.load()
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
++        )
++        self.config.runner.pcmk.load_agent(
++            agent_name="ocf:heartbeat:IPaddr2",
++            name="runner.pcmk.load_agent.ipaddr2",
++        )
++        self.config.runner.pcmk.load_agent(
++            agent_name="ocf:pacemaker:booth-site",
++            agent_is_missing=True,
++            name="runner.pcmk.load_agent.booth-site",
++            stderr=REASON,
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.create_in_cluster(
+-                self.env_assist.get_env(),
+-                self.site_ip,
++                self.env_assist.get_env(), self.site_ip
+             )
+         )
+         self.env_assist.assert_reports(
+@@ -1993,30 +1864,28 @@ class CreateInCluster(TestCase, FixtureMixin):
+                 ),
+             ]
+         )
+-
+-    def test_agents_missing_forced(self):
+-        (
+-            self.config.runner.cib.load()
+-            .raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-            )
+-            .runner.pcmk.load_agent(
+-                agent_name="ocf:heartbeat:IPaddr2",
+-                agent_is_missing=True,
+-                name="runner.pcmk.load_agent.ipaddr2",
+-                stderr=REASON,
+-            )
+-            .runner.pcmk.load_agent(
+-                agent_name="ocf:pacemaker:booth-site",
+-                agent_is_missing=True,
+-                name="runner.pcmk.load_agent.booth-site",
+-                stderr=REASON,
+-            )
+-            .env.push_cib(
+-                resources=self.fixture_cib_booth_group(default_operations=True)
+-            )
++
++    def test_agents_missing_forced(self):
++        self.config.runner.cib.load()
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
++        )
++        self.config.runner.pcmk.load_agent(
++            agent_name="ocf:heartbeat:IPaddr2",
++            agent_is_missing=True,
++            name="runner.pcmk.load_agent.ipaddr2",
++            stderr=REASON,
++        )
++        self.config.runner.pcmk.load_agent(
++            agent_name="ocf:pacemaker:booth-site",
++            agent_is_missing=True,
++            name="runner.pcmk.load_agent.booth-site",
++            stderr=REASON,
++        )
++        self.config.env.push_cib(
++            resources=self.fixture_cib_booth_group(default_operations=True)
+         )
+         commands.create_in_cluster(
+             self.env_assist.get_env(),
+@@ -2061,10 +1930,9 @@ class RemoveFromCluster(TestCase, FixtureMixin):
+         self.resource_remove.assert_not_called()
+ 
+     def test_success_default_instance(self):
+-        (self.config.runner.cib.load(resources=self.fixture_cib_booth_group()))
++        self.config.runner.cib.load(resources=self.fixture_cib_booth_group())
+         commands.remove_from_cluster(
+-            self.env_assist.get_env(),
+-            self.resource_remove,
++            self.env_assist.get_env(), self.resource_remove
+         )
+         self.resource_remove.assert_has_calls(
+             [
+@@ -2075,10 +1943,8 @@ class RemoveFromCluster(TestCase, FixtureMixin):
+ 
+     def test_success_custom_instance(self):
+         instance_name = "my_booth"
+-        (
+-            self.config.runner.cib.load(
+-                resources=self.fixture_cib_booth_group(instance_name)
+-            )
++        self.config.runner.cib.load(
++            resources=self.fixture_cib_booth_group(instance_name)
+         )
+         commands.remove_from_cluster(
+             self.env_assist.get_env(),
+@@ -2099,16 +1965,12 @@ class RemoveFromCluster(TestCase, FixtureMixin):
+         cib_xml_man.append_to_first_tag_name(
+             "resources", self.fixture_cib_booth_group(wrap_in_resources=False)
+         )
+-        (
+-            self.config
+-            # This makes env.is_cib_live return False
+-            .env.set_cib_data(str(cib_xml_man), cib_tempfile=tmp_file)
+-            # This instructs the runner to actually return our mocked cib
+-            .runner.cib.load_content(str(cib_xml_man), env=env)
+-        )
++        # This makes env.is_cib_live return False
++        self.config.env.set_cib_data(str(cib_xml_man), cib_tempfile=tmp_file)
++        # This instructs the runner to actually return our mocked cib
++        self.config.runner.cib.load_content(str(cib_xml_man), env=env)
+         commands.remove_from_cluster(
+-            self.env_assist.get_env(),
+-            self.resource_remove,
++            self.env_assist.get_env(), self.resource_remove
+         )
+         self.resource_remove.assert_has_calls(
+             [
+@@ -2127,8 +1989,7 @@ class RemoveFromCluster(TestCase, FixtureMixin):
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.remove_from_cluster(
+-                self.env_assist.get_env(),
+-                self.resource_remove,
++                self.env_assist.get_env(), self.resource_remove
+             ),
+             [
+                 fixture.error(
+@@ -2147,8 +2008,7 @@ class RemoveFromCluster(TestCase, FixtureMixin):
+         (self.config.runner.cib.load())
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.remove_from_cluster(
+-                self.env_assist.get_env(),
+-                self.resource_remove,
++                self.env_assist.get_env(), self.resource_remove
+             ),
+         )
+         self.env_assist.assert_reports(
+@@ -2162,15 +2022,10 @@ class RemoveFromCluster(TestCase, FixtureMixin):
+         self.resource_remove.assert_not_called()
+ 
+     def test_more_booth_resources(self):
+-        (
+-            self.config.runner.cib.load(
+-                resources=self.fixture_cib_more_resources()
+-            )
+-        )
++        self.config.runner.cib.load(resources=self.fixture_cib_more_resources())
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.remove_from_cluster(
+-                self.env_assist.get_env(),
+-                self.resource_remove,
++                self.env_assist.get_env(), self.resource_remove
+             ),
+         )
+         self.env_assist.assert_reports(
+@@ -2185,11 +2040,7 @@ class RemoveFromCluster(TestCase, FixtureMixin):
+         self.resource_remove.assert_not_called()
+ 
+     def test_more_booth_resources_forced(self):
+-        (
+-            self.config.runner.cib.load(
+-                resources=self.fixture_cib_more_resources()
+-            )
+-        )
++        self.config.runner.cib.load(resources=self.fixture_cib_more_resources())
+         commands.remove_from_cluster(
+             self.env_assist.get_env(),
+             self.resource_remove,
+@@ -2234,11 +2085,8 @@ class Restart(TestCase, FixtureMixin):
+         self.resource_restart.assert_not_called()
+ 
+     def test_success_default_instance(self):
+-        (self.config.runner.cib.load(resources=self.fixture_cib_booth_group()))
+-        commands.restart(
+-            self.env_assist.get_env(),
+-            self.resource_restart,
+-        )
++        self.config.runner.cib.load(resources=self.fixture_cib_booth_group())
++        commands.restart(self.env_assist.get_env(), self.resource_restart)
+         self.resource_restart.assert_has_calls(
+             [
+                 mock.call(["booth-booth-service"]),
+@@ -2247,10 +2095,8 @@ class Restart(TestCase, FixtureMixin):
+ 
+     def test_success_custom_instance(self):
+         instance_name = "my_booth"
+-        (
+-            self.config.runner.cib.load(
+-                resources=self.fixture_cib_booth_group(instance_name)
+-            )
++        self.config.runner.cib.load(
++            resources=self.fixture_cib_booth_group(instance_name)
+         )
+         commands.restart(
+             self.env_assist.get_env(),
+@@ -2274,8 +2120,7 @@ class Restart(TestCase, FixtureMixin):
+         self.config.env.set_cib_data("<cib />")
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.restart(
+-                self.env_assist.get_env(),
+-                self.resource_restart,
++                self.env_assist.get_env(), self.resource_restart
+             ),
+             [
+                 fixture.error(
+@@ -2295,8 +2140,7 @@ class Restart(TestCase, FixtureMixin):
+         (self.config.runner.cib.load())
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.restart(
+-                self.env_assist.get_env(),
+-                self.resource_restart,
++                self.env_assist.get_env(), self.resource_restart
+             ),
+         )
+         self.env_assist.assert_reports(
+@@ -2310,15 +2154,10 @@ class Restart(TestCase, FixtureMixin):
+         self.resource_restart.assert_not_called()
+ 
+     def test_more_booth_resources(self):
+-        (
+-            self.config.runner.cib.load(
+-                resources=self.fixture_cib_more_resources()
+-            )
+-        )
++        self.config.runner.cib.load(resources=self.fixture_cib_more_resources())
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.restart(
+-                self.env_assist.get_env(),
+-                self.resource_restart,
++                self.env_assist.get_env(), self.resource_restart
+             ),
+         )
+         self.env_assist.assert_reports(
+@@ -2333,11 +2172,7 @@ class Restart(TestCase, FixtureMixin):
+         self.resource_restart.assert_not_called()
+ 
+     def test_more_booth_resources_forced(self):
+-        (
+-            self.config.runner.cib.load(
+-                resources=self.fixture_cib_more_resources()
+-            )
+-        )
++        self.config.runner.cib.load(resources=self.fixture_cib_more_resources())
+         commands.restart(
+             self.env_assist.get_env(),
+             self.resource_restart,
+@@ -2390,10 +2225,7 @@ class TicketGrantRevokeMixin(FixtureMixin):
+         )
+         self.config.env.set_cib_data("<cib/>")
+         self.env_assist.assert_raise_library_error(
+-            lambda: self.command(
+-                self.env_assist.get_env(),
+-                self.ticket,
+-            ),
++            lambda: self.command(self.env_assist.get_env(), self.ticket),
+             [
+                 fixture.error(
+                     reports.codes.LIVE_ENVIRONMENT_REQUIRED,
+@@ -2410,26 +2242,18 @@ class TicketGrantRevokeMixin(FixtureMixin):
+     def test_success_site_ip_specified(self):
+         self.get_booth_call()(self.ticket, self.site_ip)
+         self.command(
+-            self.env_assist.get_env(),
+-            self.ticket,
+-            site_ip=self.site_ip,
++            self.env_assist.get_env(), self.ticket, site_ip=self.site_ip
+         )
+ 
+     def test_success_site_ip_not_specified(self):
+         self.config.runner.cib.load(resources=self.fixture_cib_booth_group())
+         self.get_booth_call()(self.ticket, self.site_ip)
+-        self.command(
+-            self.env_assist.get_env(),
+-            self.ticket,
+-        )
++        self.command(self.env_assist.get_env(), self.ticket)
+ 
+     def test_cannot_find_site_ip(self):
+         self.config.runner.cib.load()
+         self.env_assist.assert_raise_library_error(
+-            lambda: self.command(
+-                self.env_assist.get_env(),
+-                self.ticket,
+-            ),
++            lambda: self.command(self.env_assist.get_env(), self.ticket),
+             [
+                 fixture.error(
+                     reports.codes.BOOTH_CANNOT_DETERMINE_LOCAL_SITE_IP,
+@@ -2448,9 +2272,7 @@ class TicketGrantRevokeMixin(FixtureMixin):
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: self.command(
+-                self.env_assist.get_env(),
+-                self.ticket,
+-                site_ip=self.site_ip,
++                self.env_assist.get_env(), self.ticket, site_ip=self.site_ip
+             ),
+             [
+                 fixture.error(
+@@ -2496,34 +2318,30 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+             self.fixture_key_path(instance_name)
+         )
+         self.fixture_config_read_success(instance_name=instance_name)
+-        (
+-            self.config.http.booth.send_config(
+-                instance_name,
+-                config_content.decode("utf-8"),
+-                authfile=os.path.basename(self.fixture_key_path(instance_name)),
+-                authfile_data=RANDOM_KEY,
+-                node_labels=self.node_list,
+-            )
++        self.config.http.booth.send_config(
++            instance_name,
++            config_content.decode("utf-8"),
++            authfile=os.path.basename(self.fixture_key_path(instance_name)),
++            authfile_data=RANDOM_KEY,
++            node_labels=self.node_list,
+         )
+ 
+     def fixture_config_read_success(self, instance_name="booth"):
+         config_content = self.fixture_cfg_content(
+             self.fixture_key_path(instance_name)
+         )
+-        (
+-            self.config.corosync_conf.load()
+-            .raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(instance_name),
+-                content=config_content,
+-                name="raw_file.read.conf",
+-            )
+-            .raw_file.read(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(instance_name),
+-                content=RANDOM_KEY,
+-                name="raw_file.read.key",
+-            )
++        self.config.corosync_conf.load()
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(instance_name),
++            content=config_content,
++            name="raw_file.read.conf",
++        )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(instance_name),
++            content=RANDOM_KEY,
++            name="raw_file.read.key",
+         )
+ 
+     def fixture_reports_success(self, instance_name="booth"):
+@@ -2552,30 +2370,23 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+ 
+     def test_success_default_instance(self):
+         self.fixture_config_success()
+-        commands.config_sync(
+-            self.env_assist.get_env(),
+-        )
++        commands.config_sync(self.env_assist.get_env())
+         self.env_assist.assert_reports(self.fixture_reports_success())
+ 
+     def test_success_custom_instance(self):
+         instance_name = "my_booth"
+         self.fixture_config_success(instance_name=instance_name)
+         commands.config_sync(
+-            self.env_assist.get_env(),
+-            instance_name=instance_name,
++            self.env_assist.get_env(), instance_name=instance_name
+         )
+         self.env_assist.assert_reports(
+-            self.fixture_reports_success(
+-                instance_name=instance_name,
+-            )
++            self.fixture_reports_success(instance_name=instance_name)
+         )
+ 
+     def test_not_live_cib(self):
+         self.config.env.set_cib_data("<cib/>")
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_sync(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: commands.config_sync(self.env_assist.get_env()),
+             [
+                 fixture.error(
+                     reports.codes.LIVE_ENVIRONMENT_REQUIRED,
+@@ -2596,56 +2407,45 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+                 "key_path": "some key path",
+             }
+         )
+-        (
+-            self.config.corosync_conf.load(
+-                node_name_list=self.node_list
+-            ).http.booth.send_config(
+-                instance_name,
+-                config_data.decode("utf-8"),
+-                authfile=os.path.basename(key_path),
+-                authfile_data=key_data,
+-                node_labels=self.node_list,
+-            )
++        self.config.corosync_conf.load(node_name_list=self.node_list)
++        self.config.http.booth.send_config(
++            instance_name,
++            config_data.decode("utf-8"),
++            authfile=os.path.basename(key_path),
++            authfile_data=key_data,
++            node_labels=self.node_list,
+         )
+ 
+     def test_not_live_booth_default_instance(self):
+         self.fixture_config_success_not_live()
+-        commands.config_sync(
+-            self.env_assist.get_env(),
+-        )
++        commands.config_sync(self.env_assist.get_env())
+         self.env_assist.assert_reports(self.fixture_reports_success())
+ 
+     def test_not_live_booth_custom_instance(self):
+         instance_name = "my_booth"
+         self.fixture_config_success_not_live(instance_name=instance_name)
+         commands.config_sync(
+-            self.env_assist.get_env(),
+-            instance_name=instance_name,
++            self.env_assist.get_env(), instance_name=instance_name
+         )
+         self.env_assist.assert_reports(
+-            self.fixture_reports_success(
+-                instance_name=instance_name,
+-            )
++            self.fixture_reports_success(instance_name=instance_name)
+         )
+ 
+     def test_some_node_names_missing(self):
+         nodes = ["rh7-2"]
+         self.fixture_config_read_success()
+-        (
+-            self.config.corosync_conf.load(
+-                filename="corosync-some-node-names.conf",
+-                instead="corosync_conf.load",
+-            ).http.booth.send_config(
+-                "booth",
+-                self.fixture_cfg_content().decode("utf-8"),
+-                authfile=os.path.basename(self.fixture_key_path()),
+-                authfile_data=RANDOM_KEY,
+-                node_labels=nodes,
+-            )
++        self.config.corosync_conf.load(
++            filename="corosync-some-node-names.conf",
++            instead="corosync_conf.load",
+         )
+-        commands.config_sync(
+-            self.env_assist.get_env(),
++        self.config.http.booth.send_config(
++            "booth",
++            self.fixture_cfg_content().decode("utf-8"),
++            authfile=os.path.basename(self.fixture_key_path()),
++            authfile_data=RANDOM_KEY,
++            node_labels=nodes,
+         )
++        commands.config_sync(self.env_assist.get_env())
+         self.env_assist.assert_reports(
+             [
+                 fixture.info(reports.codes.BOOTH_CONFIG_DISTRIBUTION_STARTED),
+@@ -2666,11 +2466,9 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+ 
+     def test_all_node_names_missing(self):
+         self.fixture_config_read_success()
+-        (
+-            self.config.corosync_conf.load(
+-                filename="corosync-no-node-names.conf",
+-                instead="corosync_conf.load",
+-            )
++        self.config.corosync_conf.load(
++            filename="corosync-no-node-names.conf",
++            instead="corosync_conf.load",
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_sync(self.env_assist.get_env())
+@@ -2687,23 +2485,21 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+ 
+     def test_node_failure(self):
+         self.fixture_config_read_success()
+-        (
+-            self.config.http.booth.send_config(
+-                "booth",
+-                self.fixture_cfg_content().decode("utf-8"),
+-                authfile=os.path.basename(self.fixture_key_path()),
+-                authfile_data=RANDOM_KEY,
+-                communication_list=[
+-                    dict(
+-                        label=self.node_list[0],
+-                        response_code=400,
+-                        output=self.reason,
+-                    ),
+-                    dict(
+-                        label=self.node_list[1],
+-                    ),
+-                ],
+-            )
++        self.config.http.booth.send_config(
++            "booth",
++            self.fixture_cfg_content().decode("utf-8"),
++            authfile=os.path.basename(self.fixture_key_path()),
++            authfile_data=RANDOM_KEY,
++            communication_list=[
++                dict(
++                    label=self.node_list[0],
++                    response_code=400,
++                    output=self.reason,
++                ),
++                dict(
++                    label=self.node_list[1],
++                ),
++            ],
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.config_sync(self.env_assist.get_env()), []
+@@ -2728,23 +2524,21 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+ 
+     def test_node_failure_skip_offline(self):
+         self.fixture_config_read_success()
+-        (
+-            self.config.http.booth.send_config(
+-                "booth",
+-                self.fixture_cfg_content().decode("utf-8"),
+-                authfile=os.path.basename(self.fixture_key_path()),
+-                authfile_data=RANDOM_KEY,
+-                communication_list=[
+-                    dict(
+-                        label=self.node_list[0],
+-                        response_code=400,
+-                        output=self.reason,
+-                    ),
+-                    dict(
+-                        label=self.node_list[1],
+-                    ),
+-                ],
+-            )
++        self.config.http.booth.send_config(
++            "booth",
++            self.fixture_cfg_content().decode("utf-8"),
++            authfile=os.path.basename(self.fixture_key_path()),
++            authfile_data=RANDOM_KEY,
++            communication_list=[
++                dict(
++                    label=self.node_list[0],
++                    response_code=400,
++                    output=self.reason,
++                ),
++                dict(
++                    label=self.node_list[1],
++                ),
++            ],
+         )
+ 
+         commands.config_sync(self.env_assist.get_env(), skip_offline_nodes=True)
+@@ -2767,24 +2561,22 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+ 
+     def test_node_offline(self):
+         self.fixture_config_read_success()
+-        (
+-            self.config.http.booth.send_config(
+-                "booth",
+-                self.fixture_cfg_content().decode("utf-8"),
+-                authfile=os.path.basename(self.fixture_key_path()),
+-                authfile_data=RANDOM_KEY,
+-                communication_list=[
+-                    dict(
+-                        label=self.node_list[0],
+-                        errno=1,
+-                        error_msg=self.reason,
+-                        was_connected=False,
+-                    ),
+-                    dict(
+-                        label=self.node_list[1],
+-                    ),
+-                ],
+-            )
++        self.config.http.booth.send_config(
++            "booth",
++            self.fixture_cfg_content().decode("utf-8"),
++            authfile=os.path.basename(self.fixture_key_path()),
++            authfile_data=RANDOM_KEY,
++            communication_list=[
++                dict(
++                    label=self.node_list[0],
++                    errno=1,
++                    error_msg=self.reason,
++                    was_connected=False,
++                ),
++                dict(
++                    label=self.node_list[1],
++                ),
++            ],
+         )
+ 
+         self.env_assist.assert_raise_library_error(
+@@ -2810,24 +2602,22 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+ 
+     def test_node_offline_skip_offline(self):
+         self.fixture_config_read_success()
+-        (
+-            self.config.http.booth.send_config(
+-                "booth",
+-                self.fixture_cfg_content().decode("utf-8"),
+-                authfile=os.path.basename(self.fixture_key_path()),
+-                authfile_data=RANDOM_KEY,
+-                communication_list=[
+-                    dict(
+-                        label=self.node_list[0],
+-                        errno=1,
+-                        error_msg=self.reason,
+-                        was_connected=False,
+-                    ),
+-                    dict(
+-                        label=self.node_list[1],
+-                    ),
+-                ],
+-            )
++        self.config.http.booth.send_config(
++            "booth",
++            self.fixture_cfg_content().decode("utf-8"),
++            authfile=os.path.basename(self.fixture_key_path()),
++            authfile_data=RANDOM_KEY,
++            communication_list=[
++                dict(
++                    label=self.node_list[0],
++                    errno=1,
++                    error_msg=self.reason,
++                    was_connected=False,
++                ),
++                dict(
++                    label=self.node_list[1],
++                ),
++            ],
+         )
+ 
+         commands.config_sync(self.env_assist.get_env(), skip_offline_nodes=True)
+@@ -2849,15 +2639,13 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+         )
+ 
+     def test_config_not_accessible(self):
+-        (
+-            self.config.corosync_conf.load().raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                exception_msg=self.reason,
+-            )
++        self.config.corosync_conf.load().raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            exception_msg=self.reason,
+         )
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_sync(self.env_assist.get_env()),
++            lambda: commands.config_sync(self.env_assist.get_env())
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -2881,7 +2669,7 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+         )
+         (self.config.corosync_conf.load())
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_sync(self.env_assist.get_env()),
++            lambda: commands.config_sync(self.env_assist.get_env())
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -2896,15 +2684,13 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+         )
+ 
+     def test_config_parse_error(self):
+-        (
+-            self.config.corosync_conf.load().raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content="invalid config".encode("utf-8"),
+-            )
++        self.config.corosync_conf.load().raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content="invalid config".encode("utf-8"),
+         )
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_sync(self.env_assist.get_env()),
++            lambda: commands.config_sync(self.env_assist.get_env())
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -2924,9 +2710,9 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+                 "key_path": "some key path",
+             }
+         )
+-        (self.config.corosync_conf.load())
++        self.config.corosync_conf.load()
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_sync(self.env_assist.get_env()),
++            lambda: commands.config_sync(self.env_assist.get_env())
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -2939,23 +2725,21 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+         )
+ 
+     def test_authfile_not_accessible(self):
+-        (
+-            self.config.corosync_conf.load()
+-            .raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=self.fixture_cfg_content(),
+-                name="raw_file.read.conf",
+-            )
+-            .raw_file.read(
+-                file_type_codes.BOOTH_KEY,
+-                self.fixture_key_path(),
+-                exception_msg=self.reason,
+-                name="raw_file.read.key",
+-            )
++        self.config.corosync_conf.load()
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=self.fixture_cfg_content(),
++            name="raw_file.read.conf",
++        )
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_KEY,
++            self.fixture_key_path(),
++            exception_msg=self.reason,
++            name="raw_file.read.key",
+         )
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_sync(self.env_assist.get_env()),
++            lambda: commands.config_sync(self.env_assist.get_env())
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -2977,9 +2761,9 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+                 "key_path": "some key path",
+             }
+         )
+-        (self.config.corosync_conf.load())
++        self.config.corosync_conf.load()
+         self.env_assist.assert_raise_library_error(
+-            lambda: commands.config_sync(self.env_assist.get_env()),
++            lambda: commands.config_sync(self.env_assist.get_env())
+         )
+         self.env_assist.assert_reports(
+             [
+@@ -2994,22 +2778,22 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+         )
+ 
+     def test_no_authfile(self):
+-        (
+-            self.config.corosync_conf.load()
+-            .raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=bytes(),
+-            )
+-            .http.booth.send_config(
+-                "booth",
+-                bytes().decode("utf-8"),
+-                node_labels=self.node_list,
+-            )
++        self.config.corosync_conf.load()
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=bytes(),
++        )
++        self.config.http.booth.send_config(
++            "booth",
++            bytes().decode("utf-8"),
++            node_labels=self.node_list,
+         )
+         commands.config_sync(self.env_assist.get_env())
+         self.env_assist.assert_reports(
+-            [fixture.info(reports.codes.BOOTH_CONFIG_DISTRIBUTION_STARTED)]
++            [
++                fixture.info(reports.codes.BOOTH_CONFIG_DISTRIBUTION_STARTED),
++            ]
+             + [
+                 fixture.info(
+                     reports.codes.BOOTH_CONFIG_ACCEPTED_BY_NODE,
+@@ -3022,18 +2806,14 @@ class ConfigSyncTest(TestCase, FixtureMixin):
+ 
+     def test_authfile_not_in_booth_dir(self):
+         config_content = "authfile=/etc/my_booth.key"
+-        (
+-            self.config.corosync_conf.load()
+-            .raw_file.read(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.fixture_cfg_path(),
+-                content=config_content.encode("utf-8"),
+-            )
+-            .http.booth.send_config(
+-                "booth",
+-                config_content,
+-                node_labels=self.node_list,
+-            )
++        self.config.corosync_conf.load()
++        self.config.raw_file.read(
++            file_type_codes.BOOTH_CONFIG,
++            self.fixture_cfg_path(),
++            content=config_content.encode("utf-8"),
++        )
++        self.config.http.booth.send_config(
++            "booth", config_content, node_labels=self.node_list
+         )
+         commands.config_sync(self.env_assist.get_env())
+         self.env_assist.assert_reports(
+@@ -3096,9 +2876,7 @@ class EnableDisableStartStopMixin(FixtureMixin):
+         )
+         self.config.env.set_cib_data("<cib/>")
+         self.env_assist.assert_raise_library_error(
+-            lambda: self.command(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: self.command(self.env_assist.get_env()),
+             [
+                 fixture.error(
+                     reports.codes.LIVE_ENVIRONMENT_REQUIRED,
+@@ -3114,9 +2892,7 @@ class EnableDisableStartStopMixin(FixtureMixin):
+ 
+     def test_success_default_instance(self):
+         self.get_external_call()("booth", instance="booth")
+-        self.command(
+-            self.env_assist.get_env(),
+-        )
++        self.command(self.env_assist.get_env())
+         self.env_assist.assert_reports(
+             [
+                 fixture.info(
+@@ -3149,9 +2925,7 @@ class EnableDisableStartStopMixin(FixtureMixin):
+         err_msg = "some stderr\nsome stdout"
+         self.get_external_call()("booth", instance="booth", failure_msg=err_msg)
+         self.env_assist.assert_raise_library_error(
+-            lambda: self.command(
+-                self.env_assist.get_env(),
+-            ),
++            lambda: self.command(self.env_assist.get_env()),
+             [
+                 fixture.error(
+                     reports.codes.SERVICE_ACTION_FAILED,
+@@ -3226,17 +3000,16 @@ class PullConfigBase(TestCase, FixtureMixin):
+ class PullConfigSuccess(PullConfigBase):
+     def setUp(self):
+         super().setUp()
+-        (
+-            self.config.http.booth.get_config(
+-                self.name,
+-                self.config_data.decode("utf-8"),
+-                node_labels=[self.node_name],
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.config_path,
+-                self.config_data,
+-                can_overwrite=True,
+-            )
++        self.config.http.booth.get_config(
++            self.name,
++            self.config_data.decode("utf-8"),
++            node_labels=[self.node_name],
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.config_path,
++            self.config_data,
++            can_overwrite=True,
+         )
+ 
+     def test_success(self):
+@@ -3265,17 +3038,16 @@ class PullConfigSuccessCustomInstance(TestCase, FixtureMixin):
+         ]
+ 
+     def test_success(self):
+-        (
+-            self.config.http.booth.get_config(
+-                self.name,
+-                self.config_data.decode("utf-8"),
+-                node_labels=[self.node_name],
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.config_path,
+-                self.config_data,
+-                can_overwrite=True,
+-            )
++        self.config.http.booth.get_config(
++            self.name,
++            self.config_data.decode("utf-8"),
++            node_labels=[self.node_name],
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.config_path,
++            self.config_data,
++            can_overwrite=True,
+         )
+         commands.pull_config(
+             self.env_assist.get_env(),
+@@ -3514,34 +3286,31 @@ class PullConfigWithAuthfile(PullConfigBase):
+         self.authfile = os.path.basename(self.authfile_path)
+         self.authfile_data = b"auth"
+ 
+-        (
+-            self.config.http.booth.get_config(
+-                self.name,
+-                self.config_data.decode("utf-8"),
+-                authfile=self.authfile,
+-                authfile_data=self.authfile_data,
+-                node_labels=[self.node_name],
+-            )
++        self.config.http.booth.get_config(
++            self.name,
++            self.config_data.decode("utf-8"),
++            authfile=self.authfile,
++            authfile_data=self.authfile_data,
++            node_labels=[self.node_name],
+         )
+ 
+ 
+ class PullConfigWithAuthfileSuccess(PullConfigWithAuthfile):
+     def setUp(self):
+         super().setUp()
+-        (
+-            self.config.raw_file.write(
+-                file_type_codes.BOOTH_KEY,
+-                self.authfile_path,
+-                self.authfile_data,
+-                can_overwrite=True,
+-                name="raw_file.write.key",
+-            ).raw_file.write(
+-                file_type_codes.BOOTH_CONFIG,
+-                self.config_path,
+-                self.config_data,
+-                can_overwrite=True,
+-                name="raw_file.write.cfg",
+-            )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_KEY,
++            self.authfile_path,
++            self.authfile_data,
++            can_overwrite=True,
++            name="raw_file.write.key",
++        )
++        self.config.raw_file.write(
++            file_type_codes.BOOTH_CONFIG,
++            self.config_path,
++            self.config_data,
++            can_overwrite=True,
++            name="raw_file.write.cfg",
+         )
+ 
+     def test_success(self):
+@@ -3642,13 +3411,13 @@ class GetStatus(TestCase):
+ 
+     def assert_success(self, instance_name=None):
+         inner_name = instance_name or "booth"
+-        (
+-            self.config.runner.booth.status_daemon(
+-                inner_name, stdout="daemon status"
+-            )
+-            .runner.booth.status_tickets(inner_name, stdout="tickets status")
+-            .runner.booth.status_peers(inner_name, stdout="peers status")
++        self.config.runner.booth.status_daemon(
++            inner_name, stdout="daemon status"
+         )
++        self.config.runner.booth.status_tickets(
++            inner_name, stdout="tickets status"
++        )
++        self.config.runner.booth.status_peers(inner_name, stdout="peers status")
+         self.assertEqual(
+             commands.get_status(
+                 self.env_assist.get_env(), instance_name=instance_name
+@@ -3667,10 +3436,8 @@ class GetStatus(TestCase):
+         self.assert_success(instance_name="my_booth")
+ 
+     def test_daemon_status_failure(self):
+-        (
+-            self.config.runner.booth.status_daemon(
+-                "booth", stdout="some output", stderr="some error", returncode=1
+-            )
++        self.config.runner.booth.status_daemon(
++            "booth", stdout="some output", stderr="some error", returncode=1
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.get_status(self.env_assist.get_env()),
+@@ -3684,12 +3451,9 @@ class GetStatus(TestCase):
+         )
+ 
+     def test_ticket_status_failure(self):
+-        (
+-            self.config.runner.booth.status_daemon(
+-                "booth", stdout="daemon status"
+-            ).runner.booth.status_tickets(
+-                "booth", stdout="some output", stderr="some error", returncode=1
+-            )
++        self.config.runner.booth.status_daemon("booth", stdout="daemon status")
++        self.config.runner.booth.status_tickets(
++            "booth", stdout="some output", stderr="some error", returncode=1
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.get_status(self.env_assist.get_env()),
+@@ -3703,14 +3467,12 @@ class GetStatus(TestCase):
+         )
+ 
+     def test_peers_status_failure(self):
+-        (
+-            self.config.runner.booth.status_daemon(
+-                "booth", stdout="daemon status"
+-            )
+-            .runner.booth.status_tickets("booth", stdout="tickets status")
+-            .runner.booth.status_peers(
+-                "booth", stdout="some output", stderr="some error", returncode=1
+-            )
++        self.config.runner.booth.status_daemon("booth", stdout="daemon status")
++        self.config.runner.booth.status_tickets(
++            "booth", stdout="tickets status"
++        )
++        self.config.runner.booth.status_peers(
++            "booth", stdout="some output", stderr="some error", returncode=1
+         )
+         self.env_assist.assert_raise_library_error(
+             lambda: commands.get_status(self.env_assist.get_env()),
+-- 
+2.35.3
+
diff --git a/SOURCES/bz2058243-02-make-booth-ticket-mode-value-case-insensitive.patch b/SOURCES/bz2058243-02-make-booth-ticket-mode-value-case-insensitive.patch
new file mode 100644
index 0000000..212472d
--- /dev/null
+++ b/SOURCES/bz2058243-02-make-booth-ticket-mode-value-case-insensitive.patch
@@ -0,0 +1,126 @@
+From de4845ea2d22c7dd9f4539360b44a900b1cea193 Mon Sep 17 00:00:00 2001
+From: Tomas Jelinek <tojeline@redhat.com>
+Date: Thu, 14 Jul 2022 16:46:33 +0200
+Subject: [PATCH 2/3] make booth ticket mode value case insensitive
+
+---
+ pcs/lib/booth/config_validators.py        | 10 ++++++++
+ pcs/lib/commands/booth.py                 | 14 +++++++++---
+ pcs_test/tier0/lib/commands/test_booth.py | 28 ++++++++++++++++-------
+ 3 files changed, 41 insertions(+), 11 deletions(-)
+
+diff --git a/pcs/lib/booth/config_validators.py b/pcs/lib/booth/config_validators.py
+index 99badc46..6c4a4ddc 100644
+--- a/pcs/lib/booth/config_validators.py
++++ b/pcs/lib/booth/config_validators.py
+@@ -100,6 +100,16 @@ def remove_ticket(conf_facade, ticket_name):
+     return []
+ 
+ 
++def ticket_options_normalization() -> validate.TypeNormalizeFunc:
++    return validate.option_value_normalization(
++        {
++            "mode": (
++                lambda value: value.lower() if isinstance(value, str) else value
++            )
++        }
++    )
++
++
+ def validate_ticket_name(ticket_name: str) -> reports.ReportItemList:
+     if not __TICKET_NAME_RE.search(ticket_name):
+         return [
+diff --git a/pcs/lib/commands/booth.py b/pcs/lib/commands/booth.py
+index e7891fbe..fc1454ce 100644
+--- a/pcs/lib/commands/booth.py
++++ b/pcs/lib/commands/booth.py
+@@ -23,7 +23,10 @@ from pcs.common.reports.item import (
+ )
+ from pcs.common.services.errors import ManageServiceError
+ from pcs.common.str_tools import join_multilines
+-from pcs.lib import tools
++from pcs.lib import (
++    tools,
++    validate,
++)
+ from pcs.lib.booth import (
+     config_files,
+     config_validators,
+@@ -329,17 +332,22 @@ def config_ticket_add(
+     booth_env = env.get_booth_env(instance_name)
+     try:
+         booth_conf = booth_env.config.read_to_facade()
++        options_pairs = validate.values_to_pairs(
++            options, config_validators.ticket_options_normalization()
++        )
+         report_processor.report_list(
+             config_validators.add_ticket(
+                 booth_conf,
+                 ticket_name,
+-                options,
++                options_pairs,
+                 allow_unknown_options=allow_unknown_options,
+             )
+         )
+         if report_processor.has_errors:
+             raise LibraryError()
+-        booth_conf.add_ticket(ticket_name, options)
++        booth_conf.add_ticket(
++            ticket_name, validate.pairs_to_values(options_pairs)
++        )
+         booth_env.config.write_facade(booth_conf, can_overwrite=True)
+     except RawFileError as e:
+         report_processor.report(raw_file_error_report(e))
+diff --git a/pcs_test/tier0/lib/commands/test_booth.py b/pcs_test/tier0/lib/commands/test_booth.py
+index 2b20a199..12b169c2 100644
+--- a/pcs_test/tier0/lib/commands/test_booth.py
++++ b/pcs_test/tier0/lib/commands/test_booth.py
+@@ -1194,7 +1194,7 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+             },
+         )
+ 
+-    def test_success_ticket_options(self):
++    def assert_success_ticket_options(self, options_command, options_config):
+         self.config.raw_file.read(
+             file_type_codes.BOOTH_CONFIG,
+             self.fixture_cfg_path(),
+@@ -1203,17 +1203,29 @@ class ConfigTicketAdd(TestCase, FixtureMixin):
+         self.config.raw_file.write(
+             file_type_codes.BOOTH_CONFIG,
+             self.fixture_cfg_path(),
+-            self.fixture_cfg_content(
+-                ticket_list=[
+-                    ["ticketA", [("retries", "10"), ("timeout", "20")]]
+-                ]
+-            ),
++            self.fixture_cfg_content(ticket_list=[["ticketA", options_config]]),
+             can_overwrite=True,
+         )
+         commands.config_ticket_add(
+-            self.env_assist.get_env(),
+-            "ticketA",
++            self.env_assist.get_env(), "ticketA", options_command
++        )
++
++    def test_success_ticket_options(self):
++        self.assert_success_ticket_options(
+             {"timeout": "20", "retries": "10"},
++            [("retries", "10"), ("timeout", "20")],
++        )
++
++    def test_success_ticket_options_mode(self):
++        self.assert_success_ticket_options(
++            {"timeout": "20", "retries": "10", "mode": "manual"},
++            [("mode", "manual"), ("retries", "10"), ("timeout", "20")],
++        )
++
++    def test_success_ticket_options_mode_case_insensitive(self):
++        self.assert_success_ticket_options(
++            {"timeout": "20", "retries": "10", "mode": "MaNuAl"},
++            [("mode", "manual"), ("retries", "10"), ("timeout", "20")],
+         )
+ 
+     def test_ticket_already_exists(self):
+-- 
+2.35.3
+
diff --git a/SOURCES/bz2102663-01-fix-pcs-resource-restart-traceback.patch b/SOURCES/bz2102663-01-fix-pcs-resource-restart-traceback.patch
new file mode 100644
index 0000000..20f2d50
--- /dev/null
+++ b/SOURCES/bz2102663-01-fix-pcs-resource-restart-traceback.patch
@@ -0,0 +1,24 @@
+From eeeaac9a46f3568e0a116048068ff99d0dccf25c Mon Sep 17 00:00:00 2001
+From: Tomas Jelinek <tojeline@redhat.com>
+Date: Thu, 30 Jun 2022 14:49:16 +0200
+Subject: [PATCH] fix 'pcs resource restart' traceback
+
+---
+ pcs/resource.py | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/pcs/resource.py b/pcs/resource.py
+index eb59d703..8d402c22 100644
+--- a/pcs/resource.py
++++ b/pcs/resource.py
+@@ -2596,7 +2596,6 @@ def resource_restart(
+     Options:
+       * --wait
+     """
+-    del lib
+     modifiers.ensure_only_supported("--wait")
+     if not argv:
+         utils.err("You must specify a resource to restart")
+-- 
+2.35.3
+
diff --git a/SOURCES/do-not-support-cluster-setup-with-udp-u-transport.patch b/SOURCES/do-not-support-cluster-setup-with-udp-u-transport.patch
index fa1ead6..ab241a5 100644
--- a/SOURCES/do-not-support-cluster-setup-with-udp-u-transport.patch
+++ b/SOURCES/do-not-support-cluster-setup-with-udp-u-transport.patch
@@ -1,4 +1,4 @@
-From 49d9c698697b0dd49f53b60340705b4fd656e248 Mon Sep 17 00:00:00 2001
+From 2a578689db8522971840dbb1644a21c341fe7d83 Mon Sep 17 00:00:00 2001
 From: Ivan Devat <idevat@redhat.com>
 Date: Tue, 20 Nov 2018 15:03:56 +0100
 Subject: [PATCH] do not support cluster setup with udp(u) transport in RHEL9
@@ -9,7 +9,7 @@ Subject: [PATCH] do not support cluster setup with udp(u) transport in RHEL9
  2 files changed, 3 insertions(+)
 
 diff --git a/pcs/pcs.8.in b/pcs/pcs.8.in
-index 0bbee071..ba14251d 100644
+index 363515bb..4c2496aa 100644
 --- a/pcs/pcs.8.in
 +++ b/pcs/pcs.8.in
 @@ -457,6 +457,8 @@ By default, encryption is enabled with cipher=aes256 and hash=sha256. To disable
@@ -22,10 +22,10 @@ index 0bbee071..ba14251d 100644
  .br
  Transport options are: ip_version, netmtu
 diff --git a/pcs/usage.py b/pcs/usage.py
-index bc885918..4e286f46 100644
+index cfa2ac9c..519c853e 100644
 --- a/pcs/usage.py
 +++ b/pcs/usage.py
-@@ -916,6 +916,7 @@ Commands:
+@@ -1429,6 +1429,7 @@ Commands:
              hash=sha256. To disable encryption, set cipher=none and hash=none.
  
          Transports udp and udpu:
@@ -34,5 +34,5 @@ index bc885918..4e286f46 100644
          support traffic encryption nor compression.
          Transport options are:
 -- 
-2.31.1
+2.35.1
 
diff --git a/SOURCES/fix-translating-resource-roles-in-colocation-constra.patch b/SOURCES/fix-translating-resource-roles-in-colocation-constra.patch
deleted file mode 100644
index a6cc80a..0000000
--- a/SOURCES/fix-translating-resource-roles-in-colocation-constra.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From f759872276ed8ff04bbf05010c18bbe4d1abdb11 Mon Sep 17 00:00:00 2001
-From: Tomas Jelinek <tojeline@redhat.com>
-Date: Tue, 1 Feb 2022 16:10:35 +0100
-Subject: [PATCH 2/2] fix translating resource roles in colocation constraints
-
----
- pcs/lib/xml_tools.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/pcs/lib/xml_tools.py b/pcs/lib/xml_tools.py
-index 07752f92..6a652fd1 100644
---- a/pcs/lib/xml_tools.py
-+++ b/pcs/lib/xml_tools.py
-@@ -66,7 +66,7 @@ def export_attributes(
-     result = {str(key): str(value) for key, value in element.attrib.items()}
-     if not with_id:
-         result.pop("id", None)
--    for role_name in ("role", "rsc-role"):
-+    for role_name in ("role", "rsc-role", "with-rsc-role"):
-         if role_name in result:
-             result[role_name] = pacemaker.role.get_value_primary(
-                 const.PcmkRoleType(result[role_name].capitalize())
--- 
-2.34.1
-
diff --git a/SOURCES/simplify-ternar-expression.patch b/SOURCES/simplify-ternar-expression.patch
deleted file mode 100644
index 0835fbd..0000000
--- a/SOURCES/simplify-ternar-expression.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From f44cdc871a39da3960bd04565b4d1d5ffa19bd23 Mon Sep 17 00:00:00 2001
-From: Ivan Devat <idevat@redhat.com>
-Date: Thu, 20 Jan 2022 13:32:49 +0100
-Subject: [PATCH 1/2] simplify ternar expression
-
-The motivation for this is that covscan complains about it.
----
- src/app/view/share/useUrlTabs.ts | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/app/view/share/useUrlTabs.ts b/src/app/view/share/useUrlTabs.ts
-index 7278dad8..a1136bf3 100644
---- a/src/app/view/share/useUrlTabs.ts
-+++ b/src/app/view/share/useUrlTabs.ts
-@@ -13,7 +13,7 @@ export const useUrlTabs = <TABS extends ReadonlyArray<string>>(
- 
-   return {
-     currentTab,
--    matchedContext: tab !== null ? tab.matched : `/${defaultTab}`,
-+    matchedContext: tab?.matched ?? `/${defaultTab}`,
-     tabList,
-   };
- };
--- 
-2.31.1
-
diff --git a/SPECS/pcs.spec b/SPECS/pcs.spec
index d4b1245..39bd67e 100644
--- a/SPECS/pcs.spec
+++ b/SPECS/pcs.spec
@@ -1,6 +1,6 @@
 Name: pcs
-Version: 0.11.1
-Release: 10%{?dist}
+Version: 0.11.3
+Release: 3%{?dist}
 # https://docs.fedoraproject.org/en-US/packaging-guidelines/LicensingGuidelines/
 # https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing#Good_Licenses
 # GPLv2: pcs
@@ -9,7 +9,7 @@ Release: 10%{?dist}
 #      rack-test, sinatra, tilt
 # GPLv2 or Ruby: eventmachne
 # (GPLv2 or Ruby) and BSD: thin
-# BSD or Ruby: open4, rexml, ruby2_keywords, webrick
+# BSD or Ruby: open4, ruby2_keywords, webrick
 # BSD and MIT: ffi
 License: GPLv2 and ASL 2.0 and MIT and BSD and (GPLv2 or Ruby) and (BSD or Ruby)
 URL: https://github.com/ClusterLabs/pcs
@@ -19,13 +19,13 @@ Summary: Pacemaker Configuration System
 ExclusiveArch: i686 x86_64 s390x ppc64le aarch64
 
 %global version_or_commit %{version}
-# %%global version_or_commit %%{version}.210-9862
+# %%global version_or_commit %%{version}.44-9da7
 
 %global pcs_source_name %{name}-%{version_or_commit}
 
 # ui_commit can be determined by hash, tag or branch
-%global ui_commit 0.1.12
-%global ui_modules_version 0.1.12
+%global ui_commit 0.1.14
+%global ui_modules_version 0.1.14
 %global ui_src_name pcs-web-ui-%{ui_commit}
 
 %global pcs_snmp_pkg_name  pcs-snmp
@@ -33,20 +33,19 @@ ExclusiveArch: i686 x86_64 s390x ppc64le aarch64
 %global pyagentx_version   0.4.pcs.2
 %global tornado_version    6.1.0
 %global dacite_version  1.6.0
-%global version_rubygem_backports  3.17.2
-%global version_rubygem_daemons  1.3.1
-%global version_rubygem_ethon  0.12.0
+%global version_rubygem_backports  3.23.0
+%global version_rubygem_daemons  1.4.1
+%global version_rubygem_ethon  0.15.0
 %global version_rubygem_eventmachine  1.2.7
-%global version_rubygem_ffi  1.13.1
+%global version_rubygem_ffi  1.15.5
 %global version_rubygem_mustermann  1.1.1
 %global version_rubygem_open4  1.3.4
-%global version_rubygem_rack  2.2.3
-%global version_rubygem_rack_protection  2.0.8.1
+%global version_rubygem_rack  2.2.3.1
+%global version_rubygem_rack_protection  2.2.0
 %global version_rubygem_rack_test  1.1.0
-%global version_rubygem_rexml  3.2.5
-%global version_rubygem_ruby2_keywords  0.0.2
-%global version_rubygem_sinatra  2.0.8.1
-%global version_rubygem_thin  1.7.2
+%global version_rubygem_ruby2_keywords  0.0.5
+%global version_rubygem_sinatra  2.2.0
+%global version_rubygem_thin  1.8.1
 %global version_rubygem_tilt  2.0.10
 %global version_rubygem_webrick  1.7.0
 
@@ -81,7 +80,6 @@ Source44: https://github.com/konradhalas/dacite/archive/v%{dacite_version}/dacit
 Source81: https://rubygems.org/downloads/backports-%{version_rubygem_backports}.gem
 Source82: https://rubygems.org/downloads/ethon-%{version_rubygem_ethon}.gem
 Source83: https://rubygems.org/downloads/ffi-%{version_rubygem_ffi}.gem
-Source85: https://rubygems.org/downloads/rexml-%{version_rubygem_rexml}.gem
 Source86: https://rubygems.org/downloads/mustermann-%{version_rubygem_mustermann}.gem
 # We needed to re-upload open4 rubygem because of issues with sources in gating.
 # Unfortunately, there was no newer version available, therefore we had to
@@ -106,26 +104,19 @@ Source101: https://github.com/ClusterLabs/pcs-web-ui/releases/download/%{ui_comm
 # Z-streams are exception here: they can come from upstream but should be
 # applied at the end to keep z-stream changes as straightforward as possible.
 # Patch1: bzNUMBER-01-name.patch
-Patch2: bz2032473-01-fix-enabling-corosync-qdevice.patch
-Patch3: bz2019836-01-fix-rsc-update-cmd-when-unable-to-get-agent-metadata.patch
-Patch4: bz1811072-01-revert-of-disallowing-to-clone-a-group-with-a-stonit.patch
-Patch5: bz2033248-01-skip-checking-of-scsi-devices-to-be-removed.patch
-Patch6: Make-ocf-linbit-drbd-agent-pass-OCF-validation.patch
-Patch7: bz1990787-01-Multiple-fixes-in-pcs-resource-move-command.patch
-Patch8: bz2040420-01-fix-creating-empty-cib.patch
-Patch9: bz20486401-01-Fix-snmp-client.patch
-Patch10: fix-translating-resource-roles-in-colocation-constra.patch
 
 # Downstream patches do not come from upstream. They adapt pcs for specific
 # RHEL needs.
 
 # pcs patches: <= 200
 Patch1: do-not-support-cluster-setup-with-udp-u-transport.patch
+Patch2: bz2102663-01-fix-pcs-resource-restart-traceback.patch
+Patch3: bz2058243-01-code-formatting.patch
+Patch4: bz2058243-02-make-booth-ticket-mode-value-case-insensitive.patch
+Patch5: bz2026725-01-booth-sync-check-whether-etc-booth-exists.patch
 
 # ui patches: >200
 # Patch201: bzNUMBER-01-name.patch
-Patch201: simplify-ternar-expression.patch
-Patch202: bz2044409-01-fix-backend-parameter-all-in-cluster-destroy.patch
 
 # git for patches
 BuildRequires: git-core
@@ -154,8 +145,9 @@ BuildRequires: ruby >= 2.5
 BuildRequires: ruby-devel
 BuildRequires: rubygems
 BuildRequires: rubygem-bundler
-# ruby libraries for tests
 BuildRequires: rubygem-json
+BuildRequires: rubygem-rexml
+# ruby libraries for tests
 BuildRequires: rubygem-test-unit
 # for touching patch files (sanitization function)
 BuildRequires: diffstat
@@ -188,6 +180,7 @@ Requires: python3-cryptography
 Requires: ruby >= 2.5
 Requires: rubygems
 Requires: rubygem-json
+Requires: rubygem-rexml
 # for killall
 Requires: psmisc
 # cluster stack and related packages
@@ -221,7 +214,6 @@ Provides: bundled(open4) = %{version_rubygem_open4}
 Provides: bundled(rack) = %{version_rubygem_rack}
 Provides: bundled(rack_protection) = %{version_rubygem_rack_protection}
 Provides: bundled(rack_test) = %{version_rubygem_rack_test}
-Provides: bundled(rexml) = %{version_rubygem_rexml}
 Provides: bundled(ruby2_keywords) = %{version_rubygem_ruby2_keywords}
 Provides: bundled(sinatra) = %{version_rubygem_sinatra}
 Provides: bundled(thin) = %{version_rubygem_thin}
@@ -301,8 +293,6 @@ update_times_patch(){
 %autosetup -D -T -b 100 -a 101 -S git -n %{ui_src_name} -N
 %autopatch -p1 -m 201
 # update_times_patch %%{PATCH201}
-update_times_patch %{PATCH201}
-update_times_patch %{PATCH202}
 
 # patch pcs sources
 %autosetup -S git -n %{pcs_source_name} -N
@@ -312,11 +302,6 @@ update_times_patch %{PATCH2}
 update_times_patch %{PATCH3}
 update_times_patch %{PATCH4}
 update_times_patch %{PATCH5}
-update_times_patch %{PATCH6}
-update_times_patch %{PATCH7}
-update_times_patch %{PATCH8}
-update_times_patch %{PATCH9}
-update_times_patch %{PATCH10}
 
 # prepare dirs/files necessary for building all bundles
 # -----------------------------------------------------
@@ -326,7 +311,6 @@ mkdir -p %{rubygem_cache_dir}
 cp -f %SOURCE81 %{rubygem_cache_dir}
 cp -f %SOURCE82 %{rubygem_cache_dir}
 cp -f %SOURCE83 %{rubygem_cache_dir}
-cp -f %SOURCE85 %{rubygem_cache_dir}
 cp -f %SOURCE86 %{rubygem_cache_dir}
 # For reason why we are renaming open4 rubygem, see comment of source
 # definition above.
@@ -385,7 +369,6 @@ mv %{rubygem_bundle_dir}/gems/ffi-%{version_rubygem_ffi}/LICENSE.SPECS ffi_LICEN
 mv %{rubygem_bundle_dir}/gems/mustermann-%{version_rubygem_mustermann}/LICENSE mustermann_LICENSE
 mv %{rubygem_bundle_dir}/gems/open4-%{version_rubygem_open4}/LICENSE open4_LICENSE
 mv %{rubygem_bundle_dir}/gems/rack-%{version_rubygem_rack}/MIT-LICENSE rack_MIT-LICENSE
-mv %{rubygem_bundle_dir}/gems/rexml-%{version_rubygem_rexml}/LICENSE.txt rexml_LICENSE.txt
 mv %{rubygem_bundle_dir}/gems/rack-protection-%{version_rubygem_rack_protection}/License rack-protection_License
 mv %{rubygem_bundle_dir}/gems/rack-test-%{version_rubygem_rack_test}/MIT-LICENSE.txt rack-test_MIT-LICENSE.txt
 mv %{rubygem_bundle_dir}/gems/sinatra-%{version_rubygem_sinatra}/LICENSE sinatra_LICENSE
@@ -513,7 +496,6 @@ run_all_tests
 %license rack_MIT-LICENSE
 %license rack-protection_License
 %license rack-test_MIT-LICENSE.txt
-%license rexml_LICENSE.txt
 %license sinatra_LICENSE
 %license tilt_COPYING
 %license webrick_LICENSE.txt
@@ -557,6 +539,32 @@ run_all_tests
 %license pyagentx_LICENSE.txt
 
 %changelog
+* Thu Jul 28 2022 Miroslav Lisik <mlisik@redhat.com> - 0.11.3-3
+- Fixed booth ticket mode value case insensitive
+- Fixed booth sync check whether /etc/booth exists
+- Resolves: rhbz#2026725 rhbz#2058243
+
+* Tue Jul 12 2022 Miroslav Lisik <mlisik@redhat.com> - 0.11.3-2
+- Fixed 'pcs resource restart' traceback
+- Resolves: rhbz#2102663
+
+* Fri Jun 24 2022 Miroslav Lisik <mlisik@redhat.com> - 0.11.3-1
+- Rebased to latest upstream sources (see CHANGELOG.md)
+- Updated pcs-web-ui
+- Updated bundled rubygems: rack
+- Resolves: rhbz#2059122 rhbz#2059177 rhbz#2059501 rhbz#2095695 rhbz#2096886 rhbz#2097730 rhbz#2097731 rhbz#2097732 rhbz#2097733 rhbz#2097778
+
+* Thu May 19 2022 Miroslav Lisik <mlisik@redhat.com> - 0.11.2-1
+- Rebased to latest upstream sources (see CHANGELOG.md)
+- Updated pcs-web-ui
+- Updated bundled rubygems: backports, daemons, ethon ffi, ruby2_keywords, thin
+- Stopped bundling rubygem-rexml (use distribution package instead)
+- Resolves: rhbz#1301204 rhbz#2024522 rhbz#2026725 rhbz#2029844 rhbz#2039884 rhbz#2053177 rhbz#2054671 rhbz#2058243 rhbz#2058246 rhbz#2058247 rhbz#2058251 rhbz#2058252 rhbz#2059142 rhbz#2059145 rhbz#2059148 rhbz#2059149 rhbz#2059501 rhbz#2064818 rhbz#2068457 rhbz#2076585
+
+* Wed May 04 2022 Miroslav Lisik <mlisik@redhat.com> - 0.11.1-11
+- Updated bundled rubygems: sinatra, rack-protection
+- Resolves: rhbz#2081334
+
 * Tue Feb 01 2022 Miroslav Lisik <mlisik@redhat.com> - 0.11.1-10
 - Fixed snmp client
 - Fixed translating resource roles in colocation constraint