Statistics
| Branch: | Tag: | Revision:

root / qa / qa_config.py @ 5d831182

History | View | Annotate | Download (2.9 kB)

1
#
2
#
3

    
4
# Copyright (C) 2007 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
import simplejson
28

    
29
import qa_error
30

    
31

    
32
cfg = None
33
options = None
34

    
35

    
36
def Load(path):
37
  """Loads the passed configuration file.
38

39
  """
40
  global cfg
41

    
42
  f = open(path, 'r')
43
  try:
44
    cfg = simplejson.load(f)
45
  finally:
46
    f.close()
47

    
48
  Validate()
49

    
50

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

    
60

    
61
def get(name, default=None):
62
  return cfg.get(name, default)
63

    
64

    
65
def TestEnabled(test):
66
  """Returns True if the given test is enabled."""
67
  return cfg.get('tests', {}).get(test, False)
68

    
69

    
70
def GetMasterNode():
71
  return cfg['nodes'][0]
72

    
73

    
74
def AcquireInstance():
75
  """Returns an instance which isn't in use.
76

77
  """
78
  # Filter out unwanted instances
79
  tmp_flt = lambda inst: not inst.get('_used', False)
80
  instances = filter(tmp_flt, cfg['instances'])
81
  del tmp_flt
82

    
83
  if len(instances) == 0:
84
    raise qa_error.OutOfInstancesError("No instances left")
85

    
86
  inst = instances[0]
87
  inst['_used'] = True
88
  return inst
89

    
90

    
91
def ReleaseInstance(inst):
92
  inst['_used'] = False
93

    
94

    
95
def AcquireNode(exclude=None):
96
  """Returns the least used node.
97

98
  """
99
  master = GetMasterNode()
100

    
101
  # Filter out unwanted nodes
102
  # TODO: Maybe combine filters
103
  if exclude is None:
104
    nodes = cfg['nodes'][:]
105
  elif isinstance(exclude, (list, tuple)):
106
    nodes = filter(lambda node: node not in exclude, cfg['nodes'])
107
  else:
108
    nodes = filter(lambda node: node != exclude, cfg['nodes'])
109

    
110
  tmp_flt = lambda node: node.get('_added', False) or node == master
111
  nodes = filter(tmp_flt, nodes)
112
  del tmp_flt
113

    
114
  if len(nodes) == 0:
115
    raise qa_error.OutOfNodesError("No nodes left")
116

    
117
  # Get node with least number of uses
118
  def compare(a, b):
119
    result = cmp(a.get('_count', 0), b.get('_count', 0))
120
    if result == 0:
121
      result = cmp(a['primary'], b['primary'])
122
    return result
123

    
124
  nodes.sort(cmp=compare)
125

    
126
  node = nodes[0]
127
  node['_count'] = node.get('_count', 0) + 1
128
  return node
129

    
130

    
131
def ReleaseNode(node):
132
  node['_count'] = node.get('_count', 0) - 1