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 ganeti import compat 
 32  from cStringIO import StringIO 
 33   
 34   
 35  #: default list of fields for L{ListGroups} 
 36  _LIST_DEF_FIELDS = ["name", "node_cnt", "pinst_cnt", "alloc_policy", "ndparams"] 
 37   
 38  _ENV_OVERRIDE = compat.UniqueFrozenset(["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 cl = GetClient(query=True) 128 129 return GenericList(constants.QR_GROUP, desired_fields, args, None, 130 opts.separator, not opts.no_headers, 131 format_override=fmtoverride, verbose=opts.verbose, 132 force_filter=opts.force_filter, cl=cl)
133 134
135 -def ListGroupFields(opts, args):
136 """List node fields. 137 138 @param opts: the command line options selected by the user 139 @type args: list 140 @param args: fields to list, or empty for all 141 @rtype: int 142 @return: the desired exit code 143 144 """ 145 cl = GetClient(query=True) 146 147 return GenericListFields(constants.QR_GROUP, args, opts.separator, 148 not opts.no_headers, cl=cl)
149 150
151 -def SetGroupParams(opts, args):
152 """Modifies a node group's parameters. 153 154 @param opts: the command line options selected by the user 155 @type args: list 156 @param args: should contain only one element, the node group name 157 158 @rtype: int 159 @return: the desired exit code 160 161 """ 162 allmods = [opts.ndparams, opts.alloc_policy, opts.diskparams, opts.hv_state, 163 opts.disk_state, opts.ispecs_mem_size, opts.ispecs_cpu_count, 164 opts.ispecs_disk_count, opts.ispecs_disk_size, 165 opts.ispecs_nic_count, opts.ipolicy_vcpu_ratio, 166 opts.ipolicy_spindle_ratio, opts.diskparams] 167 if allmods.count(None) == len(allmods): 168 ToStderr("Please give at least one of the parameters.") 169 return 1 170 171 if opts.disk_state: 172 disk_state = utils.FlatToDict(opts.disk_state) 173 else: 174 disk_state = {} 175 176 hv_state = dict(opts.hv_state) 177 178 diskparams = dict(opts.diskparams) 179 180 # set the default values 181 to_ipolicy = [ 182 opts.ispecs_mem_size, 183 opts.ispecs_cpu_count, 184 opts.ispecs_disk_count, 185 opts.ispecs_disk_size, 186 opts.ispecs_nic_count, 187 ] 188 for ispec in to_ipolicy: 189 for param in ispec: 190 if isinstance(ispec[param], basestring): 191 if ispec[param].lower() == "default": 192 ispec[param] = constants.VALUE_DEFAULT 193 # create ipolicy object 194 ipolicy = CreateIPolicyFromOpts( 195 ispecs_mem_size=opts.ispecs_mem_size, 196 ispecs_cpu_count=opts.ispecs_cpu_count, 197 ispecs_disk_count=opts.ispecs_disk_count, 198 ispecs_disk_size=opts.ispecs_disk_size, 199 ispecs_nic_count=opts.ispecs_nic_count, 200 ipolicy_disk_templates=opts.ipolicy_disk_templates, 201 ipolicy_vcpu_ratio=opts.ipolicy_vcpu_ratio, 202 ipolicy_spindle_ratio=opts.ipolicy_spindle_ratio, 203 group_ipolicy=True, 204 allowed_values=[constants.VALUE_DEFAULT]) 205 206 op = opcodes.OpGroupSetParams(group_name=args[0], 207 ndparams=opts.ndparams, 208 alloc_policy=opts.alloc_policy, 209 hv_state=hv_state, 210 disk_state=disk_state, 211 diskparams=diskparams, 212 ipolicy=ipolicy) 213 214 result = SubmitOrSend(op, opts) 215 216 if result: 217 ToStdout("Modified node group %s", args[0]) 218 for param, data in result: 219 ToStdout(" - %-5s -> %s", param, data) 220 221 return 0
222 223
224 -def RemoveGroup(opts, args):
225 """Remove a node group from the cluster. 226 227 @param opts: the command line options selected by the user 228 @type args: list 229 @param args: a list of length 1 with the name of the group to remove 230 @rtype: int 231 @return: the desired exit code 232 233 """ 234 (group_name,) = args 235 op = opcodes.OpGroupRemove(group_name=group_name) 236 SubmitOrSend(op, opts)
237 238
239 -def RenameGroup(opts, args):
240 """Rename a node group. 241 242 @param opts: the command line options selected by the user 243 @type args: list 244 @param args: a list of length 2, [old_name, new_name] 245 @rtype: int 246 @return: the desired exit code 247 248 """ 249 group_name, new_name = args 250 op = opcodes.OpGroupRename(group_name=group_name, new_name=new_name) 251 SubmitOrSend(op, opts)
252 253
254 -def EvacuateGroup(opts, args):
255 """Evacuate a node group. 256 257 """ 258 (group_name, ) = args 259 260 cl = GetClient() 261 262 op = opcodes.OpGroupEvacuate(group_name=group_name, 263 iallocator=opts.iallocator, 264 target_groups=opts.to, 265 early_release=opts.early_release) 266 result = SubmitOrSend(op, opts, cl=cl) 267 268 # Keep track of submitted jobs 269 jex = JobExecutor(cl=cl, opts=opts) 270 271 for (status, job_id) in result[constants.JOB_IDS_KEY]: 272 jex.AddJobId(None, status, job_id) 273 274 results = jex.GetResults() 275 bad_cnt = len([row for row in results if not row[0]]) 276 if bad_cnt == 0: 277 ToStdout("All instances evacuated successfully.") 278 rcode = constants.EXIT_SUCCESS 279 else: 280 ToStdout("There were %s errors during the evacuation.", bad_cnt) 281 rcode = constants.EXIT_FAILURE 282 283 return rcode
284 285
286 -def _FormatDict(custom, actual, level=2):
287 """Helper function to L{cli.FormatParameterDict}. 288 289 @param custom: The customized dict 290 @param actual: The fully filled dict 291 292 """ 293 buf = StringIO() 294 FormatParameterDict(buf, custom, actual, level=level) 295 return buf.getvalue().rstrip("\n")
296 297
298 -def GroupInfo(_, args):
299 """Shows info about node group. 300 301 """ 302 cl = GetClient(query=True) 303 selected_fields = ["name", 304 "ndparams", "custom_ndparams", 305 "diskparams", "custom_diskparams", 306 "ipolicy", "custom_ipolicy"] 307 result = cl.QueryGroups(names=args, fields=selected_fields, 308 use_locking=False) 309 310 for (name, 311 ndparams, custom_ndparams, 312 diskparams, custom_diskparams, 313 ipolicy, custom_ipolicy) in result: 314 ToStdout("Node group: %s" % name) 315 ToStdout(" Node parameters:") 316 ToStdout(_FormatDict(custom_ndparams, ndparams)) 317 ToStdout(" Disk parameters:") 318 ToStdout(_FormatDict(custom_diskparams, diskparams)) 319 ToStdout(" Instance policy:") 320 ToStdout(_FormatDict(custom_ipolicy, ipolicy))
321 322 323 commands = { 324 "add": ( 325 AddGroup, ARGS_ONE_GROUP, 326 [DRY_RUN_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT, DISK_PARAMS_OPT, 327 HV_STATE_OPT, DISK_STATE_OPT, PRIORITY_OPT, 328 SUBMIT_OPT] + INSTANCE_POLICY_OPTS, 329 "<group_name>", "Add a new node group to the cluster"), 330 "assign-nodes": ( 331 AssignNodes, ARGS_ONE_GROUP + ARGS_MANY_NODES, 332 [DRY_RUN_OPT, FORCE_OPT, PRIORITY_OPT, SUBMIT_OPT], 333 "<group_name> <node>...", "Assign nodes to a group"), 334 "list": ( 335 ListGroups, ARGS_MANY_GROUPS, 336 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT, FORCE_FILTER_OPT], 337 "[<group_name>...]", 338 "Lists the node groups in the cluster. The available fields can be shown" 339 " using the \"list-fields\" command (see the man page for details)." 340 " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)), 341 "list-fields": ( 342 ListGroupFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]", 343 "Lists all available fields for node groups"), 344 "modify": ( 345 SetGroupParams, ARGS_ONE_GROUP, 346 [DRY_RUN_OPT, SUBMIT_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT, HV_STATE_OPT, 347 DISK_STATE_OPT, DISK_PARAMS_OPT, PRIORITY_OPT] + INSTANCE_POLICY_OPTS, 348 "<group_name>", "Alters the parameters of a node group"), 349 "remove": ( 350 RemoveGroup, ARGS_ONE_GROUP, [DRY_RUN_OPT, PRIORITY_OPT, SUBMIT_OPT], 351 "[--dry-run] <group-name>", 352 "Remove an (empty) node group from the cluster"), 353 "rename": ( 354 RenameGroup, [ArgGroup(min=2, max=2)], 355 [DRY_RUN_OPT, SUBMIT_OPT, PRIORITY_OPT], 356 "[--dry-run] <group-name> <new-name>", "Rename a node group"), 357 "evacuate": ( 358 EvacuateGroup, [ArgGroup(min=1, max=1)], 359 [TO_GROUP_OPT, IALLOCATOR_OPT, EARLY_RELEASE_OPT, SUBMIT_OPT, PRIORITY_OPT], 360 "[-I <iallocator>] [--to <group>]", 361 "Evacuate all instances within a group"), 362 "list-tags": ( 363 ListTags, ARGS_ONE_GROUP, [], 364 "<group_name>", "List the tags of the given group"), 365 "add-tags": ( 366 AddTags, [ArgGroup(min=1, max=1), ArgUnknown()], 367 [TAG_SRC_OPT, PRIORITY_OPT, SUBMIT_OPT], 368 "<group_name> tag...", "Add tags to the given group"), 369 "remove-tags": ( 370 RemoveTags, [ArgGroup(min=1, max=1), ArgUnknown()], 371 [TAG_SRC_OPT, PRIORITY_OPT, SUBMIT_OPT], 372 "<group_name> tag...", "Remove tags from the given group"), 373 "info": ( 374 GroupInfo, ARGS_MANY_GROUPS, [], "<group_name>", "Show group information"), 375 } 376 377
378 -def Main():
379 return GenericMain(commands, 380 override={"tag_type": constants.TAG_NODEGROUP}, 381 env_override=_ENV_OVERRIDE)
382