]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/cephadm/nfs.py
1c0a45200ec73ca0b5517e95371a7290b8d7a9ed
[ceph.git] / ceph / src / pybind / mgr / cephadm / nfs.py
1 import logging
2 import rados
3
4 from typing import Dict, Optional
5
6 from ceph.deployment.service_spec import NFSServiceSpec
7
8 import cephadm
9 from orchestrator import OrchestratorError
10
11 from . import utils
12
13 logger = logging.getLogger(__name__)
14
15 class NFSGanesha(object):
16 def __init__(self,
17 mgr,
18 daemon_id,
19 spec):
20 # type: (cephadm.CephadmOrchestrator, str, NFSServiceSpec) -> None
21 assert spec.service_id and daemon_id.startswith(spec.service_id)
22 self.mgr = mgr
23 self.daemon_id = daemon_id
24 self.spec = spec
25
26 def get_daemon_name(self):
27 # type: () -> str
28 return '%s.%s' % (self.spec.service_type, self.daemon_id)
29
30 def get_rados_user(self):
31 # type: () -> str
32 return '%s.%s' % (self.spec.service_type, self.daemon_id)
33
34 def get_keyring_entity(self):
35 # type: () -> str
36 return utils.name_to_config_section(self.get_rados_user())
37
38 def get_or_create_keyring(self, entity=None):
39 # type: (Optional[str]) -> str
40 if not entity:
41 entity = self.get_keyring_entity()
42
43 logger.info('Create keyring: %s' % entity)
44 ret, keyring, err = self.mgr.mon_command({
45 'prefix': 'auth get-or-create',
46 'entity': entity,
47 })
48
49 if ret != 0:
50 raise OrchestratorError(
51 'Unable to create keyring %s: %s %s' \
52 % (entity, ret, err))
53 return keyring
54
55 def update_keyring_caps(self, entity=None):
56 # type: (Optional[str]) -> None
57 if not entity:
58 entity = self.get_keyring_entity()
59
60 osd_caps='allow rw pool=%s' % (self.spec.pool)
61 if self.spec.namespace:
62 osd_caps='%s namespace=%s' % (osd_caps, self.spec.namespace)
63
64 logger.info('Updating keyring caps: %s' % entity)
65 ret, out, err = self.mgr.mon_command({
66 'prefix': 'auth caps',
67 'entity': entity,
68 'caps': ['mon', 'allow r',
69 'osd', osd_caps,
70 'mds', 'allow rw'],
71 })
72
73 if ret != 0:
74 raise OrchestratorError(
75 'Unable to update keyring caps %s: %s %s' \
76 % (entity, ret, err))
77
78 def create_rados_config_obj(self, clobber=False):
79 # type: (Optional[bool]) -> None
80 obj = self.spec.rados_config_name()
81
82 with self.mgr.rados.open_ioctx(self.spec.pool) as ioctx:
83 if self.spec.namespace:
84 ioctx.set_namespace(self.spec.namespace)
85
86 exists = True
87 try:
88 ioctx.stat(obj)
89 except rados.ObjectNotFound as e:
90 exists = False
91
92 if exists and not clobber:
93 # Assume an existing config
94 logger.info('Rados config object exists: %s' % obj)
95 else:
96 # Create an empty config object
97 logger.info('Creating rados config object: %s' % obj)
98 ioctx.write_full(obj, ''.encode('utf-8'))
99
100 def get_ganesha_conf(self):
101 # type: () -> str
102 return '''# generated by cephadm
103 NFS_CORE_PARAM {{
104 Enable_NLM = false;
105 Enable_RQUOTA = false;
106 Protocols = 4;
107 }}
108
109 CACHEINODE {{
110 Dir_Chunk = 0;
111 NParts = 1;
112 Cache_Size = 1;
113 }}
114
115 EXPORT_DEFAULTS {{
116 Attr_Expiration_Time = 0;
117 }}
118
119 NFSv4 {{
120 Delegations = false;
121 RecoveryBackend = 'rados_cluster';
122 Minor_Versions = 1, 2;
123 }}
124
125 RADOS_KV {{
126 UserId = "{user}";
127 nodeid = "{nodeid}";
128 pool = "{pool}";
129 namespace = "{namespace}";
130 }}
131
132 RADOS_URLS {{
133 UserId = "{user}";
134 watch_url = "{url}";
135 }}
136
137 %url {url}
138 '''.format(user=self.get_rados_user(),
139 nodeid=self.get_daemon_name(),
140 pool=self.spec.pool,
141 namespace=self.spec.namespace if self.spec.namespace else '',
142 url=self.spec.rados_config_location())
143
144 def get_cephadm_config(self):
145 # type: () -> Dict
146 config = {'pool' : self.spec.pool} # type: Dict
147 if self.spec.namespace:
148 config['namespace'] = self.spec.namespace
149 config['userid'] = self.get_rados_user()
150 config['extra_args'] = ['-N', 'NIV_EVENT']
151 config['files'] = {
152 'ganesha.conf' : self.get_ganesha_conf(),
153 }
154 logger.debug('Generated cephadm config-json: %s' % config)
155 return config