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