]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | import logging |
2 | import threading | |
3 | import os | |
4 | import subprocess | |
5 | ||
6 | from mgr_module import MgrModule, CLICommand, HandleCommandResult, Option | |
7 | import orchestrator | |
8 | ||
9 | from ceph.deployment.service_spec import RGWSpec | |
10 | ||
11 | from typing import cast, Any, Optional, Sequence | |
12 | ||
13 | from . import * | |
14 | from ceph.rgw.types import RGWAMException, RGWAMEnvMgr | |
15 | from ceph.rgw.rgwam_core import EnvArgs, RGWAM | |
16 | ||
17 | ||
18 | class RGWAMOrchMgr(RGWAMEnvMgr): | |
19 | def __init__(self, mgr): | |
20 | self.mgr = mgr | |
21 | ||
22 | def tool_exec(self, prog, args): | |
23 | cmd = [ prog ] + args | |
24 | rc, stdout, stderr = self.mgr.tool_exec(args = cmd) | |
25 | return cmd, rc, stdout, stderr | |
26 | ||
27 | def apply_rgw(self, svc_id, realm_name, zone_name, port = None): | |
28 | spec = RGWSpec(service_id = svc_id, | |
29 | rgw_realm = realm_name, | |
30 | rgw_zone = zone_name, | |
31 | rgw_frontend_port = port) | |
32 | completion = self.mgr.apply_rgw(spec) | |
33 | orchestrator.raise_if_exception(completion) | |
34 | ||
35 | def list_daemons(self, service_name, daemon_type = None, daemon_id = None, host = None, refresh = True): | |
36 | completion = self.mgr.list_daemons(service_name, | |
37 | daemon_type, | |
38 | daemon_id=daemon_id, | |
39 | host=host, | |
40 | refresh=refresh) | |
41 | return orchestrator.raise_if_exception(completion) | |
42 | ||
43 | ||
44 | class Module(orchestrator.OrchestratorClientMixin, MgrModule): | |
45 | MODULE_OPTIONS = [] | |
46 | ||
47 | # These are "native" Ceph options that this module cares about. | |
48 | NATIVE_OPTIONS = [] | |
49 | ||
50 | def __init__(self, *args: Any, **kwargs: Any): | |
51 | self.inited = False | |
52 | self.lock = threading.Lock() | |
53 | super(Module, self).__init__(*args, **kwargs) | |
54 | ||
55 | # ensure config options members are initialized; see config_notify() | |
56 | self.config_notify() | |
57 | ||
58 | with self.lock: | |
59 | self.inited = True | |
60 | self.env = EnvArgs(RGWAMOrchMgr(self)) | |
61 | ||
62 | # set up some members to enable the serve() method and shutdown() | |
63 | self.run = True | |
64 | self.event = threading.Event() | |
65 | ||
66 | ||
67 | ||
68 | def config_notify(self) -> None: | |
69 | """ | |
70 | This method is called whenever one of our config options is changed. | |
71 | """ | |
72 | # This is some boilerplate that stores MODULE_OPTIONS in a class | |
73 | # member, so that, for instance, the 'emphatic' option is always | |
74 | # available as 'self.emphatic'. | |
75 | for opt in self.MODULE_OPTIONS: | |
76 | setattr(self, | |
77 | opt['name'], | |
78 | self.get_module_option(opt['name'])) | |
79 | self.log.debug(' mgr option %s = %s', | |
80 | opt['name'], getattr(self, opt['name'])) | |
81 | # Do the same for the native options. | |
82 | for opt in self.NATIVE_OPTIONS: | |
83 | setattr(self, | |
84 | opt, | |
85 | self.get_ceph_option(opt)) | |
86 | self.log.debug(' native option %s = %s', opt, getattr(self, opt)) | |
87 | ||
88 | ||
89 | @CLICommand('rgw admin', perm='rw') | |
90 | def _cmd_rgw_admin(self, params: Sequence[str]): | |
91 | """rgw admin""" | |
92 | cmd, returncode, out, err = self.env.mgr.tool_exec('radosgw-admin', params or []) | |
93 | ||
94 | self.log.error('retcode=%d' % returncode) | |
95 | self.log.error('out=%s' % out) | |
96 | self.log.error('err=%s' % err) | |
97 | ||
98 | return HandleCommandResult(retval=returncode, stdout=out, stderr=err) | |
99 | ||
100 | @CLICommand('rgw realm bootstrap', perm='rw') | |
101 | def _cmd_rgw_realm_bootstrap(self, | |
102 | realm_name : Optional[str] = None, | |
103 | zonegroup_name: Optional[str] = None, | |
104 | zone_name: Optional[str] = None, | |
105 | endpoints: Optional[str] = None, | |
106 | sys_uid: Optional[str] = None, | |
107 | uid: Optional[str] = None, | |
108 | start_radosgw: Optional[bool] = True): | |
109 | """Bootstrap new rgw realm, zonegroup, and zone""" | |
110 | ||
111 | ||
112 | try: | |
113 | retval, out, err = RGWAM(self.env).realm_bootstrap(realm_name, zonegroup_name, | |
114 | zone_name, endpoints, sys_uid, uid, start_radosgw) | |
115 | except RGWAMException as e: | |
116 | self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message)) | |
117 | return (e.retcode, e.message, e.stderr) | |
118 | ||
119 | return HandleCommandResult(retval=retval, stdout=out, stderr=err) | |
120 | ||
121 | @CLICommand('rgw realm zone-creds create', perm='rw') | |
122 | def _cmd_rgw_realm_new_zone_creds(self, | |
123 | realm_name: Optional[str] = None, | |
124 | endpoints: Optional[str] = None, | |
125 | sys_uid: Optional[str] = None): | |
126 | """Create credentials for new zone creation""" | |
127 | ||
128 | try: | |
129 | retval, out, err = RGWAM(self.env).realm_new_zone_creds(realm_name, endpoints, sys_uid) | |
130 | except RGWAMException as e: | |
131 | self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message)) | |
132 | return (e.retcode, e.message, e.stderr) | |
133 | ||
134 | return HandleCommandResult(retval=retval, stdout=out, stderr=err) | |
135 | ||
136 | @CLICommand('rgw realm zone-creds remove', perm='rw') | |
137 | def _cmd_rgw_realm_rm_zone_creds(self, | |
138 | realm_token : Optional[str] = None): | |
139 | """Create credentials for new zone creation""" | |
140 | ||
141 | try: | |
142 | retval, out, err = RGWAM(self.env).realm_rm_zone_creds(realm_token) | |
143 | except RGWAMException as e: | |
144 | self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message)) | |
145 | return (e.retcode, e.message, e.stderr) | |
146 | ||
147 | return HandleCommandResult(retval=retval, stdout=out, stderr=err) | |
148 | ||
149 | @CLICommand('rgw zone create', perm='rw') | |
150 | def _cmd_rgw_zone_create(self, | |
151 | realm_token : Optional[str] = None, | |
152 | zonegroup_name: Optional[str] = None, | |
153 | zone_name: Optional[str] = None, | |
154 | endpoints: Optional[str] = None, | |
155 | start_radosgw: Optional[bool] = True): | |
156 | """Bootstrap new rgw zone that syncs with existing zone""" | |
157 | ||
158 | try: | |
159 | retval, out, err = RGWAM(self.env).zone_create(realm_token, zonegroup_name, | |
160 | zone_name, endpoints, start_radosgw) | |
161 | except RGWAMException as e: | |
162 | self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message)) | |
163 | return (e.retcode, e.message, e.stderr) | |
164 | ||
165 | return HandleCommandResult(retval=retval, stdout=out, stderr=err) | |
166 | ||
167 | @CLICommand('rgw realm reconcile', perm='rw') | |
168 | def _cmd_rgw_realm_reconcile(self, | |
169 | realm_name : Optional[str] = None, | |
170 | zonegroup_name: Optional[str] = None, | |
171 | zone_name: Optional[str] = None, | |
172 | update: Optional[bool] = False): | |
173 | """Bootstrap new rgw zone that syncs with existing zone""" | |
174 | ||
175 | try: | |
176 | retval, out, err = RGWAM(self.env).realm_reconcile(realm_name, zonegroup_name, | |
177 | zone_name, update) | |
178 | except RGWAMException as e: | |
179 | self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message)) | |
180 | return (e.retcode, e.message, e.stderr) | |
181 | ||
182 | return HandleCommandResult(retval=retval, stdout=out, stderr=err) | |
183 | ||
184 | def shutdown(self) -> None: | |
185 | """ | |
186 | This method is called by the mgr when the module needs to shut | |
187 | down (i.e., when the serve() function needs to exit). | |
188 | """ | |
189 | self.log.info('Stopping') | |
190 | self.run = False | |
191 | self.event.set() |