Package ganeti :: Package client :: Module gnt_os
[hide private]
[frames] | no frames]

Source Code for Module ganeti.client.gnt_os

  1  # 
  2  # 
  3   
  4  # Copyright (C) 2006, 2007, 2010, 2013 Google Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, but 
 12  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 14  # General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
 19  # 02110-1301, USA. 
 20   
 21  """OS scripts related commands""" 
 22   
 23  # pylint: disable=W0401,W0613,W0614,C0103 
 24  # W0401: Wildcard import ganeti.cli 
 25  # W0613: Unused argument, since all functions follow the same API 
 26  # W0614: Unused import %s from wildcard import (since we need cli) 
 27  # C0103: Invalid name gnt-os 
 28   
 29  from ganeti.cli import * 
 30  from ganeti import constants 
 31  from ganeti import opcodes 
 32  from ganeti import utils 
 33   
 34   
35 -def ListOS(opts, args):
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
66 -def ShowOSInfo(opts, args):
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
118 -def _OsStatus(status, diagnose):
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
135 -def DiagnoseOS(opts, args):
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: # at least one entry in the per-node list 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 # TODO: Shouldn't the global status be calculated by the LU? 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
226 -def ModifyOS(opts, args):
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_OPT], 293 "", "Modify the OS parameters"), 294 } 295 296 #: dictionary with aliases for commands 297 aliases = { 298 "show": "info", 299 } 300 301
302 -def Main():
303 return GenericMain(commands, aliases=aliases)
304