From a7194ee79f57734b997b5911364bdcc8c24c3c58 Mon Sep 17 00:00:00 2001 From: Matej Slivka Date: Tue, 12 May 2026 14:42:51 +0200 Subject: [PATCH] Move check_sbd to python from ruby Assisted-by: ClaudeCode --- pcs/Makefile.am | 1 + pcs/cli/routing/stonith.py | 8 +- pcs/common/sbd_dto.py | 26 +++ pcs/daemon/app/api_v0.py | 52 +++++ .../async_tasks/worker/command_mapping.py | 5 + pcs/lib/commands/sbd.py | 62 +++++- pcs/lib/sbd.py | 44 ++-- pcs/stonith.py | 12 -- pcs_test/Makefile.am | 1 + pcs_test/tier0/daemon/app/test_api_v0.py | 192 +++++++++++++++++- .../tier0/lib/commands/sbd/test_check_sbd.py | 177 ++++++++++++++++ pcsd/remote.rb | 54 ----- 12 files changed, 540 insertions(+), 94 deletions(-) create mode 100644 pcs/common/sbd_dto.py create mode 100644 pcs_test/tier0/lib/commands/sbd/test_check_sbd.py diff --git a/pcs/Makefile.am b/pcs/Makefile.am index d338c40e4..d70da2895 100644 --- a/pcs/Makefile.am +++ b/pcs/Makefile.am @@ -198,6 +198,7 @@ EXTRA_DIST = \ common/services/drivers/openrc.py \ common/services/drivers/systemd.py \ common/services/drivers/sysvinit_rhel.py \ + common/sbd_dto.py \ common/services_dto.py \ common/services/errors.py \ common/services/__init__.py \ diff --git a/pcs/cli/routing/stonith.py b/pcs/cli/routing/stonith.py index a5ff7569f..580537f28 100644 --- a/pcs/cli/routing/stonith.py +++ b/pcs/cli/routing/stonith.py @@ -1,10 +1,6 @@ import pcs.cli.stonith.command as stonith_cli import pcs.cli.stonith.levels.command as levels_cli -from pcs import ( - resource, - stonith, - usage, -) +from pcs import resource, stonith, usage from pcs.cli.cib.element import command as cib_element_cmd from pcs.cli.common.routing import create_router @@ -79,8 +75,6 @@ { "list": stonith.sbd_watchdog_list, "test": stonith.sbd_watchdog_test, - # internal use only - "list_json": stonith.sbd_watchdog_list_json, }, ["stonith", "sbd", "watchdog"], ), diff --git a/pcs/common/sbd_dto.py b/pcs/common/sbd_dto.py new file mode 100644 index 000000000..dd3ab7306 --- /dev/null +++ b/pcs/common/sbd_dto.py @@ -0,0 +1,26 @@ +from dataclasses import dataclass +from typing import Optional + +from pcs.common.interface.dto import DataTransferObject +from pcs.common.services_dto import ServiceStatusDto + + +@dataclass(frozen=True) +class SbdWatchdogStatusDto(DataTransferObject): + path: str + exists: bool + is_supported: bool + + +@dataclass(frozen=True) +class SbdDeviceStatusDto(DataTransferObject): + path: str + exists: bool + is_block_device: bool + + +@dataclass(frozen=True) +class SbdCheckResultDto(DataTransferObject): + sbd_service: ServiceStatusDto + watchdog: Optional[SbdWatchdogStatusDto] = None + device_list: Optional[list[SbdDeviceStatusDto]] = None diff --git a/pcs/daemon/app/api_v0.py b/pcs/daemon/app/api_v0.py index 2ce05951f..63c7203ec 100644 --- a/pcs/daemon/app/api_v0.py +++ b/pcs/daemon/app/api_v0.py @@ -16,6 +16,7 @@ PermissionMetadataDependenciesDto, PermissionMetadataDto, ) +from pcs.common.sbd_dto import SbdCheckResultDto from pcs.common.str_tools import format_list from pcs.daemon import log from pcs.daemon.app.api_v0_tools import ( @@ -699,6 +700,56 @@ async def _handle_request(self) -> None: raise self._error(reports_to_str(result.reports)) +class CheckSbdHandler(_BaseApiV0Handler): + async def _handle_request(self) -> None: + watchdog = self.get_argument("watchdog", "") + device_list_json = self.get_argument("device_list", "[]") + try: + device_list = json.loads(device_list_json) + except json.JSONDecodeError as e: + raise self._error("Invalid input data format") from e + if not isinstance(device_list, list) or not all( + isinstance(device, str) for device in device_list + ): + raise self._error("Invalid input data format") + + result = await self._run_library_command( + "sbd.check_sbd", + dict(watchdog=watchdog, device_list=device_list), + ) + if not result.success: + raise self._error(reports_to_str(result.reports)) + # Not using to_dict to keep backward compatibility with older + # pcs versions which don't expect watchdog and device_list keys + # to be present in the response when they have no values. Also the + # response was different than our DTOs so we make them into legacy + # format by hand. + sbd_status = cast(SbdCheckResultDto, result.result) + response: dict[str, Any] = dict( + sbd=dict( + installed=sbd_status.sbd_service.installed, + enabled=sbd_status.sbd_service.enabled, + running=sbd_status.sbd_service.running, + ), + ) + if sbd_status.watchdog is not None: + response["watchdog"] = dict( + path=sbd_status.watchdog.path, + exist=sbd_status.watchdog.exists, + is_supported=sbd_status.watchdog.is_supported, + ) + if sbd_status.device_list is not None: + response["device_list"] = [ + dict( + path=device.path, + exist=device.exists, + block_device=device.is_block_device, + ) + for device in sbd_status.device_list + ] + self.write(json.dumps(response)) + + class SetCorosyncConf(_BaseApiV0Handler): async def _handle_request(self) -> None: self._check_required_params({"corosync_conf"}) @@ -806,6 +857,7 @@ def r(url: str) -> str: # cluster config (r("set_corosync_conf"), SetCorosyncConf, params), # sbd + (r("check_sbd"), CheckSbdHandler, params), (r("get_sbd_config"), GetSbdConfigHandler, params), (r("set_sbd_config"), SetSbdConfigHandler, params), ] diff --git a/pcs/daemon/async_tasks/worker/command_mapping.py b/pcs/daemon/async_tasks/worker/command_mapping.py index f1bf54a2f..a6b198535 100644 --- a/pcs/daemon/async_tasks/worker/command_mapping.py +++ b/pcs/daemon/async_tasks/worker/command_mapping.py @@ -491,6 +491,10 @@ class _Cmd: cmd=services.pacemaker_remote_off_local, required_permission=p.WRITE, ), + "sbd.check_sbd": _Cmd( + cmd=sbd.check_sbd, + required_permission=p.READ, + ), "sbd.disable_sbd": _Cmd( cmd=sbd.disable_sbd, required_permission=p.WRITE, @@ -570,6 +574,7 @@ class _Cmd: "resource_agent.list_standards", # The sbd URLs are ready to be exposed in APIv2, just waiting for all the # other URLs to get moved to APIv2 + "sbd.check_sbd", "sbd.get_node_sbd_config_text", "sbd.set_node_sbd_config_text", # There is a lot of url handlers managing cluster services and they should diff --git a/pcs/lib/commands/sbd.py b/pcs/lib/commands/sbd.py index af66ae40b..f427af452 100644 --- a/pcs/lib/commands/sbd.py +++ b/pcs/lib/commands/sbd.py @@ -3,12 +3,15 @@ from pcs import settings from pcs.common import reports from pcs.common.node_communicator import RequestTarget +from pcs.common.sbd_dto import ( + SbdCheckResultDto, + SbdDeviceStatusDto, + SbdWatchdogStatusDto, +) +from pcs.common.services_dto import ServiceStatusDto from pcs.common.types import StringSequence from pcs.common.validate import is_integer -from pcs.lib import ( - sbd, - validate, -) +from pcs.lib import sbd, validate from pcs.lib.cib.tools import get_resources from pcs.lib.communication.nodes import GetOnlineTargets from pcs.lib.communication.sbd import ( @@ -153,6 +156,57 @@ def _get_full_target_dict[T]( } +def check_sbd( + lib_env: LibraryEnvironment, + watchdog: Optional[str] = None, + device_list: Optional[StringSequence] = None, +) -> SbdCheckResultDto: + """ + Check whether sbd is installed, enabled and running. + - If watchdog is specified, also check whether the watchdog exists on the + local node. + - If device_list is specified, also check whether paths specified in the + list exist on the local node and if they are block devices. + + watchdog -- watchdog path to check + device_list -- list of paths to check + """ + sbd_status = ServiceStatusDto( + service=settings.sbd_service_name, + installed=lib_env.service_manager.is_installed( + settings.sbd_service_name + ), + enabled=lib_env.service_manager.is_enabled(settings.sbd_service_name), + running=lib_env.service_manager.is_running(settings.sbd_service_name), + ) + + watchdog_dto: Optional[SbdWatchdogStatusDto] = None + if watchdog: + available_watchdogs = sbd.get_available_watchdogs(lib_env.cmd_runner()) + exists = watchdog in available_watchdogs + # The support status provided by sbd is unreliable, so we are reporting + # every device as supported for now + # https://bugzilla.redhat.com/show_bug.cgi?id=1578891 + # https://github.com/ClusterLabs/pcs/commit/1ca412e151bf531533a525640899fbd109aa + watchdog_dto = SbdWatchdogStatusDto( + path=watchdog, + exists=exists, + is_supported=exists, + ) + + device_list_dto: Optional[list[SbdDeviceStatusDto]] = None + if device_list: + device_list_dto = [ + sbd.check_sbd_device_exists(device) for device in device_list + ] + + return SbdCheckResultDto( + sbd_service=sbd_status, + watchdog=watchdog_dto, + device_list=device_list_dto, + ) + + def enable_sbd( # noqa: PLR0913 lib_env: LibraryEnvironment, default_watchdog: Optional[str], diff --git a/pcs/lib/sbd.py b/pcs/lib/sbd.py index 15c06d10e..7cb824ed4 100644 --- a/pcs/lib/sbd.py +++ b/pcs/lib/sbd.py @@ -1,14 +1,12 @@ import fcntl +import os import re -from os import path -from typing import ( - Mapping, - Optional, - Union, -) +import stat +from typing import Mapping, Optional, Union from pcs import settings from pcs.common import reports +from pcs.common.sbd_dto import SbdDeviceStatusDto from pcs.common.services.interfaces import ServiceManagerInterface from pcs.common.types import StringSequence from pcs.common.validate import is_integer @@ -16,10 +14,7 @@ from pcs.lib.corosync.config_facade import ConfigFacade as CorosyncConfFacade from pcs.lib.errors import LibraryError from pcs.lib.external import CommandRunner -from pcs.lib.tools import ( - dict_to_environment_file, - environment_file_to_dict, -) +from pcs.lib.tools import dict_to_environment_file, environment_file_to_dict DEVICE_INITIALIZATION_OPTIONS_MAPPING = { "watchdog-timeout": "-1", @@ -212,7 +207,7 @@ def validate_nodes_devices( reports.messages.SbdDevicePathNotAbsolute(device, node_label) ) for device in device_list - if not device or not path.isabs(device) + if not device or not os.path.isabs(device) ) return report_item_list @@ -341,11 +336,34 @@ def initialize_block_devices( ) +def check_sbd_device_exists( + device: str, +) -> SbdDeviceStatusDto: + """ + Check whether a path exists on the local node and if it is a block device. + + device -- device path to be checked + """ + try: + mode = os.stat(device).st_mode + return SbdDeviceStatusDto( + path=device, + exists=True, + is_block_device=stat.S_ISBLK(mode), + ) + except OSError: + return SbdDeviceStatusDto( + path=device, + exists=False, + is_block_device=False, + ) + + def get_local_sbd_device_list() -> list[str]: """ Returns list of devices specified in local SBD config """ - if not path.exists(settings.sbd_config): + if not os.path.exists(settings.sbd_config): return [] cfg = environment_file_to_dict(get_local_sbd_config()) @@ -403,7 +421,7 @@ def _get_local_sbd_watchdog_timeout() -> int: """ Return the value of SBD_WATCHDOG_TIMEOUT used in local SBD config """ - if not path.exists(settings.sbd_config): + if not os.path.exists(settings.sbd_config): return _DEFAULT_SBD_WATCHDOG_TIMEOUT cfg = environment_file_to_dict(get_local_sbd_config()) diff --git a/pcs/stonith.py b/pcs/stonith.py index 0413857bc..2dbad34f4 100644 --- a/pcs/stonith.py +++ b/pcs/stonith.py @@ -380,18 +380,6 @@ def sbd_watchdog_list(lib: Any, argv: Argv, modifiers: InputModifiers) -> None: print_to_stderr("No available watchdog") -def sbd_watchdog_list_json( - lib: Any, argv: Argv, modifiers: InputModifiers -) -> None: - """ - Options: no options - """ - modifiers.ensure_only_supported() - if argv: - raise CmdLineInputError() - print(json.dumps(lib.sbd.get_local_available_watchdogs())) - - def sbd_watchdog_test(lib: Any, argv: Argv, modifiers: InputModifiers) -> None: """ Options: diff --git a/pcs_test/Makefile.am b/pcs_test/Makefile.am index cb0776d08..9979f04c2 100644 --- a/pcs_test/Makefile.am +++ b/pcs_test/Makefile.am @@ -343,6 +343,7 @@ EXTRA_DIST = \ tier0/lib/commands/resource/test_restart.py \ tier0/lib/commands/resource/test_stop.py \ tier0/lib/commands/sbd/__init__.py \ + tier0/lib/commands/sbd/test_check_sbd.py \ tier0/lib/commands/sbd/test_disable_sbd.py \ tier0/lib/commands/sbd/test_enable_sbd.py \ tier0/lib/commands/sbd/test_get_cluster_sbd_config.py \ diff --git a/pcs_test/tier0/daemon/app/test_api_v0.py b/pcs_test/tier0/daemon/app/test_api_v0.py index 03b9b71f5..f3ce0488c 100644 --- a/pcs_test/tier0/daemon/app/test_api_v0.py +++ b/pcs_test/tier0/daemon/app/test_api_v0.py @@ -22,10 +22,7 @@ TaskKillReason, TaskState, ) -from pcs.common.booth_dto import ( - BoothConfigAndAuthfileDto, - BoothConfigFileDto, -) +from pcs.common.booth_dto import BoothConfigAndAuthfileDto, BoothConfigFileDto from pcs.common.cluster_dto import ( ClusterComponentVersionDto, ClusterDaemonsInfoDto, @@ -44,6 +41,11 @@ PermissionGrantedType, PermissionTargetType, ) +from pcs.common.sbd_dto import ( + SbdCheckResultDto, + SbdDeviceStatusDto, + SbdWatchdogStatusDto, +) from pcs.common.services_dto import ServiceStatusDto from pcs.common.version_dto import VersionDto from pcs.daemon.app import api_v0 @@ -1042,6 +1044,188 @@ def test_failure(self): ) +class CheckSbdHandler(ApiV0HandlerTest): + url = "/remote/check_sbd" + watchdog_path = "/dev/watchdog" + device_path = "/dev/sdb" + + def test_success(self): + result_dto = SbdCheckResultDto( + sbd_service=ServiceStatusDto( + service="sbd", + installed=True, + enabled=True, + running=True, + ), + watchdog=SbdWatchdogStatusDto( + path=self.watchdog_path, + exists=True, + is_supported=True, + ), + device_list=[ + SbdDeviceStatusDto( + path=self.device_path, + exists=True, + is_block_device=True, + ), + ], + ) + self.mock_run_library_command.return_value = self.result_success( + result_dto + ) + response = self.fetch( + self.url, + body=urlencode( + { + "watchdog": self.watchdog_path, + "device_list": json.dumps([self.device_path]), + } + ), + ) + self.assertEqual(response.code, 200) + self.assert_body( + response.body, + json.dumps( + { + "sbd": { + "installed": True, + "enabled": True, + "running": True, + }, + "watchdog": { + "path": self.watchdog_path, + "exist": True, + "is_supported": True, + }, + "device_list": [ + { + "path": self.device_path, + "exist": True, + "block_device": True, + }, + ], + } + ), + ) + self.mock_run_library_command.assert_called_once_with( + "sbd.check_sbd", + dict(watchdog=self.watchdog_path, device_list=[self.device_path]), + ) + + def test_success_diskless_sbd(self): + result_dto = SbdCheckResultDto( + sbd_service=ServiceStatusDto( + service="sbd", + installed=True, + enabled=True, + running=True, + ), + watchdog=SbdWatchdogStatusDto( + path=self.watchdog_path, + exists=True, + is_supported=True, + ), + ) + self.mock_run_library_command.return_value = self.result_success( + result_dto + ) + response = self.fetch( + self.url, + body=urlencode( + { + "watchdog": self.watchdog_path, + } + ), + ) + self.assertEqual(response.code, 200) + self.assert_body( + response.body, + json.dumps( + { + "sbd": { + "installed": True, + "enabled": True, + "running": True, + }, + "watchdog": { + "path": self.watchdog_path, + "exist": True, + "is_supported": True, + }, + } + ), + ) + self.mock_run_library_command.assert_called_once_with( + "sbd.check_sbd", + dict(watchdog=self.watchdog_path, device_list=[]), + ) + + def test_success_default_params(self): + result_dto = SbdCheckResultDto( + sbd_service=ServiceStatusDto( + service="sbd", + installed=True, + enabled=False, + running=False, + ), + ) + self.mock_run_library_command.return_value = self.result_success( + result_dto + ) + response = self.fetch(self.url) + self.assertEqual(response.code, 200) + self.assert_body( + response.body, + json.dumps( + { + "sbd": { + "installed": True, + "enabled": False, + "running": False, + } + } + ), + ) + self.mock_run_library_command.assert_called_once_with( + "sbd.check_sbd", + dict(watchdog="", device_list=[]), + ) + + def test_invalid_device_list_json(self): + response = self.fetch( + self.url, + body=urlencode({"device_list": "not valid json"}), + ) + self.assertEqual(response.code, 400) + self.assert_body(response.body, "Invalid input data format") + self.mock_run_library_command.assert_not_called() + + def test_device_list_not_a_list(self): + response = self.fetch( + self.url, + body=urlencode({"device_list": '"not a list"'}), + ) + self.assertEqual(response.code, 400) + self.assert_body(response.body, "Invalid input data format") + self.mock_run_library_command.assert_not_called() + + def test_device_list_elements_not_strings(self): + response = self.fetch( + self.url, + body=urlencode({"device_list": "[1, null, {}]"}), + ) + self.assertEqual(response.code, 400) + self.assert_body(response.body, "Invalid input data format") + self.mock_run_library_command.assert_not_called() + + def test_failure(self): + self.assert_error_with_report(self.url) + self.mock_run_library_command.assert_called_once_with( + "sbd.check_sbd", + dict(watchdog="", device_list=[]), + ) + + class GetConfigsHandler(ApiV0HandlerTest): url = "/remote/get_configs" request_data = {"cluster_name": "test"} diff --git a/pcs_test/tier0/lib/commands/sbd/test_check_sbd.py b/pcs_test/tier0/lib/commands/sbd/test_check_sbd.py new file mode 100644 index 000000000..630399a02 --- /dev/null +++ b/pcs_test/tier0/lib/commands/sbd/test_check_sbd.py @@ -0,0 +1,177 @@ +import stat +from textwrap import dedent +from unittest import TestCase, mock + +from pcs.common.reports import codes as report_codes +from pcs.common.sbd_dto import ( + SbdCheckResultDto, + SbdDeviceStatusDto, + SbdWatchdogStatusDto, +) +from pcs.common.services_dto import ServiceStatusDto +from pcs.lib.commands.sbd import check_sbd + +from pcs_test.tools import fixture +from pcs_test.tools.command_env import get_env_tools + +WATCHDOG_LIST_OUTPUT = dedent( + """ + Discovered 2 watchdog devices: + + [1] /dev/watchdog + Identity: i6300ESB timer + Driver: + + [2] /dev/watchdog1 + Identity: iTCO_wdt + Driver: iTCO_wdt + """ +) + + +class TestCheckSbdServiceOnly(TestCase): + def setUp(self): + self.env_assist, self.config = get_env_tools(self) + + def test_all_true(self): + self.config.services.is_installed("sbd", return_value=True) + self.config.services.is_enabled("sbd", return_value=True) + self.config.services.is_running("sbd", return_value=True) + result = check_sbd(self.env_assist.get_env()) + self.assertEqual( + result, + SbdCheckResultDto( + sbd_service=ServiceStatusDto( + service="sbd", + installed=True, + enabled=True, + running=True, + ), + ), + ) + + def test_not_installed(self): + self.config.services.is_installed("sbd", return_value=False) + self.config.services.is_enabled("sbd", return_value=False) + self.config.services.is_running("sbd", return_value=False) + result = check_sbd(self.env_assist.get_env()) + self.assertEqual( + result, + SbdCheckResultDto( + sbd_service=ServiceStatusDto( + service="sbd", + installed=False, + enabled=False, + running=False, + ), + ), + ) + + def test_installed_not_enabled_not_running(self): + self.config.services.is_installed("sbd", return_value=True) + self.config.services.is_enabled("sbd", return_value=False) + self.config.services.is_running("sbd", return_value=False) + result = check_sbd(self.env_assist.get_env()) + self.assertEqual( + result, + SbdCheckResultDto( + sbd_service=ServiceStatusDto( + service="sbd", + installed=True, + enabled=False, + running=False, + ), + ), + ) + + +class TestCheckSbdWatchdog(TestCase): + def setUp(self): + self.env_assist, self.config = get_env_tools(self) + self.config.services.is_installed("sbd", return_value=True) + self.config.services.is_enabled("sbd", return_value=True) + self.config.services.is_running("sbd", return_value=True) + + def test_watchdog_exists(self): + self.config.runner.sbd.list_watchdogs(WATCHDOG_LIST_OUTPUT) + result = check_sbd(self.env_assist.get_env(), watchdog="/dev/watchdog") + self.assertEqual( + result.watchdog, + SbdWatchdogStatusDto( + path="/dev/watchdog", + exists=True, + is_supported=True, + ), + ) + + def test_watchdog_not_exists(self): + self.config.runner.sbd.list_watchdogs(WATCHDOG_LIST_OUTPUT) + result = check_sbd( + self.env_assist.get_env(), watchdog="/dev/nonexistent" + ) + self.assertEqual( + result.watchdog, + SbdWatchdogStatusDto( + path="/dev/nonexistent", + exists=False, + is_supported=False, + ), + ) + + def test_empty_watchdog_skips_check(self): + result = check_sbd(self.env_assist.get_env(), watchdog="") + self.assertIsNone(result.watchdog) + + def test_watchdog_query_failure(self): + reason = "some error" + self.config.runner.sbd.list_watchdogs("", stderr=reason, returncode=1) + self.env_assist.assert_raise_library_error( + lambda: check_sbd( + self.env_assist.get_env(), watchdog="/dev/watchdog" + ), + [ + fixture.error( + report_codes.SBD_LIST_WATCHDOG_ERROR, + reason=reason, + ), + ], + expected_in_processor=False, + ) + + +class TestCheckSbdDeviceList(TestCase): + def setUp(self): + self.env_assist, self.config = get_env_tools(self) + self.config.services.is_installed("sbd", return_value=True) + self.config.services.is_enabled("sbd", return_value=True) + self.config.services.is_running("sbd", return_value=True) + + @mock.patch("pcs.lib.sbd.os.stat") + def test_multiple_devices(self, mock_stat): + mock_stat.side_effect = [ + mock.Mock(st_mode=stat.S_IFBLK | 0o660), + OSError(), + mock.Mock(st_mode=stat.S_IFREG | 0o644), + ] + result = check_sbd( + self.env_assist.get_env(), + device_list=["/dev/sdb", "/dev/sdc", "/dev/sdd"], + ) + self.assertEqual( + result.device_list, + [ + SbdDeviceStatusDto( + path="/dev/sdb", exists=True, is_block_device=True + ), + SbdDeviceStatusDto( + path="/dev/sdc", exists=False, is_block_device=False + ), + SbdDeviceStatusDto( + path="/dev/sdd", exists=True, is_block_device=False + ), + ], + ) + + def test_empty_device_list(self): + result = check_sbd(self.env_assist.get_env(), device_list=[]) + self.assertIsNone(result.device_list) diff --git a/pcsd/remote.rb b/pcsd/remote.rb index 0a6337b73..1e91afebe 100644 --- a/pcsd/remote.rb +++ b/pcsd/remote.rb @@ -34,7 +34,6 @@ def remote(params, request, auth_user) :cluster_destroy => method(:cluster_destroy), :get_cluster_known_hosts => method(:get_cluster_known_hosts), :get_cluster_properties_definition => method(:get_cluster_properties_definition), - :check_sbd => method(:check_sbd), :sbd_disable => method(:sbd_disable), :sbd_enable => method(:sbd_enable), :remove_stonith_watchdog_timeout=> method(:remove_stonith_watchdog_timeout), @@ -1077,59 +1076,6 @@ def get_cluster_properties_definition(params, request, auth_user) return [400, '{}'] end -def check_sbd(param, request, auth_user) - unless allowed_for_local_cluster(auth_user, Permissions::READ) - return 403, 'Permission denied' - end - service_checker = ServiceChecker.new( - [SBD_SERVICE_NAME], installed: true, enabled: true, running: true - ) - out = { - :sbd => service_checker.get_info(SBD_SERVICE_NAME), - } - watchdog = param[:watchdog] - if not watchdog.to_s.empty? - stdout, stderr, ret_val = run_cmd( - auth_user, PCS, '--', 'stonith', 'sbd', 'watchdog', 'list_json' - ) - if ret_val != 0 - return [400, "Unable to get list of watchdogs: #{stderr.join("\n")}"] - end - begin - available_watchdogs = JSON.parse(stdout.join("\n")) - exists = available_watchdogs.include?(watchdog) - out[:watchdog] = { - :path => watchdog, - :exist => exists, - :is_supported => ( - # this method is not reliable so all watchdog devices listed by SBD - # will be listed as supported for now - # exists and available_watchdogs[watchdog]['caution'] == nil - exists - ), - } - rescue JSON::ParserError - return [400, "Unable to get list of watchdogs: unable to parse JSON"] - end - end - begin - device_list = JSON.parse(param[:device_list]) - if device_list and device_list.respond_to?('each') - out[:device_list] = [] - device_list.each { |device| - out[:device_list] << { - :path => device, - :exist => File.exist?(device), - :block_device => File.blockdev?(device), - } - } - end - rescue JSON::ParserError - return [400, 'Invalid input data format'] - end - return [200, JSON.generate(out)] -end - def sbd_disable(param, request, auth_user) unless allowed_for_local_cluster(auth_user, Permissions::WRITE) return 403, 'Permission denied'