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