Statistics
| Branch: | Tag: | Revision:

root / qa / qa_config.py @ 7af293d7

History | View | Annotate | Download (17.1 kB)

1 c68d1f43 Michael Hanselmann
#
2 c68d1f43 Michael Hanselmann
#
3 c68d1f43 Michael Hanselmann
4 906a0346 Bernardo Dal Seno
# Copyright (C) 2007, 2011, 2012, 2013 Google Inc.
5 cec9845c Michael Hanselmann
#
6 cec9845c Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 cec9845c Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 cec9845c Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 cec9845c Michael Hanselmann
# (at your option) any later version.
10 cec9845c Michael Hanselmann
#
11 cec9845c Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 cec9845c Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 cec9845c Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 cec9845c Michael Hanselmann
# General Public License for more details.
15 cec9845c Michael Hanselmann
#
16 cec9845c Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 cec9845c Michael Hanselmann
# along with this program; if not, write to the Free Software
18 cec9845c Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 cec9845c Michael Hanselmann
# 02110-1301, USA.
20 cec9845c Michael Hanselmann
21 cec9845c Michael Hanselmann
22 cec9845c Michael Hanselmann
"""QA configuration.
23 cec9845c Michael Hanselmann

24 cec9845c Michael Hanselmann
"""
25 cec9845c Michael Hanselmann
26 c9e05005 Michael Hanselmann
import os
27 cec9845c Michael Hanselmann
28 e7b6183b Michael Hanselmann
from ganeti import constants
29 a705dc05 Michael Hanselmann
from ganeti import utils
30 a705dc05 Michael Hanselmann
from ganeti import serializer
31 7d88f255 Iustin Pop
from ganeti import compat
32 76fda900 Michael Hanselmann
from ganeti import ht
33 cec9845c Michael Hanselmann
34 cec9845c Michael Hanselmann
import qa_error
35 cec9845c Michael Hanselmann
36 cec9845c Michael Hanselmann
37 c9e05005 Michael Hanselmann
_INSTANCE_CHECK_KEY = "instance-check"
38 e7b6183b Michael Hanselmann
_ENABLED_HV_KEY = "enabled-hypervisors"
39 76fda900 Michael Hanselmann
_VCLUSTER_MASTER_KEY = "vcluster-master"
40 76fda900 Michael Hanselmann
_VCLUSTER_BASEDIR_KEY = "vcluster-basedir"
41 2dae8d64 Helga Velroyen
_ENABLED_DISK_TEMPLATES_KEY = "enabled-disk-templates"
42 f9329a6c Michael Hanselmann
43 8a96c5a6 Michael Hanselmann
#: QA configuration (L{_QaConfig})
44 8a96c5a6 Michael Hanselmann
_config = None
45 cec9845c Michael Hanselmann
46 cec9845c Michael Hanselmann
47 6a654276 Michael Hanselmann
class _QaInstance(object):
48 6a654276 Michael Hanselmann
  __slots__ = [
49 6a654276 Michael Hanselmann
    "name",
50 6a654276 Michael Hanselmann
    "nicmac",
51 2176724e Michael Hanselmann
    "_used",
52 02a5fe0e Michael Hanselmann
    "_disk_template",
53 6a654276 Michael Hanselmann
    ]
54 6a654276 Michael Hanselmann
55 6a654276 Michael Hanselmann
  def __init__(self, name, nicmac):
56 6a654276 Michael Hanselmann
    """Initializes instances of this class.
57 6a654276 Michael Hanselmann

58 6a654276 Michael Hanselmann
    """
59 6a654276 Michael Hanselmann
    self.name = name
60 6a654276 Michael Hanselmann
    self.nicmac = nicmac
61 2176724e Michael Hanselmann
    self._used = None
62 02a5fe0e Michael Hanselmann
    self._disk_template = None
63 6a654276 Michael Hanselmann
64 6a654276 Michael Hanselmann
  @classmethod
65 6a654276 Michael Hanselmann
  def FromDict(cls, data):
66 6a654276 Michael Hanselmann
    """Creates instance object from JSON dictionary.
67 6a654276 Michael Hanselmann

68 6a654276 Michael Hanselmann
    """
69 6a654276 Michael Hanselmann
    nicmac = []
70 6a654276 Michael Hanselmann
71 6a654276 Michael Hanselmann
    macaddr = data.get("nic.mac/0")
72 6a654276 Michael Hanselmann
    if macaddr:
73 6a654276 Michael Hanselmann
      nicmac.append(macaddr)
74 6a654276 Michael Hanselmann
75 6a654276 Michael Hanselmann
    return cls(name=data["name"], nicmac=nicmac)
76 6a654276 Michael Hanselmann
77 e80edd3b Michael Hanselmann
  def __repr__(self):
78 e80edd3b Michael Hanselmann
    status = [
79 e80edd3b Michael Hanselmann
      "%s.%s" % (self.__class__.__module__, self.__class__.__name__),
80 e80edd3b Michael Hanselmann
      "name=%s" % self.name,
81 e80edd3b Michael Hanselmann
      "nicmac=%s" % self.nicmac,
82 e80edd3b Michael Hanselmann
      "used=%s" % self._used,
83 e80edd3b Michael Hanselmann
      "disk_template=%s" % self._disk_template,
84 e80edd3b Michael Hanselmann
      ]
85 e80edd3b Michael Hanselmann
86 e80edd3b Michael Hanselmann
    return "<%s at %#x>" % (" ".join(status), id(self))
87 e80edd3b Michael Hanselmann
88 2176724e Michael Hanselmann
  def Use(self):
89 2176724e Michael Hanselmann
    """Marks instance as being in use.
90 2176724e Michael Hanselmann

91 2176724e Michael Hanselmann
    """
92 2176724e Michael Hanselmann
    assert not self._used
93 2176724e Michael Hanselmann
    assert self._disk_template is None
94 2176724e Michael Hanselmann
95 2176724e Michael Hanselmann
    self._used = True
96 2176724e Michael Hanselmann
97 6f88e076 Michael Hanselmann
  def Release(self):
98 6f88e076 Michael Hanselmann
    """Releases instance and makes it available again.
99 6f88e076 Michael Hanselmann

100 6f88e076 Michael Hanselmann
    """
101 2176724e Michael Hanselmann
    assert self._used, \
102 6f88e076 Michael Hanselmann
      ("Instance '%s' was never acquired or released more than once" %
103 6f88e076 Michael Hanselmann
       self.name)
104 6f88e076 Michael Hanselmann
105 2176724e Michael Hanselmann
    self._used = False
106 02a5fe0e Michael Hanselmann
    self._disk_template = None
107 6f88e076 Michael Hanselmann
108 6a654276 Michael Hanselmann
  def GetNicMacAddr(self, idx, default):
109 6a654276 Michael Hanselmann
    """Returns MAC address for NIC.
110 6a654276 Michael Hanselmann

111 6a654276 Michael Hanselmann
    @type idx: int
112 6a654276 Michael Hanselmann
    @param idx: NIC index
113 6a654276 Michael Hanselmann
    @param default: Default value
114 6a654276 Michael Hanselmann

115 6a654276 Michael Hanselmann
    """
116 6a654276 Michael Hanselmann
    if len(self.nicmac) > idx:
117 6a654276 Michael Hanselmann
      return self.nicmac[idx]
118 6a654276 Michael Hanselmann
    else:
119 6a654276 Michael Hanselmann
      return default
120 6a654276 Michael Hanselmann
121 02a5fe0e Michael Hanselmann
  def SetDiskTemplate(self, template):
122 02a5fe0e Michael Hanselmann
    """Set the disk template.
123 02a5fe0e Michael Hanselmann

124 02a5fe0e Michael Hanselmann
    """
125 02a5fe0e Michael Hanselmann
    assert template in constants.DISK_TEMPLATES
126 02a5fe0e Michael Hanselmann
127 02a5fe0e Michael Hanselmann
    self._disk_template = template
128 02a5fe0e Michael Hanselmann
129 02a5fe0e Michael Hanselmann
  @property
130 2176724e Michael Hanselmann
  def used(self):
131 2176724e Michael Hanselmann
    """Returns boolean denoting whether instance is in use.
132 2176724e Michael Hanselmann

133 2176724e Michael Hanselmann
    """
134 2176724e Michael Hanselmann
    return self._used
135 2176724e Michael Hanselmann
136 2176724e Michael Hanselmann
  @property
137 02a5fe0e Michael Hanselmann
  def disk_template(self):
138 02a5fe0e Michael Hanselmann
    """Returns the current disk template.
139 02a5fe0e Michael Hanselmann

140 02a5fe0e Michael Hanselmann
    """
141 02a5fe0e Michael Hanselmann
    return self._disk_template
142 02a5fe0e Michael Hanselmann
143 6a654276 Michael Hanselmann
144 dbdb0594 Michael Hanselmann
class _QaNode(object):
145 dbdb0594 Michael Hanselmann
  __slots__ = [
146 dbdb0594 Michael Hanselmann
    "primary",
147 dbdb0594 Michael Hanselmann
    "secondary",
148 dbdb0594 Michael Hanselmann
    "_added",
149 565cb4bf Michael Hanselmann
    "_use_count",
150 dbdb0594 Michael Hanselmann
    ]
151 dbdb0594 Michael Hanselmann
152 dbdb0594 Michael Hanselmann
  def __init__(self, primary, secondary):
153 dbdb0594 Michael Hanselmann
    """Initializes instances of this class.
154 dbdb0594 Michael Hanselmann

155 dbdb0594 Michael Hanselmann
    """
156 dbdb0594 Michael Hanselmann
    self.primary = primary
157 dbdb0594 Michael Hanselmann
    self.secondary = secondary
158 dbdb0594 Michael Hanselmann
    self._added = False
159 565cb4bf Michael Hanselmann
    self._use_count = 0
160 dbdb0594 Michael Hanselmann
161 dbdb0594 Michael Hanselmann
  @classmethod
162 dbdb0594 Michael Hanselmann
  def FromDict(cls, data):
163 dbdb0594 Michael Hanselmann
    """Creates node object from JSON dictionary.
164 dbdb0594 Michael Hanselmann

165 dbdb0594 Michael Hanselmann
    """
166 dbdb0594 Michael Hanselmann
    return cls(primary=data["primary"], secondary=data.get("secondary"))
167 dbdb0594 Michael Hanselmann
168 e80edd3b Michael Hanselmann
  def __repr__(self):
169 e80edd3b Michael Hanselmann
    status = [
170 e80edd3b Michael Hanselmann
      "%s.%s" % (self.__class__.__module__, self.__class__.__name__),
171 e80edd3b Michael Hanselmann
      "primary=%s" % self.primary,
172 e80edd3b Michael Hanselmann
      "secondary=%s" % self.secondary,
173 e80edd3b Michael Hanselmann
      "added=%s" % self._added,
174 e80edd3b Michael Hanselmann
      "use_count=%s" % self._use_count,
175 e80edd3b Michael Hanselmann
      ]
176 e80edd3b Michael Hanselmann
177 e80edd3b Michael Hanselmann
    return "<%s at %#x>" % (" ".join(status), id(self))
178 e80edd3b Michael Hanselmann
179 dbdb0594 Michael Hanselmann
  def Use(self):
180 dbdb0594 Michael Hanselmann
    """Marks a node as being in use.
181 dbdb0594 Michael Hanselmann

182 dbdb0594 Michael Hanselmann
    """
183 565cb4bf Michael Hanselmann
    assert self._use_count >= 0
184 dbdb0594 Michael Hanselmann
185 565cb4bf Michael Hanselmann
    self._use_count += 1
186 dbdb0594 Michael Hanselmann
187 dbdb0594 Michael Hanselmann
    return self
188 dbdb0594 Michael Hanselmann
189 565cb4bf Michael Hanselmann
  def Release(self):
190 565cb4bf Michael Hanselmann
    """Release a node (opposite of L{Use}).
191 565cb4bf Michael Hanselmann

192 565cb4bf Michael Hanselmann
    """
193 565cb4bf Michael Hanselmann
    assert self.use_count > 0
194 565cb4bf Michael Hanselmann
195 565cb4bf Michael Hanselmann
    self._use_count -= 1
196 565cb4bf Michael Hanselmann
197 dbdb0594 Michael Hanselmann
  def MarkAdded(self):
198 dbdb0594 Michael Hanselmann
    """Marks node as having been added to a cluster.
199 dbdb0594 Michael Hanselmann

200 dbdb0594 Michael Hanselmann
    """
201 dbdb0594 Michael Hanselmann
    assert not self._added
202 dbdb0594 Michael Hanselmann
    self._added = True
203 dbdb0594 Michael Hanselmann
204 dbdb0594 Michael Hanselmann
  def MarkRemoved(self):
205 dbdb0594 Michael Hanselmann
    """Marks node as having been removed from a cluster.
206 dbdb0594 Michael Hanselmann

207 dbdb0594 Michael Hanselmann
    """
208 dbdb0594 Michael Hanselmann
    assert self._added
209 dbdb0594 Michael Hanselmann
    self._added = False
210 dbdb0594 Michael Hanselmann
211 dbdb0594 Michael Hanselmann
  @property
212 dbdb0594 Michael Hanselmann
  def added(self):
213 dbdb0594 Michael Hanselmann
    """Returns whether a node is part of a cluster.
214 dbdb0594 Michael Hanselmann

215 dbdb0594 Michael Hanselmann
    """
216 dbdb0594 Michael Hanselmann
    return self._added
217 dbdb0594 Michael Hanselmann
218 565cb4bf Michael Hanselmann
  @property
219 565cb4bf Michael Hanselmann
  def use_count(self):
220 565cb4bf Michael Hanselmann
    """Returns number of current uses (controlled by L{Use} and L{Release}).
221 565cb4bf Michael Hanselmann

222 565cb4bf Michael Hanselmann
    """
223 565cb4bf Michael Hanselmann
    return self._use_count
224 565cb4bf Michael Hanselmann
225 dbdb0594 Michael Hanselmann
226 6a654276 Michael Hanselmann
_RESOURCE_CONVERTER = {
227 6a654276 Michael Hanselmann
  "instances": _QaInstance.FromDict,
228 dbdb0594 Michael Hanselmann
  "nodes": _QaNode.FromDict,
229 6a654276 Michael Hanselmann
  }
230 6a654276 Michael Hanselmann
231 6a654276 Michael Hanselmann
232 6a654276 Michael Hanselmann
def _ConvertResources((key, value)):
233 6a654276 Michael Hanselmann
  """Converts cluster resources in configuration to Python objects.
234 6a654276 Michael Hanselmann

235 6a654276 Michael Hanselmann
  """
236 6a654276 Michael Hanselmann
  fn = _RESOURCE_CONVERTER.get(key, None)
237 6a654276 Michael Hanselmann
  if fn:
238 6a654276 Michael Hanselmann
    return (key, map(fn, value))
239 6a654276 Michael Hanselmann
  else:
240 6a654276 Michael Hanselmann
    return (key, value)
241 6a654276 Michael Hanselmann
242 6a654276 Michael Hanselmann
243 8a96c5a6 Michael Hanselmann
class _QaConfig(object):
244 8a96c5a6 Michael Hanselmann
  def __init__(self, data):
245 8a96c5a6 Michael Hanselmann
    """Initializes instances of this class.
246 cec9845c Michael Hanselmann

247 8a96c5a6 Michael Hanselmann
    """
248 8a96c5a6 Michael Hanselmann
    self._data = data
249 8a96c5a6 Michael Hanselmann
250 a08e181f Michael Hanselmann
    #: Cluster-wide run-time value of the exclusive storage flag
251 a08e181f Michael Hanselmann
    self._exclusive_storage = None
252 a08e181f Michael Hanselmann
253 8a96c5a6 Michael Hanselmann
  @classmethod
254 8a96c5a6 Michael Hanselmann
  def Load(cls, filename):
255 8a96c5a6 Michael Hanselmann
    """Loads a configuration file and produces a configuration object.
256 8a96c5a6 Michael Hanselmann

257 8a96c5a6 Michael Hanselmann
    @type filename: string
258 8a96c5a6 Michael Hanselmann
    @param filename: Path to configuration file
259 8a96c5a6 Michael Hanselmann
    @rtype: L{_QaConfig}
260 8a96c5a6 Michael Hanselmann

261 8a96c5a6 Michael Hanselmann
    """
262 8a96c5a6 Michael Hanselmann
    data = serializer.LoadJson(utils.ReadFile(filename))
263 8a96c5a6 Michael Hanselmann
264 6a654276 Michael Hanselmann
    result = cls(dict(map(_ConvertResources,
265 6a654276 Michael Hanselmann
                          data.items()))) # pylint: disable=E1103
266 8a96c5a6 Michael Hanselmann
    result.Validate()
267 8a96c5a6 Michael Hanselmann
268 8a96c5a6 Michael Hanselmann
    return result
269 8a96c5a6 Michael Hanselmann
270 8a96c5a6 Michael Hanselmann
  def Validate(self):
271 8a96c5a6 Michael Hanselmann
    """Validates loaded configuration data.
272 8a96c5a6 Michael Hanselmann

273 8a96c5a6 Michael Hanselmann
    """
274 47aa6ec9 Michael Hanselmann
    if not self.get("name"):
275 47aa6ec9 Michael Hanselmann
      raise qa_error.Error("Cluster name is required")
276 47aa6ec9 Michael Hanselmann
277 8a96c5a6 Michael Hanselmann
    if not self.get("nodes"):
278 8a96c5a6 Michael Hanselmann
      raise qa_error.Error("Need at least one node")
279 8a96c5a6 Michael Hanselmann
280 8a96c5a6 Michael Hanselmann
    if not self.get("instances"):
281 8a96c5a6 Michael Hanselmann
      raise qa_error.Error("Need at least one instance")
282 8a96c5a6 Michael Hanselmann
283 090128b6 Christos Stavrakakis
    disks = self.GetDiskOptions()
284 090128b6 Christos Stavrakakis
    if disks is None:
285 090128b6 Christos Stavrakakis
      raise qa_error.Error("Config option 'disks' must exist")
286 090128b6 Christos Stavrakakis
    else:
287 090128b6 Christos Stavrakakis
      for d in disks:
288 090128b6 Christos Stavrakakis
        if d.get("size") is None or d.get("growth") is None:
289 090128b6 Christos Stavrakakis
          raise qa_error.Error("Config options `size` and `growth` must exist"
290 090128b6 Christos Stavrakakis
                               " for all `disks` items")
291 8a96c5a6 Michael Hanselmann
    check = self.GetInstanceCheckScript()
292 8a96c5a6 Michael Hanselmann
    if check:
293 8a96c5a6 Michael Hanselmann
      try:
294 8a96c5a6 Michael Hanselmann
        os.stat(check)
295 8a96c5a6 Michael Hanselmann
      except EnvironmentError, err:
296 8a96c5a6 Michael Hanselmann
        raise qa_error.Error("Can't find instance check script '%s': %s" %
297 8a96c5a6 Michael Hanselmann
                             (check, err))
298 8a96c5a6 Michael Hanselmann
299 8a96c5a6 Michael Hanselmann
    enabled_hv = frozenset(self.GetEnabledHypervisors())
300 8a96c5a6 Michael Hanselmann
    if not enabled_hv:
301 8a96c5a6 Michael Hanselmann
      raise qa_error.Error("No hypervisor is enabled")
302 8a96c5a6 Michael Hanselmann
303 8a96c5a6 Michael Hanselmann
    difference = enabled_hv - constants.HYPER_TYPES
304 8a96c5a6 Michael Hanselmann
    if difference:
305 8a96c5a6 Michael Hanselmann
      raise qa_error.Error("Unknown hypervisor(s) enabled: %s" %
306 8a96c5a6 Michael Hanselmann
                           utils.CommaJoin(difference))
307 8a96c5a6 Michael Hanselmann
308 76fda900 Michael Hanselmann
    (vc_master, vc_basedir) = self.GetVclusterSettings()
309 76fda900 Michael Hanselmann
    if bool(vc_master) != bool(vc_basedir):
310 76fda900 Michael Hanselmann
      raise qa_error.Error("All or none of the config options '%s' and '%s'"
311 76fda900 Michael Hanselmann
                           " must be set" %
312 76fda900 Michael Hanselmann
                           (_VCLUSTER_MASTER_KEY, _VCLUSTER_BASEDIR_KEY))
313 76fda900 Michael Hanselmann
314 76fda900 Michael Hanselmann
    if vc_basedir and not utils.IsNormAbsPath(vc_basedir):
315 76fda900 Michael Hanselmann
      raise qa_error.Error("Path given in option '%s' must be absolute and"
316 76fda900 Michael Hanselmann
                           " normalized" % _VCLUSTER_BASEDIR_KEY)
317 76fda900 Michael Hanselmann
318 8a96c5a6 Michael Hanselmann
  def __getitem__(self, name):
319 8a96c5a6 Michael Hanselmann
    """Returns configuration value.
320 8a96c5a6 Michael Hanselmann

321 8a96c5a6 Michael Hanselmann
    @type name: string
322 8a96c5a6 Michael Hanselmann
    @param name: Name of configuration entry
323 8a96c5a6 Michael Hanselmann

324 8a96c5a6 Michael Hanselmann
    """
325 8a96c5a6 Michael Hanselmann
    return self._data[name]
326 8a96c5a6 Michael Hanselmann
327 8a96c5a6 Michael Hanselmann
  def get(self, name, default=None):
328 8a96c5a6 Michael Hanselmann
    """Returns configuration value.
329 8a96c5a6 Michael Hanselmann

330 8a96c5a6 Michael Hanselmann
    @type name: string
331 8a96c5a6 Michael Hanselmann
    @param name: Name of configuration entry
332 8a96c5a6 Michael Hanselmann
    @param default: Default value
333 8a96c5a6 Michael Hanselmann

334 8a96c5a6 Michael Hanselmann
    """
335 8a96c5a6 Michael Hanselmann
    return self._data.get(name, default)
336 cec9845c Michael Hanselmann
337 8a96c5a6 Michael Hanselmann
  def GetMasterNode(self):
338 8a96c5a6 Michael Hanselmann
    """Returns the default master node for the cluster.
339 cec9845c Michael Hanselmann

340 8a96c5a6 Michael Hanselmann
    """
341 8a96c5a6 Michael Hanselmann
    return self["nodes"][0]
342 8a96c5a6 Michael Hanselmann
343 8a96c5a6 Michael Hanselmann
  def GetInstanceCheckScript(self):
344 8a96c5a6 Michael Hanselmann
    """Returns path to instance check script or C{None}.
345 8a96c5a6 Michael Hanselmann

346 8a96c5a6 Michael Hanselmann
    """
347 8a96c5a6 Michael Hanselmann
    return self._data.get(_INSTANCE_CHECK_KEY, None)
348 cec9845c Michael Hanselmann
349 8a96c5a6 Michael Hanselmann
  def GetEnabledHypervisors(self):
350 8a96c5a6 Michael Hanselmann
    """Returns list of enabled hypervisors.
351 cec9845c Michael Hanselmann

352 8a96c5a6 Michael Hanselmann
    @rtype: list
353 cec9845c Michael Hanselmann

354 8a96c5a6 Michael Hanselmann
    """
355 dacd8ba4 Helga Velroyen
    return self._GetStringListParameter(
356 dacd8ba4 Helga Velroyen
      _ENABLED_HV_KEY,
357 dacd8ba4 Helga Velroyen
      [constants.DEFAULT_ENABLED_HYPERVISOR])
358 dacd8ba4 Helga Velroyen
359 dacd8ba4 Helga Velroyen
  def GetDefaultHypervisor(self):
360 dacd8ba4 Helga Velroyen
    """Returns the default hypervisor to be used.
361 dacd8ba4 Helga Velroyen

362 dacd8ba4 Helga Velroyen
    """
363 dacd8ba4 Helga Velroyen
    return self.GetEnabledHypervisors()[0]
364 dacd8ba4 Helga Velroyen
365 2dae8d64 Helga Velroyen
  def GetEnabledDiskTemplates(self):
366 2dae8d64 Helga Velroyen
    """Returns the list of enabled disk templates.
367 dacd8ba4 Helga Velroyen

368 dacd8ba4 Helga Velroyen
    @rtype: list
369 dacd8ba4 Helga Velroyen

370 dacd8ba4 Helga Velroyen
    """
371 dacd8ba4 Helga Velroyen
    return self._GetStringListParameter(
372 2dae8d64 Helga Velroyen
      _ENABLED_DISK_TEMPLATES_KEY,
373 decf86f9 Helga Velroyen
      constants.DEFAULT_ENABLED_DISK_TEMPLATES)
374 dacd8ba4 Helga Velroyen
375 2dae8d64 Helga Velroyen
  def GetDefaultDiskTemplate(self):
376 2dae8d64 Helga Velroyen
    """Returns the default disk template to be used.
377 dacd8ba4 Helga Velroyen

378 dacd8ba4 Helga Velroyen
    """
379 2dae8d64 Helga Velroyen
    return self.GetEnabledDiskTemplates()[0]
380 dacd8ba4 Helga Velroyen
381 dacd8ba4 Helga Velroyen
  def _GetStringListParameter(self, key, default_values):
382 dacd8ba4 Helga Velroyen
    """Retrieves a parameter's value that is supposed to be a list of strings.
383 dacd8ba4 Helga Velroyen

384 dacd8ba4 Helga Velroyen
    @rtype: list
385 dacd8ba4 Helga Velroyen

386 dacd8ba4 Helga Velroyen
    """
387 c9e05005 Michael Hanselmann
    try:
388 dacd8ba4 Helga Velroyen
      value = self._data[key]
389 8a96c5a6 Michael Hanselmann
    except KeyError:
390 dacd8ba4 Helga Velroyen
      return default_values
391 8a96c5a6 Michael Hanselmann
    else:
392 8a96c5a6 Michael Hanselmann
      if value is None:
393 8a96c5a6 Michael Hanselmann
        return []
394 8a96c5a6 Michael Hanselmann
      elif isinstance(value, basestring):
395 8a96c5a6 Michael Hanselmann
        return value.split(",")
396 8a96c5a6 Michael Hanselmann
      else:
397 8a96c5a6 Michael Hanselmann
        return value
398 8a96c5a6 Michael Hanselmann
399 a08e181f Michael Hanselmann
  def SetExclusiveStorage(self, value):
400 a08e181f Michael Hanselmann
    """Set the expected value of the C{exclusive_storage} flag for the cluster.
401 a08e181f Michael Hanselmann

402 a08e181f Michael Hanselmann
    """
403 a08e181f Michael Hanselmann
    self._exclusive_storage = bool(value)
404 a08e181f Michael Hanselmann
405 a08e181f Michael Hanselmann
  def GetExclusiveStorage(self):
406 a08e181f Michael Hanselmann
    """Get the expected value of the C{exclusive_storage} flag for the cluster.
407 a08e181f Michael Hanselmann

408 a08e181f Michael Hanselmann
    """
409 a08e181f Michael Hanselmann
    value = self._exclusive_storage
410 a08e181f Michael Hanselmann
    assert value is not None
411 a08e181f Michael Hanselmann
    return value
412 a08e181f Michael Hanselmann
413 a08e181f Michael Hanselmann
  def IsTemplateSupported(self, templ):
414 a08e181f Michael Hanselmann
    """Is the given disk template supported by the current configuration?
415 a08e181f Michael Hanselmann

416 a08e181f Michael Hanselmann
    """
417 02cff8aa Bernardo Dal Seno
    enabled = templ in self.GetEnabledDiskTemplates()
418 02cff8aa Bernardo Dal Seno
    return enabled and (not self.GetExclusiveStorage() or
419 02cff8aa Bernardo Dal Seno
                        templ in constants.DTS_EXCL_STORAGE)
420 a08e181f Michael Hanselmann
421 345d395d Bernardo Dal Seno
  def AreSpindlesSupported(self):
422 345d395d Bernardo Dal Seno
    """Are spindles supported by the current configuration?
423 345d395d Bernardo Dal Seno

424 345d395d Bernardo Dal Seno
    """
425 345d395d Bernardo Dal Seno
    return self.GetExclusiveStorage()
426 345d395d Bernardo Dal Seno
427 76fda900 Michael Hanselmann
  def GetVclusterSettings(self):
428 76fda900 Michael Hanselmann
    """Returns settings for virtual cluster.
429 76fda900 Michael Hanselmann

430 76fda900 Michael Hanselmann
    """
431 76fda900 Michael Hanselmann
    master = self.get(_VCLUSTER_MASTER_KEY)
432 76fda900 Michael Hanselmann
    basedir = self.get(_VCLUSTER_BASEDIR_KEY)
433 76fda900 Michael Hanselmann
434 76fda900 Michael Hanselmann
    return (master, basedir)
435 76fda900 Michael Hanselmann
436 090128b6 Christos Stavrakakis
  def GetDiskOptions(self):
437 090128b6 Christos Stavrakakis
    """Return options for the disks of the instances.
438 090128b6 Christos Stavrakakis

439 090128b6 Christos Stavrakakis
    Get 'disks' parameter from the configuration data. If 'disks' is missing,
440 090128b6 Christos Stavrakakis
    try to create it from the legacy 'disk' and 'disk-growth' parameters.
441 090128b6 Christos Stavrakakis

442 090128b6 Christos Stavrakakis
    """
443 090128b6 Christos Stavrakakis
    try:
444 090128b6 Christos Stavrakakis
      return self._data["disks"]
445 090128b6 Christos Stavrakakis
    except KeyError:
446 090128b6 Christos Stavrakakis
      pass
447 090128b6 Christos Stavrakakis
448 090128b6 Christos Stavrakakis
    # Legacy interface
449 090128b6 Christos Stavrakakis
    sizes = self._data.get("disk")
450 090128b6 Christos Stavrakakis
    growths = self._data.get("disk-growth")
451 090128b6 Christos Stavrakakis
    if sizes or growths:
452 090128b6 Christos Stavrakakis
      if (sizes is None or growths is None or len(sizes) != len(growths)):
453 090128b6 Christos Stavrakakis
        raise qa_error.Error("Config options 'disk' and 'disk-growth' must"
454 090128b6 Christos Stavrakakis
                             " exist and have the same number of items")
455 090128b6 Christos Stavrakakis
      disks = []
456 090128b6 Christos Stavrakakis
      for (size, growth) in zip(sizes, growths):
457 090128b6 Christos Stavrakakis
        disks.append({"size": size, "growth": growth})
458 090128b6 Christos Stavrakakis
      return disks
459 090128b6 Christos Stavrakakis
    else:
460 090128b6 Christos Stavrakakis
      return None
461 090128b6 Christos Stavrakakis
462 8a96c5a6 Michael Hanselmann
463 8a96c5a6 Michael Hanselmann
def Load(path):
464 8a96c5a6 Michael Hanselmann
  """Loads the passed configuration file.
465 8a96c5a6 Michael Hanselmann

466 8a96c5a6 Michael Hanselmann
  """
467 8a96c5a6 Michael Hanselmann
  global _config # pylint: disable=W0603
468 8a96c5a6 Michael Hanselmann
469 8a96c5a6 Michael Hanselmann
  _config = _QaConfig.Load(path)
470 c9e05005 Michael Hanselmann
471 e7b6183b Michael Hanselmann
472 8a96c5a6 Michael Hanselmann
def GetConfig():
473 8a96c5a6 Michael Hanselmann
  """Returns the configuration object.
474 8a96c5a6 Michael Hanselmann

475 8a96c5a6 Michael Hanselmann
  """
476 8a96c5a6 Michael Hanselmann
  if _config is None:
477 8a96c5a6 Michael Hanselmann
    raise RuntimeError("Configuration not yet loaded")
478 8a96c5a6 Michael Hanselmann
479 8a96c5a6 Michael Hanselmann
  return _config
480 e7b6183b Michael Hanselmann
481 cec9845c Michael Hanselmann
482 cec9845c Michael Hanselmann
def get(name, default=None):
483 8a96c5a6 Michael Hanselmann
  """Wrapper for L{_QaConfig.get}.
484 8a96c5a6 Michael Hanselmann

485 8a96c5a6 Michael Hanselmann
  """
486 8a96c5a6 Michael Hanselmann
  return GetConfig().get(name, default=default)
487 cec9845c Michael Hanselmann
488 cec9845c Michael Hanselmann
489 a0c3e726 Michael Hanselmann
class Either:
490 a0c3e726 Michael Hanselmann
  def __init__(self, tests):
491 a0c3e726 Michael Hanselmann
    """Initializes this class.
492 a0c3e726 Michael Hanselmann

493 a0c3e726 Michael Hanselmann
    @type tests: list or string
494 a0c3e726 Michael Hanselmann
    @param tests: List of test names
495 a0c3e726 Michael Hanselmann
    @see: L{TestEnabled} for details
496 a0c3e726 Michael Hanselmann

497 a0c3e726 Michael Hanselmann
    """
498 a0c3e726 Michael Hanselmann
    self.tests = tests
499 a0c3e726 Michael Hanselmann
500 a0c3e726 Michael Hanselmann
501 a0c3e726 Michael Hanselmann
def _MakeSequence(value):
502 a0c3e726 Michael Hanselmann
  """Make sequence of single argument.
503 a0c3e726 Michael Hanselmann

504 a0c3e726 Michael Hanselmann
  If the single argument is not already a list or tuple, a list with the
505 a0c3e726 Michael Hanselmann
  argument as a single item is returned.
506 a0c3e726 Michael Hanselmann

507 a0c3e726 Michael Hanselmann
  """
508 a0c3e726 Michael Hanselmann
  if isinstance(value, (list, tuple)):
509 a0c3e726 Michael Hanselmann
    return value
510 a0c3e726 Michael Hanselmann
  else:
511 a0c3e726 Michael Hanselmann
    return [value]
512 a0c3e726 Michael Hanselmann
513 a0c3e726 Michael Hanselmann
514 a0c3e726 Michael Hanselmann
def _TestEnabledInner(check_fn, names, fn):
515 a0c3e726 Michael Hanselmann
  """Evaluate test conditions.
516 a0c3e726 Michael Hanselmann

517 a0c3e726 Michael Hanselmann
  @type check_fn: callable
518 a0c3e726 Michael Hanselmann
  @param check_fn: Callback to check whether a test is enabled
519 a0c3e726 Michael Hanselmann
  @type names: sequence or string
520 a0c3e726 Michael Hanselmann
  @param names: Test name(s)
521 a0c3e726 Michael Hanselmann
  @type fn: callable
522 a0c3e726 Michael Hanselmann
  @param fn: Aggregation function
523 a0c3e726 Michael Hanselmann
  @rtype: bool
524 a0c3e726 Michael Hanselmann
  @return: Whether test is enabled
525 a0c3e726 Michael Hanselmann

526 a0c3e726 Michael Hanselmann
  """
527 a0c3e726 Michael Hanselmann
  names = _MakeSequence(names)
528 a0c3e726 Michael Hanselmann
529 a0c3e726 Michael Hanselmann
  result = []
530 a0c3e726 Michael Hanselmann
531 a0c3e726 Michael Hanselmann
  for name in names:
532 a0c3e726 Michael Hanselmann
    if isinstance(name, Either):
533 a0c3e726 Michael Hanselmann
      value = _TestEnabledInner(check_fn, name.tests, compat.any)
534 a0c3e726 Michael Hanselmann
    elif isinstance(name, (list, tuple)):
535 a0c3e726 Michael Hanselmann
      value = _TestEnabledInner(check_fn, name, compat.all)
536 c072e788 Michael Hanselmann
    elif callable(name):
537 c072e788 Michael Hanselmann
      value = name()
538 a0c3e726 Michael Hanselmann
    else:
539 a0c3e726 Michael Hanselmann
      value = check_fn(name)
540 a0c3e726 Michael Hanselmann
541 a0c3e726 Michael Hanselmann
    result.append(value)
542 a0c3e726 Michael Hanselmann
543 a0c3e726 Michael Hanselmann
  return fn(result)
544 a0c3e726 Michael Hanselmann
545 a0c3e726 Michael Hanselmann
546 a0c3e726 Michael Hanselmann
def TestEnabled(tests, _cfg=None):
547 7d88f255 Iustin Pop
  """Returns True if the given tests are enabled.
548 7d88f255 Iustin Pop

549 a0c3e726 Michael Hanselmann
  @param tests: A single test as a string, or a list of tests to check; can
550 a0c3e726 Michael Hanselmann
    contain L{Either} for OR conditions, AND is default
551 1010ec70 Michael Hanselmann

552 1010ec70 Michael Hanselmann
  """
553 a0c3e726 Michael Hanselmann
  if _cfg is None:
554 8a96c5a6 Michael Hanselmann
    cfg = GetConfig()
555 8a96c5a6 Michael Hanselmann
  else:
556 8a96c5a6 Michael Hanselmann
    cfg = _cfg
557 59a8fe48 Michael Hanselmann
558 59a8fe48 Michael Hanselmann
  # Get settings for all tests
559 8a96c5a6 Michael Hanselmann
  cfg_tests = cfg.get("tests", {})
560 59a8fe48 Michael Hanselmann
561 59a8fe48 Michael Hanselmann
  # Get default setting
562 a0c3e726 Michael Hanselmann
  default = cfg_tests.get("default", True)
563 59a8fe48 Michael Hanselmann
564 a0c3e726 Michael Hanselmann
  return _TestEnabledInner(lambda name: cfg_tests.get(name, default),
565 a0c3e726 Michael Hanselmann
                           tests, compat.all)
566 cec9845c Michael Hanselmann
567 cec9845c Michael Hanselmann
568 8a96c5a6 Michael Hanselmann
def GetInstanceCheckScript(*args):
569 8a96c5a6 Michael Hanselmann
  """Wrapper for L{_QaConfig.GetInstanceCheckScript}.
570 c9e05005 Michael Hanselmann

571 c9e05005 Michael Hanselmann
  """
572 8a96c5a6 Michael Hanselmann
  return GetConfig().GetInstanceCheckScript(*args)
573 c9e05005 Michael Hanselmann
574 e7b6183b Michael Hanselmann
575 8a96c5a6 Michael Hanselmann
def GetEnabledHypervisors(*args):
576 8a96c5a6 Michael Hanselmann
  """Wrapper for L{_QaConfig.GetEnabledHypervisors}.
577 e7b6183b Michael Hanselmann

578 e7b6183b Michael Hanselmann
  """
579 8a96c5a6 Michael Hanselmann
  return GetConfig().GetEnabledHypervisors(*args)
580 e7b6183b Michael Hanselmann
581 e7b6183b Michael Hanselmann
582 8a96c5a6 Michael Hanselmann
def GetDefaultHypervisor(*args):
583 8a96c5a6 Michael Hanselmann
  """Wrapper for L{_QaConfig.GetDefaultHypervisor}.
584 e7b6183b Michael Hanselmann

585 e7b6183b Michael Hanselmann
  """
586 8a96c5a6 Michael Hanselmann
  return GetConfig().GetDefaultHypervisor(*args)
587 dacd8ba4 Helga Velroyen
588 dacd8ba4 Helga Velroyen
589 2dae8d64 Helga Velroyen
def GetEnabledDiskTemplates(*args):
590 2dae8d64 Helga Velroyen
  """Wrapper for L{_QaConfig.GetEnabledDiskTemplates}.
591 dacd8ba4 Helga Velroyen

592 dacd8ba4 Helga Velroyen
  """
593 2dae8d64 Helga Velroyen
  return GetConfig().GetEnabledDiskTemplates(*args)
594 dacd8ba4 Helga Velroyen
595 dacd8ba4 Helga Velroyen
596 2dae8d64 Helga Velroyen
def GetDefaultDiskTemplate(*args):
597 2dae8d64 Helga Velroyen
  """Wrapper for L{_QaConfig.GetDefaultDiskTemplate}.
598 dacd8ba4 Helga Velroyen

599 dacd8ba4 Helga Velroyen
  """
600 2dae8d64 Helga Velroyen
  return GetConfig().GetDefaultDiskTemplate(*args)
601 e7b6183b Michael Hanselmann
602 e7b6183b Michael Hanselmann
603 cec9845c Michael Hanselmann
def GetMasterNode():
604 8a96c5a6 Michael Hanselmann
  """Wrapper for L{_QaConfig.GetMasterNode}.
605 8a96c5a6 Michael Hanselmann

606 8a96c5a6 Michael Hanselmann
  """
607 8a96c5a6 Michael Hanselmann
  return GetConfig().GetMasterNode()
608 cec9845c Michael Hanselmann
609 cec9845c Michael Hanselmann
610 6a654276 Michael Hanselmann
def AcquireInstance(_cfg=None):
611 cec9845c Michael Hanselmann
  """Returns an instance which isn't in use.
612 cec9845c Michael Hanselmann

613 cec9845c Michael Hanselmann
  """
614 6a654276 Michael Hanselmann
  if _cfg is None:
615 6a654276 Michael Hanselmann
    cfg = GetConfig()
616 6a654276 Michael Hanselmann
  else:
617 6a654276 Michael Hanselmann
    cfg = _cfg
618 6a654276 Michael Hanselmann
619 cec9845c Michael Hanselmann
  # Filter out unwanted instances
620 6a654276 Michael Hanselmann
  instances = filter(lambda inst: not inst.used, cfg["instances"])
621 cec9845c Michael Hanselmann
622 6a654276 Michael Hanselmann
  if not instances:
623 cec9845c Michael Hanselmann
    raise qa_error.OutOfInstancesError("No instances left")
624 cec9845c Michael Hanselmann
625 2176724e Michael Hanselmann
  instance = instances[0]
626 2176724e Michael Hanselmann
  instance.Use()
627 6a654276 Michael Hanselmann
628 2176724e Michael Hanselmann
  return instance
629 cec9845c Michael Hanselmann
630 cec9845c Michael Hanselmann
631 6a0f22e1 Bernardo Dal Seno
def SetExclusiveStorage(value):
632 a08e181f Michael Hanselmann
  """Wrapper for L{_QaConfig.SetExclusiveStorage}.
633 6a0f22e1 Bernardo Dal Seno

634 6a0f22e1 Bernardo Dal Seno
  """
635 a08e181f Michael Hanselmann
  return GetConfig().SetExclusiveStorage(value)
636 6a0f22e1 Bernardo Dal Seno
637 6a0f22e1 Bernardo Dal Seno
638 6a0f22e1 Bernardo Dal Seno
def GetExclusiveStorage():
639 a08e181f Michael Hanselmann
  """Wrapper for L{_QaConfig.GetExclusiveStorage}.
640 6a0f22e1 Bernardo Dal Seno

641 6a0f22e1 Bernardo Dal Seno
  """
642 a08e181f Michael Hanselmann
  return GetConfig().GetExclusiveStorage()
643 6a0f22e1 Bernardo Dal Seno
644 6a0f22e1 Bernardo Dal Seno
645 27eba428 Bernardo Dal Seno
def IsTemplateSupported(templ):
646 02cff8aa Bernardo Dal Seno
  """Wrapper for L{_QaConfig.IsTemplateSupported}.
647 27eba428 Bernardo Dal Seno

648 27eba428 Bernardo Dal Seno
  """
649 a08e181f Michael Hanselmann
  return GetConfig().IsTemplateSupported(templ)
650 27eba428 Bernardo Dal Seno
651 27eba428 Bernardo Dal Seno
652 345d395d Bernardo Dal Seno
def AreSpindlesSupported():
653 345d395d Bernardo Dal Seno
  """Wrapper for L{_QaConfig.AreSpindlesSupported}.
654 345d395d Bernardo Dal Seno

655 345d395d Bernardo Dal Seno
  """
656 345d395d Bernardo Dal Seno
  return GetConfig().AreSpindlesSupported()
657 345d395d Bernardo Dal Seno
658 345d395d Bernardo Dal Seno
659 41be279f Michael Hanselmann
def _NodeSortKey(node):
660 41be279f Michael Hanselmann
  """Returns sort key for a node.
661 41be279f Michael Hanselmann

662 41be279f Michael Hanselmann
  @type node: L{_QaNode}
663 41be279f Michael Hanselmann

664 41be279f Michael Hanselmann
  """
665 41be279f Michael Hanselmann
  return (node.use_count, utils.NiceSortKey(node.primary))
666 41be279f Michael Hanselmann
667 41be279f Michael Hanselmann
668 dbdb0594 Michael Hanselmann
def AcquireNode(exclude=None, _cfg=None):
669 cec9845c Michael Hanselmann
  """Returns the least used node.
670 cec9845c Michael Hanselmann

671 cec9845c Michael Hanselmann
  """
672 dbdb0594 Michael Hanselmann
  if _cfg is None:
673 dbdb0594 Michael Hanselmann
    cfg = GetConfig()
674 dbdb0594 Michael Hanselmann
  else:
675 dbdb0594 Michael Hanselmann
    cfg = _cfg
676 dbdb0594 Michael Hanselmann
677 dbdb0594 Michael Hanselmann
  master = cfg.GetMasterNode()
678 cec9845c Michael Hanselmann
679 cec9845c Michael Hanselmann
  # Filter out unwanted nodes
680 cec9845c Michael Hanselmann
  # TODO: Maybe combine filters
681 cec9845c Michael Hanselmann
  if exclude is None:
682 d0c8c01d Iustin Pop
    nodes = cfg["nodes"][:]
683 4b62db14 Michael Hanselmann
  elif isinstance(exclude, (list, tuple)):
684 d0c8c01d Iustin Pop
    nodes = filter(lambda node: node not in exclude, cfg["nodes"])
685 cec9845c Michael Hanselmann
  else:
686 d0c8c01d Iustin Pop
    nodes = filter(lambda node: node != exclude, cfg["nodes"])
687 cec9845c Michael Hanselmann
688 dbdb0594 Michael Hanselmann
  nodes = filter(lambda node: node.added or node == master, nodes)
689 cec9845c Michael Hanselmann
690 dbdb0594 Michael Hanselmann
  if not nodes:
691 cec9845c Michael Hanselmann
    raise qa_error.OutOfNodesError("No nodes left")
692 cec9845c Michael Hanselmann
693 41be279f Michael Hanselmann
  # Return node with least number of uses
694 41be279f Michael Hanselmann
  return sorted(nodes, key=_NodeSortKey)[0].Use()
695 cec9845c Michael Hanselmann
696 cec9845c Michael Hanselmann
697 7d4f1b45 Bernardo Dal Seno
def AcquireManyNodes(num, exclude=None):
698 7d4f1b45 Bernardo Dal Seno
  """Return the least used nodes.
699 7d4f1b45 Bernardo Dal Seno

700 7d4f1b45 Bernardo Dal Seno
  @type num: int
701 7d4f1b45 Bernardo Dal Seno
  @param num: Number of nodes; can be 0.
702 7d4f1b45 Bernardo Dal Seno
  @type exclude: list of nodes or C{None}
703 7d4f1b45 Bernardo Dal Seno
  @param exclude: nodes to be excluded from the choice
704 7d4f1b45 Bernardo Dal Seno
  @rtype: list of nodes
705 7d4f1b45 Bernardo Dal Seno
  @return: C{num} different nodes
706 7d4f1b45 Bernardo Dal Seno

707 7d4f1b45 Bernardo Dal Seno
  """
708 7d4f1b45 Bernardo Dal Seno
  nodes = []
709 7d4f1b45 Bernardo Dal Seno
  if exclude is None:
710 7d4f1b45 Bernardo Dal Seno
    exclude = []
711 7d4f1b45 Bernardo Dal Seno
  elif isinstance(exclude, (list, tuple)):
712 7d4f1b45 Bernardo Dal Seno
    # Don't modify the incoming argument
713 7d4f1b45 Bernardo Dal Seno
    exclude = list(exclude)
714 7d4f1b45 Bernardo Dal Seno
  else:
715 7d4f1b45 Bernardo Dal Seno
    exclude = [exclude]
716 7d4f1b45 Bernardo Dal Seno
717 7d4f1b45 Bernardo Dal Seno
  try:
718 7d4f1b45 Bernardo Dal Seno
    for _ in range(0, num):
719 7d4f1b45 Bernardo Dal Seno
      n = AcquireNode(exclude=exclude)
720 7d4f1b45 Bernardo Dal Seno
      nodes.append(n)
721 7d4f1b45 Bernardo Dal Seno
      exclude.append(n)
722 7d4f1b45 Bernardo Dal Seno
  except qa_error.OutOfNodesError:
723 7d4f1b45 Bernardo Dal Seno
    ReleaseManyNodes(nodes)
724 7d4f1b45 Bernardo Dal Seno
    raise
725 7d4f1b45 Bernardo Dal Seno
  return nodes
726 7d4f1b45 Bernardo Dal Seno
727 7d4f1b45 Bernardo Dal Seno
728 7d4f1b45 Bernardo Dal Seno
def ReleaseManyNodes(nodes):
729 565cb4bf Michael Hanselmann
  for node in nodes:
730 565cb4bf Michael Hanselmann
    node.Release()
731 76fda900 Michael Hanselmann
732 76fda900 Michael Hanselmann
733 76fda900 Michael Hanselmann
def GetVclusterSettings():
734 76fda900 Michael Hanselmann
  """Wrapper for L{_QaConfig.GetVclusterSettings}.
735 76fda900 Michael Hanselmann

736 76fda900 Michael Hanselmann
  """
737 76fda900 Michael Hanselmann
  return GetConfig().GetVclusterSettings()
738 76fda900 Michael Hanselmann
739 76fda900 Michael Hanselmann
740 76fda900 Michael Hanselmann
def UseVirtualCluster(_cfg=None):
741 76fda900 Michael Hanselmann
  """Returns whether a virtual cluster is used.
742 76fda900 Michael Hanselmann

743 76fda900 Michael Hanselmann
  @rtype: bool
744 76fda900 Michael Hanselmann

745 76fda900 Michael Hanselmann
  """
746 76fda900 Michael Hanselmann
  if _cfg is None:
747 76fda900 Michael Hanselmann
    cfg = GetConfig()
748 76fda900 Michael Hanselmann
  else:
749 76fda900 Michael Hanselmann
    cfg = _cfg
750 76fda900 Michael Hanselmann
751 76fda900 Michael Hanselmann
  (master, _) = cfg.GetVclusterSettings()
752 76fda900 Michael Hanselmann
753 76fda900 Michael Hanselmann
  return bool(master)
754 76fda900 Michael Hanselmann
755 76fda900 Michael Hanselmann
756 76fda900 Michael Hanselmann
@ht.WithDesc("No virtual cluster")
757 76fda900 Michael Hanselmann
def NoVirtualCluster():
758 76fda900 Michael Hanselmann
  """Used to disable tests for virtual clusters.
759 76fda900 Michael Hanselmann

760 76fda900 Michael Hanselmann
  """
761 76fda900 Michael Hanselmann
  return not UseVirtualCluster()
762 090128b6 Christos Stavrakakis
763 090128b6 Christos Stavrakakis
764 090128b6 Christos Stavrakakis
def GetDiskOptions():
765 090128b6 Christos Stavrakakis
  """Wrapper for L{_QaConfig.GetDiskOptions}.
766 090128b6 Christos Stavrakakis

767 090128b6 Christos Stavrakakis
  """
768 090128b6 Christos Stavrakakis
  return GetConfig().GetDiskOptions()