diff --git a/CHANGELOG.md b/CHANGELOG.md index 34424589c..d0933d00a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,12 @@ - Do not wrap resource and stonith agent description to preserve existing formatting ([RHEL-113763]) +### Deprecated +- Value `sctp` of the knet link option `transport` is deprecated in + corosync / knet and might be removed in a future release ([RHEL-126842]) + [RHEL-113763]: https://issues.redhat.com/browse/RHEL-113763 +[RHEL-126842]: https://issues.redhat.com/browse/RHEL-126842 ## [0.11.10] - 2025-07-09 diff --git a/pcs/lib/corosync/config_validators.py b/pcs/lib/corosync/config_validators.py index 8636f3756..19f9bdf47 100644 --- a/pcs/lib/corosync/config_validators.py +++ b/pcs/lib/corosync/config_validators.py @@ -840,6 +840,8 @@ def _get_link_options_validators_knet( validate.ValueNonnegativeInteger("ping_timeout"), validate.ValueNonnegativeInteger("pong_count"), validate.ValueIn("transport", ("sctp", "udp")), + # DEPRECATED in knet 1, to be removed in knet 2.0 + validate.ValueDeprecated("transport", {"sctp": None}), ] if including_linknumber: diff --git a/pcs_test/tier0/lib/commands/cluster/test_add_link.py b/pcs_test/tier0/lib/commands/cluster/test_add_link.py index d259caf90..98be8f138 100644 --- a/pcs_test/tier0/lib/commands/cluster/test_add_link.py +++ b/pcs_test/tier0/lib/commands/cluster/test_add_link.py @@ -87,11 +87,10 @@ def setUp(self): ) def test_success(self): - ( - self.config.corosync_conf.load_content(self.before) - .runner.cib.load() - .env.push_corosync_conf(corosync_conf_text=self.after) - ) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load() + self.config.env.push_corosync_conf(corosync_conf_text=self.after) + cluster.add_link( self.env_assist.get_env(), self.node_addr_map, @@ -101,8 +100,35 @@ def test_success(self): # hidden in self.config.env.push_corosync_conf. self.env_assist.assert_reports([]) + def test_success_deprecated_sctp(self): + after = self.after.replace( + "knet_transport: udp", "knet_transport: sctp" + ) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load() + self.config.env.push_corosync_conf(corosync_conf_text=after) + + cluster.add_link( + self.env_assist.get_env(), + self.node_addr_map, + {"transport": "sctp"}, + ) + # Reports from pushing corosync.conf are produced in env. That code is + # hidden in self.config.env.push_corosync_conf. + self.env_assist.assert_reports( + [ + fixture.deprecation( + report_codes.DEPRECATED_OPTION_VALUE, + option_name="transport", + deprecated_value="sctp", + replaced_by=None, + ) + ] + ) + def test_not_live(self): - (self.config.env.set_corosync_conf_data(self.before)) + self.config.env.set_corosync_conf_data(self.before) + self.env_assist.assert_raise_library_error( lambda: cluster.add_link( self.env_assist.get_env(), @@ -120,7 +146,9 @@ def test_not_live(self): def test_validation(self): patch_getaddrinfo(self, ["node2-addr0"]) - (self.config.corosync_conf.load_content(self.before).runner.cib.load()) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load() + self.env_assist.assert_raise_library_error( lambda: cluster.add_link( self.env_assist.get_env(), @@ -182,7 +210,9 @@ def test_validation(self): ) def test_missing_input_data(self): - (self.config.corosync_conf.load_content(self.before).runner.cib.load()) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load() + self.env_assist.assert_raise_library_error( lambda: cluster.add_link(self.env_assist.get_env(), {}, {}), [] ) @@ -223,7 +253,9 @@ def test_missing_node_names(self): } """ ) - self.config.corosync_conf.load_content(before).runner.cib.load() + self.config.corosync_conf.load_content(before) + self.config.runner.cib.load() + self.env_assist.assert_raise_library_error( lambda: cluster.add_link( self.env_assist.get_env(), @@ -259,11 +291,10 @@ def test_cib_guest_node(self): """ - ( - self.config.corosync_conf.load_content(self.before).runner.cib.load( - resources=resources - ) - ) + + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load(resources=resources) + self.env_assist.assert_raise_library_error( lambda: cluster.add_link( self.env_assist.get_env(), @@ -295,11 +326,9 @@ def test_cib_remote_node(self): """ - ( - self.config.corosync_conf.load_content(self.before).runner.cib.load( - resources=resources - ) - ) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load(resources=resources) + self.env_assist.assert_raise_library_error( lambda: cluster.add_link( self.env_assist.get_env(), @@ -318,11 +347,9 @@ def test_cib_remote_node(self): ) def test_cib_not_available(self): - ( - self.config.corosync_conf.load_content(self.before).runner.cib.load( - stderr="an error", returncode=1 - ) - ) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load(stderr="an error", returncode=1) + self.env_assist.assert_raise_library_error( lambda: cluster.add_link( self.env_assist.get_env(), @@ -341,11 +368,10 @@ def test_cib_not_available(self): ) def test_cib_not_available_forced(self): - ( - self.config.corosync_conf.load_content(self.before) - .runner.cib.load(stderr="an error", returncode=1) - .env.push_corosync_conf(corosync_conf_text=self.after) - ) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load(stderr="an error", returncode=1) + self.config.env.push_corosync_conf(corosync_conf_text=self.after) + cluster.add_link( self.env_assist.get_env(), self.node_addr_map, @@ -361,14 +387,13 @@ def test_cib_not_available_forced(self): ) def test_offline_nodes(self): - ( - self.config.corosync_conf.load_content(self.before) - .runner.cib.load() - .env.push_corosync_conf( - corosync_conf_text=self.after, - skip_offline_targets=True, - ) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load() + self.config.env.push_corosync_conf( + corosync_conf_text=self.after, + skip_offline_targets=True, ) + cluster.add_link( self.env_assist.get_env(), self.node_addr_map, @@ -378,7 +403,9 @@ def test_offline_nodes(self): def test_unresolvable_addresses(self): patch_getaddrinfo(self, []) - (self.config.corosync_conf.load_content(self.before).runner.cib.load()) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load() + self.env_assist.assert_raise_library_error( lambda: cluster.add_link( self.env_assist.get_env(), @@ -399,11 +426,10 @@ def test_unresolvable_addresses(self): def test_unresolvable_addresses_forced(self): patch_getaddrinfo(self, []) - ( - self.config.corosync_conf.load_content(self.before) - .runner.cib.load() - .env.push_corosync_conf(corosync_conf_text=self.after) - ) + self.config.corosync_conf.load_content(self.before) + self.config.runner.cib.load() + self.config.env.push_corosync_conf(corosync_conf_text=self.after) + cluster.add_link( self.env_assist.get_env(), self.node_addr_map, diff --git a/pcs_test/tier0/lib/commands/cluster/test_setup.py b/pcs_test/tier0/lib/commands/cluster/test_setup.py index 2638132cf..b7ead6e4c 100644 --- a/pcs_test/tier0/lib/commands/cluster/test_setup.py +++ b/pcs_test/tier0/lib/commands/cluster/test_setup.py @@ -2088,7 +2088,21 @@ def test_all_options(self): quorum_options=QUORUM_OPTIONS, ) self.env_assist.assert_reports( - reports_success_minimal_fixture(using_known_hosts_addresses=False) + [ + fixture.deprecation( + reports.codes.DEPRECATED_OPTION_VALUE, + option_name="transport", + deprecated_value="sctp", + replaced_by=None, + ), + fixture.deprecation( + reports.codes.DEPRECATED_OPTION_VALUE, + option_name="transport", + deprecated_value="sctp", + replaced_by=None, + ), + ] + + reports_success_minimal_fixture(using_known_hosts_addresses=False) ) def test_disable_crypto(self): diff --git a/pcs_test/tier0/lib/commands/cluster/test_update_link.py b/pcs_test/tier0/lib/commands/cluster/test_update_link.py index 8941b9df5..49eafeadf 100644 --- a/pcs_test/tier0/lib/commands/cluster/test_update_link.py +++ b/pcs_test/tier0/lib/commands/cluster/test_update_link.py @@ -256,6 +256,88 @@ def test_success(self): # hidden in self.config.env.push_corosync_conf. self.env_assist.assert_reports([]) + def test_success_deprecated_sctp(self): + before = dedent( + """\ + totem { + transport: knet + + interface { + linknumber: 2 + knet_transport: udp + } + } + + nodelist { + node { + ring0_addr: node1-addr0 + ring2_addr: node1-addr2 + name: node1 + nodeid: 1 + } + + node { + ring0_addr: node2-addr0 + ring2_addr: node2-addr2a + name: node2 + nodeid: 2 + } + } + """ + ) + after = dedent( + """\ + totem { + transport: knet + + interface { + linknumber: 2 + knet_transport: sctp + } + } + + nodelist { + node { + ring0_addr: node1-addr0 + ring2_addr: node1-addr2 + name: node1 + nodeid: 1 + } + + node { + ring0_addr: node2-addr0 + ring2_addr: node2-addr2a + name: node2 + nodeid: 2 + } + } + """ + ) + patch_getaddrinfo(self, self.existing_addrs + ["node2-addr2a"]) + self.config.corosync_conf.load_content(before) + self.config.env.push_corosync_conf( + corosync_conf_text=after, need_stopped_cluster=True + ) + + cluster.update_link( + self.env_assist.get_env(), + "2", + {"node2": "node2-addr2a"}, + {"transport": "sctp"}, + ) + # Reports from pushing corosync.conf are produced in env. That code is + # hidden in self.config.env.push_corosync_conf. + self.env_assist.assert_reports( + [ + fixture.deprecation( + report_codes.DEPRECATED_OPTION_VALUE, + option_name="transport", + deprecated_value="sctp", + replaced_by=None, + ) + ] + ) + def test_validation(self): patch_getaddrinfo(self, self.existing_addrs + ["node2-addr0"]) self.config.corosync_conf.load_content(self.before) diff --git a/pcs_test/tier0/lib/corosync/test_config_validators_create.py b/pcs_test/tier0/lib/corosync/test_config_validators_create.py index 65a422d28..b8e4d54bf 100644 --- a/pcs_test/tier0/lib/corosync/test_config_validators_create.py +++ b/pcs_test/tier0/lib/corosync/test_config_validators_create.py @@ -1204,7 +1204,14 @@ def test_all_valid(self): ], 2, ), - [], + [ + fixture.deprecation( + report_codes.DEPRECATED_OPTION_VALUE, + option_name="transport", + deprecated_value="sctp", + replaced_by=None, + ) + ], ) def test_invalid_all_values(self): diff --git a/pcs_test/tier0/lib/corosync/test_config_validators_links.py b/pcs_test/tier0/lib/corosync/test_config_validators_links.py index fce50e3c9..a00f1956c 100644 --- a/pcs_test/tier0/lib/corosync/test_config_validators_links.py +++ b/pcs_test/tier0/lib/corosync/test_config_validators_links.py @@ -765,6 +765,29 @@ def test_forbidden_characters(self): ], ) + def test_deprecated_sctp_knet_transport(self): + assert_report_item_list_equal( + config_validators.add_link( + self.new_addrs, + { + "transport": "sctp", + }, + self.coro_nodes, + self.pcmk_nodes, + self.existing_link_list, + self.transport, + constants.IP_VERSION_64, + ), + [ + fixture.deprecation( + report_codes.DEPRECATED_OPTION_VALUE, + option_name="transport", + deprecated_value="sctp", + replaced_by=None, + ) + ], + ) + class RemoveLinks(TestCase): def setUp(self): @@ -1837,6 +1860,33 @@ def test_forbidden_characters(self): ], ) + def test_deprecated_sctp_knet_transport(self): + assert_report_item_list_equal( + config_validators.update_link( + "2", + {}, + { + "transport": "sctp", + }, + {}, + [], + [], + [ + "2", + ], + constants.TRANSPORTS_KNET[0], + constants.IP_VERSION_64, + ), + [ + fixture.deprecation( + report_codes.DEPRECATED_OPTION_VALUE, + option_name="transport", + deprecated_value="sctp", + replaced_by=None, + ), + ], + ) + class UpdateLinkUdp(TestCase): broadcast_values = (None, "", "0", "1") diff --git a/pcs_test/tier1/cluster/test_setup_local.py b/pcs_test/tier1/cluster/test_setup_local.py index b05614161..762ee6323 100644 --- a/pcs_test/tier1/cluster/test_setup_local.py +++ b/pcs_test/tier1/cluster/test_setup_local.py @@ -171,7 +171,12 @@ def test_multiple_options(self): "totem consensus=0 downcheck=1 token=12 " "quorum last_man_standing=1 last_man_standing_window=10 " "--overwrite --no-cluster-uuid" - ).split() + ).split(), + stderr_full=( + "Deprecation Warning: Value 'sctp' of option transport is " + "deprecated and might be removed in a future release, " + "therefore it should not be used\n" + ), ) self.assertEqual( self.corosync_conf_file.read(), @@ -279,6 +284,7 @@ def test_failure(self): Error: All nodes must have the same number of addresses; nodes 'node1', 'node3' have 3 addresses; node 'node2' has 2 addresses Error: invalid link option 'pong__count', allowed options are: 'link_priority', 'linknumber', 'mcastport', 'ping_interval', 'ping_precision', 'ping_timeout', 'pong_count', 'transport' Error: '123450' is not a valid mcastport value, use a port number (1..65535) + Deprecation Warning: Value 'sctp' of option transport is deprecated and might be removed in a future release, therefore it should not be used Error: Cannot set options for non-existent link '3', existing links: '0', '1', '2' Error: invalid quorum option 'lst_man_standing', allowed options are: 'auto_tie_breaker', 'last_man_standing', 'last_man_standing_window', 'wait_for_all' Error: If quorum option 'last_man_standing_window' is enabled, quorum option 'last_man_standing' must be enabled as well