1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 """Logical units dealing with OS."""
32
33 from ganeti import locking
34 from ganeti import qlang
35 from ganeti import query
36 from ganeti.cmdlib.base import QueryBase, NoHooksLU
40 FIELDS = query.OS_FIELDS
41
43
44
45
46 lu.needed_locks = {}
47
48
49
50
51 if self.names:
52 self.wanted = self.names
53 else:
54 self.wanted = locking.ALL_SET
55
56 self.do_locking = self.use_locking
57
60
61 @staticmethod
63 """Remaps a per-node return list into a per-os per-node dictionary
64
65 @param rlist: a map with node names as keys and OS objects as values
66
67 @rtype: dict
68 @return: a dictionary with osnames as keys and as value another
69 map, with node UUIDs as keys and tuples of (path, status, diagnose,
70 variants, parameters, api_versions) as values, eg::
71
72 {"debian-etch": {"node1-uuid": [(/usr/lib/..., True, "", [], []),
73 (/srv/..., False, "invalid api")],
74 "node2-uuid": [(/srv/..., True, "", [], [])]}
75 }
76
77 """
78 all_os = {}
79
80
81
82 good_node_uuids = [node_uuid for node_uuid in rlist
83 if not rlist[node_uuid].fail_msg]
84 for node_uuid, nr in rlist.items():
85 if nr.fail_msg or not nr.payload:
86 continue
87 for (name, path, status, diagnose, variants,
88 params, api_versions, trusted) in nr.payload:
89 if name not in all_os:
90
91
92 all_os[name] = {}
93 for nuuid in good_node_uuids:
94 all_os[name][nuuid] = []
95
96 params = [tuple(v) for v in params]
97 all_os[name][node_uuid].append((path, status, diagnose, variants,
98 params, api_versions, trusted))
99 return all_os
100
102 """Computes the list of nodes and their attributes.
103
104 """
105 valid_node_uuids = [node.uuid
106 for node in lu.cfg.GetAllNodesInfo().values()
107 if not node.offline and node.vm_capable]
108 pol = self._DiagnoseByOS(lu.rpc.call_os_diagnose(valid_node_uuids))
109 cluster = lu.cfg.GetClusterInfo()
110
111 data = {}
112
113 for (os_name, os_data) in pol.items():
114 info = query.OsInfo(name=os_name, valid=True, node_status=os_data,
115 hidden=(os_name in cluster.hidden_os),
116 blacklisted=(os_name in cluster.blacklisted_os),
117 os_hvp={}, osparams={})
118
119 variants = set()
120 parameters = set()
121 api_versions = set()
122 trusted = True
123
124 for idx, osl in enumerate(os_data.values()):
125 info.valid = bool(info.valid and osl and osl[0][1])
126 if not info.valid:
127 break
128
129 (node_variants, node_params, node_api, node_trusted) = osl[0][3:7]
130 if idx == 0:
131
132 variants.update(node_variants)
133 parameters.update(node_params)
134 api_versions.update(node_api)
135 else:
136
137 variants.intersection_update(node_variants)
138 parameters.intersection_update(node_params)
139 api_versions.intersection_update(node_api)
140
141 if not node_trusted:
142 trusted = False
143
144 info.variants = list(variants)
145 info.parameters = list(parameters)
146 info.api_versions = list(api_versions)
147 info.trusted = trusted
148
149 for variant in variants:
150 name = "+".join([os_name, variant])
151 if name in cluster.os_hvp.keys():
152 info.os_hvp[name] = cluster.os_hvp.get(name)
153 if name in cluster.osparams.keys():
154 info.osparams[name] = cluster.osparams.get(name)
155
156 data[os_name] = info
157
158
159 return [data[name] for name in self._GetNames(lu, pol.keys(), None)
160 if name in data]
161
164 """Logical unit for OS diagnose/query.
165
166 """
167 REQ_BGL = False
168
169 @staticmethod
171 """Builds a filter for querying OSes.
172
173 """
174 name_filter = qlang.MakeSimpleFilter("name", names)
175
176
177
178 status_filter = [[qlang.OP_NOT, [qlang.OP_TRUE, fname]]
179 for fname in ["hidden", "blacklisted"]
180 if fname not in fields]
181 if "valid" not in fields:
182 status_filter.append([qlang.OP_TRUE, "valid"])
183
184 if status_filter:
185 status_filter.insert(0, qlang.OP_AND)
186 else:
187 status_filter = None
188
189 if name_filter and status_filter:
190 return [qlang.OP_AND, name_filter, status_filter]
191 elif name_filter:
192 return name_filter
193 else:
194 return status_filter
195
197 self.oq = OsQuery(self._BuildFilter(self.op.output_fields, self.op.names),
198 self.op.output_fields, False)
199
202
203 - def Exec(self, feedback_fn):
205