1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """Node group related commands"""
22
23
24
25
26
27 from ganeti.cli import *
28 from ganeti import constants
29 from ganeti import opcodes
30 from ganeti import utils
31
32
33
34 _LIST_DEF_FIELDS = ["name", "node_cnt", "pinst_cnt", "alloc_policy", "ndparams"]
35
36
38 """Add a node group to the cluster.
39
40 @param opts: the command line options selected by the user
41 @type args: list
42 @param args: a list of length 1 with the name of the group to create
43 @rtype: int
44 @return: the desired exit code
45
46 """
47 (group_name,) = args
48 op = opcodes.OpGroupAdd(group_name=group_name, ndparams=opts.ndparams,
49 alloc_policy=opts.alloc_policy)
50 SubmitOpCode(op, opts=opts)
51
52
54 """Assign nodes to a group.
55
56 @param opts: the command line options selected by the user
57 @type args: list
58 @param args: args[0]: group to assign nodes to; args[1:]: nodes to assign
59 @rtype: int
60 @return: the desired exit code
61
62 """
63 group_name = args[0]
64 node_names = args[1:]
65
66 op = opcodes.OpGroupAssignNodes(group_name=group_name, nodes=node_names,
67 force=opts.force)
68 SubmitOpCode(op, opts=opts)
69
70
72 """Format dict data into command-line format.
73
74 @param data: The input dict to be formatted
75 @return: The formatted dict
76
77 """
78 if not data:
79 return "(empty)"
80
81 return utils.CommaJoin(["%s=%s" % (key, value)
82 for key, value in data.items()])
83
84
86 """List node groups and their properties.
87
88 @param opts: the command line options selected by the user
89 @type args: list
90 @param args: groups to list, or empty for all
91 @rtype: int
92 @return: the desired exit code
93
94 """
95 desired_fields = ParseFields(opts.output, _LIST_DEF_FIELDS)
96 fmtoverride = {
97 "node_list": (",".join, False),
98 "pinst_list": (",".join, False),
99 "ndparams": (_FmtDict, False),
100 }
101
102 return GenericList(constants.QR_GROUP, desired_fields, args, None,
103 opts.separator, not opts.no_headers,
104 format_override=fmtoverride, verbose=opts.verbose,
105 force_filter=opts.force_filter)
106
107
109 """List node fields.
110
111 @param opts: the command line options selected by the user
112 @type args: list
113 @param args: fields to list, or empty for all
114 @rtype: int
115 @return: the desired exit code
116
117 """
118 return GenericListFields(constants.QR_GROUP, args, opts.separator,
119 not opts.no_headers)
120
121
123 """Modifies a node group's parameters.
124
125 @param opts: the command line options selected by the user
126 @type args: list
127 @param args: should contain only one element, the node group name
128
129 @rtype: int
130 @return: the desired exit code
131
132 """
133 if opts.ndparams is None and opts.alloc_policy is None:
134 ToStderr("Please give at least one of the parameters.")
135 return 1
136
137 op = opcodes.OpGroupSetParams(group_name=args[0],
138 ndparams=opts.ndparams,
139 alloc_policy=opts.alloc_policy)
140 result = SubmitOrSend(op, opts)
141
142 if result:
143 ToStdout("Modified node group %s", args[0])
144 for param, data in result:
145 ToStdout(" - %-5s -> %s", param, data)
146
147 return 0
148
149
151 """Remove a node group from the cluster.
152
153 @param opts: the command line options selected by the user
154 @type args: list
155 @param args: a list of length 1 with the name of the group to remove
156 @rtype: int
157 @return: the desired exit code
158
159 """
160 (group_name,) = args
161 op = opcodes.OpGroupRemove(group_name=group_name)
162 SubmitOpCode(op, opts=opts)
163
164
166 """Rename a node group.
167
168 @param opts: the command line options selected by the user
169 @type args: list
170 @param args: a list of length 2, [old_name, new_name]
171 @rtype: int
172 @return: the desired exit code
173
174 """
175 group_name, new_name = args
176 op = opcodes.OpGroupRename(group_name=group_name, new_name=new_name)
177 SubmitOpCode(op, opts=opts)
178
179
181 """Evacuate a node group.
182
183 """
184 (group_name, ) = args
185
186 cl = GetClient()
187
188 op = opcodes.OpGroupEvacuate(group_name=group_name,
189 iallocator=opts.iallocator,
190 target_groups=opts.to,
191 early_release=opts.early_release)
192 result = SubmitOpCode(op, cl=cl, opts=opts)
193
194
195 jex = JobExecutor(cl=cl, opts=opts)
196
197 for (status, job_id) in result[constants.JOB_IDS_KEY]:
198 jex.AddJobId(None, status, job_id)
199
200 results = jex.GetResults()
201 bad_cnt = len([row for row in results if not row[0]])
202 if bad_cnt == 0:
203 ToStdout("All instances evacuated successfully.")
204 rcode = constants.EXIT_SUCCESS
205 else:
206 ToStdout("There were %s errors during the evacuation.", bad_cnt)
207 rcode = constants.EXIT_FAILURE
208
209 return rcode
210
211
212 commands = {
213 "add": (
214 AddGroup, ARGS_ONE_GROUP, [DRY_RUN_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT],
215 "<group_name>", "Add a new node group to the cluster"),
216 "assign-nodes": (
217 AssignNodes, ARGS_ONE_GROUP + ARGS_MANY_NODES, [DRY_RUN_OPT, FORCE_OPT],
218 "<group_name> <node>...", "Assign nodes to a group"),
219 "list": (
220 ListGroups, ARGS_MANY_GROUPS,
221 [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT, FORCE_FILTER_OPT],
222 "[<group_name>...]",
223 "Lists the node groups in the cluster. The available fields can be shown"
224 " using the \"list-fields\" command (see the man page for details)."
225 " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)),
226 "list-fields": (
227 ListGroupFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]",
228 "Lists all available fields for node groups"),
229 "modify": (
230 SetGroupParams, ARGS_ONE_GROUP,
231 [DRY_RUN_OPT, SUBMIT_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT],
232 "<group_name>", "Alters the parameters of a node group"),
233 "remove": (
234 RemoveGroup, ARGS_ONE_GROUP, [DRY_RUN_OPT],
235 "[--dry-run] <group-name>",
236 "Remove an (empty) node group from the cluster"),
237 "rename": (
238 RenameGroup, [ArgGroup(min=2, max=2)], [DRY_RUN_OPT],
239 "[--dry-run] <group-name> <new-name>", "Rename a node group"),
240 "evacuate": (
241 EvacuateGroup, [ArgGroup(min=1, max=1)],
242 [TO_GROUP_OPT, IALLOCATOR_OPT, EARLY_RELEASE_OPT],
243 "[-I <iallocator>] [--to <group>]",
244 "Evacuate all instances within a group"),
245 "list-tags": (
246 ListTags, ARGS_ONE_GROUP, [PRIORITY_OPT],
247 "<group_name>", "List the tags of the given group"),
248 "add-tags": (
249 AddTags, [ArgGroup(min=1, max=1), ArgUnknown()],
250 [TAG_SRC_OPT, PRIORITY_OPT],
251 "<group_name> tag...", "Add tags to the given group"),
252 "remove-tags": (
253 RemoveTags, [ArgGroup(min=1, max=1), ArgUnknown()],
254 [TAG_SRC_OPT, PRIORITY_OPT],
255 "<group_name> tag...", "Remove tags from the given group"),
256 }
257
258
260 return GenericMain(commands,
261 override={"tag_type": constants.TAG_NODEGROUP})
262