Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / pybind / mgr / restful / common.py
1 # List of valid osd flags
2 OSD_FLAGS = [
3     'pause', 'noup', 'nodown', 'noout', 'noin', 'nobackfill',
4     'norecover', 'noscrub', 'nodeep-scrub',
5 ]
6
7 # Implemented osd commands
8 OSD_IMPLEMENTED_COMMANDS = [
9     'scrub', 'deep_scrub', 'repair'
10 ]
11
12 # Valid values for the 'var' argument to 'ceph osd pool set'
13 POOL_PROPERTIES_1 = [
14     'size', 'min_size', 'crash_replay_interval', 'pg_num',
15     'crush_rule', 'hashpspool',
16 ]
17
18 POOL_PROPERTIES_2 = [
19     'pgp_num'
20 ]
21
22 POOL_PROPERTIES = POOL_PROPERTIES_1 + POOL_PROPERTIES_2
23
24 # Valid values for the 'ceph osd pool set-quota' command
25 POOL_QUOTA_PROPERTIES = [
26     ('quota_max_bytes', 'max_bytes'),
27     ('quota_max_objects', 'max_objects'),
28 ]
29
30 POOL_ARGS = POOL_PROPERTIES + map(
31     lambda x: x[0],
32     POOL_QUOTA_PROPERTIES
33 )
34
35
36 # Transform command to a human readable form
37 def humanify_command(command):
38     out = [command['prefix']]
39
40     for arg, val in command.iteritems():
41         if arg != 'prefix':
42             out.append("%s=%s" % (str(arg), str(val)))
43
44     return " ".join(out)
45
46
47 def invalid_pool_args(args):
48     invalid = []
49     for arg in args:
50         if arg not in POOL_ARGS:
51             invalid.append(arg)
52
53     return invalid
54
55
56 def pool_update_commands(pool_name, args):
57     commands = [[], []]
58
59     # We should increase pgp_num when we are re-setting pg_num
60     if 'pg_num' in args and 'pgp_num' not in args:
61         args['pgp_num'] = args['pg_num']
62
63     # Run the first pool set and quota properties in parallel
64     for var in POOL_PROPERTIES_1:
65         if var in args:
66             commands[0].append({
67                 'prefix': 'osd pool set',
68                 'pool': pool_name,
69                 'var': var,
70                 'val': args[var],
71             })
72
73     for (var, field) in POOL_QUOTA_PROPERTIES:
74         if var in args:
75             commands[0].append({
76                 'prefix': 'osd pool set-quota',
77                 'pool': pool_name,
78                 'field': field,
79                 'val': str(args[var]),
80             })
81
82     # The second pool set properties need to be run after the first wave
83     for var in POOL_PROPERTIES_2:
84         if var in args:
85             commands[1].append({
86                 'prefix': 'osd pool set',
87                 'pool': pool_name,
88                 'var': var,
89             })
90
91     return commands
92
93
94 def crush_rule_osds(nodes, rule):
95     nodes_by_id = dict((n['id'], n) for n in nodes)
96
97     def _gather_leaf_ids(node):
98         if node['id'] >= 0:
99             return set([node['id']])
100
101         result = set()
102         for child_id in node['children']:
103             if child_id >= 0:
104                 result.add(child_id)
105             else:
106                 result |= _gather_leaf_ids(nodes_by_id[child_id])
107
108         return result
109
110     def _gather_descendent_ids(node, typ):
111         result = set()
112         for child_id in node['children']:
113             child_node = nodes_by_id[child_id]
114             if child_node['type'] == typ:
115                 result.add(child_node['id'])
116             elif 'children' in child_node:
117                 result |= _gather_descendent_ids(child_node, typ)
118
119         return result
120
121     def _gather_osds(root, steps):
122         if root['id'] >= 0:
123             return set([root['id']])
124
125         osds = set()
126         step = steps[0]
127         if step['op'] == 'choose_firstn':
128             # Choose all descendents of the current node of type 'type'
129             d = _gather_descendent_ids(root, step['type'])
130             for desc_node in [nodes_by_id[i] for i in d]:
131                 osds |= _gather_osds(desc_node, steps[1:])
132         elif step['op'] == 'chooseleaf_firstn':
133             # Choose all descendents of the current node of type 'type',
134             # and select all leaves beneath those
135             for desc_node in [nodes_by_id[i] for i in _gather_descendent_ids(root, step['type'])]:
136                 # Short circuit another iteration to find the emit
137                 # and assume anything we've done a chooseleaf on
138                 # is going to be part of the selected set of osds
139                 osds |= _gather_leaf_ids(desc_node)
140         elif step['op'] == 'emit':
141             if root['id'] >= 0:
142                 osds |= root['id']
143
144         return osds
145
146     osds = set()
147     for i, step in enumerate(rule['steps']):
148         if step['op'] == 'take':
149             osds |= _gather_osds(nodes_by_id[step['item']], rule['steps'][i + 1:])
150     return osds