Statistics
| Branch: | Tag: | Revision:

root / lib / client / gnt_group.py @ 36c70d4d

History | View | Annotate | Download (10.2 kB)

1 667dbd6b Adeodato Simo
#
2 667dbd6b Adeodato Simo
#
3 667dbd6b Adeodato Simo
4 57dc299a Iustin Pop
# Copyright (C) 2010, 2011, 2012 Google Inc.
5 667dbd6b Adeodato Simo
#
6 667dbd6b Adeodato Simo
# This program is free software; you can redistribute it and/or modify
7 667dbd6b Adeodato Simo
# it under the terms of the GNU General Public License as published by
8 667dbd6b Adeodato Simo
# the Free Software Foundation; either version 2 of the License, or
9 667dbd6b Adeodato Simo
# (at your option) any later version.
10 667dbd6b Adeodato Simo
#
11 667dbd6b Adeodato Simo
# This program is distributed in the hope that it will be useful, but
12 667dbd6b Adeodato Simo
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 667dbd6b Adeodato Simo
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 667dbd6b Adeodato Simo
# General Public License for more details.
15 667dbd6b Adeodato Simo
#
16 667dbd6b Adeodato Simo
# You should have received a copy of the GNU General Public License
17 667dbd6b Adeodato Simo
# along with this program; if not, write to the Free Software
18 667dbd6b Adeodato Simo
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 667dbd6b Adeodato Simo
# 02110-1301, USA.
20 667dbd6b Adeodato Simo
21 667dbd6b Adeodato Simo
"""Node group related commands"""
22 667dbd6b Adeodato Simo
23 b459a848 Andrea Spadaccini
# pylint: disable=W0401,W0614
24 667dbd6b Adeodato Simo
# W0401: Wildcard import ganeti.cli
25 667dbd6b Adeodato Simo
# W0614: Unused import %s from wildcard import (since we need cli)
26 667dbd6b Adeodato Simo
27 667dbd6b Adeodato Simo
from ganeti.cli import *
28 ca4ac9c9 Adeodato Simo
from ganeti import constants
29 1f5d9bf8 Agata Murawska
from ganeti import objects
30 66e884e1 Adeodato Simo
from ganeti import opcodes
31 4edc512c Adeodato Simo
from ganeti import utils
32 667dbd6b Adeodato Simo
33 667dbd6b Adeodato Simo
34 667dbd6b Adeodato Simo
#: default list of fields for L{ListGroups}
35 b288b6f3 René Nussbaumer
_LIST_DEF_FIELDS = ["name", "node_cnt", "pinst_cnt", "alloc_policy", "ndparams"]
36 667dbd6b Adeodato Simo
37 667dbd6b Adeodato Simo
38 ef9fa5b9 René Nussbaumer
_ENV_OVERRIDE = frozenset(["list"])
39 ef9fa5b9 René Nussbaumer
40 ef9fa5b9 René Nussbaumer
41 66e884e1 Adeodato Simo
def AddGroup(opts, args):
42 66e884e1 Adeodato Simo
  """Add a node group to the cluster.
43 66e884e1 Adeodato Simo

44 66e884e1 Adeodato Simo
  @param opts: the command line options selected by the user
45 66e884e1 Adeodato Simo
  @type args: list
46 66e884e1 Adeodato Simo
  @param args: a list of length 1 with the name of the group to create
47 66e884e1 Adeodato Simo
  @rtype: int
48 66e884e1 Adeodato Simo
  @return: the desired exit code
49 66e884e1 Adeodato Simo

50 66e884e1 Adeodato Simo
  """
51 1f5d9bf8 Agata Murawska
  ipolicy = \
52 1f5d9bf8 Agata Murawska
    objects.CreateIPolicyFromOpts(ispecs_mem_size=opts.ispecs_mem_size,
53 1f5d9bf8 Agata Murawska
                                  ispecs_cpu_count=opts.ispecs_cpu_count,
54 1f5d9bf8 Agata Murawska
                                  ispecs_disk_count=opts.ispecs_disk_count,
55 1f5d9bf8 Agata Murawska
                                  ispecs_disk_size=opts.ispecs_disk_size,
56 1f5d9bf8 Agata Murawska
                                  ispecs_nic_count=opts.ispecs_nic_count,
57 1f5d9bf8 Agata Murawska
                                  group_ipolicy=True)
58 1f5d9bf8 Agata Murawska
59 66e884e1 Adeodato Simo
  (group_name,) = args
60 bc5d0215 Andrea Spadaccini
  diskparams = dict(opts.diskparams)
61 e4c03256 René Nussbaumer
62 e4c03256 René Nussbaumer
  if opts.disk_state:
63 e4c03256 René Nussbaumer
    disk_state = utils.FlatToDict(opts.disk_state)
64 e4c03256 René Nussbaumer
  else:
65 e4c03256 René Nussbaumer
    disk_state = {}
66 e4c03256 René Nussbaumer
  hv_state = dict(opts.hv_state)
67 e4c03256 René Nussbaumer
68 fabf1731 Iustin Pop
  op = opcodes.OpGroupAdd(group_name=group_name, ndparams=opts.ndparams,
69 bc5d0215 Andrea Spadaccini
                          alloc_policy=opts.alloc_policy,
70 e4c03256 René Nussbaumer
                          diskparams=diskparams, ipolicy=ipolicy,
71 e4c03256 René Nussbaumer
                          hv_state=hv_state,
72 e4c03256 René Nussbaumer
                          disk_state=disk_state)
73 66e884e1 Adeodato Simo
  SubmitOpCode(op, opts=opts)
74 66e884e1 Adeodato Simo
75 66e884e1 Adeodato Simo
76 919852da Adeodato Simo
def AssignNodes(opts, args):
77 919852da Adeodato Simo
  """Assign nodes to a group.
78 919852da Adeodato Simo

79 919852da Adeodato Simo
  @param opts: the command line options selected by the user
80 919852da Adeodato Simo
  @type args: list
81 919852da Adeodato Simo
  @param args: args[0]: group to assign nodes to; args[1:]: nodes to assign
82 919852da Adeodato Simo
  @rtype: int
83 919852da Adeodato Simo
  @return: the desired exit code
84 919852da Adeodato Simo

85 919852da Adeodato Simo
  """
86 919852da Adeodato Simo
  group_name = args[0]
87 919852da Adeodato Simo
  node_names = args[1:]
88 919852da Adeodato Simo
89 934704ae Iustin Pop
  op = opcodes.OpGroupAssignNodes(group_name=group_name, nodes=node_names,
90 919852da Adeodato Simo
                                  force=opts.force)
91 919852da Adeodato Simo
  SubmitOpCode(op, opts=opts)
92 919852da Adeodato Simo
93 919852da Adeodato Simo
94 b288b6f3 René Nussbaumer
def _FmtDict(data):
95 b288b6f3 René Nussbaumer
  """Format dict data into command-line format.
96 b288b6f3 René Nussbaumer

97 b288b6f3 René Nussbaumer
  @param data: The input dict to be formatted
98 b288b6f3 René Nussbaumer
  @return: The formatted dict
99 b288b6f3 René Nussbaumer

100 b288b6f3 René Nussbaumer
  """
101 b288b6f3 René Nussbaumer
  if not data:
102 b288b6f3 René Nussbaumer
    return "(empty)"
103 b288b6f3 René Nussbaumer
104 b288b6f3 René Nussbaumer
  return utils.CommaJoin(["%s=%s" % (key, value)
105 b288b6f3 René Nussbaumer
                          for key, value in data.items()])
106 b288b6f3 René Nussbaumer
107 b288b6f3 René Nussbaumer
108 667dbd6b Adeodato Simo
def ListGroups(opts, args):
109 667dbd6b Adeodato Simo
  """List node groups and their properties.
110 667dbd6b Adeodato Simo

111 667dbd6b Adeodato Simo
  @param opts: the command line options selected by the user
112 667dbd6b Adeodato Simo
  @type args: list
113 667dbd6b Adeodato Simo
  @param args: groups to list, or empty for all
114 667dbd6b Adeodato Simo
  @rtype: int
115 667dbd6b Adeodato Simo
  @return: the desired exit code
116 667dbd6b Adeodato Simo

117 667dbd6b Adeodato Simo
  """
118 667dbd6b Adeodato Simo
  desired_fields = ParseFields(opts.output, _LIST_DEF_FIELDS)
119 b288b6f3 René Nussbaumer
  fmtoverride = {
120 b288b6f3 René Nussbaumer
    "node_list": (",".join, False),
121 b288b6f3 René Nussbaumer
    "pinst_list": (",".join, False),
122 b288b6f3 René Nussbaumer
    "ndparams": (_FmtDict, False),
123 b288b6f3 René Nussbaumer
    }
124 667dbd6b Adeodato Simo
125 ca4ac9c9 Adeodato Simo
  return GenericList(constants.QR_GROUP, desired_fields, args, None,
126 ca4ac9c9 Adeodato Simo
                     opts.separator, not opts.no_headers,
127 1b1a08e8 Michael Hanselmann
                     format_override=fmtoverride, verbose=opts.verbose,
128 1b1a08e8 Michael Hanselmann
                     force_filter=opts.force_filter)
129 667dbd6b Adeodato Simo
130 667dbd6b Adeodato Simo
131 ca4ac9c9 Adeodato Simo
def ListGroupFields(opts, args):
132 ca4ac9c9 Adeodato Simo
  """List node fields.
133 667dbd6b Adeodato Simo

134 ca4ac9c9 Adeodato Simo
  @param opts: the command line options selected by the user
135 ca4ac9c9 Adeodato Simo
  @type args: list
136 ca4ac9c9 Adeodato Simo
  @param args: fields to list, or empty for all
137 ca4ac9c9 Adeodato Simo
  @rtype: int
138 ca4ac9c9 Adeodato Simo
  @return: the desired exit code
139 667dbd6b Adeodato Simo

140 ca4ac9c9 Adeodato Simo
  """
141 ca4ac9c9 Adeodato Simo
  return GenericListFields(constants.QR_GROUP, args, opts.separator,
142 ca4ac9c9 Adeodato Simo
                           not opts.no_headers)
143 667dbd6b Adeodato Simo
144 667dbd6b Adeodato Simo
145 4da7909a Adeodato Simo
def SetGroupParams(opts, args):
146 4da7909a Adeodato Simo
  """Modifies a node group's parameters.
147 4da7909a Adeodato Simo

148 fecbc0b6 Stephen Shirley
  @param opts: the command line options selected by the user
149 4da7909a Adeodato Simo
  @type args: list
150 4da7909a Adeodato Simo
  @param args: should contain only one element, the node group name
151 4da7909a Adeodato Simo

152 4da7909a Adeodato Simo
  @rtype: int
153 4da7909a Adeodato Simo
  @return: the desired exit code
154 4da7909a Adeodato Simo

155 4da7909a Adeodato Simo
  """
156 fb644e77 Agata Murawska
  allmods = [opts.ndparams, opts.alloc_policy, opts.diskparams, opts.hv_state,
157 fb644e77 Agata Murawska
             opts.disk_state, opts.ispecs_mem_size, opts.ispecs_cpu_count,
158 fb644e77 Agata Murawska
             opts.ispecs_disk_count, opts.ispecs_disk_size,
159 fb644e77 Agata Murawska
             opts.ispecs_nic_count, opts.diskparams]
160 fb644e77 Agata Murawska
  if allmods.count(None) == len(allmods):
161 4da7909a Adeodato Simo
    ToStderr("Please give at least one of the parameters.")
162 4da7909a Adeodato Simo
    return 1
163 4da7909a Adeodato Simo
164 a8282327 René Nussbaumer
  if opts.disk_state:
165 a8282327 René Nussbaumer
    disk_state = utils.FlatToDict(opts.disk_state)
166 a8282327 René Nussbaumer
  else:
167 a8282327 René Nussbaumer
    disk_state = {}
168 a8282327 René Nussbaumer
169 a8282327 René Nussbaumer
  hv_state = dict(opts.hv_state)
170 a8282327 René Nussbaumer
171 bc5d0215 Andrea Spadaccini
  diskparams = dict(opts.diskparams)
172 fb644e77 Agata Murawska
173 fb644e77 Agata Murawska
  # set the default values
174 fb644e77 Agata Murawska
  to_ipolicy = [
175 fb644e77 Agata Murawska
    opts.ispecs_mem_size,
176 fb644e77 Agata Murawska
    opts.ispecs_cpu_count,
177 fb644e77 Agata Murawska
    opts.ispecs_disk_count,
178 fb644e77 Agata Murawska
    opts.ispecs_disk_size,
179 fb644e77 Agata Murawska
    opts.ispecs_nic_count,
180 fb644e77 Agata Murawska
    ]
181 fb644e77 Agata Murawska
  for ispec in to_ipolicy:
182 fb644e77 Agata Murawska
    for param in ispec:
183 fb644e77 Agata Murawska
      if isinstance(ispec[param], basestring):
184 fb644e77 Agata Murawska
        if ispec[param].lower() == "default":
185 fb644e77 Agata Murawska
          ispec[param] = constants.VALUE_DEFAULT
186 fb644e77 Agata Murawska
  # create ipolicy object
187 fb644e77 Agata Murawska
  ipolicy = objects.CreateIPolicyFromOpts(\
188 fb644e77 Agata Murawska
    ispecs_mem_size=opts.ispecs_mem_size,
189 fb644e77 Agata Murawska
    ispecs_cpu_count=opts.ispecs_cpu_count,
190 fb644e77 Agata Murawska
    ispecs_disk_count=opts.ispecs_disk_count,
191 fb644e77 Agata Murawska
    ispecs_disk_size=opts.ispecs_disk_size,
192 fb644e77 Agata Murawska
    ispecs_nic_count=opts.ispecs_nic_count,
193 d04c9d45 Iustin Pop
    ipolicy_disk_templates=opts.ipolicy_disk_templates,
194 fb644e77 Agata Murawska
    group_ipolicy=True,
195 fb644e77 Agata Murawska
    allowed_values=[constants.VALUE_DEFAULT])
196 fb644e77 Agata Murawska
197 8e47b5da Michael Hanselmann
  op = opcodes.OpGroupSetParams(group_name=args[0],
198 8e47b5da Michael Hanselmann
                                ndparams=opts.ndparams,
199 bc5d0215 Andrea Spadaccini
                                alloc_policy=opts.alloc_policy,
200 a8282327 René Nussbaumer
                                hv_state=hv_state,
201 a8282327 René Nussbaumer
                                disk_state=disk_state,
202 fb644e77 Agata Murawska
                                diskparams=diskparams,
203 fb644e77 Agata Murawska
                                ipolicy=ipolicy)
204 fb644e77 Agata Murawska
205 4da7909a Adeodato Simo
  result = SubmitOrSend(op, opts)
206 4da7909a Adeodato Simo
207 4da7909a Adeodato Simo
  if result:
208 4da7909a Adeodato Simo
    ToStdout("Modified node group %s", args[0])
209 4da7909a Adeodato Simo
    for param, data in result:
210 4da7909a Adeodato Simo
      ToStdout(" - %-5s -> %s", param, data)
211 4da7909a Adeodato Simo
212 4da7909a Adeodato Simo
  return 0
213 4da7909a Adeodato Simo
214 4da7909a Adeodato Simo
215 66e884e1 Adeodato Simo
def RemoveGroup(opts, args):
216 66e884e1 Adeodato Simo
  """Remove a node group from the cluster.
217 66e884e1 Adeodato Simo

218 66e884e1 Adeodato Simo
  @param opts: the command line options selected by the user
219 66e884e1 Adeodato Simo
  @type args: list
220 66e884e1 Adeodato Simo
  @param args: a list of length 1 with the name of the group to remove
221 66e884e1 Adeodato Simo
  @rtype: int
222 66e884e1 Adeodato Simo
  @return: the desired exit code
223 66e884e1 Adeodato Simo

224 66e884e1 Adeodato Simo
  """
225 66e884e1 Adeodato Simo
  (group_name,) = args
226 4d1baa51 Iustin Pop
  op = opcodes.OpGroupRemove(group_name=group_name)
227 66e884e1 Adeodato Simo
  SubmitOpCode(op, opts=opts)
228 66e884e1 Adeodato Simo
229 66e884e1 Adeodato Simo
230 66e884e1 Adeodato Simo
def RenameGroup(opts, args):
231 66e884e1 Adeodato Simo
  """Rename a node group.
232 66e884e1 Adeodato Simo

233 66e884e1 Adeodato Simo
  @param opts: the command line options selected by the user
234 66e884e1 Adeodato Simo
  @type args: list
235 66e884e1 Adeodato Simo
  @param args: a list of length 2, [old_name, new_name]
236 66e884e1 Adeodato Simo
  @rtype: int
237 66e884e1 Adeodato Simo
  @return: the desired exit code
238 66e884e1 Adeodato Simo

239 66e884e1 Adeodato Simo
  """
240 12da663a Michael Hanselmann
  group_name, new_name = args
241 12da663a Michael Hanselmann
  op = opcodes.OpGroupRename(group_name=group_name, new_name=new_name)
242 66e884e1 Adeodato Simo
  SubmitOpCode(op, opts=opts)
243 66e884e1 Adeodato Simo
244 66e884e1 Adeodato Simo
245 f6eb380d Michael Hanselmann
def EvacuateGroup(opts, args):
246 f6eb380d Michael Hanselmann
  """Evacuate a node group.
247 f6eb380d Michael Hanselmann

248 f6eb380d Michael Hanselmann
  """
249 f6eb380d Michael Hanselmann
  (group_name, ) = args
250 f6eb380d Michael Hanselmann
251 f6eb380d Michael Hanselmann
  cl = GetClient()
252 f6eb380d Michael Hanselmann
253 f6eb380d Michael Hanselmann
  op = opcodes.OpGroupEvacuate(group_name=group_name,
254 f6eb380d Michael Hanselmann
                               iallocator=opts.iallocator,
255 f6eb380d Michael Hanselmann
                               target_groups=opts.to,
256 f6eb380d Michael Hanselmann
                               early_release=opts.early_release)
257 f6eb380d Michael Hanselmann
  result = SubmitOpCode(op, cl=cl, opts=opts)
258 f6eb380d Michael Hanselmann
259 f6eb380d Michael Hanselmann
  # Keep track of submitted jobs
260 f6eb380d Michael Hanselmann
  jex = JobExecutor(cl=cl, opts=opts)
261 f6eb380d Michael Hanselmann
262 f6eb380d Michael Hanselmann
  for (status, job_id) in result[constants.JOB_IDS_KEY]:
263 f6eb380d Michael Hanselmann
    jex.AddJobId(None, status, job_id)
264 f6eb380d Michael Hanselmann
265 f6eb380d Michael Hanselmann
  results = jex.GetResults()
266 f6eb380d Michael Hanselmann
  bad_cnt = len([row for row in results if not row[0]])
267 f6eb380d Michael Hanselmann
  if bad_cnt == 0:
268 f6eb380d Michael Hanselmann
    ToStdout("All instances evacuated successfully.")
269 f6eb380d Michael Hanselmann
    rcode = constants.EXIT_SUCCESS
270 f6eb380d Michael Hanselmann
  else:
271 f6eb380d Michael Hanselmann
    ToStdout("There were %s errors during the evacuation.", bad_cnt)
272 f6eb380d Michael Hanselmann
    rcode = constants.EXIT_FAILURE
273 f6eb380d Michael Hanselmann
274 f6eb380d Michael Hanselmann
  return rcode
275 f6eb380d Michael Hanselmann
276 667dbd6b Adeodato Simo
commands = {
277 66e884e1 Adeodato Simo
  "add": (
278 bc5d0215 Andrea Spadaccini
    AddGroup, ARGS_ONE_GROUP,
279 e4c03256 René Nussbaumer
    [DRY_RUN_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT, DISK_PARAMS_OPT,
280 e4c03256 René Nussbaumer
     HV_STATE_OPT, DISK_STATE_OPT] + INSTANCE_POLICY_OPTS,
281 66e884e1 Adeodato Simo
    "<group_name>", "Add a new node group to the cluster"),
282 919852da Adeodato Simo
  "assign-nodes": (
283 919852da Adeodato Simo
    AssignNodes, ARGS_ONE_GROUP + ARGS_MANY_NODES, [DRY_RUN_OPT, FORCE_OPT],
284 919852da Adeodato Simo
    "<group_name> <node>...", "Assign nodes to a group"),
285 667dbd6b Adeodato Simo
  "list": (
286 667dbd6b Adeodato Simo
    ListGroups, ARGS_MANY_GROUPS,
287 1b1a08e8 Michael Hanselmann
    [NOHDR_OPT, SEP_OPT, FIELDS_OPT, VERBOSE_OPT, FORCE_FILTER_OPT],
288 4edc512c Adeodato Simo
    "[<group_name>...]",
289 ca4ac9c9 Adeodato Simo
    "Lists the node groups in the cluster. The available fields can be shown"
290 ca4ac9c9 Adeodato Simo
    " using the \"list-fields\" command (see the man page for details)."
291 ca4ac9c9 Adeodato Simo
    " The default list is (in order): %s." % utils.CommaJoin(_LIST_DEF_FIELDS)),
292 ca4ac9c9 Adeodato Simo
  "list-fields": (
293 ca4ac9c9 Adeodato Simo
    ListGroupFields, [ArgUnknown()], [NOHDR_OPT, SEP_OPT], "[fields...]",
294 ca4ac9c9 Adeodato Simo
    "Lists all available fields for node groups"),
295 4da7909a Adeodato Simo
  "modify": (
296 4da7909a Adeodato Simo
    SetGroupParams, ARGS_ONE_GROUP,
297 a8282327 René Nussbaumer
    [DRY_RUN_OPT, SUBMIT_OPT, ALLOC_POLICY_OPT, NODE_PARAMS_OPT, HV_STATE_OPT,
298 fb644e77 Agata Murawska
     DISK_STATE_OPT, DISK_PARAMS_OPT] + INSTANCE_POLICY_OPTS,
299 4da7909a Adeodato Simo
    "<group_name>", "Alters the parameters of a node group"),
300 66e884e1 Adeodato Simo
  "remove": (
301 66e884e1 Adeodato Simo
    RemoveGroup, ARGS_ONE_GROUP, [DRY_RUN_OPT],
302 12da663a Michael Hanselmann
    "[--dry-run] <group-name>",
303 66e884e1 Adeodato Simo
    "Remove an (empty) node group from the cluster"),
304 66e884e1 Adeodato Simo
  "rename": (
305 66e884e1 Adeodato Simo
    RenameGroup, [ArgGroup(min=2, max=2)], [DRY_RUN_OPT],
306 12da663a Michael Hanselmann
    "[--dry-run] <group-name> <new-name>", "Rename a node group"),
307 f6eb380d Michael Hanselmann
  "evacuate": (
308 f6eb380d Michael Hanselmann
    EvacuateGroup, [ArgGroup(min=1, max=1)],
309 f6eb380d Michael Hanselmann
    [TO_GROUP_OPT, IALLOCATOR_OPT, EARLY_RELEASE_OPT],
310 6e80da8b Michael Hanselmann
    "[-I <iallocator>] [--to <group>]",
311 6e80da8b Michael Hanselmann
    "Evacuate all instances within a group"),
312 819cbfe5 Michael Hanselmann
  "list-tags": (
313 819cbfe5 Michael Hanselmann
    ListTags, ARGS_ONE_GROUP, [PRIORITY_OPT],
314 36c70d4d Iustin Pop
    "<group_name>", "List the tags of the given group"),
315 819cbfe5 Michael Hanselmann
  "add-tags": (
316 819cbfe5 Michael Hanselmann
    AddTags, [ArgGroup(min=1, max=1), ArgUnknown()],
317 819cbfe5 Michael Hanselmann
    [TAG_SRC_OPT, PRIORITY_OPT],
318 36c70d4d Iustin Pop
    "<group_name> tag...", "Add tags to the given group"),
319 819cbfe5 Michael Hanselmann
  "remove-tags": (
320 819cbfe5 Michael Hanselmann
    RemoveTags, [ArgGroup(min=1, max=1), ArgUnknown()],
321 819cbfe5 Michael Hanselmann
    [TAG_SRC_OPT, PRIORITY_OPT],
322 36c70d4d Iustin Pop
    "<group_name> tag...", "Remove tags from the given group"),
323 819cbfe5 Michael Hanselmann
  }
324 667dbd6b Adeodato Simo
325 667dbd6b Adeodato Simo
326 667dbd6b Adeodato Simo
def Main():
327 819cbfe5 Michael Hanselmann
  return GenericMain(commands,
328 ef9fa5b9 René Nussbaumer
                     override={"tag_type": constants.TAG_NODEGROUP},
329 ef9fa5b9 René Nussbaumer
                     env_override=_ENV_OVERRIDE)