Skip to content

Commit 27fa5c7

Browse files
ShwetaBhosale1adk3798
authored andcommitted
mgr/cephadm: while updating nfs kmip certs do not restart service instead send SIGHUP to ganesha service
Signed-off-by: Shweta Bhosale <[email protected]> (cherry picked from commit c99d6c6) Conflicts: src/cephadm/cephadm.py src/pybind/mgr/cephadm/module.py src/pybind/mgr/cephadm/serve.py src/pybind/mgr/cephadm/services/nfs.py src/pybind/mgr/cephadm/templates/services/nfs/ganesha.conf.j2 Resolves: rhbz#2373703
1 parent 6ade282 commit 27fa5c7

File tree

10 files changed

+121
-15
lines changed

10 files changed

+121
-15
lines changed

src/cephadm/cephadm.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,10 +1147,14 @@ def deploy_daemon(
11471147
# If this was a reconfig and the daemon is not a Ceph daemon, restart it
11481148
# so it can pick up potential changes to its configuration files
11491149
if deployment_type == DeploymentType.RECONFIG and daemon_type not in ceph_daemons():
1150-
# ceph daemons do not need a restart; others (presumably) do to pick
1151-
# up the new config
1152-
call_throws(ctx, ['systemctl', 'reset-failed', ident.unit_name])
1153-
call_throws(ctx, ['systemctl', 'restart', ident.unit_name])
1150+
if not ctx.skip_restart:
1151+
# ceph daemons do not need a restart; others (presumably) do to pick
1152+
# up the new config
1153+
call_throws(ctx, ['systemctl', 'reset-failed', ident.unit_name])
1154+
call_throws(ctx, ['systemctl', 'restart', ident.unit_name])
1155+
else:
1156+
# perform default action
1157+
daemon_form_create(ctx, ident).perform_default_restart()
11541158

11551159

11561160
def clean_cgroup(ctx: CephadmContext, fsid: str, unit_name: str) -> None:
@@ -5264,6 +5268,12 @@ def _add_deploy_parser_args(
52645268
default=False,
52655269
help='Set LimitCORE=infinity in ceph unit files'
52665270
)
5271+
parser_deploy.add_argument(
5272+
'--skip-restart',
5273+
action='store_true',
5274+
default=False,
5275+
help='skip restart for non ceph daemons and perform default action'
5276+
)
52675277

52685278

52695279
def _get_parser():

src/cephadm/cephadmlib/daemon_form.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ def identity(self) -> DaemonIdentity:
4444
"""
4545
raise NotImplementedError() # pragma: no cover
4646

47+
def perform_default_restart(self) -> int:
48+
return 0
49+
4750

4851
DF = TypeVar('DF', bound=DaemonForm)
4952

src/cephadm/cephadmlib/daemons/nfs.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import logging
22
import os
33
import re
4-
4+
import signal
5+
import subprocess
56
from typing import Dict, List, Optional, Tuple, Union
67

78
from ..call_wrappers import call, CallVerbosity
@@ -236,3 +237,25 @@ def customize_container_args(
236237

237238
def default_entrypoint(self) -> str:
238239
return self.entrypoint
240+
241+
def perform_default_restart(self) -> int:
242+
pid = None
243+
try:
244+
output = subprocess.check_output(['pidof', 'ganesha.nfsd'])
245+
pid = int(output.strip())
246+
except subprocess.CalledProcessError:
247+
return 1
248+
if pid:
249+
logger.debug(
250+
f'Sending SIGHUP signal to ganesha.nfsd process, pid: {pid}'
251+
)
252+
try:
253+
os.kill(pid, signal.SIGHUP)
254+
except Exception:
255+
logger.error(
256+
f'Not able to send SIGHUP signal to ganesha.nfsd process, pid: {pid}'
257+
)
258+
return 1
259+
return 0
260+
logger.error('Process ganesha.nfsd not found.')
261+
return 1

src/pybind/mgr/cephadm/module.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,7 +2685,8 @@ def _daemon_action(self,
26852685
daemon_spec: CephadmDaemonDeploySpec,
26862686
action: str,
26872687
image: Optional[str] = None,
2688-
spec: Optional[ServiceSpec] = None) -> str:
2688+
spec: Optional[ServiceSpec] = None,
2689+
skip_restart: bool = False) -> str:
26892690
self._daemon_action_set_image(action, image, daemon_spec.daemon_type,
26902691
daemon_spec.daemon_id)
26912692

@@ -2711,7 +2712,7 @@ def _daemon_action(self,
27112712
daemon_spec)
27122713
with self.async_timeout_handler(daemon_spec.host, f'cephadm deploy ({daemon_spec.daemon_type} daemon)'):
27132714
successes, failures = self.wait_async(
2714-
CephadmServe(self)._create_daemon([daemon_spec], reconfig=(action == 'reconfig')))
2715+
CephadmServe(self)._create_daemon([daemon_spec], reconfig=(action == 'reconfig'), skip_restart=skip_restart))
27152716
# we're only deploying one daemon here, so we expect successes or failures to container one entry
27162717
for res in [successes, failures]:
27172718
if daemon_spec.name() in res:

src/pybind/mgr/cephadm/serve.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,7 @@ def _check_daemons(self) -> None:
13421342
if last_deps is None:
13431343
last_deps = []
13441344
action = self.mgr.cache.get_scheduled_daemon_action(dd.hostname, dd.name())
1345+
skip_restart = False
13451346
if not last_config:
13461347
self.log.info('Reconfiguring %s (unknown last config time)...' % (
13471348
dd.name()))
@@ -1357,6 +1358,13 @@ def _check_daemons(self) -> None:
13571358
REDEPLOY_TRIGGERS = ['secure_monitoring_stack', 'mgmt-gateway']
13581359
if any(svc in e for e in diff for svc in REDEPLOY_TRIGGERS):
13591360
action = 'redeploy'
1361+
elif dd.daemon_type == 'nfs':
1362+
# check what has changed, based on that decide action
1363+
only_kmip_updated = all(s.startswith('kmip') for s in list(sym_diff))
1364+
if not only_kmip_updated:
1365+
action = 'redeploy'
1366+
else:
1367+
skip_restart = True
13601368

13611369
elif spec is not None and hasattr(spec, 'extra_container_args') and dd.extra_container_args != spec.extra_container_args:
13621370
self.log.debug(
@@ -1385,7 +1393,7 @@ def _check_daemons(self) -> None:
13851393
action = 'redeploy'
13861394
try:
13871395
daemon_spec = CephadmDaemonDeploySpec.from_daemon_description(dd)
1388-
self.mgr._daemon_action(daemon_spec, action=action, spec=spec)
1396+
self.mgr._daemon_action(daemon_spec, action=action, spec=spec, skip_restart=skip_restart)
13891397
if self.mgr.cache.rm_scheduled_daemon_action(dd.hostname, dd.name()):
13901398
self.mgr.cache.save_host(dd.hostname)
13911399
except OrchestratorError as e:
@@ -1565,6 +1573,7 @@ async def _create_daemon(self,
15651573
daemon_specs: List[CephadmDaemonDeploySpec],
15661574
reconfig: bool = False,
15671575
osd_uuid_map: Optional[Dict[str, Any]] = None,
1576+
skip_restart: bool = False
15681577
) -> Tuple[Dict[str, str], Dict[str, str]]:
15691578

15701579
exchanges: List[exchange.Deploy] = []
@@ -1610,6 +1619,8 @@ async def _create_daemon(self,
16101619
daemon_params['allow_ptrace'] = True
16111620
if self.mgr.set_coredump_overrides:
16121621
daemon_params['limit_core_infinity'] = True
1622+
if skip_restart:
1623+
daemon_params['skip_restart'] = True
16131624

16141625
daemon_spec, extra_container_args, extra_entrypoint_args = self._setup_extra_deployment_args(daemon_spec, daemon_params)
16151626
init_containers = self._setup_init_containers(daemon_spec, daemon_params)

src/pybind/mgr/cephadm/service_discovery.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Server: # type: ignore
1212
from mgr_module import ServiceInfoT
1313
from mgr_util import build_url
1414
from typing import Dict, List, TYPE_CHECKING, cast, Collection, Callable, NamedTuple, Optional, IO
15-
from cephadm.services.nfs import NFSService
15+
1616
from cephadm.services.smb import SMBService
1717
from cephadm.services.monitoring import AlertmanagerService, NodeExporterService, PrometheusService
1818
import secrets
@@ -265,6 +265,7 @@ def nvmeof_sd_config(self) -> List[Dict[str, Collection[str]]]:
265265
def nfs_sd_config(self) -> List[Dict[str, Collection[str]]]:
266266
"""Return <http_sd_config> compatible prometheus config for nfs service."""
267267
srv_entries = []
268+
from cephadm.services.nfs import NFSService
268269
for dd in self.mgr.cache.get_daemons_by_type('nfs'):
269270
assert dd.hostname is not None
270271
nfs = cast(NFSService, service_registry.get_service('nfs'))

src/pybind/mgr/cephadm/services/nfs.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import os
55
import subprocess
66
import tempfile
7-
from typing import Dict, Tuple, Any, List, cast, Optional
7+
from typing import Dict, Tuple, Any, List, cast, Optional, TYPE_CHECKING
88
from configparser import ConfigParser
99
from io import StringIO
1010

@@ -17,6 +17,8 @@
1717
from orchestrator import DaemonDescription, OrchestratorError
1818

1919
from cephadm.services.cephadmservice import AuthEntity, CephadmDaemonDeploySpec, CephService
20+
if TYPE_CHECKING:
21+
from ..module import CephadmOrchestrator
2022

2123
logger = logging.getLogger(__name__)
2224

@@ -72,6 +74,25 @@ def get_daemon_nodeid(self, service_name: str, rank: Optional[int]) -> str:
7274
return f'{service_name}.{rank}'
7375
return str(rank)
7476

77+
@classmethod
78+
def get_dependencies(
79+
cls,
80+
mgr: "CephadmOrchestrator",
81+
spec: Optional[ServiceSpec] = None,
82+
daemon_type: Optional[str] = None
83+
) -> List[str]:
84+
deps: List[str] = []
85+
if not spec:
86+
return deps
87+
nfs_spec = cast(NFSServiceSpec, spec)
88+
if (nfs_spec.kmip_cert and nfs_spec.kmip_key and nfs_spec.kmip_ca_cert and nfs_spec.kmip_host_list):
89+
# add dependency of kmip fields
90+
deps.append(f'kmip_cert: {nfs_spec.kmip_cert}')
91+
deps.append(f'kmip_key: {nfs_spec.kmip_key}')
92+
deps.append(f'kmip_ca_cert: {nfs_spec.kmip_ca_cert}')
93+
deps.append(f'kmip_host_list: {nfs_spec.kmip_host_list}')
94+
return deps
95+
7596
def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]:
7697
assert self.TYPE == daemon_spec.daemon_type
7798

@@ -80,8 +101,6 @@ def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[st
80101
host = daemon_spec.host
81102
spec = cast(NFSServiceSpec, self.mgr.spec_store[daemon_spec.service_name].spec)
82103

83-
deps: List[str] = []
84-
85104
nodeid = self.get_daemon_nodeid(spec.service_name(), daemon_spec.rank)
86105

87106
nfs_idmap_conf = '/etc/ganesha/idmap.conf'
@@ -199,7 +218,7 @@ def get_cephadm_config() -> Dict[str, Any]:
199218
logger.debug('Generated cephadm config-json: %s' % config)
200219
return config
201220

202-
return get_cephadm_config(), deps
221+
return get_cephadm_config(), sorted(self.get_dependencies(self.mgr, spec))
203222

204223
def create_rados_config_obj(self,
205224
spec: NFSServiceSpec,

src/pybind/mgr/cephadm/templates/services/nfs/ganesha.conf.j2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Ceph {
5454
{% endif %}
5555

5656
{% if kmip_addrs %}
57+
5758
KMIP {
5859
HOST {
5960
{% for kmip_addr in kmip_addrs %}

src/pybind/mgr/cephadm/tests/test_services.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,6 +3748,45 @@ def test_nfs_config_bind_addr(self, _run_cephadm, cephadm_module: CephadmOrchest
37483748
assert "Bind_addr = 1.2.3.7" in ganesha_conf
37493749

37503750

3751+
class TestNFS:
3752+
@patch("cephadm.serve.CephadmServe._run_cephadm")
3753+
@patch("cephadm.services.nfs.NFSService.fence_old_ranks", MagicMock())
3754+
@patch("cephadm.services.nfs.NFSService.run_grace_tool", MagicMock())
3755+
@patch("cephadm.services.nfs.NFSService.purge", MagicMock())
3756+
@patch("cephadm.services.nfs.NFSService.create_rados_config_obj", MagicMock())
3757+
def test_nfs_byok_config(self, _run_cephadm, cephadm_module: CephadmOrchestrator):
3758+
_run_cephadm.side_effect = async_side_effect(('{}', '', 0))
3759+
3760+
with with_host(cephadm_module, 'test', addr='1.2.3.7'):
3761+
cephadm_module.cache.update_host_networks('test', {
3762+
'1.2.3.0/24': {
3763+
'if0': ['1.2.3.1']
3764+
}
3765+
})
3766+
3767+
nfs_spec = NFSServiceSpec(service_id="foo", placement=PlacementSpec(hosts=['test']),
3768+
kmip_cert='kmip_cert', kmip_key='kmip_key',
3769+
kmip_ca_cert='kmip_ca_cert', kmip_host_list=['test'])
3770+
with with_service(cephadm_module, nfs_spec) as _:
3771+
nfs_generated_conf, _ = service_registry.get_service('nfs').generate_config(
3772+
CephadmDaemonDeploySpec(host='test', daemon_id='foo.test.0.0', service_name=nfs_spec.service_name()))
3773+
ganesha_conf = nfs_generated_conf['files']['ganesha.conf']
3774+
expected_kmip_block = (
3775+
'KMIP {\n'
3776+
' HOST {\n'
3777+
' addr = test;\n'
3778+
' }\n'
3779+
' cert = /etc/ganesha/kmip/kmip_cert.pem;\n'
3780+
' key = /etc/ganesha/kmip/kmip_key.pem;\n'
3781+
' ca = /etc/ganesha/kmip/kmip_ca_cert.pem;\n'
3782+
'}\n'
3783+
)
3784+
assert expected_kmip_block in ganesha_conf
3785+
assert nfs_generated_conf['files']['kmip_cert.pem'] == 'kmip_cert'
3786+
assert nfs_generated_conf['files']['kmip_key.pem'] == 'kmip_key'
3787+
assert nfs_generated_conf['files']['kmip_ca_cert.pem'] == 'kmip_ca_cert'
3788+
3789+
37513790
class TestCephFsMirror:
37523791
@patch("cephadm.serve.CephadmServe._run_cephadm")
37533792
def test_config(self, _run_cephadm, cephadm_module: CephadmOrchestrator):

src/python-common/ceph/deployment/service_spec.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
import fnmatch
42
import os
53
import re

0 commit comments

Comments
 (0)