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

Source Code for Module ganeti.client.gnt_group

  1  # 
  2  # 
  3   
  4  # Copyright (C) 2010, 2011, 2012 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  """Node group related commands""" 
 22   
 23  # pylint: disable=W0401,W0614 
 24  # W0401: Wildcard import ganeti.cli 
 25  # W0614: Unused import %s from wildcard import (since we need cli) 
 26   
 27  from ganeti.cli import * 
 28  from ganeti import constants 
 29  from ganeti import opcodes 
 30  from ganeti import utils 
 31  from cStringIO import StringIO 
 32   
 33   
 34  #: default list of fields for L{ListGroups} 
 35  _LIST_DEF_FIELDS = ["name", "node_cnt", "pinst_cnt", "alloc_policy", "ndparams"] 
 36   
 37   
 38  _ENV_OVERRIDE = frozenset(["list"]) 
 39   
 40   
41 -def AddGroup(opts, args):
42 """Add a node group to the cluster. 43 44 @param opts: the command line options selected by the user 45 @type args: list 46 @param args: a list of length 1 with the name of the group to create 47 @rtype: int 48 @return: the desired exit code 49 50 """ 51 ipolicy = CreateIPolicyFromOpts( 52 ispecs_mem_size=opts.ispecs_mem_size, 53 ispecs_cpu_count=opts.ispecs_cpu_count, 54 ispecs_disk_count=opts.ispecs_disk_count, 55 ispecs_disk_size=opts.ispecs_disk_size, 56 ispecs_nic_count=opts.ispecs_nic_count, 57 ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio, 58 ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio, 59 group_ipolicy=True) 60 61 (group_name,) = args 62 diskparams = dict(opts.diskparams) 63 64 if opts.disk_state: 65 disk_state = utils.FlatToDict(opts.disk_state) 66 else: 67 disk_state = {} 68 hv_state = dict(opts.hv_state) 69 70 op = opcodes.OpGroupAdd(group_name=group_name, ndparams=opts.ndparams, 71 alloc_policy=opts.alloc_policy, 72 diskparams=diskparams, ipolicy=ipolicy, 73 hv_state=hv_state, 74 disk_state=disk_state) 75 SubmitOrSend(op, opts)
76 77
78 -def AssignNodes(opts, args):
79 """Assign nodes to a group. 80 81 @param opts: the command line options selected by the user 82 @type args: list 83 @param args: args[0]: group to assign nodes to; args[1:]: nodes to assign 84 @rtype: int 85 @return: the desired exit code 86 87 """ 88 group_name = args[0] 89 node_names = args[1:] 90 91 op = opcodes.OpGroupAssignNodes(group_name=group_name, nodes=node_names, 92 force=opts.force) 93 SubmitOrSend(op, opts)
94 95
96 -def _FmtDict(data):
97 """Format dict data into command-line format. 98 99 @param data: The input dict to be formatted 100 @return: The formatted dict 101 102 """ 103 if not data: 104 return "(empty)" 105 106 return utils.CommaJoin(["%s=%s" % (key, value) 107 for key, value in data.items()])
108 109
110 -def ListGroups(opts, args):
111 """List node groups and their properties. 112 113 @param opts: the command line options selected by the user 114 @type args: list 115 @param args: groups to list, or empty for all 116 @rtype: int 117 @return: the desired exit code 118 119 """ 120 desired_fields = ParseFields(opts.output, _LIST_DEF_FIELDS) 121 fmtoverride = { 122 "node_list": (",".join, False), 123 "pinst_list": (",".join, False), 124 "ndparams": (_FmtDict, False), 125 } 126 127 return GenericList(constants.QR_GROUP, desired_fields, args, None, 128 opts.separator, not opts.no_headers, 129 format_override=fmtoverride, verbose=opts.verbose, 130 force_filter=opts.force_filter)
131 132
133 -def ListGroupFields(opts, args):
134 """List node fields. 135 136 @param opts: the command line options selected by the user 137 @type args: list 138 @param args: fields to list, or empty for all 139 @rtype: int 140 @return: the desired exit code 141 142 """ 143 return GenericListFields(constants.QR_GROUP, args, opts.separator, 144 not opts.no_headers)
145 146
147 -def SetGroupParams(opts, args):
148 """Modifies a node group's parameters. 149 150 @param opts: the command line options selected by the user 151 @type args: list 152 @param args: should contain only one element, the node group name 153 154 @rtype: int 155 @return: the desired exit code 156 157 """ 158 allmods = [opts.ndparams, opts.alloc_policy, opts.diskparams, opts.hv_state, 159 opts.disk_state, opts.ispecs_mem_size, opts.ispecs_cpu_count, 160 opts.ispecs_disk_count, opts.ispecs_disk_size, 161 opts.ispecs_nic_count, opts.ipolicy_vcpu_ratio, 162 opts.ipolicy_spindle_ratio, opts.diskparams] 163 if allmods.count(None) == len(allmods): 164 ToStderr("Please give at least one of the parameters.") 165 return 1 166 167 if opts.disk_state: 168 disk_state = utils.FlatToDict(opts.disk_state) 169 else: 170 disk_state = {} 171 172 hv_state = dict(opts.hv_state) 173 174 diskparams = dict(opts.diskparams) 175 176 # set the default values 177 to_ipolicy = [ 178 opts.ispecs_mem_size, 179 opts.ispecs_cpu_count, 180 opts.ispecs_disk_count, 181 opts.ispecs_disk_size, 182 opts.ispecs_nic_count, 183 ] 184 for ispec in to_ipolicy: 185 for param in ispec: 186 if isinstance(ispec[param], basestring): 187 if ispec[param].lower() == "default": 188 ispec[param] = constants.VALUE_DEFAULT 189 # create ipolicy object 190 ipolicy = CreateIPolicyFromOpts( 191 ispecs_mem_size=opts.ispecs_mem_size, 192 ispecs_cpu_count=opts.ispecs_cpu_count, 193 ispecs_disk_count=opts.ispecs_disk_count, 194 ispecs_disk_size=opts.ispecs_disk_size, 195 ispecs_nic_count=opts.ispecs_nic_count, 196 ipolicy_disk_templates=opts.ipolicy_disk_templates, 197 ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio, 198 ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio, 199 group_ipolicy=True, 200 allowed_values=[constants.VALUE_DEFAULT]) 201 202 op = opcodes.OpGroupSetParams(group_name=args[0], 203 ndparams=opts.ndparams, 204 alloc_policy=opts.alloc_policy, 205 hv_state=hv_state, 206 disk_state=disk_state, 207 diskparams=diskparams, 208 ipolicy=ipolicy) 209 210 result = SubmitOrSend(op, opts) 211 212 if result: 213 ToStdout("Modified node group %s", args[0]) 214 for param, data in result: 215 ToStdout(" - %-5s -> %s", param, data) 216 217 return 0
218 219
220 -def RemoveGroup(opts, args):
221 """Remove a node group from the cluster. 222 223 @param opts: the command line options selected by the user 224 @type args: list 225 @param args: a list of length 1 with the name of the group to remove 226 @rtype: int 227 @return: the desired exit code 228 229 """ 230 (group_name,) = args 231 op = opcodes.OpGroupRemove(group_name=group_name) 232 SubmitOrSend(op, opts)
233 234
235 -def RenameGroup(opts, args):
236 """Rename a node group. 237 238 @param opts: the command line options selected by the user 239 @type args: list 240 @param args: a list of length 2, [old_name, new_name] 241 @rtype: int 242 @return: the desired exit code 243 244 """ 245 group_name, new_name = args 246 op = opcodes.OpGroupRename(group_name=group_name, new_name=new_name) 247 SubmitOrSend(op, opts)
248 249
250 -def EvacuateGroup(opts, args):
251 """Evacuate a node group. 252 253 """ 254 (group_name, ) = args 255 256 cl = GetClient() 257 258 op = opcodes.OpGroupEvacuate(group_name=group_name, 259 iallocator=opts.iallocator, 260 target_groups=opts.to, 261 early_release=opts.early_release) 262 result = SubmitOrSend(op, opts, cl=cl) 263 264 # Keep track of submitted jobs 265 jex = JobExecutor(cl=cl, opts=opts) 266 267 for (status, job_id) in result[constants.JOB_IDS_KEY]: 268 jex.AddJobId(None, status, job_id) 269 270 results = jex.GetResults() 271 bad_cnt = len([row for row in results if not row[0]]) 272 if bad_cnt == 0: 273 ToStdout("All instances evacuated successfully.") 274 rcode = constants.EXIT_SUCCESS 275 else: 276 ToStdout("There were %s errors during the evacuation.", bad_cnt) 277 rcode = constants.EXIT_FAILURE 278 279 return rcode
280 281
282 -def _FormatDict(custom, actual, level=2):
283 """Helper function to L{cli.FormatParameterDict}. 284 285 @param custom: The customized dict 286 @param actual: The fully filled dict 287 288 """ 289 buf = StringIO() 290 FormatParameterDict(buf, custom, actual, level=level) 291 return buf.getvalue().rstrip("\n")
292 293
294 -def GroupInfo(_, args):
295 """Shows info about node group. 296 297 """ 298 cl = GetClient() 299 selected_fields = ["name", 300 "ndparams", "custom_ndparams", 301 "diskparams", "custom_diskparams", 302 "ipolicy", "custom_ipolicy"] 303 result = cl.QueryGroups(names=args, fields=selected_fields, 304 use_locking=False) 305 306 for (name, 307 ndparams, custom_ndparams, 308 diskparams, custom_diskparams, 309 ipolicy, custom_ipolicy) in result: 310 ToStdout("Node group: %s" % name) 311 ToStdout(" Node parameters:") 312 ToStdout(_FormatDict(custom_ndparams, ndparams)) 313 ToStdout(" Disk parameters:") 314 ToStdout(_FormatDict(custom_diskparams, diskparams)) 315 ToStdout(" Instance policy:") 316 ToStdout(_FormatDict(custom_ipolicy, ipolicy))
317 318 319 commands = { 320 "add": ( 321 AddGroup, ARGS_ONE_GROUP, 322 [DRY_RUN_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT, DISK_PARAMS_OPT, 323 HV_STATE_OPT, DISK_STATE_OPT, PRIORITY_OPT, 324 SUBMIT_OPT] + INSTANCE_POLICY_OPTS, 325 "<group_name>", "Add a new node group to the cluster"), 326 "assign-nodes": ( 327 AssignNodes, ARGS_ONE_GROUP + ARGS_MANY_NODES, 328 [DRY_RUN_OPT, FORCE_OPT, PRIORITY_OPT, SUBMIT_OPT], 329 "<group_name> <node>...", "Assign nodes to a group"), 330 "list": ( 331 ListGroups, ARGS_MANY_GROUPS, 332 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT, FORCE_FILTER_OPT], 333 "[<group_name>...]", 334 "Lists the node groups in the cluster. The available fields can be shown" 335 " using the \"list-fields\" command (see the man page for details)." 336 " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)), 337 "list-fields": ( 338 ListGroupFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]", 339 "Lists all available fields for node groups"), 340 "modify": ( 341 SetGroupParams, ARGS_ONE_GROUP, 342 [DRY_RUN_OPT, SUBMIT_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT, HV_STATE_OPT, 343 DISK_STATE_OPT, DISK_PARAMS_OPT, PRIORITY_OPT] + INSTANCE_POLICY_OPTS, 344 "<group_name>", "Alters the parameters of a node group"), 345 "remove": ( 346 RemoveGroup, ARGS_ONE_GROUP, [DRY_RUN_OPT, PRIORITY_OPT, SUBMIT_OPT], 347 "[--dry-run] <group-name>", 348 "Remove an (empty) node group from the cluster"), 349 "rename": ( 350 RenameGroup, [ArgGroup(min=2, max=2)], 351 [DRY_RUN_OPT, SUBMIT_OPT, PRIORITY_OPT], 352 "[--dry-run] <group-name> <new-name>", "Rename a node group"), 353 "evacuate": ( 354 EvacuateGroup, [ArgGroup(min=1, max=1)], 355 [TO_GROUP_OPT, IALLOCATOR_OPT, EARLY_RELEASE_OPT, SUBMIT_OPT, PRIORITY_OPT], 356 "[-I <iallocator>] [--to <group>]", 357 "Evacuate all instances within a group"), 358 "list-tags": ( 359 ListTags, ARGS_ONE_GROUP, [], 360 "<group_name>", "List the tags of the given group"), 361 "add-tags": ( 362 AddTags, [ArgGroup(min=1, max=1), ArgUnknown()], 363 [TAG_SRC_OPT, PRIORITY_OPT, SUBMIT_OPT], 364 "<group_name> tag...", "Add tags to the given group"), 365 "remove-tags": ( 366 RemoveTags, [ArgGroup(min=1, max=1), ArgUnknown()], 367 [TAG_SRC_OPT, PRIORITY_OPT, SUBMIT_OPT], 368 "<group_name> tag...", "Remove tags from the given group"), 369 "info": ( 370 GroupInfo, ARGS_MANY_GROUPS, [], "<group_name>", "Show group information"), 371 } 372 373
374 -def Main():
375 return GenericMain(commands, 376 override={"tag_type": constants.TAG_NODEGROUP}, 377 env_override=_ENV_OVERRIDE)
378