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