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 """OS scripts related commands"""
31
32
33
34
35
36
37
38 from ganeti.cli import *
39 from ganeti import constants
40 from ganeti import opcodes
41 from ganeti import utils
42
43
45 """List the valid OSes in the cluster.
46
47 @param opts: the command line options selected by the user
48 @type args: list
49 @param args: should be an empty list
50 @rtype: int
51 @return: the desired exit code
52
53 """
54 op = opcodes.OpOsDiagnose(output_fields=["name", "variants"],
55 names=[])
56 result = SubmitOpCode(op, opts=opts)
57
58 if not opts.no_headers:
59 headers = {"name": "Name"}
60 else:
61 headers = None
62
63 os_names = []
64 for (name, variants) in result:
65 os_names.extend([[n] for n in CalculateOSNames(name, variants)])
66
67 data = GenerateTable(separator=None, headers=headers, fields=["name"],
68 data=os_names, units=None)
69
70 for line in data:
71 ToStdout(line)
72
73 return 0
74
75
77 """List detailed information about OSes in the cluster.
78
79 @param opts: the command line options selected by the user
80 @type args: list
81 @param args: should be an empty list
82 @rtype: int
83 @return: the desired exit code
84
85 """
86 op = opcodes.OpOsDiagnose(output_fields=["name", "valid", "variants",
87 "parameters", "api_versions",
88 "blacklisted", "hidden", "os_hvp",
89 "osparams", "trusted"],
90 names=[])
91 result = SubmitOpCode(op, opts=opts)
92
93 if result is None:
94 ToStderr("Can't get the OS list")
95 return 1
96
97 do_filter = bool(args)
98
99 total_os_hvp = {}
100 total_osparams = {}
101
102 for (name, valid, variants, parameters, api_versions, blk, hid, os_hvp,
103 osparams, trusted) in result:
104 total_os_hvp.update(os_hvp)
105 total_osparams.update(osparams)
106 if do_filter:
107 if name not in args:
108 continue
109 else:
110 args.remove(name)
111 ToStdout("%s:", name)
112 ToStdout(" - valid: %s", valid)
113 ToStdout(" - hidden: %s", hid)
114 ToStdout(" - blacklisted: %s", blk)
115 if valid:
116 ToStdout(" - API versions:")
117 for version in sorted(api_versions):
118 ToStdout(" - %s", version)
119 ToStdout(" - variants:")
120 for vname in variants:
121 ToStdout(" - %s", vname)
122 ToStdout(" - parameters:")
123 for pname, pdesc in parameters:
124 ToStdout(" - %s: %s", pname, pdesc)
125 ToStdout(" - trusted: %s", trusted)
126 ToStdout("")
127
128 if args:
129 all_names = total_os_hvp.keys() + total_osparams.keys()
130 for name in args:
131 if not name in all_names:
132 ToStdout("%s: ", name)
133 else:
134 info = [
135 (name, [
136 ("OS-specific hypervisor parameters", total_os_hvp.get(name, {})),
137 ("OS parameters", total_osparams.get(name, {})),
138 ]),
139 ]
140 PrintGenericInfo(info)
141 ToStdout("")
142
143 return 0
144
145
147 """Beautifier function for OS status.
148
149 @type status: boolean
150 @param status: is the OS valid
151 @type diagnose: string
152 @param diagnose: the error message for invalid OSes
153 @rtype: string
154 @return: a formatted status
155
156 """
157 if status:
158 return "valid"
159 else:
160 return "invalid - %s" % diagnose
161
162
164 """Analyse all OSes on this cluster.
165
166 @param opts: the command line options selected by the user
167 @type args: list
168 @param args: should be an empty list
169 @rtype: int
170 @return: the desired exit code
171
172 """
173 op = opcodes.OpOsDiagnose(output_fields=["name", "valid", "variants",
174 "node_status", "hidden",
175 "blacklisted"], names=[])
176 result = SubmitOpCode(op, opts=opts)
177
178 if result is None:
179 ToStderr("Can't get the OS list")
180 return 1
181
182 has_bad = False
183
184 for os_name, _, os_variants, node_data, hid, blk in result:
185 nodes_valid = {}
186 nodes_bad = {}
187 nodes_hidden = {}
188 for node_name, node_info in node_data.iteritems():
189 nodes_hidden[node_name] = []
190 if node_info:
191 (fo_path, fo_status, fo_msg, fo_variants,
192 fo_params, fo_api, fo_trusted) = node_info.pop(0)
193 fo_msg = "%s (path: %s)" % (_OsStatus(fo_status, fo_msg), fo_path)
194 if fo_api:
195 max_os_api = max(fo_api)
196 fo_msg += " [API versions: %s]" % utils.CommaJoin(fo_api)
197 else:
198 max_os_api = 0
199 fo_msg += " [no API versions declared]"
200
201 if max_os_api >= constants.OS_API_V15:
202 if fo_variants:
203 fo_msg += " [variants: %s]" % utils.CommaJoin(fo_variants)
204 else:
205 fo_msg += " [no variants]"
206 if max_os_api >= constants.OS_API_V20:
207 if fo_params:
208 fo_msg += (" [parameters: %s]" %
209 utils.CommaJoin([v[0] for v in fo_params]))
210 else:
211 fo_msg += " [no parameters]"
212 if fo_trusted:
213 fo_msg += " [trusted]"
214 else:
215 fo_msg += " [untrusted]"
216 if fo_status:
217 nodes_valid[node_name] = fo_msg
218 else:
219 nodes_bad[node_name] = fo_msg
220 for hpath, hstatus, hmsg, _, _, _ in node_info:
221 nodes_hidden[node_name].append(" [hidden] path: %s, status: %s" %
222 (hpath, _OsStatus(hstatus, hmsg)))
223 else:
224 nodes_bad[node_name] = "OS not found"
225
226
227 if nodes_valid and not nodes_bad:
228 status = "valid"
229 elif not nodes_valid and nodes_bad:
230 status = "invalid"
231 has_bad = True
232 else:
233 status = "partial valid"
234 has_bad = True
235
236 def _OutputPerNodeOSStatus(msg_map):
237 map_k = utils.NiceSort(msg_map.keys())
238 for node_name in map_k:
239 ToStdout(" Node: %s, status: %s", node_name, msg_map[node_name])
240 for msg in nodes_hidden[node_name]:
241 ToStdout(msg)
242
243 st_msg = "OS: %s [global status: %s]" % (os_name, status)
244 if hid:
245 st_msg += " [hidden]"
246 if blk:
247 st_msg += " [blacklisted]"
248 ToStdout(st_msg)
249 if os_variants:
250 ToStdout(" Variants: [%s]" % utils.CommaJoin(os_variants))
251 _OutputPerNodeOSStatus(nodes_valid)
252 _OutputPerNodeOSStatus(nodes_bad)
253 ToStdout("")
254
255 return int(has_bad)
256
257
259 """Modify OS parameters for one OS.
260
261 @param opts: the command line options selected by the user
262 @type args: list
263 @param args: should be a list with one entry
264 @rtype: int
265 @return: the desired exit code
266
267 """
268
269
270
271
272
273 os = args[0]
274
275 if opts.hvparams:
276 os_hvp = {os: dict(opts.hvparams)}
277 else:
278 os_hvp = None
279
280 if opts.osparams:
281 osp = {os: opts.osparams}
282 else:
283 osp = None
284
285 if opts.osparams_private:
286 osp_private = {os: opts.osparams_private}
287 else:
288 osp_private = None
289
290 if opts.hidden is not None:
291 if opts.hidden:
292 ohid = [(constants.DDM_ADD, os)]
293 else:
294 ohid = [(constants.DDM_REMOVE, os)]
295 else:
296 ohid = None
297
298 if opts.blacklisted is not None:
299 if opts.blacklisted:
300 oblk = [(constants.DDM_ADD, os)]
301 else:
302 oblk = [(constants.DDM_REMOVE, os)]
303 else:
304 oblk = None
305
306 if not (os_hvp or osp or osp_private or ohid or oblk):
307 ToStderr("At least one of OS parameters or hypervisor parameters"
308 " must be passed")
309 return 1
310
311 op = opcodes.OpClusterSetParams(os_hvp=os_hvp,
312 osparams=osp,
313 osparams_private_cluster=osp_private,
314 hidden_os=ohid,
315 blacklisted_os=oblk)
316 SubmitOrSend(op, opts)
317
318 return 0
319
320
321 commands = {
322 "list": (
323 ListOS, ARGS_NONE, [NOHDR_OPT, PRIORITY_OPT],
324 "", "Lists all valid operating systems on the cluster"),
325 "diagnose": (
326 DiagnoseOS, ARGS_NONE, [PRIORITY_OPT],
327 "", "Diagnose all operating systems"),
328 "info": (
329 ShowOSInfo, [ArgOs()], [PRIORITY_OPT],
330 "", "Show detailed information about "
331 "operating systems"),
332 "modify": (
333 ModifyOS, ARGS_ONE_OS,
334 [HVLIST_OPT, OSPARAMS_OPT, OSPARAMS_PRIVATE_OPT,
335 DRY_RUN_OPT, PRIORITY_OPT, HID_OS_OPT, BLK_OS_OPT] + SUBMIT_OPTS,
336 "", "Modify the OS parameters"),
337 }
338
339
340 aliases = {
341 "show": "info",
342 }
343
344
347