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, 2013, 2014 Google Inc. 
  5  # All rights reserved. 
  6  # 
  7  # Redistribution and use in source and binary forms, with or without 
  8  # modification, are permitted provided that the following conditions are 
  9  # met: 
 10  # 
 11  # 1. Redistributions of source code must retain the above copyright notice, 
 12  # this list of conditions and the following disclaimer. 
 13  # 
 14  # 2. Redistributions in binary form must reproduce the above copyright 
 15  # notice, this list of conditions and the following disclaimer in the 
 16  # documentation and/or other materials provided with the distribution. 
 17  # 
 18  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
 19  # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
 20  # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 21  # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
 22  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 23  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 24  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 25  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 26  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 27  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 28  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 29   
 30  """Node group related commands""" 
 31   
 32  # pylint: disable=W0401,W0614 
 33  # W0401: Wildcard import ganeti.cli 
 34  # W0614: Unused import %s from wildcard import (since we need cli) 
 35   
 36  from cStringIO import StringIO 
 37   
 38  from ganeti.cli import * 
 39  from ganeti import constants 
 40  from ganeti import opcodes 
 41  from ganeti import utils 
 42  from ganeti import compat 
 43  from ganeti.client import base 
 44   
 45   
 46  #: default list of fields for L{ListGroups} 
 47  _LIST_DEF_FIELDS = ["name", "node_cnt", "pinst_cnt", "alloc_policy", "ndparams"] 
 48   
 49  _ENV_OVERRIDE = compat.UniqueFrozenset(["list"]) 
 50   
 51   
52 -def AddGroup(opts, args):
53 """Add a node group to the cluster. 54 55 @param opts: the command line options selected by the user 56 @type args: list 57 @param args: a list of length 1 with the name of the group to create 58 @rtype: int 59 @return: the desired exit code 60 61 """ 62 ipolicy = CreateIPolicyFromOpts( 63 minmax_ispecs=opts.ipolicy_bounds_specs, 64 ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio, 65 ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio, 66 ipolicy_disk_templates=opts.ipolicy_disk_templates, 67 group_ipolicy=True) 68 69 (group_name,) = args 70 diskparams = dict(opts.diskparams) 71 72 if opts.disk_state: 73 disk_state = utils.FlatToDict(opts.disk_state) 74 else: 75 disk_state = {} 76 hv_state = dict(opts.hv_state) 77 78 op = opcodes.OpGroupAdd(group_name=group_name, ndparams=opts.ndparams, 79 alloc_policy=opts.alloc_policy, 80 diskparams=diskparams, ipolicy=ipolicy, 81 hv_state=hv_state, 82 disk_state=disk_state) 83 return base.GetResult(None, opts, SubmitOrSend(op, opts))
84 85
86 -def AssignNodes(opts, args):
87 """Assign nodes to a group. 88 89 @param opts: the command line options selected by the user 90 @type args: list 91 @param args: args[0]: group to assign nodes to; args[1:]: nodes to assign 92 @rtype: int 93 @return: the desired exit code 94 95 """ 96 group_name = args[0] 97 node_names = args[1:] 98 99 op = opcodes.OpGroupAssignNodes(group_name=group_name, nodes=node_names, 100 force=opts.force) 101 SubmitOrSend(op, opts)
102 103
104 -def _FmtDict(data):
105 """Format dict data into command-line format. 106 107 @param data: The input dict to be formatted 108 @return: The formatted dict 109 110 """ 111 if not data: 112 return "(empty)" 113 114 return utils.CommaJoin(["%s=%s" % (key, value) 115 for key, value in data.items()])
116 117
118 -def ListGroups(opts, args):
119 """List node groups and their properties. 120 121 @param opts: the command line options selected by the user 122 @type args: list 123 @param args: groups to list, or empty for all 124 @rtype: int 125 @return: the desired exit code 126 127 """ 128 desired_fields = ParseFields(opts.output, _LIST_DEF_FIELDS) 129 fmtoverride = { 130 "node_list": (",".join, False), 131 "pinst_list": (",".join, False), 132 "ndparams": (_FmtDict, False), 133 } 134 135 cl = GetClient() 136 137 return GenericList(constants.QR_GROUP, desired_fields, args, None, 138 opts.separator, not opts.no_headers, 139 format_override=fmtoverride, verbose=opts.verbose, 140 force_filter=opts.force_filter, cl=cl)
141 142
143 -def ListGroupFields(opts, args):
144 """List node fields. 145 146 @param opts: the command line options selected by the user 147 @type args: list 148 @param args: fields to list, or empty for all 149 @rtype: int 150 @return: the desired exit code 151 152 """ 153 cl = GetClient() 154 155 return GenericListFields(constants.QR_GROUP, args, opts.separator, 156 not opts.no_headers, cl=cl)
157 158
159 -def SetGroupParams(opts, args):
160 """Modifies a node group's parameters. 161 162 @param opts: the command line options selected by the user 163 @type args: list 164 @param args: should contain only one element, the node group name 165 166 @rtype: int 167 @return: the desired exit code 168 169 """ 170 allmods = [opts.ndparams, opts.alloc_policy, opts.diskparams, opts.hv_state, 171 opts.disk_state, opts.ipolicy_bounds_specs, 172 opts.ipolicy_vcpu_ratio, opts.ipolicy_spindle_ratio, 173 opts.diskparams, opts.ipolicy_disk_templates] 174 if allmods.count(None) == len(allmods): 175 ToStderr("Please give at least one of the parameters.") 176 return 1 177 178 if opts.disk_state: 179 disk_state = utils.FlatToDict(opts.disk_state) 180 else: 181 disk_state = {} 182 183 hv_state = dict(opts.hv_state) 184 185 diskparams = dict(opts.diskparams) 186 187 # create ipolicy object 188 ipolicy = CreateIPolicyFromOpts( 189 minmax_ispecs=opts.ipolicy_bounds_specs, 190 ipolicy_disk_templates=opts.ipolicy_disk_templates, 191 ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio, 192 ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio, 193 group_ipolicy=True, 194 allowed_values=[constants.VALUE_DEFAULT]) 195 196 op = opcodes.OpGroupSetParams(group_name=args[0], 197 ndparams=opts.ndparams, 198 alloc_policy=opts.alloc_policy, 199 hv_state=hv_state, 200 disk_state=disk_state, 201 diskparams=diskparams, 202 ipolicy=ipolicy) 203 204 result = SubmitOrSend(op, opts) 205 206 if result: 207 ToStdout("Modified node group %s", args[0]) 208 for param, data in result: 209 ToStdout(" - %-5s -> %s", param, data) 210 211 return 0
212 213
214 -def RemoveGroup(opts, args):
215 """Remove a node group from the cluster. 216 217 @param opts: the command line options selected by the user 218 @type args: list 219 @param args: a list of length 1 with the name of the group to remove 220 @rtype: int 221 @return: the desired exit code 222 223 """ 224 (group_name,) = args 225 op = opcodes.OpGroupRemove(group_name=group_name) 226 SubmitOrSend(op, opts)
227 228
229 -def RenameGroup(opts, args):
230 """Rename a node group. 231 232 @param opts: the command line options selected by the user 233 @type args: list 234 @param args: a list of length 2, [old_name, new_name] 235 @rtype: int 236 @return: the desired exit code 237 238 """ 239 group_name, new_name = args 240 op = opcodes.OpGroupRename(group_name=group_name, new_name=new_name) 241 SubmitOrSend(op, opts)
242 243
244 -def EvacuateGroup(opts, args):
245 """Evacuate a node group. 246 247 """ 248 (group_name, ) = args 249 250 cl = GetClient() 251 252 op = opcodes.OpGroupEvacuate(group_name=group_name, 253 iallocator=opts.iallocator, 254 target_groups=opts.to, 255 early_release=opts.early_release, 256 sequential=opts.sequential, 257 force_failover=opts.force_failover) 258 result = SubmitOrSend(op, opts, cl=cl) 259 260 # Keep track of submitted jobs 261 jex = JobExecutor(cl=cl, opts=opts) 262 263 for (status, job_id) in result[constants.JOB_IDS_KEY]: 264 jex.AddJobId(None, status, job_id) 265 266 results = jex.GetResults() 267 bad_cnt = len([row for row in results if not row[0]]) 268 if bad_cnt == 0: 269 ToStdout("All instances evacuated successfully.") 270 rcode = constants.EXIT_SUCCESS 271 else: 272 ToStdout("There were %s errors during the evacuation.", bad_cnt) 273 rcode = constants.EXIT_FAILURE 274 275 return rcode
276 277
278 -def _FormatGroupInfo(group):
279 (name, ndparams, custom_ndparams, diskparams, custom_diskparams, 280 ipolicy, custom_ipolicy) = group 281 return [ 282 ("Node group", name), 283 ("Node parameters", FormatParamsDictInfo(custom_ndparams, ndparams)), 284 ("Disk parameters", FormatParamsDictInfo(custom_diskparams, diskparams)), 285 ("Instance policy", FormatPolicyInfo(custom_ipolicy, ipolicy, False)), 286 ]
287 288
289 -def GroupInfo(_, args):
290 """Shows info about node group. 291 292 """ 293 cl = GetClient() 294 selected_fields = ["name", 295 "ndparams", "custom_ndparams", 296 "diskparams", "custom_diskparams", 297 "ipolicy", "custom_ipolicy"] 298 result = cl.QueryGroups(names=args, fields=selected_fields, 299 use_locking=False) 300 301 PrintGenericInfo([ 302 _FormatGroupInfo(group) for group in result 303 ])
304 305
306 -def _GetCreateCommand(group):
307 (name, ipolicy) = group 308 buf = StringIO() 309 buf.write("gnt-group add") 310 PrintIPolicyCommand(buf, ipolicy, True) 311 buf.write(" ") 312 buf.write(name) 313 return buf.getvalue()
314 315
316 -def ShowCreateCommand(opts, args):
317 """Shows the command that can be used to re-create a node group. 318 319 Currently it works only for ipolicy specs. 320 321 """ 322 cl = GetClient() 323 selected_fields = ["name"] 324 if opts.include_defaults: 325 selected_fields += ["ipolicy"] 326 else: 327 selected_fields += ["custom_ipolicy"] 328 result = cl.QueryGroups(names=args, fields=selected_fields, 329 use_locking=False) 330 331 for group in result: 332 ToStdout(_GetCreateCommand(group))
333 334 335 commands = { 336 "add": ( 337 AddGroup, ARGS_ONE_GROUP, 338 [DRY_RUN_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT, DISK_PARAMS_OPT, 339 HV_STATE_OPT, DISK_STATE_OPT, PRIORITY_OPT] 340 + SUBMIT_OPTS + INSTANCE_POLICY_OPTS, 341 "<group_name>", "Add a new node group to the cluster"), 342 "assign-nodes": ( 343 AssignNodes, ARGS_ONE_GROUP + ARGS_MANY_NODES, 344 [DRY_RUN_OPT, FORCE_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 345 "<group_name> <node>...", "Assign nodes to a group"), 346 "list": ( 347 ListGroups, ARGS_MANY_GROUPS, 348 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT, FORCE_FILTER_OPT], 349 "[<group_name>...]", 350 "Lists the node groups in the cluster. The available fields can be shown" 351 " using the \"list-fields\" command (see the man page for details)." 352 " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)), 353 "list-fields": ( 354 ListGroupFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]", 355 "Lists all available fields for node groups"), 356 "modify": ( 357 SetGroupParams, ARGS_ONE_GROUP, 358 [DRY_RUN_OPT] + SUBMIT_OPTS + 359 [ALLOC_POLICY_OPT, NODE_PARAMS_OPT, HV_STATE_OPT, DISK_STATE_OPT, 360 DISK_PARAMS_OPT, PRIORITY_OPT] 361 + INSTANCE_POLICY_OPTS, 362 "<group_name>", "Alters the parameters of a node group"), 363 "remove": ( 364 RemoveGroup, ARGS_ONE_GROUP, [DRY_RUN_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 365 "[--dry-run] <group-name>", 366 "Remove an (empty) node group from the cluster"), 367 "rename": ( 368 RenameGroup, [ArgGroup(min=2, max=2)], 369 [DRY_RUN_OPT] + SUBMIT_OPTS + [PRIORITY_OPT], 370 "[--dry-run] <group-name> <new-name>", "Rename a node group"), 371 "evacuate": ( 372 EvacuateGroup, [ArgGroup(min=1, max=1)], 373 [TO_GROUP_OPT, IALLOCATOR_OPT, EARLY_RELEASE_OPT, SEQUENTIAL_OPT, 374 FORCE_FAILOVER_OPT] 375 + SUBMIT_OPTS, 376 "[-I <iallocator>] [--to <group>]", 377 "Evacuate all instances within a group"), 378 "list-tags": ( 379 ListTags, ARGS_ONE_GROUP, [], 380 "<group_name>", "List the tags of the given group"), 381 "add-tags": ( 382 AddTags, [ArgGroup(min=1, max=1), ArgUnknown()], 383 [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 384 "<group_name> tag...", "Add tags to the given group"), 385 "remove-tags": ( 386 RemoveTags, [ArgGroup(min=1, max=1), ArgUnknown()], 387 [TAG_SRC_OPT, PRIORITY_OPT] + SUBMIT_OPTS, 388 "<group_name> tag...", "Remove tags from the given group"), 389 "info": ( 390 GroupInfo, ARGS_MANY_GROUPS, [], "[<group_name>...]", 391 "Show group information"), 392 "show-ispecs-cmd": ( 393 ShowCreateCommand, ARGS_MANY_GROUPS, [INCLUDEDEFAULTS_OPT], 394 "[--include-defaults] [<group_name>...]", 395 "Show the command line to re-create a group"), 396 } 397 398
399 -def Main():
400 return GenericMain(commands, 401 override={"tag_type": constants.TAG_NODEGROUP}, 402 env_override=_ENV_OVERRIDE)
403