Statistics
| Branch: | Tag: | Revision:

root / qa / qa_config.py @ 1010ec70

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
from ganeti import utils
28
from ganeti import serializer
29

    
30
import qa_error
31

    
32

    
33
cfg = None
34
options = None
35

    
36

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

40
  """
41
  global cfg
42

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

    
45
  Validate()
46

    
47

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

    
57

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

    
61

    
62
def TestEnabled(test):
63
  """Returns True if the given test is enabled.
64

65
  """
66
  return cfg.get("tests", {}).get(test, True)
67

    
68

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

    
72

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

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

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

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

    
89

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

    
93

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

97
  """
98
  master = GetMasterNode()
99

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

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

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

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

    
123
  nodes.sort(cmp=compare)
124

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

    
129

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