Statistics
| Branch: | Tag: | Revision:

root / qa / qa_config.py @ 8fada090

History | View | Annotate | Download (16.8 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 76fda900 Michael Hanselmann
  def GetVclusterSettings(self):
422 76fda900 Michael Hanselmann
    """Returns settings for virtual cluster.
423 76fda900 Michael Hanselmann

424 76fda900 Michael Hanselmann
    """
425 76fda900 Michael Hanselmann
    master = self.get(_VCLUSTER_MASTER_KEY)
426 76fda900 Michael Hanselmann
    basedir = self.get(_VCLUSTER_BASEDIR_KEY)
427 76fda900 Michael Hanselmann
428 76fda900 Michael Hanselmann
    return (master, basedir)
429 76fda900 Michael Hanselmann
430 090128b6 Christos Stavrakakis
  def GetDiskOptions(self):
431 090128b6 Christos Stavrakakis
    """Return options for the disks of the instances.
432 090128b6 Christos Stavrakakis

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

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

460 8a96c5a6 Michael Hanselmann
  """
461 8a96c5a6 Michael Hanselmann
  global _config # pylint: disable=W0603
462 8a96c5a6 Michael Hanselmann
463 8a96c5a6 Michael Hanselmann
  _config = _QaConfig.Load(path)
464 c9e05005 Michael Hanselmann
465 e7b6183b Michael Hanselmann
466 8a96c5a6 Michael Hanselmann
def GetConfig():
467 8a96c5a6 Michael Hanselmann
  """Returns the configuration object.
468 8a96c5a6 Michael Hanselmann

469 8a96c5a6 Michael Hanselmann
  """
470 8a96c5a6 Michael Hanselmann
  if _config is None:
471 8a96c5a6 Michael Hanselmann
    raise RuntimeError("Configuration not yet loaded")
472 8a96c5a6 Michael Hanselmann
473 8a96c5a6 Michael Hanselmann
  return _config
474 e7b6183b Michael Hanselmann
475 cec9845c Michael Hanselmann
476 cec9845c Michael Hanselmann
def get(name, default=None):
477 8a96c5a6 Michael Hanselmann
  """Wrapper for L{_QaConfig.get}.
478 8a96c5a6 Michael Hanselmann

479 8a96c5a6 Michael Hanselmann
  """
480 8a96c5a6 Michael Hanselmann
  return GetConfig().get(name, default=default)
481 cec9845c Michael Hanselmann
482 cec9845c Michael Hanselmann
483 a0c3e726 Michael Hanselmann
class Either:
484 a0c3e726 Michael Hanselmann
  def __init__(self, tests):
485 a0c3e726 Michael Hanselmann
    """Initializes this class.
486 a0c3e726 Michael Hanselmann

487 a0c3e726 Michael Hanselmann
    @type tests: list or string
488 a0c3e726 Michael Hanselmann
    @param tests: List of test names
489 a0c3e726 Michael Hanselmann
    @see: L{TestEnabled} for details
490 a0c3e726 Michael Hanselmann

491 a0c3e726 Michael Hanselmann
    """
492 a0c3e726 Michael Hanselmann
    self.tests = tests
493 a0c3e726 Michael Hanselmann
494 a0c3e726 Michael Hanselmann
495 a0c3e726 Michael Hanselmann
def _MakeSequence(value):
496 a0c3e726 Michael Hanselmann
  """Make sequence of single argument.
497 a0c3e726 Michael Hanselmann

498 a0c3e726 Michael Hanselmann
  If the single argument is not already a list or tuple, a list with the
499 a0c3e726 Michael Hanselmann
  argument as a single item is returned.
500 a0c3e726 Michael Hanselmann

501 a0c3e726 Michael Hanselmann
  """
502 a0c3e726 Michael Hanselmann
  if isinstance(value, (list, tuple)):
503 a0c3e726 Michael Hanselmann
    return value
504 a0c3e726 Michael Hanselmann
  else:
505 a0c3e726 Michael Hanselmann
    return [value]
506 a0c3e726 Michael Hanselmann
507 a0c3e726 Michael Hanselmann
508 a0c3e726 Michael Hanselmann
def _TestEnabledInner(check_fn, names, fn):
509 a0c3e726 Michael Hanselmann
  """Evaluate test conditions.
510 a0c3e726 Michael Hanselmann

511 a0c3e726 Michael Hanselmann
  @type check_fn: callable
512 a0c3e726 Michael Hanselmann
  @param check_fn: Callback to check whether a test is enabled
513 a0c3e726 Michael Hanselmann
  @type names: sequence or string
514 a0c3e726 Michael Hanselmann
  @param names: Test name(s)
515 a0c3e726 Michael Hanselmann
  @type fn: callable
516 a0c3e726 Michael Hanselmann
  @param fn: Aggregation function
517 a0c3e726 Michael Hanselmann
  @rtype: bool
518 a0c3e726 Michael Hanselmann
  @return: Whether test is enabled
519 a0c3e726 Michael Hanselmann

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

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

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

565 c9e05005 Michael Hanselmann
  """
566 8a96c5a6 Michael Hanselmann
  return GetConfig().GetInstanceCheckScript(*args)
567 c9e05005 Michael Hanselmann
568 e7b6183b Michael Hanselmann
569 8a96c5a6 Michael Hanselmann
def GetEnabledHypervisors(*args):
570 8a96c5a6 Michael Hanselmann
  """Wrapper for L{_QaConfig.GetEnabledHypervisors}.
571 e7b6183b Michael Hanselmann

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

579 e7b6183b Michael Hanselmann
  """
580 8a96c5a6 Michael Hanselmann
  return GetConfig().GetDefaultHypervisor(*args)
581 dacd8ba4 Helga Velroyen
582 dacd8ba4 Helga Velroyen
583 2dae8d64 Helga Velroyen
def GetEnabledDiskTemplates(*args):
584 2dae8d64 Helga Velroyen
  """Wrapper for L{_QaConfig.GetEnabledDiskTemplates}.
585 dacd8ba4 Helga Velroyen

586 dacd8ba4 Helga Velroyen
  """
587 2dae8d64 Helga Velroyen
  return GetConfig().GetEnabledDiskTemplates(*args)
588 dacd8ba4 Helga Velroyen
589 dacd8ba4 Helga Velroyen
590 2dae8d64 Helga Velroyen
def GetDefaultDiskTemplate(*args):
591 2dae8d64 Helga Velroyen
  """Wrapper for L{_QaConfig.GetDefaultDiskTemplate}.
592 dacd8ba4 Helga Velroyen

593 dacd8ba4 Helga Velroyen
  """
594 2dae8d64 Helga Velroyen
  return GetConfig().GetDefaultDiskTemplate(*args)
595 e7b6183b Michael Hanselmann
596 e7b6183b Michael Hanselmann
597 cec9845c Michael Hanselmann
def GetMasterNode():
598 8a96c5a6 Michael Hanselmann
  """Wrapper for L{_QaConfig.GetMasterNode}.
599 8a96c5a6 Michael Hanselmann

600 8a96c5a6 Michael Hanselmann
  """
601 8a96c5a6 Michael Hanselmann
  return GetConfig().GetMasterNode()
602 cec9845c Michael Hanselmann
603 cec9845c Michael Hanselmann
604 6a654276 Michael Hanselmann
def AcquireInstance(_cfg=None):
605 cec9845c Michael Hanselmann
  """Returns an instance which isn't in use.
606 cec9845c Michael Hanselmann

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

628 6a0f22e1 Bernardo Dal Seno
  """
629 a08e181f Michael Hanselmann
  return GetConfig().SetExclusiveStorage(value)
630 6a0f22e1 Bernardo Dal Seno
631 6a0f22e1 Bernardo Dal Seno
632 6a0f22e1 Bernardo Dal Seno
def GetExclusiveStorage():
633 a08e181f Michael Hanselmann
  """Wrapper for L{_QaConfig.GetExclusiveStorage}.
634 6a0f22e1 Bernardo Dal Seno

635 6a0f22e1 Bernardo Dal Seno
  """
636 a08e181f Michael Hanselmann
  return GetConfig().GetExclusiveStorage()
637 6a0f22e1 Bernardo Dal Seno
638 6a0f22e1 Bernardo Dal Seno
639 27eba428 Bernardo Dal Seno
def IsTemplateSupported(templ):
640 02cff8aa Bernardo Dal Seno
  """Wrapper for L{_QaConfig.IsTemplateSupported}.
641 27eba428 Bernardo Dal Seno

642 27eba428 Bernardo Dal Seno
  """
643 a08e181f Michael Hanselmann
  return GetConfig().IsTemplateSupported(templ)
644 27eba428 Bernardo Dal Seno
645 27eba428 Bernardo Dal Seno
646 41be279f Michael Hanselmann
def _NodeSortKey(node):
647 41be279f Michael Hanselmann
  """Returns sort key for a node.
648 41be279f Michael Hanselmann

649 41be279f Michael Hanselmann
  @type node: L{_QaNode}
650 41be279f Michael Hanselmann

651 41be279f Michael Hanselmann
  """
652 41be279f Michael Hanselmann
  return (node.use_count, utils.NiceSortKey(node.primary))
653 41be279f Michael Hanselmann
654 41be279f Michael Hanselmann
655 dbdb0594 Michael Hanselmann
def AcquireNode(exclude=None, _cfg=None):
656 cec9845c Michael Hanselmann
  """Returns the least used node.
657 cec9845c Michael Hanselmann

658 cec9845c Michael Hanselmann
  """
659 dbdb0594 Michael Hanselmann
  if _cfg is None:
660 dbdb0594 Michael Hanselmann
    cfg = GetConfig()
661 dbdb0594 Michael Hanselmann
  else:
662 dbdb0594 Michael Hanselmann
    cfg = _cfg
663 dbdb0594 Michael Hanselmann
664 dbdb0594 Michael Hanselmann
  master = cfg.GetMasterNode()
665 cec9845c Michael Hanselmann
666 cec9845c Michael Hanselmann
  # Filter out unwanted nodes
667 cec9845c Michael Hanselmann
  # TODO: Maybe combine filters
668 cec9845c Michael Hanselmann
  if exclude is None:
669 d0c8c01d Iustin Pop
    nodes = cfg["nodes"][:]
670 4b62db14 Michael Hanselmann
  elif isinstance(exclude, (list, tuple)):
671 d0c8c01d Iustin Pop
    nodes = filter(lambda node: node not in exclude, cfg["nodes"])
672 cec9845c Michael Hanselmann
  else:
673 d0c8c01d Iustin Pop
    nodes = filter(lambda node: node != exclude, cfg["nodes"])
674 cec9845c Michael Hanselmann
675 dbdb0594 Michael Hanselmann
  nodes = filter(lambda node: node.added or node == master, nodes)
676 cec9845c Michael Hanselmann
677 dbdb0594 Michael Hanselmann
  if not nodes:
678 cec9845c Michael Hanselmann
    raise qa_error.OutOfNodesError("No nodes left")
679 cec9845c Michael Hanselmann
680 41be279f Michael Hanselmann
  # Return node with least number of uses
681 41be279f Michael Hanselmann
  return sorted(nodes, key=_NodeSortKey)[0].Use()
682 cec9845c Michael Hanselmann
683 cec9845c Michael Hanselmann
684 7d4f1b45 Bernardo Dal Seno
def AcquireManyNodes(num, exclude=None):
685 7d4f1b45 Bernardo Dal Seno
  """Return the least used nodes.
686 7d4f1b45 Bernardo Dal Seno

687 7d4f1b45 Bernardo Dal Seno
  @type num: int
688 7d4f1b45 Bernardo Dal Seno
  @param num: Number of nodes; can be 0.
689 7d4f1b45 Bernardo Dal Seno
  @type exclude: list of nodes or C{None}
690 7d4f1b45 Bernardo Dal Seno
  @param exclude: nodes to be excluded from the choice
691 7d4f1b45 Bernardo Dal Seno
  @rtype: list of nodes
692 7d4f1b45 Bernardo Dal Seno
  @return: C{num} different nodes
693 7d4f1b45 Bernardo Dal Seno

694 7d4f1b45 Bernardo Dal Seno
  """
695 7d4f1b45 Bernardo Dal Seno
  nodes = []
696 7d4f1b45 Bernardo Dal Seno
  if exclude is None:
697 7d4f1b45 Bernardo Dal Seno
    exclude = []
698 7d4f1b45 Bernardo Dal Seno
  elif isinstance(exclude, (list, tuple)):
699 7d4f1b45 Bernardo Dal Seno
    # Don't modify the incoming argument
700 7d4f1b45 Bernardo Dal Seno
    exclude = list(exclude)
701 7d4f1b45 Bernardo Dal Seno
  else:
702 7d4f1b45 Bernardo Dal Seno
    exclude = [exclude]
703 7d4f1b45 Bernardo Dal Seno
704 7d4f1b45 Bernardo Dal Seno
  try:
705 7d4f1b45 Bernardo Dal Seno
    for _ in range(0, num):
706 7d4f1b45 Bernardo Dal Seno
      n = AcquireNode(exclude=exclude)
707 7d4f1b45 Bernardo Dal Seno
      nodes.append(n)
708 7d4f1b45 Bernardo Dal Seno
      exclude.append(n)
709 7d4f1b45 Bernardo Dal Seno
  except qa_error.OutOfNodesError:
710 7d4f1b45 Bernardo Dal Seno
    ReleaseManyNodes(nodes)
711 7d4f1b45 Bernardo Dal Seno
    raise
712 7d4f1b45 Bernardo Dal Seno
  return nodes
713 7d4f1b45 Bernardo Dal Seno
714 7d4f1b45 Bernardo Dal Seno
715 7d4f1b45 Bernardo Dal Seno
def ReleaseManyNodes(nodes):
716 565cb4bf Michael Hanselmann
  for node in nodes:
717 565cb4bf Michael Hanselmann
    node.Release()
718 76fda900 Michael Hanselmann
719 76fda900 Michael Hanselmann
720 76fda900 Michael Hanselmann
def GetVclusterSettings():
721 76fda900 Michael Hanselmann
  """Wrapper for L{_QaConfig.GetVclusterSettings}.
722 76fda900 Michael Hanselmann

723 76fda900 Michael Hanselmann
  """
724 76fda900 Michael Hanselmann
  return GetConfig().GetVclusterSettings()
725 76fda900 Michael Hanselmann
726 76fda900 Michael Hanselmann
727 76fda900 Michael Hanselmann
def UseVirtualCluster(_cfg=None):
728 76fda900 Michael Hanselmann
  """Returns whether a virtual cluster is used.
729 76fda900 Michael Hanselmann

730 76fda900 Michael Hanselmann
  @rtype: bool
731 76fda900 Michael Hanselmann

732 76fda900 Michael Hanselmann
  """
733 76fda900 Michael Hanselmann
  if _cfg is None:
734 76fda900 Michael Hanselmann
    cfg = GetConfig()
735 76fda900 Michael Hanselmann
  else:
736 76fda900 Michael Hanselmann
    cfg = _cfg
737 76fda900 Michael Hanselmann
738 76fda900 Michael Hanselmann
  (master, _) = cfg.GetVclusterSettings()
739 76fda900 Michael Hanselmann
740 76fda900 Michael Hanselmann
  return bool(master)
741 76fda900 Michael Hanselmann
742 76fda900 Michael Hanselmann
743 76fda900 Michael Hanselmann
@ht.WithDesc("No virtual cluster")
744 76fda900 Michael Hanselmann
def NoVirtualCluster():
745 76fda900 Michael Hanselmann
  """Used to disable tests for virtual clusters.
746 76fda900 Michael Hanselmann

747 76fda900 Michael Hanselmann
  """
748 76fda900 Michael Hanselmann
  return not UseVirtualCluster()
749 090128b6 Christos Stavrakakis
750 090128b6 Christos Stavrakakis
751 090128b6 Christos Stavrakakis
def GetDiskOptions():
752 090128b6 Christos Stavrakakis
  """Wrapper for L{_QaConfig.GetDiskOptions}.
753 090128b6 Christos Stavrakakis

754 090128b6 Christos Stavrakakis
  """
755 090128b6 Christos Stavrakakis
  return GetConfig().GetDiskOptions()