]>
Commit | Line | Data |
---|---|---|
3efd9988 FG |
1 | from mgr_module import MgrModule, CommandResult |
2 | import json | |
3 | import threading | |
4 | ||
5 | class 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() |