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
199 if nodes_valid and not nodes_bad:
200 status = "valid"
201 elif not nodes_valid and nodes_bad:
202 status = "invalid"
203 has_bad = True
204 else:
205 status = "partial valid"
206 has_bad = True
207
208 def _OutputPerNodeOSStatus(msg_map):
209 map_k = utils.NiceSort(msg_map.keys())
210 for node_name in map_k:
211 ToStdout(" Node: %s, status: %s", node_name, msg_map[node_name])
212 for msg in nodes_hidden[node_name]:
213 ToStdout(msg)
214
215 st_msg = "OS: %s [global status: %s]" % (os_name, status)
216 if hid:
217 st_msg += " [hidden]"
218 if blk:
219 st_msg += " [blacklisted]"
220 ToStdout(st_msg)
221 if os_variants:
222 ToStdout(" Variants: [%s]" % utils.CommaJoin(os_variants))
223 _OutputPerNodeOSStatus(nodes_valid)
224 _OutputPerNodeOSStatus(nodes_bad)
225 ToStdout("")
226
227 return int(has_bad)
228
229
231 """Modify OS parameters for one OS.
232
233 @param opts: the command line options selected by the user
234 @type args: list
235 @param args: should be a list with one entry
236 @rtype: int
237 @return: the desired exit code
238
239 """
240 os = args[0]
241
242 if opts.hvparams:
243 os_hvp = {os: dict(opts.hvparams)}
244 else:
245 os_hvp = None
246
247 if opts.osparams:
248 osp = {os: opts.osparams}
249 else:
250 osp = None
251
252 if opts.hidden is not None:
253 if opts.hidden:
254 ohid = [(constants.DDM_ADD, os)]
255 else:
256 ohid = [(constants.DDM_REMOVE, os)]
257 else:
258 ohid = None
259
260 if opts.blacklisted is not None:
261 if opts.blacklisted:
262 oblk = [(constants.DDM_ADD, os)]
263 else:
264 oblk = [(constants.DDM_REMOVE, os)]
265 else:
266 oblk = None
267
268 if not (os_hvp or osp or ohid or oblk):
269 ToStderr("At least one of OS parameters or hypervisor parameters"
270 " must be passed")
271 return 1
272
273 op = opcodes.OpClusterSetParams(os_hvp=os_hvp,
274 osparams=osp,
275 hidden_os=ohid,
276 blacklisted_os=oblk)
277 SubmitOpCode(op, opts=opts)
278
279 return 0
280
281
282 commands = {
283 "list": (
284 ListOS, ARGS_NONE, [NOHDR_OPT, PRIORITY_OPT],
285 "", "Lists all valid operating systems on the cluster"),
286 "diagnose": (
287 DiagnoseOS, ARGS_NONE, [PRIORITY_OPT],
288 "", "Diagnose all operating systems"),
289 "info": (
290 ShowOSInfo, [ArgOs()], [PRIORITY_OPT],
291 "", "Show detailed information about "
292 "operating systems"),
293 "modify": (
294 ModifyOS, ARGS_ONE_OS,
295 [HVLIST_OPT, OSPARAMS_OPT, DRY_RUN_OPT, PRIORITY_OPT,
296 HID_OS_OPT, BLK_OS_OPT],
297 "", "Modify the OS parameters"),
298 }
299
300
303