1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-10-28 19:54:55 +03:00

Check dirs permissions only when not in container

This commit is contained in:
Alexander Presnyakov
2025-10-13 16:57:20 +00:00
parent c766fc2ff9
commit e8244ff63f
7 changed files with 101 additions and 100 deletions

View File

@@ -29,7 +29,7 @@ from cmapi_server.failover_agent import FailoverAgent
from cmapi_server.managers.application import AppManager
from cmapi_server.managers.process import MCSProcessManager
from cmapi_server.managers.certificate import CertificateManager
from cmapi_server.state_checks import run_state_checks
from cmapi_server.invariant_checks import run_invariant_checks
from failover.node_monitor import NodeMonitor
from mcs_node_control.models.dbrm_socket import SOCK_TIMEOUT, DBRMSocketHandler
from mcs_node_control.models.node_config import NodeConfig
@@ -153,7 +153,7 @@ if __name__ == '__main__':
CertificateManager.renew_certificate()
# Run checks, if some of them fail -- log and exit
run_state_checks()
run_invariant_checks()
app = cherrypy.tree.mount(root=None, config=CMAPI_CONF_PATH)
root_config = {

View File

@@ -0,0 +1,95 @@
import logging
import os
import sys
from mr_kot import Runner, RunResult, Status, check, check_all, fact, parametrize
from mr_kot_fs_validators import GroupIs, HasMode, IsDir, OwnerIs
from cmapi_server import helpers
from cmapi_server.constants import MCS_DATA_PATH
from mcs_node_control.models.node_config import NodeConfig
logger = logging.getLogger(__name__)
def run_invariant_checks() -> RunResult:
"""Run invariant checks, log warnings/errors/failures, and exit the process on failure/error.
"""
logger.info('Starting invariant checks')
try:
runner = Runner()
result = runner.run()
except Exception:
logger.exception('Got unexpected exception while checking invariants')
sys.exit(1)
# Log each fail/error/warning for diagnostics
for item in result.items:
if item.status in (Status.FAIL, Status.ERROR, Status.WARN):
fn = logger.warning if item.status == Status.WARN else logger.error
fn(
'Invariant check with id=%s produced %s: %r',
item.id, item.status, item.evidence,
)
logger.info('Stats: overall=%s counts=%s', result.overall, {k.value: v for k, v in result.counts.items() if v != 0})
if result.overall in (Status.FAIL, Status.ERROR):
logger.error('Invariant checks failed, exiting')
sys.exit(1)
else:
logger.info('Invariant checks passed')
return result
### Facts
@fact
def storage_type() -> str:
"""Provides storage type: shared_fs or s3."""
return 's3' if NodeConfig().s3_enabled() else 'shared_fs'
@fact
def is_shared_fs(storage_type: str) -> bool:
return storage_type == 'shared_fs'
@fact
def dispatcher_name() -> str:
"""Provides environment dispatcher name: systemd or container"""
cfg = helpers.get_config_parser()
name, _ = helpers.get_dispatcher_name_and_path(cfg)
return name
@fact
def is_systemd_disp(dispatcher_name: str) -> bool:
return dispatcher_name == 'systemd'
### Checks
REQUIRED_LOCAL_DIRS = [
os.path.join(MCS_DATA_PATH, 'data1'),
os.path.join(MCS_DATA_PATH, 'data1', 'systemFiles'),
os.path.join(MCS_DATA_PATH, 'data1', 'systemFiles', 'dbrm'),
]
@check(selector='is_shared_fs')
@parametrize('dir', values=REQUIRED_LOCAL_DIRS, fail_fast=True)
def required_dirs_perms(dir: str) -> tuple[Status, str]:
status, ev = check_all(
dir,
IsDir(),
HasMode('1755'),
)
return (status, ev)
@check(selector='is_shared_fs, is_systemd_disp')
@parametrize('dir', values=REQUIRED_LOCAL_DIRS, fail_fast=True)
def required_dirs_ownership(dir: str) -> tuple[Status, str]:
# Check ownership only when not in containers
status, ev = check_all(
dir,
OwnerIs('mysql'),
GroupIs('mysql'),
)
return (status, ev)

View File

@@ -1,25 +0,0 @@
[tool.ruff]
line-length = 80
target-version = "py39"
# Enable common rule sets
select = [
"E", # pycodestyle errors
"F", # pyflakes: undefined names, unused imports, etc.
"I", # isort: import sorting
"B", # flake8-bugbear: common bugs and anti-patterns
"UP", # pyupgrade: use modern Python syntax
"N", # pep8-naming: naming conventions
]
ignore = []
# Exclude cache and temporary directories
exclude = [
"__pycache__",
]
[tool.ruff.format]
quote-style = "single"
[tool.ruff.lint.isort]
force-single-line = false

View File

@@ -1,70 +0,0 @@
from __future__ import annotations
import logging
import os
import sys
from mcs_node_control.models.node_config import NodeConfig
from mr_kot import Status, check, check_all, fact, parametrize
from mr_kot.runner import Runner, RunResult
from mr_kot_fs_validators import GroupIs, HasMode, IsDir, OwnerIs
from cmapi_server.constants import MCS_DATA_PATH
logger = logging.getLogger(__name__)
def run_state_checks(*, verbose: bool = False) -> RunResult:
"""Run state checks, log warnings/errors/failures, and exit the process on failure/error.
"""
logger.info("Starting invariant checks")
try:
runner = Runner(verbose=verbose, include_tags=True)
result = runner.run()
except Exception:
logger.exception('Unexpected exception during state checks')
sys.exit(1)
# Log each fail/error/warning for diagnostics
for item in result.items:
if item.status in (Status.FAIL, Status.ERROR, Status.WARN):
logger.error(
'State check with id=%s produced %s: %r',
item.id, item.status, item.evidence,
)
logger.info('Stats: overall=%s counts=%s', result.overall, {k.value: v for k, v in result.counts.items() if v != 0})
if result.overall in (Status.FAIL, Status.ERROR):
logger.error('State check failed, exiting')
sys.exit(1)
return result
@fact
def storage_type() -> str:
"""Provides storage type: shared_fs or s3."""
return 's3' if NodeConfig().s3_enabled() else 'shared_fs'
@fact
def is_shared_fs(storage_type: str) -> bool:
return storage_type == 'shared_fs'
@check(selector='is_shared_fs')
@parametrize(
'required_local_dir',
values=[
os.path.join(MCS_DATA_PATH, 'data1'),
os.path.join(MCS_DATA_PATH, 'data1', 'systemFiles'),
os.path.join(MCS_DATA_PATH, 'data1', 'systemFiles', 'dbrm'),
],
fail_fast=True,
)
def required_dirs_fs_state(required_local_dir: str) -> tuple[Status, str]:
status, ev = check_all(
required_local_dir,
IsDir(),
HasMode('1755'),
OwnerIs('mysql'),
GroupIs('mysql'),
)
return (status, ev)

View File

@@ -23,6 +23,7 @@ exclude = [
quote-style = "single"
[tool.ruff.lint.isort]
known-first-party = ["cmapi_server", "failover", "mcs_node_control", "tracing"]
force-single-line = false
combine-as-imports = true

View File

@@ -18,6 +18,6 @@ Routes==2.5.1
typer==0.15.2
pydantic==2.11.7
sentry-sdk==2.34.1
# State checks
mr_kot==0.8.1
# Invariant checks
mr_kot==0.8.3
mr_kot_fs_validators==0.1.0

View File

@@ -144,7 +144,7 @@ more-itertools==10.7.0
# cherrypy
# jaraco-functools
# jaraco-text
mr-kot==0.8.1
mr-kot==0.8.3
# via -r requirements.in
mr-kot-fs-validators==0.1.0
# via -r requirements.in