diff --git a/pcs/cli/routing/cluster.py b/pcs/cli/routing/cluster.py index 4a53cad6c..49755645a 100644 --- a/pcs/cli/routing/cluster.py +++ b/pcs/cli/routing/cluster.py @@ -83,6 +83,8 @@ def pcsd_status( "kill": cluster.kill_cluster, "enable": cluster.cluster_enable_cmd, "disable": cluster.cluster_disable_cmd, + "enable-corosync-notifyd": cluster.corosync_notifyd_enable_cmd, + "disable-corosync-notifyd": cluster.corosync_notifyd_disable_cmd, "cib": cluster.get_cib, "cib-push": cluster.cluster_push, "cib-upgrade": cluster.cluster_cib_upgrade_cmd, diff --git a/pcs/cluster.py b/pcs/cluster.py index dd8fbfaa4..e367f5c87 100644 --- a/pcs/cluster.py +++ b/pcs/cluster.py @@ -118,6 +118,50 @@ def cluster_enable_cmd(lib, argv, modifiers): enable_cluster(argv) +def corosync_notifyd_disable_cmd(lib, argv, modifiers): + del lib + all_nodes, report_list = get_existing_nodes_names( + utils.get_corosync_conf_facade() + ) + if not all_nodes: + report_list.append( + reports.ReportItem.error( + reports.messages.CorosyncConfigNoNodesDefined() + ) + ) + if report_list: + process_library_reports(report_list) + for node in all_nodes: + retval, output = utils.set_corosync_notifyd_enabled(node, "false") + if retval != 0: + utils.err(output) + else: + print(output.rstrip()) + return + + +def corosync_notifyd_enable_cmd(lib, argv, modifiers): + del lib + all_nodes, report_list = get_existing_nodes_names( + utils.get_corosync_conf_facade() + ) + if not all_nodes: + report_list.append( + reports.ReportItem.error( + reports.messages.CorosyncConfigNoNodesDefined() + ) + ) + if report_list: + process_library_reports(report_list) + for node in all_nodes: + retval, output = utils.set_corosync_notifyd_enabled(node, "true") + if retval != 0: + utils.err(output) + else: + print(output.rstrip()) + return + + def cluster_stop_cmd(lib, argv, modifiers): """ Options: @@ -260,6 +304,8 @@ def start_cluster(argv): service_list = ["corosync"] if utils.need_to_handle_qdevice_service(): service_list.append("corosync-qdevice") + if utils.need_to_handle_corosync_notifyd(): + service_list.append("corosync-notifyd") service_list.append("pacemaker") for service in service_list: utils.start_service(service) @@ -695,6 +741,8 @@ def stop_cluster_corosync(): service_list = [] if utils.need_to_handle_qdevice_service(): service_list.append("corosync-qdevice") + if utils.need_to_handle_corosync_notifyd(): + service_list.append("corosync-notifyd") service_list.append("corosync") for service in service_list: utils.stop_service(service) @@ -735,6 +783,7 @@ def kill_local_cluster_services(): "gfs_controld", # Corosync daemons "corosync-qdevice", + "corosync-notifyd", "corosync", ] return utils.run([settings.killall_executable, "-9"] + all_cluster_daemons) @@ -1284,7 +1333,7 @@ def cluster_destroy(lib, argv, modifiers): destroy_cluster(corosync_nodes) else: print("Shutting down pacemaker/corosync services...") - for service in ["pacemaker", "corosync-qdevice", "corosync"]: + for service in ["pacemaker", "corosync-qdevice", "corosync-notifyd", "corosync"]: try: utils.stop_service(service) except LibraryError: diff --git a/pcs/lib/commands/status.py b/pcs/lib/commands/status.py index f80f696e7..6659bade3 100644 --- a/pcs/lib/commands/status.py +++ b/pcs/lib/commands/status.py @@ -220,6 +220,7 @@ def _get_local_services_status( service_def = [ # (service name, display even if not enabled nor running) ("corosync", True), + ("corosync-notifyd", True), ("pacemaker", True), ("pacemaker_remote", False), ("pcsd", True), diff --git a/pcs/usage.py b/pcs/usage.py index e169e2362..1d7bce4d8 100644 --- a/pcs/usage.py +++ b/pcs/usage.py @@ -1011,6 +1011,14 @@ def cluster(args=(), pout=True): is not specified then cluster is disabled on the local node. If --all is specified then cluster is disabled on all nodes. + enable-corosync-notifyd + Configure corosync-notifyd to also start when cluster starts. + + disable-corosync-notifyd + Configure corosync-notifyd not to start when cluster starts. + By default (unless you run 'pcs cluster enable-corosync-notifyd'), + corosync-notifyd will not be start when cluster starts. + auth [-u ] [-p ] Authenticate pcs/pcsd to pcsd on nodes configured in the local cluster. diff --git a/pcs/utils.py b/pcs/utils.py index 3a6ea16a1..326d2fccd 100644 --- a/pcs/utils.py +++ b/pcs/utils.py @@ -2122,6 +2122,8 @@ def enableServices(): service_list = ["corosync", "pacemaker"] if need_to_handle_qdevice_service(): service_list.append("corosync-qdevice") + if need_to_handle_corosync_notifyd(): + service_list.append("corosync-notifyd") service_manager = get_service_manager() report_item_list = [] @@ -2142,6 +2144,8 @@ def disableServices(): service_list = ["corosync", "pacemaker"] if need_to_handle_qdevice_service(): service_list.append("corosync-qdevice") + if need_to_handle_corosync_notifyd(): + service_list.append("corosync-notifyd") service_manager = get_service_manager() report_item_list = [] @@ -2883,3 +2887,19 @@ def get_token_from_file(file_name: str) -> str: except OSError as e: err(f"Unable to read file '{file_name}': {e}", exit_after_error=False) raise SystemExit(1) from e + + +def need_to_handle_corosync_notifyd(): + if not os.path.exists(settings.pcsd_settings_conf_location): + return False + try: + out = json.loads(open(settings.pcsd_settings_conf_location, "r", encoding="utf-8").read()) + except IOError as e: + err("Unable to read %s: %s" % (settings.pcsd_settings_conf_location, e.strerror)) + return False + return out["corosync_notifyd_enabled"] == "true" + + +def set_corosync_notifyd_enabled(node, value): + data = urlencode({"corosync_notifyd_enabled": value}) + return sendHTTPRequest(node, "remote/set_corosync_notifyd_enabled", data, False, False) diff --git a/pcsd/config.rb b/pcsd/config.rb index 843458b7e..9e734082d 100644 --- a/pcsd/config.rb +++ b/pcsd/config.rb @@ -5,11 +5,12 @@ class PCSConfig CURRENT_FORMAT = 2 - attr_accessor :clusters, :permissions_local, :format_version, :data_version + attr_accessor :clusters, :permissions_local, :format_version, :data_version, :corosync_notifyd_enabled def initialize(cfg_text) @format_version = 0 @data_version = 0 + @corosync_notifyd_enabled = 'false' @clusters = [] @permissions_local = Permissions::PermissionsSet.new([]) @@ -75,6 +76,7 @@ def initialize(cfg_text) if @format_version >= 2 @data_version = json["data_version"] || 0 + @corosync_notifyd_enabled = json["corosync_notifyd_enabled"] || 'false' input_clusters = json["clusters"] || [] input_permissions = json['permissions'] || {} elsif @format_version == 1 @@ -126,6 +128,7 @@ def text() out_hash = Hash.new out_hash['format_version'] = CURRENT_FORMAT out_hash['data_version'] = @data_version + out_hash['corosync_notifyd_enabled'] = @corosync_notifyd_enabled out_hash['clusters'] = [] out_hash['permissions'] = Hash.new out_hash['permissions']['local_cluster'] = [] diff --git a/pcsd/remote.rb b/pcsd/remote.rb index c49db1160..51e753693 100644 --- a/pcsd/remote.rb +++ b/pcsd/remote.rb @@ -57,6 +57,7 @@ def remote(params, request, auth_user) :node_unstandby => method(:node_unstandby), :cluster_enable => method(:cluster_enable), :cluster_disable => method(:cluster_disable), + :set_corosync_notifyd_enabled => method(:set_corosync_notifyd_enabled), # TODO deprecated, remove, not used anymore :resource_status => method(:resource_status), :get_sw_versions => method(:get_sw_versions), @@ -502,6 +503,26 @@ def cluster_disable(params, request, auth_user) end end +def set_corosync_notifyd_enabled(params, request, auth_user) + if not allowed_for_local_cluster(auth_user, Permissions::GRANT) + return 403, 'Permission denied' + end + if params[:corosync_notifyd_enabled] != nil and params[:corosync_notifyd_enabled].strip != "" + data = params[:corosync_notifyd_enabled] + else + $logger.info "Invalid corosync_notifyd_enabled" + return 400, "Failed" + end + pcs_config = PCSConfig.new(Cfgsync::PcsdSettings.from_file().text()) + pcs_config.corosync_notifyd_enabled = data + sync_config = Cfgsync::PcsdSettings.from_text(pcs_config.text()) + pushed, _ = Cfgsync::save_sync_new_version( + sync_config, get_corosync_nodes_names(), $cluster_name, true + ) + return [200, 'corosync_notifyd_enabled saved'] if pushed + return 400, 'Unable to save corosync_notifyd_enabled' +end + def get_quorum_info(params, request, auth_user) if not allowed_for_local_cluster(auth_user, Permissions::READ) return 403, 'Permission denied'