Statistics
| Branch: | Tag: | Revision:

root / qa / qa_config.py @ 69a15dd7

History | View | Annotate | Download (3.3 kB)

1
#
2
#
3

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

    
21

    
22
"""QA configuration.
23

24
"""
25

    
26

    
27
from ganeti import utils
28
from ganeti import serializer
29
from ganeti import compat
30

    
31
import qa_error
32

    
33

    
34
cfg = None
35
options = None
36

    
37

    
38
def Load(path):
39
  """Loads the passed configuration file.
40

41
  """
42
  global cfg # pylint: disable=W0603
43

    
44
  cfg = serializer.LoadJson(utils.ReadFile(path))
45

    
46
  Validate()
47

    
48

    
49
def Validate():
50
  if len(cfg["nodes"]) < 1:
51
    raise qa_error.Error("Need at least one node")
52
  if len(cfg["instances"]) < 1:
53
    raise qa_error.Error("Need at least one instance")
54
  if len(cfg["disk"]) != len(cfg["disk-growth"]):
55
    raise qa_error.Error("Config options 'disk' and 'disk-growth' must have"
56
                         " the same number of items")
57

    
58

    
59
def get(name, default=None):
60
  return cfg.get(name, default)
61

    
62

    
63
def TestEnabled(tests):
64
  """Returns True if the given tests are enabled.
65

66
  @param tests: a single test, or a list of tests to check
67

68
  """
69
  if isinstance(tests, basestring):
70
    tests = [tests]
71

    
72
  # Get settings for all tests
73
  all_tests = cfg.get("tests", {})
74

    
75
  # Get default setting
76
  default = all_tests.get("default", True)
77

    
78
  return compat.all(all_tests.get(name, default) for name in tests)
79

    
80

    
81
def GetMasterNode():
82
  return cfg["nodes"][0]
83

    
84

    
85
def AcquireInstance():
86
  """Returns an instance which isn't in use.
87

88
  """
89
  # Filter out unwanted instances
90
  tmp_flt = lambda inst: not inst.get("_used", False)
91
  instances = filter(tmp_flt, cfg["instances"])
92
  del tmp_flt
93

    
94
  if len(instances) == 0:
95
    raise qa_error.OutOfInstancesError("No instances left")
96

    
97
  inst = instances[0]
98
  inst["_used"] = True
99
  return inst
100

    
101

    
102
def ReleaseInstance(inst):
103
  inst["_used"] = False
104

    
105

    
106
def AcquireNode(exclude=None):
107
  """Returns the least used node.
108

109
  """
110
  master = GetMasterNode()
111

    
112
  # Filter out unwanted nodes
113
  # TODO: Maybe combine filters
114
  if exclude is None:
115
    nodes = cfg["nodes"][:]
116
  elif isinstance(exclude, (list, tuple)):
117
    nodes = filter(lambda node: node not in exclude, cfg["nodes"])
118
  else:
119
    nodes = filter(lambda node: node != exclude, cfg["nodes"])
120

    
121
  tmp_flt = lambda node: node.get("_added", False) or node == master
122
  nodes = filter(tmp_flt, nodes)
123
  del tmp_flt
124

    
125
  if len(nodes) == 0:
126
    raise qa_error.OutOfNodesError("No nodes left")
127

    
128
  # Get node with least number of uses
129
  def compare(a, b):
130
    result = cmp(a.get("_count", 0), b.get("_count", 0))
131
    if result == 0:
132
      result = cmp(a["primary"], b["primary"])
133
    return result
134

    
135
  nodes.sort(cmp=compare)
136

    
137
  node = nodes[0]
138
  node["_count"] = node.get("_count", 0) + 1
139
  return node
140

    
141

    
142
def ReleaseNode(node):
143
  node["_count"] = node.get("_count", 0) - 1