Revision 667dbd6b

b/.gitignore
76 76
/scripts/gnt-backup
77 77
/scripts/gnt-cluster
78 78
/scripts/gnt-debug
79
/scripts/gnt-group
79 80
/scripts/gnt-instance
80 81
/scripts/gnt-job
81 82
/scripts/gnt-node
b/Makefile.am
156 156
	lib/client/gnt_backup.py \
157 157
	lib/client/gnt_cluster.py \
158 158
	lib/client/gnt_debug.py \
159
	lib/client/gnt_group.py \
159 160
	lib/client/gnt_instance.py \
160 161
	lib/client/gnt_job.py \
161 162
	lib/client/gnt_node.py \
......
286 287
	scripts/gnt-backup \
287 288
	scripts/gnt-cluster \
288 289
	scripts/gnt-debug \
290
	scripts/gnt-group \
289 291
	scripts/gnt-instance \
290 292
	scripts/gnt-job \
291 293
	scripts/gnt-node \
......
300 302
	scripts/gnt-backup \
301 303
	scripts/gnt-cluster \
302 304
	scripts/gnt-debug \
305
	scripts/gnt-group \
303 306
	scripts/gnt-instance \
304 307
	scripts/gnt-job \
305 308
	scripts/gnt-node \
......
396 399
	man/gnt-backup.8 \
397 400
	man/gnt-cluster.8 \
398 401
	man/gnt-debug.8 \
402
	man/gnt-group.8 \
399 403
	man/gnt-instance.8 \
400 404
	man/gnt-job.8 \
401 405
	man/gnt-node.8 \
b/autotools/build-bash-completion
434 434
          choices = "$(_ganeti_instances)"
435 435
        elif isinstance(arg, cli.ArgNode):
436 436
          choices = "$(_ganeti_nodes)"
437
        elif isinstance(arg, cli.ArgGroup):
438
          choices = "$(_ganeti_nodegroup)"
437 439
        elif isinstance(arg, cli.ArgJobId):
438 440
          choices = "$(_ganeti_jobs)"
439 441
        elif isinstance(arg, cli.ArgOs):
b/lib/cli.py
183 183
  # command line options support infrastructure
184 184
  "ARGS_MANY_INSTANCES",
185 185
  "ARGS_MANY_NODES",
186
  "ARGS_MANY_GROUPS",
186 187
  "ARGS_NONE",
187 188
  "ARGS_ONE_INSTANCE",
188 189
  "ARGS_ONE_NODE",
190
  "ARGS_ONE_GROUP",
189 191
  "ARGS_ONE_OS",
190 192
  "ArgChoice",
191 193
  "ArgCommand",
192 194
  "ArgFile",
195
  "ArgGroup",
193 196
  "ArgHost",
194 197
  "ArgInstance",
195 198
  "ArgJobId",
......
279 282

  
280 283
  """
281 284

  
285

  
286
class ArgGroup(_Argument):
287
  """Node group argument.
288

  
289
  """
290

  
291

  
282 292
class ArgJobId(_Argument):
283 293
  """Job ID argument.
284 294

  
......
312 322
ARGS_NONE = []
313 323
ARGS_MANY_INSTANCES = [ArgInstance()]
314 324
ARGS_MANY_NODES = [ArgNode()]
325
ARGS_MANY_GROUPS = [ArgGroup()]
315 326
ARGS_ONE_INSTANCE = [ArgInstance(min=1, max=1)]
316 327
ARGS_ONE_NODE = [ArgNode(min=1, max=1)]
328
ARGS_ONE_GROUP = [ArgInstance(min=1, max=1)]
317 329
ARGS_ONE_OS = [ArgOs(min=1, max=1)]
318 330

  
319 331

  
b/lib/client/gnt_group.py
1
#
2
#
3

  
4
# Copyright (C) 2010 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-msg=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 compat
29

  
30

  
31
#: default list of fields for L{ListGroups}
32
_LIST_DEF_FIELDS = ["name", "node_cnt", "pinst_cnt"]
33

  
34

  
35
#: headers (and full field list) for L{ListGroups}
36
_LIST_HEADERS = {
37
  "name": "Group", "uuid": "UUID",
38
  "node_cnt": "Nodes", "node_list": "NodeList",
39
  "pinst_cnt": "Instances", "pinst_list": "InstanceList",
40
}
41

  
42

  
43
def ListGroups(opts, args):
44
  """List node groups and their properties.
45

  
46
  @param opts: the command line options selected by the user
47
  @type args: list
48
  @param args: groups to list, or empty for all
49
  @rtype: int
50
  @return: the desired exit code
51

  
52
  """
53
  desired_fields = ParseFields(opts.output, _LIST_DEF_FIELDS)
54

  
55
  output = GetClient().QueryGroups(args, desired_fields, opts.do_locking)
56

  
57
  if opts.no_headers:
58
    headers = None
59
  else:
60
    headers = _LIST_HEADERS
61

  
62
  int_type_fields = frozenset(["node_cnt", "pinst_cnt"])
63
  list_type_fields = frozenset(["node_list", "pinst_list"])
64

  
65
  for row in output:
66
    for idx, field in enumerate(desired_fields):
67
      val = row[idx]
68

  
69
      if field in list_type_fields:
70
        val = ",".join(val)
71
      elif opts.roman_integers and field in int_type_fields:
72
        val = compat.TryToRoman(val)
73
      elif val is None:
74
        val = "?"
75

  
76
      row[idx] = str(val)
77

  
78
  data = GenerateTable(separator=opts.separator, headers=headers,
79
                       fields=desired_fields, data=output)
80

  
81
  for line in data:
82
    ToStdout(line)
83

  
84
  return 0
85

  
86

  
87
commands = {
88
  "list": (
89
    ListGroups, ARGS_MANY_GROUPS,
90
    [NOHDR_OPT, SEP_OPT, FIELDS_OPT, SYNC_OPT, ROMAN_OPT],
91
    "[<group_name>...]", "Lists the node groups in the cluster."),
92
}
93

  
94

  
95
def Main():
96
  return GenericMain(commands)
b/man/footer.rst
14 14
Ganeti commands: **gnt-cluster**(8) (cluster-wide commands),
15 15
**gnt-job**(8) (job-related commands), **gnt-node**(8) (node-related
16 16
commands), **gnt-instance**(8) (instance commands), **gnt-os**(8)
17
(guest OS commands), **gnt-backup**(8) (instance import/export
18
commands), **gnt-debug**(8) (debug commands).
17
(guest OS commands), **gnt-group**(8) (node group commands),
18
**gnt-backup**(8) (instance import/export commands), **gnt-debug**(8)
19
(debug commands).
19 20

  
20 21
Ganeti daemons: **ganeti-watcher**(8) (automatic instance restarter),
21 22
**ganeti-cleaner**(8) (job queue cleaner), **ganeti-noded**(8) (node
b/man/gnt-group.rst
1
gnt-group(8) Ganeti | Version @GANETI_VERSION@
2
==============================================
3

  
4
Name
5
----
6

  
7
gnt-group - Ganeti node-group administration
8

  
9
Synopsis
10
--------
11

  
12
**gnt-group** {command} [arguments...]
13

  
14
DESCRIPTION
15
-----------
16

  
17
The **gnt-group** command is used for node group administration in
18
the Ganeti system.
19

  
20
COMMANDS
21
--------
22

  
23
LIST
24
~~~~
25

  
26
| **list** [--no-headers] [--separator=*SEPARATOR*]
27
| [-o *[+]FIELD,...*] [group...]
28

  
29
Lists all existing node groups in the cluster.
30

  
31
The ``--no-headers`` option will skip the initial header line. The
32
``--separator`` option takes an argument which denotes what will be
33
used between the output fields. Both these options are to help
34
scripting.
35

  
36
The ``-o`` option takes a comma-separated list of output fields.
37
If the value of the option starts with the character ``+``, the new
38
fields will be added to the default list. This allows to quickly
39
see the default list plus a few other fields, instead of retyping
40
the entire list of fields.
41

  
42
The available fields and their meaning are:
43

  
44
name
45
    the group name
46

  
47
uuid
48
    the group's UUID
49

  
50
node_cnt
51
    the number of nodes in the node group
52

  
53
node_list
54
    the list of nodes that belong to this group
55

  
56
pinst_cnt
57
    the number of primary instances in the group (i.e., the number of
58
    primary instances nodes in this group have)
59

  
60
pinst_list
61
    the list of primary instances in the group
62

  
63
If no group names are given, then all groups are included. Otherwise,
64
only the named groups will be listed.

Also available in: Unified diff