]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/localpool/module.py
buildsys: switch source download to quincy
[ceph.git] / ceph / src / pybind / mgr / localpool / module.py
CommitLineData
3efd9988
FG
1from mgr_module import MgrModule, CommandResult
2import json
3import threading
4
5class Module(MgrModule):
11fdf7f2
TL
6
7 MODULE_OPTIONS = [
8 {
9 'name': 'subtree',
10 'type': 'str',
11 'default': 'rack',
12 'desc': 'CRUSH level for which to create a local pool',
13 'runtime': True,
14 },
15 {
16 'name': 'failure_domain',
17 'type': 'str',
18 'default': 'host',
19 'desc': 'failure domain for any created local pool',
20 'runtime': True,
21 },
22 {
23 'name': 'min_size',
24 'type': 'int',
25 'desc': 'default min_size for any created local pool',
26 'runtime': True,
27 },
28 {
29 'name': 'num_rep',
30 'type': 'int',
31 'default': 3,
32 'desc': 'default replica count for any created local pool',
33 'runtime': True,
34 },
35 {
36 'name': 'pg_num',
37 'type': 'int',
38 'default': 128,
39 'desc': 'default pg_num for any created local pool',
40 'runtime': True,
41 },
42 {
43 'name': 'prefix',
44 'type': 'str',
45 'default': '',
46 'desc': 'name prefix for any created local pool',
47 'runtime': True,
48 },
49 ]
50
3efd9988
FG
51 def __init__(self, *args, **kwargs):
52 super(Module, self).__init__(*args, **kwargs)
53 self.serve_event = threading.Event()
54
55 def notify(self, notify_type, notify_id):
56 if notify_type == 'osd_map':
57 self.handle_osd_map()
58
59 def handle_osd_map(self):
60 """
61 Check pools on each OSDMap change
62 """
11fdf7f2
TL
63 subtree_type = self.get_module_option('subtree')
64 failure_domain = self.get_module_option('failure_domain')
65 pg_num = self.get_module_option('pg_num')
66 num_rep = self.get_module_option('num_rep')
67 min_size = self.get_module_option('min_size')
68 prefix = self.get_module_option('prefix') or 'by-' + subtree_type + '-'
3efd9988
FG
69
70 osdmap = self.get("osd_map")
71 lpools = []
72 for pool in osdmap['pools']:
73 if pool['pool_name'].find(prefix) == 0:
74 lpools.append(pool['pool_name'])
75
76 self.log.debug('localized pools = %s', lpools)
77 subtrees = []
78 tree = self.get('osd_map_tree')
79 for node in tree['nodes']:
80 if node['type'] == subtree_type:
81 subtrees.append(node['name'])
82 pool_name = prefix + node['name']
83 if pool_name not in lpools:
84 self.log.info('Creating localized pool %s', pool_name)
85 #
86 result = CommandResult("")
87 self.send_command(result, "mon", "", json.dumps({
88 "prefix": "osd crush rule create-replicated",
89 "format": "json",
90 "name": pool_name,
91 "root": node['name'],
92 "type": failure_domain,
93 }), "")
94 r, outb, outs = result.wait()
95
96 result = CommandResult("")
97 self.send_command(result, "mon", "", json.dumps({
98 "prefix": "osd pool create",
99 "format": "json",
100 "pool": pool_name,
101 'rule': pool_name,
3efd9988 102 "pool_type": 'replicated',
11fdf7f2 103 'pg_num': pg_num,
3efd9988
FG
104 }), "")
105 r, outb, outs = result.wait()
106
107 result = CommandResult("")
108 self.send_command(result, "mon", "", json.dumps({
109 "prefix": "osd pool set",
110 "format": "json",
111 "pool": pool_name,
112 'var': 'size',
113 "val": str(num_rep),
114 }), "")
115 r, outb, outs = result.wait()
116
117 if min_size:
118 result = CommandResult("")
119 self.send_command(result, "mon", "", json.dumps({
120 "prefix": "osd pool set",
121 "format": "json",
122 "pool": pool_name,
123 'var': 'min_size',
124 "val": str(min_size),
125 }), "")
126 r, outb, outs = result.wait()
127
128 # TODO remove pools for hosts that don't exist?
129
130 def serve(self):
131 self.handle_osd_map()
132 self.serve_event.wait()
133 self.serve_event.clear()
134
135 def shutdown(self):
136 self.serve_event.set()