]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/cephadm/services/nfs.py
2 from typing
import TYPE_CHECKING
, Dict
, Tuple
, Any
, List
4 from ceph
.deployment
.service_spec
import NFSServiceSpec
7 from orchestrator
import OrchestratorError
, DaemonDescription
9 from cephadm
import utils
10 from cephadm
.services
.cephadmservice
import AuthEntity
, CephadmDaemonSpec
, CephService
13 from cephadm
.module
import CephadmOrchestrator
15 logger
= logging
.getLogger(__name__
)
18 class NFSService(CephService
):
21 def config(self
, spec
: NFSServiceSpec
) -> None:
22 assert self
.TYPE
== spec
.service_type
23 self
.mgr
._check
_pool
_exists
(spec
.pool
, spec
.service_name())
25 logger
.info('Saving service %s spec with placement %s' % (
26 spec
.service_name(), spec
.placement
.pretty_str()))
27 self
.mgr
.spec_store
.save(spec
)
29 def prepare_create(self
, daemon_spec
: CephadmDaemonSpec
[NFSServiceSpec
]) -> CephadmDaemonSpec
:
30 assert self
.TYPE
== daemon_spec
.daemon_type
31 assert daemon_spec
.spec
33 daemon_id
= daemon_spec
.daemon_id
34 host
= daemon_spec
.host
35 spec
= daemon_spec
.spec
37 logger
.info('Create daemon %s on host %s with spec %s' % (
38 daemon_id
, host
, spec
))
41 def generate_config(self
, daemon_spec
: CephadmDaemonSpec
[NFSServiceSpec
]) -> Tuple
[Dict
[str, Any
], List
[str]]:
42 assert self
.TYPE
== daemon_spec
.daemon_type
43 assert daemon_spec
.spec
45 daemon_type
= daemon_spec
.daemon_type
46 daemon_id
= daemon_spec
.daemon_id
47 host
= daemon_spec
.host
48 spec
= daemon_spec
.spec
52 # create the RADOS recovery pool keyring
53 rados_user
= f
'{daemon_type}.{daemon_id}'
54 rados_keyring
= self
.create_keyring(daemon_spec
)
56 # create the rados config object
57 self
.create_rados_config_obj(spec
)
59 # create the RGW keyring
60 rgw_user
= f
'{rados_user}-rgw'
61 rgw_keyring
= self
.create_rgw_keyring(daemon_spec
)
63 # generate the ganesha config
64 def get_ganesha_conf() -> str:
65 context
= dict(user
=rados_user
,
66 nodeid
=daemon_spec
.name(),
68 namespace
=spec
.namespace
if spec
.namespace
else '',
70 url
=spec
.rados_config_location())
71 return self
.mgr
.template
.render('services/nfs/ganesha.conf.j2', context
)
73 # generate the cephadm config json
74 def get_cephadm_config() -> Dict
[str, Any
]:
75 config
: Dict
[str, Any
] = {}
76 config
['pool'] = spec
.pool
78 config
['namespace'] = spec
.namespace
79 config
['userid'] = rados_user
80 config
['extra_args'] = ['-N', 'NIV_EVENT']
82 'ganesha.conf': get_ganesha_conf(),
85 self
.get_config_and_keyring(
86 daemon_type
, daemon_id
,
87 keyring
=rados_keyring
,
94 'keyring': rgw_keyring
,
96 logger
.debug('Generated cephadm config-json: %s' % config
)
99 return get_cephadm_config(), deps
101 def create_rados_config_obj(self
,
102 spec
: NFSServiceSpec
,
103 clobber
: bool = False) -> None:
104 with self
.mgr
.rados
.open_ioctx(spec
.pool
) as ioctx
:
106 ioctx
.set_namespace(spec
.namespace
)
108 obj
= spec
.rados_config_name()
112 except rados
.ObjectNotFound
as e
:
115 if exists
and not clobber
:
116 # Assume an existing config
117 logger
.info('Rados config object exists: %s' % obj
)
119 # Create an empty config object
120 logger
.info('Creating rados config object: %s' % obj
)
121 ioctx
.write_full(obj
, ''.encode('utf-8'))
123 def create_keyring(self
, daemon_spec
: CephadmDaemonSpec
[NFSServiceSpec
]) -> str:
124 assert daemon_spec
.spec
125 daemon_id
= daemon_spec
.daemon_id
126 spec
= daemon_spec
.spec
127 entity
: AuthEntity
= self
.get_auth_entity(daemon_id
)
129 osd_caps
= 'allow rw pool=%s' % (spec
.pool
)
131 osd_caps
= '%s namespace=%s' % (osd_caps
, spec
.namespace
)
133 logger
.info('Create keyring: %s' % entity
)
134 ret
, keyring
, err
= self
.mgr
.check_mon_command({
135 'prefix': 'auth get-or-create',
137 'caps': ['mon', 'allow r',
143 def create_rgw_keyring(self
, daemon_spec
: CephadmDaemonSpec
[NFSServiceSpec
]) -> str:
144 daemon_id
= daemon_spec
.daemon_id
145 entity
: AuthEntity
= self
.get_auth_entity(f
'{daemon_id}-rgw')
147 logger
.info('Create keyring: %s' % entity
)
148 ret
, keyring
, err
= self
.mgr
.check_mon_command({
149 'prefix': 'auth get-or-create',
151 'caps': ['mon', 'allow r',
152 'osd', 'allow rwx tag rgw *=*'],
157 def remove_rgw_keyring(self
, daemon
: DaemonDescription
) -> None:
158 daemon_id
: str = daemon
.daemon_id
159 entity
: AuthEntity
= self
.get_auth_entity(f
'{daemon_id}-rgw')
161 logger
.info(f
'Remove keyring: {entity}')
162 ret
, out
, err
= self
.mgr
.check_mon_command({
167 def post_remove(self
, daemon
: DaemonDescription
) -> None:
168 super().post_remove(daemon
)
169 self
.remove_rgw_keyring(daemon
)